verilator-3.856/0000775000177100017500000000000012307720634013527 5ustar wsnyderwsnyderverilator-3.856/TODO0000775000177100017500000001511312306677750014234 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: List of To Do issues. // // Copyright 2004-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. 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. * Integrate SystemPerl coverage (Note in /usr/include there are no upper cased include files.) Coverage.pm -- Need all functionality, but in C? Coverage/Item.pm -- Need all functionality, but in C? Coverage/ItemKey.pm -- Need all functionality, but in C? sp_preproc -- Some steps in here need to be moved to generated C src/Sp.cpp -- n/a src/SpCommon.h -- mostly overlaps verilatedos.h src/SpCoverage.cpp/h -- All needed src/SpFunctor.cpp/h -- No longer used src/SpTraceVcd.cpp/h -- MOVED src/SpTraceVcdC.cpp/h -- MOVED src/sp_log.cpp/h -- Not needed src/systemperl.h -- some stuff may be cut vcoverage -- Need all functionality, but in C? 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 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.856/bin/0000775000177100017500000000000012307720633014276 5ustar wsnyderwsnyderverilator-3.856/bin/verilator_difftree0000775000177100017500000001532512306677750020123 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-2014 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.856/bin/verilator_profcfunc0000775000177100017500000001336712306677750020324 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; } 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(" 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("\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-2014 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.856/bin/verilator0000775000177100017500000043257112306677750016261 0ustar wsnyderwsnyder: # -*-Mode: perl;-*- use perl, wherever it is eval 'exec perl -wS $0 ${1+"$@"}' if 0; ###################################################################### # # Copyright 2003-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. # # 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 File::Path; use File::Basename; use Getopt::Long; use FindBin qw($RealBin $RealScript); use IO::File; use Pod::Usage; use Config; use Cwd qw(abs_path getcwd); 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 and Sugar/PSL assertions, into C++, SystemC or SystemPerl code. It is not a complete simulator, just 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. For SystemPerl format, it outputs .sp files for the SystemPerl preprocessor, which greatly simplifies writing SystemC code and is available at L. 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 --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 PSL/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 -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-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 --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 --psl Enable PSL parsing --public Debugging; see docs --report-unoptflat Extra diagnostics for UNOPTFLAT --savable Enable model save-restore --sc Create SystemC output --sp Create SystemPerl output --stats Create statistics file -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-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, includes enabling the --psl flag. (If psl is not desired, but other assertions are, use --assert --nopsl.) 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 and --sp. =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 --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 PSL which must be separately enabled with --psl. For example, the following PSL statement will add a coverage point, with the comment "DefaultClock": // psl default clock = posedge clk; // psl cover {cyc==9} report "DefaultClock,expect=1"; =item -DI=I Defines the given preprocessor symbol. Same as +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, debugging messages, and intermediate form dump files. =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 source file to the specified level. Higher levels produce more detailed messages (plain C<--debug> is equivalent to C<--debugi 4>). =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 Defines the given preprocessor symbol. Same as -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 Rarely needed. Enable writing .tree debug files with a specific dumping level, 0 disbles dumps and is equivelent 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-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. This 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 --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 --psl Enable PSL parsing. Without this switch, PSL meta-comments are ignored. See the --assert flag to enable all assertions, and --coverage-user to enable functional coverage. =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 analysing 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 and -sp. =item --sp Specifies SystemPerl output mode; see also --cc and -sc. =item --stats Creates a dump file with statistics on the design in {prefix}__stats.txt. =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 --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. =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-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-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 behaviour. 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 SystemPerl. 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 --sp our.v Then we convert the SystemPerl output to SystemC. cd obj_dir export SYSTEMPERL=/path/to/where/systemperl/kit/came/from $SYSTEMPERL/sp_preproc --preproc *.sp (You can also skip the above sp_preproc by getting pure SystemC from Verilator by replacing the verilator --sp flag in the previous step with -sc.) 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 # 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_sp 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. 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 For -sp mode, instead of .cpp and .h it creates: {prefix}.sp // Top level SystemC file {prefix}{each_verilog_module}.sp // Lower level internal SC 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 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 SYSTEMPERL Specifies the directory containing the SystemPerl distribution kit. This is used to find the SystemPerl library and include files. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). See also SYSTEMPERL_INCLUDE. =item SYSTEMPERL_INCLUDE Specifies the directory containing the Verilog-Perl include .cpp files, from the src/ directory of the SystemPerl kit. If not specified, it will be computed from the SYSTEMPERL environment variable if it is set, and if SYSTEMPERL is not set SYSTEMPERL_INCLUDE will come from a default optionally specified at configure time (before Verilator was compiled). =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). 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 equivelents 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 Sugar/PSL Support Most future work is being directed towards improving SystemVerilog assertions instead of PSL. If you are using these PSL features, please contact the author as they may be depreciated in future versions. With the --assert switch, Verilator enables support of the Property Specification Language (PSL), specifically the simple PSL subset without time-branching primitives. Verilator currently only converts PSL assertions to simple "if (...) error" statements, and coverage statements to increment the line counters described in the coverage section. Verilator implements these keywords: assert, assume (same as assert), default (for clocking), countones, cover, isunknown, onehot, onehot0, report, and true. Verilator implements these operators: -> (logical if). Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. PSL vmode/vprop/vunits are not supported. PSL statements must be in the module they reference, at the module level where you would put an initial... statement. Verilator only supports (posedge CLK) or (negedge CLK), where CLK is the name of a one bit signal. You may not use arbitrary expressions as assertion clocks. =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 statements. However, "unique if" and "priority if" are 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 _(I) A underline followed by an expression in parenthesis returns a Verilog expression. This is different from normal parenthesis in special contexts, such as PSL expressions, and can be used to embed bit concatenation ({}) inside of PSL statements. =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 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. SystemPerl when tracing such signals 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*/ (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. Often this is placed just after a primitive's module statement, so that the entire module is not traced. =item /*verilator tracing_on*/ Re-enable waveform tracing for all future signals 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. Unititialized 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 passed to DPI imports. =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 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 +include used on the command line to specify the top include source directory. 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 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 Error 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 error message as you would disable warnings, 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 copyright? 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. Note also older versions of Verilator used the SystemPerl package and SpTraceVcdC class. This still works, but is depreciated as it requires strong coupling between the Verilator and SystemPerl versions. #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_sp/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. Both require the SystemPerl package to be installed but do not require use of the SystemPerl output mode. First, run verilator with the --coverage option. If you're using your own makefile, compile the model with the GCC flag -DSP_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, the vcoverage utility (from the SystemPerl package) is executed. Vcoverage 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_sp/logs/coverage_source 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 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 Cavium Networks, Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems, Nauticus Networks, and SiCortex Inc. The people who have contributed major functionality are Byron Bradley, Jeremy Bennett, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers include Jeff Dutton, Ralf Karge, David Hewson, Wim Michiels, Alex Solomatnikov, Sebastien Van Cauwenberghe and Gene Weber. Some of the people who have provided ideas and feedback for Verilator include: David Addison, Vasu Arasanipalai, Jens Arm, J Baxter, Jeremy Bennett, David Black, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee, Lawrence Butcher, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike Denio, John Deroo, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic, Alex Duller, Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete, Andrea Foletto, Bob Fredieu, Shankar Giri, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Thomas Hawkins, David Hewson, Jae Hossell, Ben Jackson, Iztok Jeras, Christophe Joly, Mike Kagen, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki, David Kravitz, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber, John Li, Charlie Lind, Andrew Ling, Paul Liu, Dan Lussier, Fred Ma, Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, Dominic Plunkett, Niranjan Prabhu, Usha Priyadharshini, Alberto Del Rio, Oleg Rodionov, John Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Brian Small, Alex Solomatnikov, Art Stamness, John Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Stefan Thiede, Gary Thomas, Steve Tong, Hans Van Antwerpen, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston, Joshua Wise, Johan Wouters, and Ding Xiaoliang. Thanks to them, and all those we've missed including above. =head1 DISTRIBUTION The latest version is available from L. Copyright 2003-2014 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 When possible, please instead report bugs to L. Wilson Snyder Major concepts by Paul Wasson and Duane Galbi. =head1 SEE ALSO L, L, L, L, L which is the source for this document, and internals.txt in the distribution. =cut ###################################################################### verilator-3.856/bin/verilator_includer0000775000177100017500000000115112306677750020130 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-2014 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) { print "#include \"$param\"\n" } verilator-3.856/MANIFEST.SKIP0000664000177100017500000000067412151516723015433 0ustar wsnyderwsnyder^CVS/ /CVS/ \.git/ \.svn/ \.(bak|old)/ \.(bak|old)$ \.tar\. .*\.tgz .*\.log \..*\.swp .*\.tmp .*\.tex .*\.key .*\.vcd /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_bin.* .vcsmx_rebuild$ autom4te\.cache/ nodist/ /simv$ /simv.daidir/ /vc_hdrs.h$ /csrc/ doxygen-doc/.* TAGS .*~ verilator-3.856/verilator.10000664000177100017500000050307112307146775015636 0ustar wsnyderwsnyder.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "VERILATOR 1" .TH VERILATOR 1 "2014-03-08" "perl v5.14.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Verilator \- Convert Verilog code to C++/SystemC .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 5 \& 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]... .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Verilator converts synthesizable (not behavioral) Verilog code, plus some Synthesis, SystemVerilog and a small subset of Verilog \s-1AMS\s0 and Sugar/PSL assertions, into \*(C+, SystemC or SystemPerl code. It is not a complete simulator, just a compiler. .PP Verilator is invoked with parameters similar to \s-1GCC\s0, Cadence Verilog\-XL/NC\-Verilog, or Synopsys's \s-1VCS\s0. 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. For SystemPerl format, it outputs .sp files for the SystemPerl preprocessor, which greatly simplifies writing SystemC code and is available at . .PP 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. .PP The resulting executable will perform the actual simulation. .PP To get started, jump down to \*(L"\s-1EXAMPLE\s0 \*(C+ \s-1EXECUTION\s0\*(R". .SH "ARGUMENT SUMMARY" .IX Header "ARGUMENT SUMMARY" This is a short summary of the arguments to Verilator. See the detailed descriptions in the next sections for more information. .PP .Vb 3 \& {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 \& \-\-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 PSL/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 \& \-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\-pins64 Don\*(Aqt use vluint64_t\*(Aqs 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 \& \-\-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 \& \-\-psl Enable PSL parsing \& \-\-public Debugging; see docs \& \-\-report\-unoptflat Extra diagnostics for UNOPTFLAT \& \-\-savable Enable model save\-restore \& \-\-sc Create SystemC output \& \-\-sp Create SystemPerl output \& \-\-stats Create statistics file \& \-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\-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 .Ve .SH "ARGUMENTS" .IX Header "ARGUMENTS" .IP "{file.v}" 4 .IX Item "{file.v}" Specifies the Verilog file containing the top module to be Verilated. .IP "{file.c/.cc/.cpp/.cxx}" 4 .IX 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 \fImodule\fR executable. Without any \*(C+ files, Verilator will stop at the \fImodule\fR_\|_ALL.a library, and presume you'll continue linking with make rules you write yourself. See also the \-CFLAGS option. .IP "{file.a/.o/.so}" 4 .IX Item "{file.a/.o/.so}" Specifies optional object or library files to be linked in with the Verilog code, as a shorthand for \-LDFLAGS \*(L"\*(R". If any files are specified in this way, Verilator will include a make rule that uses these files when linking the \fImodule\fR executable. This generally is only useful when used with the \-\-exe option. .IP "+1364\-1995ext+\fIext\fR" 4 .IX Item "+1364-1995ext+ext" .PD 0 .IP "+1364\-2001ext+\fIext\fR" 4 .IX Item "+1364-2001ext+ext" .IP "+1364\-2005ext+\fIext\fR" 4 .IX Item "+1364-2005ext+ext" .IP "+1800\-2005ext+\fIext\fR" 4 .IX Item "+1800-2005ext+ext" .IP "+1800\-2009ext+\fIext\fR" 4 .IX Item "+1800-2009ext+ext" .IP "+1800\-2012ext+\fIext\fR" 4 .IX Item "+1800-2012ext+ext" .PD Specifies the language standard to be used with a specific filename extension, \fIext\fR. .Sp For compatibility with other simulators, see also the synonyms \&\f(CW\*(C`+verilog1995ext+\*(C'\fR\fIext\fR, \f(CW\*(C`+verilog2001ext+\*(C'\fR\fIext\fR, and \&\f(CW\*(C`+systemverilogext+\*(C'\fR\fIext\fR. .Sp For any source file, the language specified by these options takes precedence over any language specified by the \f(CW\*(C`\-\-default\-language\*(C'\fR or \&\f(CW\*(C`\-\-language\*(C'\fR options. .Sp These options take effect in the order they are encountered. Thus the following would use Verilog 1995 for \f(CW\*(C`a.v\*(C'\fR and Verilog 2001 for \f(CW\*(C`b.v\*(C'\fR. .Sp .Vb 1 \& verilator ... +1364\-1995ext+v a.v +1364\-2001ext+v b.v .Ve .Sp 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 \f(CW\*(C`\`begin_keywords\*(C'\fR. .Sp \&\fBNote\fR \f(CW\*(C`\`begin_keywords\*(C'\fR is a SystemVerilog construct, which specifies \&\fIonly\fR which the set of keywords is to be recognized. Whatever set is chosen, the semantics will be those of SystemVerilog. By contrast \&\f(CW\*(C`+1364\-1995ext+\*(C'\fR etc. specify both the syntax \fIand\fR semantics to be used. .IP "\-\-assert" 4 .IX Item "--assert" Enable all assertions, includes enabling the \-\-psl flag. (If psl is not desired, but other assertions are, use \-\-assert \-\-nopsl.) .Sp See also \-\-x\-assign and \-\-x\-initial\-edge; setting \*(L"\-\-x\-assign unique\*(R" and/or \*(L"\-\-x\-initial\-edge\*(R" may be desirable. .IP "\-\-autoflush" 4 .IX Item "--autoflush" After every \f(CW$display\fR or \f(CW$fdisplay\fR, flush the output stream. This insures that messages will appear immediately but may reduce performance; for best performance call \*(L"fflush(stdout)\*(R" occasionally in the main C loop. Defaults off, which will buffer output as provided by the normal C stdio calls. .IP "\-\-bbox\-sys" 4 .IX Item "--bbox-sys" Black box any unknown \f(CW$system\fR 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 \s-1PLI\s0 calls. .IP "\-\-bbox\-unsup" 4 .IX Item "--bbox-unsup" Black box some unsupported language features, currently \s-1UDP\s0 tables and the cmos and tran gate primitives. This may enable linting the rest of the design even when unsupported constructs are present. .IP "\-\-bin \fIfilename\fR" 4 .IX Item "--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. .IP "\-CFLAGS \fIflags\fR" 4 .IX Item "-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++). .IP "\-\-cc" 4 .IX Item "--cc" Specifies \*(C+ without SystemC output mode; see also \-\-sc and \-\-sp. .IP "\-\-cdc" 4 .IX Item "--cdc" Experimental. Perform some clock domain crossing checks and issue related warnings (\s-1CDCRSTLOGIC\s0) and then exit; if warnings other than \s-1CDC\s0 warnings are needed make a second run with \-\-lint\-only. Additional warning information is also written to the file {prefix}_\|_cdc.txt. .Sp Currently only checks some items that other \s-1CDC\s0 tools missed; if you have interest in adding more traditional \s-1CDC\s0 checks, please contact the authors. .IP "\-\-compiler \fIcompiler-name\fR" 4 .IX Item "--compiler compiler-name" Enables tunings and work-arounds for the specified \*(C+ compiler. .RS 4 .IP "clang" 4 .IX 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. .IP "gcc" 4 .IX Item "gcc" Tune for Gnu \*(C+, although generated code should work on almost any compliant \*(C+ compiler. Currently the default. .IP "msvc" 4 .IX Item "msvc" Tune for Microsoft Visual \*(C+. This may reduce execution speed as it enables several workarounds to avoid silly hardcoded limits in \s-1MSVC++\s0. This includes breaking deeply nested parenthesized expressions into sub-expressions to avoid error C1009, and breaking deep blocks into functions to avoid error C1061. .RE .RS 4 .RE .IP "\-\-converge\-limit " 4 .IX Item "--converge-limit " Rarely needed. Specifies the maximum number of runtime iterations before creating a model failed to converge error. Defaults to 100. .IP "\-\-coverage" 4 .IX Item "--coverage" Enables all forms of coverage, alias for \*(L"\-\-coverage\-line \-\-coverage\-toggle \&\-\-coverage\-user\*(R". .IP "\-\-coverage\-line" 4 .IX Item "--coverage-line" Specifies basic block line coverage analysis code should be inserted. .Sp Coverage analysis adds statements at each code flow change point, which are the branches of \s-1IF\s0 and \s-1CASE\s0 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. .Sp Verilator automatically disables coverage of branches that have a \f(CW$stop\fR in them, as it is assumed \f(CW$stop\fR 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. .Sp Note Verilator may over-count combinatorial (non-clocked) blocks when those blocks receive signals which have had the \s-1UNOPTFLAT\s0 warning disabled; for most accurate results do not disable this warning when using coverage. .IP "\-\-coverage\-toggle" 4 .IX Item "--coverage-toggle" Specifies signal toggle coverage analysis code should be inserted. .Sp Every bit of every signal in a module has a counter inserted. The counter will increment on every edge change of the corresponding bit. .Sp 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. .Sp Hierarchy is compressed, such that if a module is instantiated multiple times, coverage will be summed for that bit across \s-1ALL\s0 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. .Sp 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. .Sp 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. .Sp A /*verilator coverage_off/on */ comment pair can be used around signals that do not need toggle analysis, such as RAMs and register files. .IP "\-\-coverage\-underscore" 4 .IX Item "--coverage-underscore" Enable coverage of signals that start with an underscore. Normally, these signals are not covered. See also \-\-trace\-underscore. .IP "\-\-coverage\-user" 4 .IX Item "--coverage-user" Enables user inserted functional coverage. Currently, all functional coverage points are specified using \s-1PSL\s0 which must be separately enabled with \-\-psl. .Sp For example, the following \s-1PSL\s0 statement will add a coverage point, with the comment \*(L"DefaultClock\*(R": .Sp .Vb 2 \& // psl default clock = posedge clk; \& // psl cover {cyc==9} report "DefaultClock,expect=1"; .Ve .IP "\-D\fIvar\fR=\fIvalue\fR" 4 .IX Item "-Dvar=value" Defines the given preprocessor symbol. Same as +define; +define is fairly standard across Verilog tools while \-D is an alias for \s-1GCC\s0 compatibility. .IP "\-\-debug" 4 .IX Item "--debug" Select the debug built image of Verilator (if available), and enable more internal assertions, debugging messages, and intermediate form dump files. .IP "\-\-debug\-check" 4 .IX Item "--debug-check" Rarely needed. Enable internal debugging assertion checks, without changing debug verbosity. Enabled automatically when \-\-debug specified. .IP "\-\-debugi " 4 .IX Item "--debugi " .PD 0 .IP "\-\-debugi\- " 4 .IX Item "--debugi- " .PD Rarely needed \- for developer use. Set 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 \&\f(CW\*(C`\-\-debug\*(C'\fR is equivalent to \f(CW\*(C`\-\-debugi 4\*(C'\fR). .IP "\-\-default\-language \fIvalue\fR" 4 .IX Item "--default-language value" Select the language to be used by default when first processing each Verilog file. The language value must be \*(L"1364\-1995\*(R", \*(L"1364\-2001\*(R", \&\*(L"1364\-2005\*(R", \*(L"1800\-2005\*(R", \*(L"1800\-2009\*(R" or \*(L"1800\-2012\*(R". .Sp Any language associated with a particular file extension (see the various +\fIlang\fRext+ options) will be used in preference to the language specified by \-\-default\-language. .Sp 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 \f(CW\*(C`\`begin_keywords\*(C'\fR. For legacy mixed language designs, the various +\fIlang\fRext+ options should be used. .Sp If no language is specified, either by this flag or +\fIlang\fRext+ options, then the latest SystemVerilog language (\s-1IEEE\s0 1800\-2012) is used. .IP "+define+\fIvar\fR+\fIvalue\fR" 4 .IX Item "+define+var+value" Defines the given preprocessor symbol. Same as \-D; +define is fairly standard across Verilog tools while \-D is an alias for \s-1GCC\s0 compatibility. .IP "\-\-dump\-tree" 4 .IX 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 \*(L"\-\-debug \-\-no\-dump\-tree\*(R" may be useful if the dump files are large and not desired. .IP "\-\-dump\-treei " 4 .IX Item "--dump-treei " Rarely needed. Enable writing .tree debug files with a specific dumping level, 0 disbles dumps and is equivelent to \*(L"\-\-no\-dump\-tree\*(R". Level 9 enables dumping of every stage. .IP "\-E" 4 .IX 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. .IP "\-\-error\-limit " 4 .IX Item "--error-limit " After this number of errors or warnings are encountered, exit. Defaults to 50. .IP "\-\-exe" 4 .IX 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. .IP "\-F \fIfile\fR" 4 .IX Item "-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. .IP "\-f \fIfile\fR" 4 .IX Item "-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. .Sp The file may contain // comments which are ignored to the end of the line. Any \f(CW$VAR\fR, $(\s-1VAR\s0), or ${\s-1VAR\s0} will be replaced with the specified environment variable. .IP "\-\-gdb" 4 .IX Item "--gdb" Run Verilator underneath an interactive \s-1GDB\s0 (or \s-1VERILATOR_GDB\s0 environment variable value) session. See also \-\-gdbbt. .IP "\-\-gdbbt" 4 .IX Item "--gdbbt" If \-\-debug is specified, run Verilator underneath a \s-1GDB\s0 process and print a backtrace on exit, then exit \s-1GDB\s0 immediately. Without \-\-debug or if \s-1GDB\s0 doesn't seem to work, this flag is ignored. Intended for easy creation of backtraces by users; otherwise see the \-\-gdb flag. .IP "\-\-help" 4 .IX Item "--help" Displays this message and program version and exits. .IP "\-I\fIdir\fR" 4 .IX Item "-Idir" See \-y. .IP "\-\-if\-depth \fIvalue\fR" 4 .IX Item "--if-depth value" Rarely needed. Set the depth at which the \s-1IFDEPTH\s0 warning will fire, defaults to 0 which disables this warning. .IP "+incdir+\fIdir\fR" 4 .IX Item "+incdir+dir" See \-y. .IP "\-\-inhibit\-sim" 4 .IX Item "--inhibit-sim" Rarely needed. Create a \*(L"inhibitSim(bool)\*(R" 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. .IP "\-\-inline\-mult \fIvalue\fR" 4 .IX Item "--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. .IP "\-LDFLAGS \fIflags\fR" 4 .IX Item "-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 \s-1LDLIBS\s0 as that's the Makefile variable it controls. (In Make, \&\s-1LDFLAGS\s0 is before the first object, \s-1LDLIBS\s0 after. \-L libraries need to be in the Make variable \s-1LDLIBS\s0, not \s-1LDFLAGS\s0.) .IP "\-\-language \fIvalue\fR" 4 .IX Item "--language value" A synonym for \f(CW\*(C`\-\-default\-langauge\*(C'\fR, for compatibility with other tools and earlier versions of Verilator. .IP "+libext+\fIext\fR+\fIext\fR..." 4 .IX Item "+libext+ext+ext..." Specify the extensions that should be used for finding modules. If for example module \fIx\fR is referenced, look in \fIx\fR.\fIext\fR. Note +libext+ is fairly standard across Verilog tools. Defaults to .v and .sv. .IP "\-\-lint\-only" 4 .IX Item "--lint-only" Check the files for lint violations only, do not create any other output. .Sp You may also want the \-Wall option to enable messages that are considered stylistic and not enabled by default. .Sp If the design is not to be completely Verilated see also the \-\-bbox\-sys and \&\-\-bbox\-unsup options. .IP "\-\-MMD" 4 .IX 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. .IP "\-\-MP" 4 .IX Item "--MP" When creating .d dependency files with \-\-MMD, make phony targets. Similar to gcc \-MP option. .IP "\-\-Mdir \fIdirectory\fR" 4 .IX Item "--Mdir directory" Specifies the name of the Make object directory. All generated files will be placed in this directory. If not specified, \*(L"obj_dir\*(R" is used. The directory is created if it does not exist and the parent directories exist; otherwise manually create the Mdir before calling Verilator. .IP "\-\-mod\-prefix \fItopname\fR" 4 .IX Item "--mod-prefix topname" Specifies the name to prepend to all lower level classes. Defaults to the same as \-\-prefix. .IP "\-\-no\-pins64" 4 .IX Item "--no-pins64" Backward compatible alias for \*(L"\-\-pins\-bv 33\*(R". .IP "\-\-no\-skip\-identical" 4 .IX 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. .IP "+notimingchecks" 4 .IX Item "+notimingchecks" Ignored for compatibility with other simulators. .IP "\-O0" 4 .IX Item "-O0" Disables optimization of the model. .IP "\-O3" 4 .IX Item "-O3" Enables slow optimizations. This may reduce simulation runtimes at the cost of compile time. This currently sets \-\-inline\-mult \-1. .IP "\-O\fIoptimization-letter\fR" 4 .IX Item "-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. .IP "\-o " 4 .IX Item "-o " Specify the name for the final executable built if using \-\-exe. Defaults to the \-\-prefix if not specified. .IP "\-\-no\-order\-clock\-delay" 4 .IX 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. .IP "\-\-output\-split \fIbytes\fR" 4 .IX Item "--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 \s-1GCC\s0 3.3 on a 2GHz Opteron, \&\-\-output\-split 20000 will result in splitting into approximately one-minute-compile chunks. .IP "\-\-output\-split\-cfuncs \fIstatements\fR" 4 .IX Item "--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 \s-1GCC\s0 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. .IP "\-\-output\-split\-ctrace \fIstatements\fR" 4 .IX Item "--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. .IP "\-\-pins64" 4 .IX Item "--pins64" Backward compatible alias for \*(L"\-\-pins\-bv 65\*(R". Note that's a 65, not a 64. .IP "\-\-pins\-bv \fIwidth\fR" 4 .IX Item "--pins-bv width" Specifies SystemC inputs/outputs of greater than or equal to \fIwidth\fR bits wide should use sc_bv's instead of uint32/vluint64_t's. The default is \&\*(L"\-\-pins\-bv 65\*(R". Versions before Verilator 3.671 defaulted to \*(L"\-\-pins\-bv 33\*(R". The more sc_bv is used, the worse for performance. Use the \&\*(L"/*verilator sc_bv*/\*(R" attribute to select specific ports to be sc_bv. .IP "\-\-pins\-sc\-uint" 4 .IX 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 \*(L"\-\-pins\-sc\-biguint\*(R" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. .IP "\-\-pins\-sc\-biguint" 4 .IX 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 \*(L"\-\-pins\-sc\-uint\*(R" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. .IP "\-\-pins\-uint8" 4 .IX 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. .IP "\-\-pipe\-filter \fIcommand\fR" 4 .IX Item "--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. .Sp Before reading each Verilog file, Verilator will pass the file name to the subprocess' stdin with 'read_verilog \*(L"\*(R"'. 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. .Sp To debug the output of the filter, try using the \-E option to see preprocessed output. .IP "\-\-prefix \fItopname\fR" 4 .IX Item "--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. .IP "\-\-profile\-cfuncs" 4 .IX Item "--profile-cfuncs" Modify the created \*(C+ functions to support profiling. The functions will be minimized to contain one \*(L"basic\*(R" 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. .IP "\-\-private" 4 .IX Item "--private" Opposite of \-\-public. Is the default; this option exists for backwards compatibility. .IP "\-\-psl" 4 .IX Item "--psl" Enable \s-1PSL\s0 parsing. Without this switch, \s-1PSL\s0 meta-comments are ignored. See the \-\-assert flag to enable all assertions, and \-\-coverage\-user to enable functional coverage. .IP "\-\-public" 4 .IX Item "--public" This is only for historical debug use. Using it may result in mis-simulation of generated clocks. .Sp 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*/. .IP "\-\-report\-unoptflat" 4 .IX Item "--report-unoptflat" Extra diagnostics for \s-1UNOPTFLAT\s0 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. .Sp In addition produces a GraphViz \s-1DOT\s0 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 analysing the problem, but can be very large indeed. .Sp Various commands exist for viewing and manipulating \s-1DOT\s0 files. For example the \fIdot\fR command can be used to convert a \s-1DOT\s0 file to a \s-1PDF\s0 for printing. For example: .Sp .Vb 1 \& dot \-Tpdf \-O Vt_unoptflat_simple_2_35_unoptflat.dot .Ve .Sp will generate a \s-1PDF\s0 Vt_unoptflat_simple_2_35_unoptflat.dot.pdf from the \s-1DOT\s0 file. .IP "\-\-savable" 4 .IX Item "--savable" Enable including save and restore functions in the generated model. .Sp 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: .Sp .Vb 12 \& 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; \& } .Ve .IP "\-\-sc" 4 .IX Item "--sc" Specifies SystemC output mode; see also \-\-cc and \-sp. .IP "\-\-sp" 4 .IX Item "--sp" Specifies SystemPerl output mode; see also \-\-cc and \-sc. .IP "\-\-stats" 4 .IX Item "--stats" Creates a dump file with statistics on the design in {prefix}_\|_stats.txt. .IP "\-sv" 4 .IX Item "-sv" Specifies SystemVerilog language features should be enabled; equivalent to \&\*(L"\-\-language 1800\-2005\*(R". This option is selected by default, it exists for compatibility with other simulators. .IP "+systemverilogext+\fIext\fR" 4 .IX Item "+systemverilogext+ext" A synonym for \f(CW\*(C`+1800\-2012ext+\*(C'\fR\fIext\fR. .IP "\-\-top\-module \fItopname\fR" 4 .IX Item "--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. .IP "\-\-trace" 4 .IX 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. .Sp Having tracing compiled in may result in some small performance losses, even when waveforms are not turned on during model execution. .IP "\-\-trace\-depth \fIlevels\fR" 4 .IX Item "--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. .IP "\-\-trace\-max\-array \fIdepth\fR" 4 .IX Item "--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. .IP "\-\-trace\-max\-width \fIwidth\fR" 4 .IX Item "--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. .IP "\-\-trace\-structs" 4 .IX 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 \s-1VCD\s0 file format constraints this may result in significantly slower trace times and larger trace files. .IP "\-\-trace\-underscore" 4 .IX Item "--trace-underscore" Enable tracing of signals that start with an underscore. Normally, these signals are not output during tracing. See also \-\-coverage\-underscore. .IP "\-U\fIvar\fR" 4 .IX Item "-Uvar" Undefines the given preprocessor symbol. .IP "\-\-unroll\-count \fIloops\fR" 4 .IX Item "--unroll-count loops" Rarely needed. Specifies the maximum number of loop iterations that may be unrolled. See also \s-1BLKLOOPINIT\s0 warning. .IP "\-\-unroll\-stmts \fIstatements\fR" 4 .IX Item "--unroll-stmts statements" Rarely needed. Specifies the maximum number of statements in a loop for that loop to be unrolled. See also \s-1BLKLOOPINIT\s0 warning. .IP "\-\-unused\-regexp \fIregexp\fR" 4 .IX Item "--unused-regexp regexp" Rarely needed. Specifies a simple regexp with * and ? that if a signal name matches will suppress the \s-1UNUSED\s0 warning. Defaults to \*(L"*unused*\*(R". Setting it to "" disables matching. .IP "\-V" 4 .IX Item "-V" Shows the verbose version, including configuration information compiled into Verilator. (Similar to perl \-V.) .IP "\-v \fIfilename\fR" 4 .IX Item "-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. .IP "+verilog1995ext+\fIext\fR" 4 .IX Item "+verilog1995ext+ext" .PD 0 .IP "+verilog2001ext+\fIext\fR" 4 .IX Item "+verilog2001ext+ext" .PD Synonyms for \f(CW\*(C`+1364\-1995ext+\*(C'\fR\fIext\fR and \f(CW\*(C`+1364\-2001ext+\*(C'\fR\fIext\fR respectively .IP "\-Wall" 4 .IX Item "-Wall" Enable all warnings, including code style warnings that are normally disabled by default. .IP "\-Werror\-\fImessage\fR" 4 .IX Item "-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 \f(CW\*(C`\-Werror\-NOUNOPTFLAT\*(C'\fR. .IP "\-Wfuture\-\fImessage\fR" 4 .IX Item "-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. .IP "\-Wno\-\fImessage\fR" 4 .IX Item "-Wno-message" Disable the specified warning message. .IP "\-Wno\-lint" 4 .IX Item "-Wno-lint" Disable all lint related warning messages, and all style warnings. This is equivalent to \*(L"\-Wno\-ALWCOMBORDER \-Wno\-CASEINCOMPLETE \-Wno\-CASEOVERLAP \&\-Wno\-CASEX \-Wno\-CASEWITHX \-Wno\-CMPCONST \-Wno\-ENDLABEL \-Wno\-IMPLICIT \&\-Wno\-LITENDIAN \-Wno\-PINMISSING \-Wno\-SYNCASYNCNET \-Wno\-UNDRIVEN \&\-Wno\-UNSIGNED \-Wno\-UNUSED \-Wno\-WIDTH\*(R" plus the list shown for Wno-style. .Sp 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. .IP "\-Wno\-style" 4 .IX Item "-Wno-style" Disable all code style related warning messages (note by default they are already disabled). This is equivalent to \*(L"\-Wno\-DECLFILENAME \-Wno\-DEFPARAM \&\-Wno\-INCABSPATH \-Wno\-PINNOCONNECT \-Wno\-SYNCASYNCNET \-Wno\-UNDRIVEN \&\-Wno\-UNUSED \-Wno\-VARHIDDEN\*(R". .IP "\-Wno\-fatal" 4 .IX Item "-Wno-fatal" When warnings are detected, print them, but do not exit the simulator. .Sp 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. .IP "\-Wwarn\-\fImessage\fR" 4 .IX Item "-Wwarn-message" Enables the specified warning message. .IP "\-Wwarn\-lint" 4 .IX 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 \&\*(L"\-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\*(R". .IP "\-Wwarn\-style" 4 .IX Item "-Wwarn-style" Enable all code style related warning messages. This is equivalent to \&\*(L"\-Wwarn \s-1ASSIGNDLY\s0 \-Wwarn\-DECLFILENAME \-Wwarn\-DEFPARAM \-Wwarn\-INCABSPATH \&\-Wwarn\-PINNOCONNECT \-Wwarn\-SYNCASYNCNET \-Wwarn\-UNDRIVEN \-Wwarn\-UNUSED \&\-Wwarn\-VARHIDDEN\*(R". .IP "\-\-x\-assign 0" 4 .IX Item "--x-assign 0" .PD 0 .IP "\-\-x\-assign 1" 4 .IX Item "--x-assign 1" .IP "\-\-x\-assign fast (default)" 4 .IX Item "--x-assign fast (default)" .IP "\-\-x\-assign unique" 4 .IX Item "--x-assign unique" .PD 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. .Sp 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 \fIsrand48()\fR or for Windows \fIsrand()\fR 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. .Sp \&\fBNote.\fR 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. .IP "\-\-x\-initial\-edge" 4 .IX Item "--x-initial-edge" Enables emulation of event driven simulators which generally trigger an edge on a transition from X to 1 (\f(CW\*(C`posedge\*(C'\fR) or X to 0 (\f(CW\*(C`negedge\*(C'\fR). Thus the following code, where \f(CW\*(C`rst_n\*(C'\fR is uninitialized would set \f(CW\*(C`res_n\*(C'\fR to \&\f(CW\*(C`1\*(Aqb1\*(C'\fR when \f(CW\*(C`rst_n\*(C'\fR is first set to zero: .Sp .Vb 1 \& reg res_n = 1\*(Aqb0; \& \& always @(negedge rst_n) begin \& if (rst_n == 1\*(Aqb0) begin \& res_n <= 1\*(Aqb1; \& end \& end .Ve .Sp In Verilator, by default, uninitialized clocks are given a value of zero, so the above \f(CW\*(C`always\*(C'\fR block would not trigger. .Sp While it is not good practice, there are some designs that rely on X X 0 triggering a \f(CW\*(C`negedge\*(C'\fR, particularly in reset sequences. Using \&\-\-x\-initial\-edge with Verilator will replicate this behaviour. It will also ensure that X X 1 triggers a \f(CW\*(C`posedge\*(C'\fR. .Sp \&\fBNote.\fR 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. .IP "\-y \fIdir\fR" 4 .IX Item "-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 \s-1GCC\s0 compatibility. .Sp Verilator defaults to the current directory (\*(L"\-y .\*(R") and any specified \&\-\-Mdir, though these default paths are used after any user specified directories. This allows '\-y \*(L"$(pwd)\*(R"' to be used if absolute filenames are desired for error messages instead of relative filenames. .SH "EXAMPLE \*(C+ EXECUTION" .IX Header "EXAMPLE EXECUTION" We'll compile this example into \*(C+. .PP .Vb 2 \& 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 .Ve .PP If you installed Verilator from sources, or a tarball, but not as part of your operating system (as an \s-1RPM\s0), first you need to point to the kit: .PP .Vb 2 \& export VERILATOR_ROOT=/path/to/where/verilator/was/installed \& export PATH=$VERILATOR_ROOT/bin:$PATH .Ve .PP Now we run Verilator on our little example. .PP .Vb 1 \& verilator \-Wall \-\-cc our.v \-\-exe sim_main.cpp .Ve .PP We can see the source code under the \*(L"obj_dir\*(R" directory. See the \s-1FILES\s0 section below for descriptions of some of the files that were created. .PP .Vb 1 \& ls \-l obj_dir .Ve .PP We then can compile it .PP .Vb 2 \& cd obj_dir \& make \-j \-f Vour.mk Vour .Ve .PP (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 \s-1SYSTEMC\s0 section.) .PP And now we run it .PP .Vb 2 \& cd .. \& obj_dir/Vour .Ve .PP And we get as output .PP .Vb 2 \& Hello World \& \- our.v:2: Verilog $finish .Ve .PP 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. .SH "EXAMPLE SYSTEMC EXECUTION" .IX Header "EXAMPLE SYSTEMC EXECUTION" This is an example similar to the above, but using SystemPerl. .PP .Vb 2 \& 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 .Ve .PP If you installed Verilator from sources, or a tarball, but not as part of your operating system (as an \s-1RPM\s0), first you need to point to the kit: .PP .Vb 2 \& export VERILATOR_ROOT=/path/to/where/verilator/was/installed \& export PATH=$VERILATOR_ROOT/bin:$PATH .Ve .PP Now we run Verilator on our little example. .PP .Vb 1 \& verilator \-Wall \-\-sp our.v .Ve .PP Then we convert the SystemPerl output to SystemC. .PP .Vb 3 \& cd obj_dir \& export SYSTEMPERL=/path/to/where/systemperl/kit/came/from \& $SYSTEMPERL/sp_preproc \-\-preproc *.sp .Ve .PP (You can also skip the above sp_preproc by getting pure SystemC from Verilator by replacing the verilator \-\-sp flag in the previous step with \&\-sc.) .PP We then can compile it .PP .Vb 2 \& make \-j \-f Vour.mk Vour_\|_ALL.a \& make \-j \-f Vour.mk ../sc_main.o verilated.o .Ve .PP And link with SystemC. Note your path to the libraries may vary, depending on the operating system. .PP .Vb 3 \& export SYSTEMC_LIBDIR=/path/to/where/libsystemc.a/exists \& # 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 \e \& \-o Vour \-lsystemc .Ve .PP And now we run it .PP .Vb 2 \& cd .. \& obj_dir/Vour .Ve .PP And we get the same output as the \*(C+ example: .PP .Vb 2 \& Hello World \& \- our.v:2: Verilog $finish .Ve .PP 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_sp directory in the distribution for an example. .SH "BENCHMARKING & OPTIMIZATION" .IX Header "BENCHMARKING & OPTIMIZATION" For best performance, run Verilator with the \*(L"\-O3 \-\-x\-assign=fast \&\-\-noassert\*(R" 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. .PP Minor Verilog code changes can also give big wins. You should not have any \&\s-1UNOPTFLAT\s0 warnings from Verilator. Fixing these warnings can result in huge improvements; one user fixed their one \s-1UNOPTFLAT\s0 warning by making a simple change to a clock latch used to gate clocks and gained a 60% performance improvement. .PP Beyond that, the performance of a Verilated model depends mostly on your \&\*(C+ compiler and size of your \s-1CPU\s0's caches. .PP 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, \&\s-1OPT\s0, \s-1OPT_FAST\s0, or \s-1OPT_SLOW\s0 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: .PP .Vb 1 \& make OPT_FAST="\-O2" \-f Vour.mk Vour_\|_ALL.a .Ve .PP \&\s-1OPT_FAST\s0 specifies optimizations for those programs that are part of the fast path, mostly code that is executed every cycle. \s-1OPT_SLOW\s0 specifies optimizations for slow-path files (plus tracing), which execute only rarely, yet take a long time to compile with optimization on. \s-1OPT\s0 specifies overall optimization and affects all compiles, including those \&\s-1OPT_FAST\s0 and \s-1OPT_SLOW\s0 affect. For best results, use OPT=\*(L"\-O2\*(R", and link with \*(L"\-static\*(R". Nearly the same results can be had with much better compile times with OPT_FAST=\*(L"\-O1 \-fstrict\-aliasing\*(R". Higher optimization such as \*(L"\-O3\*(R" may help, but gcc compile times may be excessive under O3 on even medium sized designs. Alternatively, some larger designs report better performance using \*(L"\-Os\*(R". .PP 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.) .PP For best results, use \s-1GCC\s0 3.3 or newer. \s-1GCC\s0 3.2 and earlier have optimization bugs around pointer aliasing detection, which can result in 2x performance losses. .PP If you will be running many simulations on a single compile, investigate feedback driven compilation. With \s-1GCC\s0, using \-fprofile\-arcs, then \&\-fbranch\-probabilities will yield another 15% or so. .PP Modern compilers also support link-time optimization (\s-1LTO\s0), which can help especially if you link in \s-1DPI\s0 code. To enable \s-1LTO\s0 on \s-1GCC\s0, pass \*(L"\-flto\*(R" in both compilation and link. Note \s-1LTO\s0 may cause excessive compile times on large designs. .PP You may uncover further tuning possibilities by profiling the Verilog code. Use Verilator's \-\-profile\-cfuncs, then \s-1GCC\s0'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. .PP 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. .SH "FILES" .IX Header "FILES" All output files are placed in the output directory name specified with the \&\-Mdir option, or \*(L"obj_dir\*(R" if not specified. .PP Verilator creates the following files in the output directory: .PP .Vb 2 \& {prefix}.mk // Make include file for compiling \& {prefix}_classes.mk // Make include file with class names .Ve .PP For \-cc and \-sc mode, it also creates: .PP .Vb 4 \& {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 .Ve .PP For \-sp mode, instead of .cpp and .h it creates: .PP .Vb 2 \& {prefix}.sp // Top level SystemC file \& {prefix}{each_verilog_module}.sp // Lower level internal SC files .Ve .PP In certain optimization modes, it also creates: .PP .Vb 8 \& {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) .Ve .PP It also creates internal files that can be mostly ignored: .PP .Vb 7 \& {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) .Ve .PP After running Make, the \*(C+ compiler should produce the following: .PP .Vb 3 \& {prefix} // Final executable (w/\-\-exe argument) \& {prefix}_\|_ALL.a // Library of all Verilated objects \& {prefix}{misc}.o // Intermediate objects .Ve .SH "ENVIRONMENT" .IX Header "ENVIRONMENT" .IP "\s-1OBJCACHE\s0" 4 .IX Item "OBJCACHE" Optionally specifies a caching or distribution program to place in front of all runs of the \*(C+ Compiler. For example, \*(L"objcache \-\-read \-\-write\*(R", or \&\*(L"ccache\*(R". If using distcc, it would generally be run under either objcache or ccache; see the documentation for those programs. .IP "\s-1SYSTEMC\s0" 4 .IX Item "SYSTEMC" Deprecated. Used only if \s-1SYSTEMC_INCLUDE\s0 or \s-1SYSTEMC_LIBDIR\s0 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). .IP "\s-1SYSTEMC_ARCH\s0" 4 .IX Item "SYSTEMC_ARCH" Deprecated. Used only if \s-1SYSTEMC_LIBDIR\s0 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). .IP "\s-1SYSTEMC_CXX_FLAGS\s0" 4 .IX Item "SYSTEMC_CXX_FLAGS" Specifies additional flags that are required to be passed to \s-1GCC\s0 when building the SystemC model. System 2.3.0 may need this set to \*(L"\-pthread\*(R". .IP "\s-1SYSTEMC_INCLUDE\s0" 4 .IX 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. .IP "\s-1SYSTEMC_LIBDIR\s0" 4 .IX 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. .IP "\s-1SYSTEMPERL\s0" 4 .IX Item "SYSTEMPERL" Specifies the directory containing the SystemPerl distribution kit. This is used to find the SystemPerl library and include files. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). See also \s-1SYSTEMPERL_INCLUDE\s0. .IP "\s-1SYSTEMPERL_INCLUDE\s0" 4 .IX Item "SYSTEMPERL_INCLUDE" Specifies the directory containing the Verilog-Perl include .cpp files, from the src/ directory of the SystemPerl kit. If not specified, it will be computed from the \s-1SYSTEMPERL\s0 environment variable if it is set, and if \&\s-1SYSTEMPERL\s0 is not set \s-1SYSTEMPERL_INCLUDE\s0 will come from a default optionally specified at configure time (before Verilator was compiled). .IP "\s-1VCS_HOME\s0" 4 .IX Item "VCS_HOME" If set, specifies the directory containing the Synopsys \s-1VCS\s0 distribution. When set, a 'make test' in the Verilator distribution will also run \s-1VCS\s0 baseline regression tests. .IP "\s-1VERILATOR_BIN\s0" 4 .IX 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. .IP "\s-1VERILATOR_GDB\s0" 4 .IX Item "VERILATOR_GDB" If set, the command to run when using the \-\-gdb option, such as \*(L"ddd\*(R". If not specified, it will use \*(L"gdb\*(R". .IP "\s-1VERILATOR_ROOT\s0" 4 .IX 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 \s-1RPM\s0 as the hardcoded value should be correct. .SH "CONNECTING TO \*(C+" .IX Header "CONNECTING TO " 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. .PP After the modules are completed, there will be a \fImodule\fR.mk file that may be used with Make to produce a \fImodule\fR_\|_ALL.a file with all required objects in it. This is then linked with the user's top level to create the simulation executable. .PP The user must write the top level of the simulation. Here's a simple example: .PP .Vb 2 \& #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\*(Aqt get here) \& delete top; \& } .Ve .PP Note signals are read and written as member variables of the lower module. You call the \fIeval()\fR method to evaluate the model. When the simulation is complete call the \fIfinal()\fR method to wrap up any SystemVerilog final blocks, and complete any assertions. .SH "CONNECTING TO SYSTEMC" .IX Header "CONNECTING TO SYSTEMC" Verilator will convert the top level module to a \s-1SC_MODULE\s0. This module will plug directly into a SystemC netlist. .PP The \s-1SC_MODULE\s0 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.) .PP 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. .SH "DIRECT PROGRAMMING INTERFACE (DPI)" .IX Header "DIRECT PROGRAMMING INTERFACE (DPI)" Verilator supports SystemVerilog Direct Programming Interface import and export statements. Only the SystemVerilog form (\*(L"DPI-C\*(R") is supported, not the original Synopsys-only \s-1DPI\s0. .SS "\s-1DPI\s0 Example" .IX Subsection "DPI Example" In the \s-1SYSTEMC\s0 example above, if you wanted to import \*(C+ functions into Verilog, put in our.v: .PP .Vb 1 \& import "DPI\-C" function integer add (input integer a, input integer b); \& \& initial begin \& $display("%x + %x = %x", 1, 2, add(1,2)); \& endtask .Ve .PP Then after Verilating, Verilator will create a file Vour_\|_Dpi.h with the prototype to call this function: .PP .Vb 1 \& extern int add (int a, int b); .Ve .PP From the sc_main.cpp file (or another .cpp file passed to the Verilator command line, or the link), you'd then: .PP .Vb 3 \& #include "svdpi.h" \& #include "Vour_\|_Dpi.h" \& int add (int a, int b) { return a+b; } .Ve .SS "\s-1DPI\s0 System Task/Functions" .IX Subsection "DPI System Task/Functions" Verilator extends the \s-1DPI\s0 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. .PP .Vb 1 \& export "DPI\-C" function integer \e$myRand; \& \& initial $display("myRand=%d", $myRand()); .Ve .PP Going the other direction, you can export Verilog tasks so they can be called from \*(C+: .PP .Vb 1 \& export "DPI\-C" task publicSetBool; \& \& task publicSetBool; \& input bit in_bool; \& var_bool = in_bool; \& endtask .Ve .PP Then after Verilating, Verilator will create a file Vour_\|_Dpi.h with the prototype to call this function: .PP .Vb 1 \& extern bool publicSetBool(bool in_bool); .Ve .PP From the sc_main.cpp file, you'd then: .PP .Vb 2 \& #include "Vour_\|_Dpi.h" \& publicSetBool(value); .Ve .PP Or, alternatively, call the function under the design class. This isn't \&\s-1DPI\s0 compatible but is easier to read and better supports multiple designs. .PP .Vb 3 \& #include "Vour_\|_Dpi.h" \& Vour::publicSetBool(value); \& // or top\->publicSetBool(value); .Ve .PP Note that if the \s-1DPI\s0 task or function accesses any register or net within the \&\s-1RTL\s0, 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. .PP For example, if the top level module is instantiated with the name \*(L"dut\*(R" 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 .PP .Vb 3 \& #include "svdpi.h" \& ... \& svSetScope (svGetScopeFromName ("dut")); .Ve .PP (Remember that Verilator adds a \*(L"V\*(R" to the top of the module hierarchy.) .PP Scope can also be set from within a \s-1DPI\s0 imported C function that has been called from Verilog by querying the scope of that function. See the sections on \s-1DPI\s0 Context Functions and \s-1DPI\s0 Header Isolation below and the comments within the svdpi.h header for more information. .SS "\s-1DPI\s0 Display Functions" .IX Subsection "DPI Display Functions" Verilator allows writing \f(CW$display\fR like functions using this syntax: .PP .Vb 2 \& import "DPI\-C" function void \& \e$my_display (input string formatted /*verilator sformat*/ ); .Ve .PP The /*verilator sformat*/ indicates that this function accepts a \f(CW$display\fR like format specifier followed by any number of arguments to satisfy the format. .SS "\s-1DPI\s0 Context Functions" .IX Subsection "DPI Context Functions" Verilator supports \s-1IEEE\s0 \s-1DPI\s0 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: .PP .Vb 2 \& import "DPI\-C" context function int dpic_line(); \& initial $display("This is line %d, again, line %d\en", \`line, dpic_line()); .Ve .PP 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: .PP .Vb 2 \& 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\en", \& scopenamep, lineno); \& return lineno; \& } else { \& return 0; \& } \& } .Ve .PP See the \s-1IEEE\s0 Standard for more information. .SS "\s-1DPI\s0 Header Isolation" .IX Subsection "DPI Header Isolation" Verilator places the \s-1IEEE\s0 standard header files such as svdpi.h into a separate include directory, vltstd (VeriLaTor STandarD). When compiling most applications \f(CW$VERILATOR_ROOT\fR/include/vltstd would be in the include path along with the normal \f(CW$VERILATOR_ROOT\fR/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. .SS "Public Functions" .IX Subsection "Public Functions" Instead of \s-1DPI\s0 exporting, there's also Verilator public functions, which are slightly faster, but less compatible. .SH "VERIFICATION PROCEDURAL INTERFACE (VPI)" .IX Header "VERIFICATION PROCEDURAL INTERFACE (VPI)" Verilator supports a very limited subset of the \s-1VPI\s0. This subset allows inspection, examination, value change callbacks, and depositing of values to public signals only. .PP To access signals via the \s-1VPI\s0, Verilator must be told exactly which signals are to be accessed. This is done using the Verilator public pragmas documented below. .PP Verilator has an important difference from an event based simulator; signal values that are changed by the \s-1VPI\s0 will not immediately propagate their values, instead the top level header file's \fIeval()\fR method must be called. Normally this would be part of the normal evaluation (\s-1IE\s0 the next clock edge), not as part of the value change. This makes the performance of \s-1VPI\s0 routines extremely fast compared to event based simulators, but can confuse some test-benches that expect immediate propagation. .PP Note the \s-1VPI\s0 by it's specified implementation will always be much slower than accessing the Verilator values by direct reference (structure\->module\->signame), as the \s-1VPI\s0 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. .SS "\s-1VPI\s0 Example" .IX Subsection "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. .PP .Vb 4 \& module t; \& reg readme /*verilator public_flat_rd*/; \& reg writeme /*verilator public_flat_rw @(posedge clk) */; \& endmodule .Ve .PP There are many online tutorials and books on the \s-1VPI\s0, but an example that accesses the above would be: .PP void \fIread_and_check()\fR { vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)\*(L"t.readme\*(R", \s-1NULL\s0); if (!vh1) { error... } const char* name = vpi_get_str(vpiName, vh1); printf(\*(L"Module name: \f(CW%s\fR\en\*(R"); // Prints \*(L"readme\*(R" .PP .Vb 5 \& s_vpi_value v; \& v.format = vpiIntVal; \& vpi_get_value(vh1, &v); \& printf("Value of v: %d\en", v.value.integer); // Prints "readme" \&} .Ve .SH "CROSS COMPILATION" .IX Header "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. .PP 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. .PP 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. .PP 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. .PP 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. .SS "Cadence NC-SystemC Models" .IX Subsection "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.) .PP Using the example files above, the following command will build the model underneath \s-1NC:\s0 .PP .Vb 6 \& cd obj_dir \& ncsc_run \e \& sc_main.cpp \e \& Vour_\|_ALLcls.cpp \e \& Vour_\|_ALLsup.cpp \e \& verilated.cpp .Ve .PP 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. .SH "CONFIGURATION FILES" .IX Header "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: .PP .Vb 3 \& \`verilator_config \& lint_off \-msg WIDTH \& lint_off \-msg CASEX \-file "silly_vendor_code.v" .Ve .PP This disables \s-1WIDTH\s0 warnings globally, and \s-1CASEX\s0 for a specific file. .PP Configuration files are parsed after the normal Verilog preprocessing, so `ifdefs, `defines, and comments may be used as if it were normal Verilog code. .PP The grammar of configuration commands is as follows: .IP "`verilator_config" 4 .IX Item "`verilator_config" Take remaining text up the the next `verilog mode switch and treat it as Verilator configuration commands. .ie n .IP "coverage_off [\-file """" [\-lines [ \- ]]]" 4 .el .IP "coverage_off [\-file ``'' [\-lines [ \- ]]]" 4 .IX 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. .ie n .IP "lint_off [\-msg ] [\-file """" [\-lines [ \- ]]]" 4 .el .IP "lint_off [\-msg ] [\-file ``'' [\-lines [ \- ]]]" 4 .IX 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). .Sp If the \-msg is omitted, all lint warnings are disabled. This will override all later lint warning enables for the specified region. .ie n .IP "tracing_off [\-file """" [\-lines [ \- ]]]" 4 .el .IP "tracing_off [\-file ``'' [\-lines [ \- ]]]" 4 .IX 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). .SH "LANGUAGE STANDARD SUPPORT" .IX Header "LANGUAGE STANDARD SUPPORT" .SS "Verilog 2001 (\s-1IEEE\s0 1364\-2001) Support" .IX Subsection "Verilog 2001 (IEEE 1364-2001) Support" Verilator supports most Verilog 2001 language features. This includes signed numbers, \*(L"always @*\*(R", generate statements, multidimensional arrays, localparam, and C\-style declarations inside port lists. .SS "Verilog 2005 (\s-1IEEE\s0 1364\-2005) Support" .IX Subsection "Verilog 2005 (IEEE 1364-2005) Support" Verilator supports most Verilog 2005 language features. This includes the `begin_keywords and `end_keywords compiler directives, \f(CW$clog2\fR, and the uwire keyword. .SS "SystemVerilog 2005 (\s-1IEEE\s0 1800\-2005) Support" .IX Subsection "SystemVerilog 2005 (IEEE 1800-2005) Support" Verilator supports ==? and !=? operators, ++ and \*(-- in some contexts, \&\f(CW$bits\fR, \f(CW$countones\fR, \f(CW$error\fR, \f(CW$fatal\fR, \f(CW$info\fR, \f(CW$isunknown\fR, \f(CW$onehot\fR, \f(CW$onehot0\fR, \&\f(CW$unit\fR, \f(CW$warning\fR, 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. .PP It also supports .name and .* interconnection. .PP Verilator partially supports concurrent assert and cover statements; see the enclosed coverage tests for the syntax which is allowed. .SS "SystemVerilog 2012 (\s-1IEEE\s0 1800\-2012) Support" .IX Subsection "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. .PP 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. .SS "Verilog \s-1AMS\s0 Support" .IX Subsection "Verilog AMS Support" Verilator implements a very small subset of Verilog \s-1AMS\s0 (Verilog Analog and Mixed-Signal Extensions) with the subset corresponding to those \s-1VMS\s0 keywords with near equivelents in the Verilog 2005 or SystemVerilog 2009 languages. .PP \&\s-1AMS\s0 parsing is enabled with \*(L"\-\-language \s-1VAMS\s0\*(R" or \*(L"\-\-language 1800+VAMS\*(R". .PP At present Verilator implements ceil, exp, floor, ln, log, pow, sqrt, string, and wreal. .SS "Sugar/PSL Support" .IX Subsection "Sugar/PSL Support" Most future work is being directed towards improving SystemVerilog assertions instead of \s-1PSL\s0. If you are using these \s-1PSL\s0 features, please contact the author as they may be depreciated in future versions. .PP With the \-\-assert switch, Verilator enables support of the Property Specification Language (\s-1PSL\s0), specifically the simple \s-1PSL\s0 subset without time-branching primitives. Verilator currently only converts \s-1PSL\s0 assertions to simple \*(L"if (...) error\*(R" statements, and coverage statements to increment the line counters described in the coverage section. .PP Verilator implements these keywords: assert, assume (same as assert), default (for clocking), countones, cover, isunknown, onehot, onehot0, report, and true. .PP Verilator implements these operators: \-> (logical if). .PP Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. \s-1PSL\s0 vmode/vprop/vunits are not supported. \s-1PSL\s0 statements must be in the module they reference, at the module level where you would put an initial... statement. .PP Verilator only supports (posedge \s-1CLK\s0) or (negedge \s-1CLK\s0), where \s-1CLK\s0 is the name of a one bit signal. You may not use arbitrary expressions as assertion clocks. .SS "Synthesis Directive Assertion Support" .IX Subsection "Synthesis Directive Assertion Support" With the \-\-assert switch, Verilator reads any \*(L"//synopsys full_case\*(R" or \&\*(L"//synopsys parallel_case\*(R" directives. The same applies to any \&\*(L"//ambit synthesis\*(R", \*(L"//cadence\*(R" or \*(L"//pragma\*(R" directives of the same form. .PP 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 \*(L"Assertion failed\*(R" error message. .PP Verilator likewise also asserts any \*(L"unique\*(R" or \*(L"priority\*(R" SystemVerilog keywords on case statements. However, \*(L"unique if\*(R" and \*(L"priority if\*(R" are currently simply ignored. .SH "LANGUAGE EXTENSIONS" .IX Header "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. .IP "`_\|_FILE_\|_" 4 .IX 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!) .IP "`_\|_LINE_\|_" 4 .IX 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!) .IP "`error \fIstring\fR" 4 .IX Item "`error string" This will report an error when encountered, like \*(C+'s #error. .IP "_(\fIexpr\fR)" 4 .IX Item "_(expr)" A underline followed by an expression in parenthesis returns a Verilog expression. This is different from normal parenthesis in special contexts, such as \s-1PSL\s0 expressions, and can be used to embed bit concatenation ({}) inside of \s-1PSL\s0 statements. .IP "$c(\fIstring\fR, ...);" 4 .IX Item "$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. .Sp 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(\*(L"func(\*(R",a,\*(L")\*(R") will result in 'func(a)' in the output \*(C+ code. For input arguments, rather than hard-coding variable names in the string $c(\*(L"func(a)\*(R"), instead pass the variable as an expression $c(\*(L"func(\*(R",a,\*(L")\*(R"). This will allow the call to work inside Verilog functions where the variable is flattened out, and also enable other optimizations. .Sp If you will be reading or writing any Verilog variables inside the \*(C+ functions, the Verilog signals must be declared with /*verilator public*/. .Sp You may also append an arbitrary number to \f(CW$c\fR, generally the width of the output. [signal_32_bits = \f(CW$c3\fR2(\*(L"...\*(R");] This allows for compatibility with other simulators which require a differently named \s-1PLI\s0 function name for each different output width. .ie n .IP "$display, $write, $fdisplay, $fwrite, $sformat, $swrite" 4 .el .IP "\f(CW$display\fR, \f(CW$write\fR, \f(CW$fdisplay\fR, \f(CW$fwrite\fR, \f(CW$sformat\fR, \f(CW$swrite\fR" 4 .IX Item "$display, $write, $fdisplay, $fwrite, $sformat, $swrite" Format arguments may use C fprintf sizes after the % escape. Per the Verilog standard, \f(CW%x\fR prints a number with the natural width, and \f(CW%0x\fR prints a number with minimum width. Verilator extends this so \f(CW%5x\fR prints 5 digits per the C standard (it's unspecified in Verilog). .IP "`coverage_block_off" 4 .IX Item "`coverage_block_off" Specifies the entire begin/end block should be ignored for coverage analysis. Same as /* verilator coverage_block_off */. .IP "`systemc_header" 4 .IX 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. .IP "`systemc_ctor" 4 .IX 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. .IP "`systemc_dtor" 4 .IX 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. .IP "`systemc_interface" 4 .IX 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. .IP "`systemc_imp_header" 4 .IX 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. .IP "`systemc_implementation" 4 .IX 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. .Sp 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. .IP "`\s-1SYSTEMVERILOG\s0" 4 .IX Item "`SYSTEMVERILOG" The \s-1SYSTEMVERILOG\s0, \s-1SV_COV_START\s0 and related standard defines are set by default when \-\-language is 1800\-*. .IP "`\s-1VERILATOR\s0" 4 .IX Item "`VERILATOR" .PD 0 .IP "`verilator" 4 .IX Item "`verilator" .IP "`verilator3" 4 .IX Item "`verilator3" .PD The \s-1VERILATOR\s0, verilator and verilator3 defines are set by default so you may `ifdef around compiler specific constructs. .IP "`verilator_config" 4 .IX Item "`verilator_config" Take remaining text up the the next `verilog mode switch and treat it as Verilator configuration commands. .IP "`verilog" 4 .IX 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. .IP "/*verilator clock_enable*/" 4 .IX 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: .Sp .Vb 4 \& reg enable_r /*verilator clock_enable*/; \& wire gated_clk = clk & enable_r; \& always_ff @ (posedge clk) \& enable_r <= enable_early; .Ve .Sp 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 \&\s-1IMPERFECTSCH\s0 warning, to insure all clock enables are properly recognized. .IP "/*verilator coverage_block_off*/" 4 .IX Item "/*verilator coverage_block_off*/" Specifies the entire begin/end block should be ignored for coverage analysis purposes. .IP "/*verilator coverage_off*/" 4 .IX 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. .IP "/*verilator coverage_on*/" 4 .IX 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*/. .IP "/*verilator inline_module*/" 4 .IX 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 \fIsubmodule\fR_\|_DOT_\|_\fIsubsignal\fR as \*(C+ does not allow \*(L".\*(R" in signal names. SystemPerl when tracing such signals will replace the _\|_DOT_\|_ with the period. .IP "/*verilator isolate_assignments*/" 4 .IX 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 \s-1UNOPTFLAT\s0 warning, attaching this to the signal causing a false loop may clear up the problem. .Sp \&\s-1IE\s0, with the following .Sp .Vb 8 \& reg splitme /* verilator isolate_assignments*/; \& // Note the placement of the semicolon above \& always @* begin \& if (....) begin \& splitme = ....; \& other assignments \& end \& end .Ve .Sp Verilator will internally split the block that assigns to \*(L"splitme\*(R" into two blocks: .Sp It would then internally break it into (sort of): .Sp .Vb 12 \& // 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 .Ve .IP "/*verilator lint_off \fImsg\fR*/" 4 .IX Item "/*verilator lint_off msg*/" Disable the specified warning message for any warnings following the comment. .IP "/*verilator lint_on \fImsg\fR*/" 4 .IX Item "/*verilator lint_on msg*/" Re-enable the specified warning message for any warnings following the comment. .IP "/*verilator lint_restore*/" 4 .IX 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. .IP "/*verilator lint_save*/" 4 .IX 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: .Sp .Vb 4 \& // verilator lint_save \& // verilator lint_off SOME_WARNING \& ... // code needing SOME_WARNING turned off \& // verilator lint_restore .Ve .Sp If \s-1SOME_WARNING\s0 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. .IP "/*verilator no_inline_task*/" 4 .IX 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. .IP "/*verilator public*/ (variable)" 4 .IX 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*/. .Sp Instead of using public variables, consider instead making a \s-1DPI\s0 or public function that accesses the variable. This is nicer as it provides an obvious entry point that is also compatible across simulators. .IP "/*verilator public*/ (task/function)" 4 .IX 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. .Sp 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. .Sp Generally, only the values of stored state (flops) should be written, as the model will \s-1NOT\s0 notice changes made to variables in these functions. (Same as when a signal is declared public.) .Sp You may want to use \s-1DPI\s0 exports instead, as it's compatible with other simulators. .IP "/*verilator public_flat*/ (variable)" 4 .IX 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. .IP "/*verilator public_flat_rd*/ (variable)" 4 .IX 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. .IP "/*verilator public_flat_rw @() */ (variable)" 4 .IX 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. .IP "/*verilator public_module*/" 4 .IX 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. .IP "/*verilator sc_clock*/" 4 .IX 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. .IP "/*verilator sc_bv*/" 4 .IX Item "/*verilator sc_bv*/" Used after a port declaration. It sets the port to be of sc_bv<\fIwidth\fR> 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. .IP "/*verilator sformat*/" 4 .IX Item "/*verilator sformat*/" Attached to the final input of a function or task \*(L"input string\*(R" to indicate the function or task should pass all remaining arguments through \&\f(CW$sformatf\fR. This allows creation of \s-1DPI\s0 functions with \f(CW$display\fR like behavior. See the test_regress/t/t_dpi_display.v file for an example. .IP "/*verilator tracing_off*/" 4 .IX Item "/*verilator tracing_off*/" Disable waveform tracing for all future signals that are declared in this module. Often this is placed just after a primitive's module statement, so that the entire module is not traced. .IP "/*verilator tracing_on*/" 4 .IX Item "/*verilator tracing_on*/" Re-enable waveform tracing for all future signals that are declared. .SH "LANGUAGE LIMITATIONS" .IX Header "LANGUAGE LIMITATIONS" There are some limitations and lack of features relative to a commercial simulator, by intent. User beware. .PP 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. .SS "Synthesis Subset" .IX Subsection "Synthesis Subset" Verilator supports only the Synthesis subset with a few minor additions such as \f(CW$stop\fR, \f(CW$finish\fR and \f(CW$display\fR. 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: .PP .Vb 1 \& always @ (x) y = x & z; .Ve .PP 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 \f(CW$displays\fR in combo blocks, as they may print multiple times when not desired, even on compliant simulators as event ordering is not specified. .SS "Bind" .IX Subsection "Bind" Verilator only supports \*(L"bind\*(R" to a target module name, not an instance path. .SS "Dotted cross-hierarchy references" .IX Subsection "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. .PP 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. .PP Verilator creates numbered \*(L"genblk\*(R" 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. .PP 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. .SS "Floating Point" .IX Subsection "Floating Point" Floating Point (real) numbers are supported. .SS "Latches" .IX Subsection "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. .SS "Structures and Unions" .IX Subsection "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. .SS "Time" .IX Subsection "Time" All delays (#) are ignored, as they are in synthesis. .SS "Unknown states" .IX Subsection "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.) .PP 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. .PP 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. .PP 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. .PP \&\fBNote.\fR \-\-x\-assign applies to variables explicitly initialized or assigned to X. Unititialized clocks are initialized to zero, while all other state holding variables are initialized to a random value. .PP Event driven simulators will generally trigger an edge on a transition from X to 1 (\f(CW\*(C`posedge\*(C'\fR) or X to 0 (\f(CW\*(C`negedge\*(C'\fR). 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. .SS "Tri/Inout" .IX Subsection "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. .PP An assignment of the form: .PP .Vb 2 \& inout driver; \& wire driver = (enable) ? output_value : 1\*(Aqbz; .Ve .PP Will be converted to .PP .Vb 3 \& 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 .Ve .PP External logic will be needed to combine these signals with any external drivers. .PP 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. .SS "Functions & Tasks" .IX Subsection "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). .PP Recursive functions and tasks are not supported. All inputs and outputs are automatic, as if they had the Verilog 2001 \*(L"automatic\*(R" 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.) .SS "Generated Clocks" .IX Subsection "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. .SS "Ranges must be big-bit-endian" .IX Subsection "Ranges must be big-bit-endian" Bit ranges must be numbered with the \s-1MSB\s0 being numbered greater or the same as the \s-1LSB\s0. Little-bit-endian busses [0:15] are not supported as they aren't easily made compatible with \*(C+. .SS "Gate Primitives" .IX Subsection "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 \s-1MOS\s0 gate primitives are not supported. Tables are not supported. .SS "Specify blocks" .IX Subsection "Specify blocks" All specify blocks and timing checks are ignored. .SS "Array Initialization" .IX Subsection "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 \s-1BLKLOOPINIT\s0 error for more information. .SS "Array Out of Bounds" .IX Subsection "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. .PP 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. .SS "Assertions" .IX Subsection "Assertions" Verilator is beginning to add support for assertions. Verilator currently only converts assertions to simple \*(L"if (...) error\*(R" statements, and coverage statements to increment the line counters described in the coverage section. .PP 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.) .SS "Language Keyword Limitations" .IX Subsection "Language Keyword Limitations" This section describes specific limitations for each language keyword. .IP "`_\|_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" 4 .IX 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. .IP "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" 4 .IX 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. .IP "++, \*(-- operators" 4 .IX 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 (\*(L"a = b++;\*(R"). .IP "'{} operator" 4 .IX 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. .IP "cast operator" 4 .IX Item "cast operator" Casting is supported only between simple scalar types, signed and unsigned, not arrays nor structs. .IP "chandle" 4 .IX Item "chandle" Treated as a \*(L"longint\*(R"; does not yet warn about operations that are specified as illegal on chandles. .IP "disable" 4 .IX 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. .IP "inside" 4 .IX Item "inside" Inside expressions may not include unpacked array traversal or $ as an upper bound. Case inside and case matches are also unsupported. .IP "interface" 4 .IX 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. .IP "priority if, unique if" 4 .IX Item "priority if, unique if" Priority and unique if's are treated as normal ifs and not asserted to be full nor unique. .IP "specify specparam" 4 .IX Item "specify specparam" All specify blocks and timing checks are ignored. .IP "string" 4 .IX Item "string" String is supported only to the point that they can be passed to \s-1DPI\s0 imports. .IP "timeunit, timeprecision" 4 .IX Item "timeunit, timeprecision" All timing control statements are ignored. .IP "uwire" 4 .IX Item "uwire" Verilator does not perform warning checking on uwires, it treats the uwire keyword as if it were the normal wire keyword. .ie n .IP "$bits, $countones, $error, $fatal, $finish, $info, $isunknown, $onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time, $unsigned, $warning." 4 .el .IP "\f(CW$bits\fR, \f(CW$countones\fR, \f(CW$error\fR, \f(CW$fatal\fR, \f(CW$finish\fR, \f(CW$info\fR, \f(CW$isunknown\fR, \f(CW$onehot\fR, \f(CW$onehot0\fR, \f(CW$readmemb\fR, \f(CW$readmemh\fR, \f(CW$signed\fR, \f(CW$stime\fR, \f(CW$stop\fR, \f(CW$time\fR, \f(CW$unsigned\fR, \f(CW$warning\fR." 4 .IX Item "$bits, $countones, $error, $fatal, $finish, $info, $isunknown, $onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time, $unsigned, $warning." Generally supported. .ie n .IP "$display, $write, $fdisplay, $fwrite, $swrite" 4 .el .IP "\f(CW$display\fR, \f(CW$write\fR, \f(CW$fdisplay\fR, \f(CW$fwrite\fR, \f(CW$swrite\fR" 4 .IX Item "$display, $write, $fdisplay, $fwrite, $swrite" \&\f(CW$display\fR 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. .ie n .IP "$displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc" 4 .el .IP "\f(CW$displayb\fR, \f(CW$displayh\fR, \f(CW$displayo\fR, \f(CW$writeb\fR, \f(CW$writeh\fR, \f(CW$writeo\fR, etc" 4 .IX Item "$displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc" The sized display functions are rarely used and so not supported. Replace them with a \f(CW$write\fR with the appropriate format specifier. .ie n .IP "$finish, $stop" 4 .el .IP "\f(CW$finish\fR, \f(CW$stop\fR" 4 .IX Item "$finish, $stop" The rarely used optional parameter to \f(CW$finish\fR and \f(CW$stop\fR is ignored. .ie n .IP "$fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fscanf, $fwrite" 4 .el .IP "\f(CW$fopen\fR, \f(CW$fclose\fR, \f(CW$fdisplay\fR, \f(CW$feof\fR, \f(CW$fflush\fR, \f(CW$fgetc\fR, \f(CW$fgets\fR, \f(CW$fscanf\fR, \f(CW$fwrite\fR" 4 .IX Item "$fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fscanf, $fwrite" File descriptors passed to the file \s-1PLI\s0 calls must be file descriptors, not MCDs, which includes the mode parameter to \f(CW$fopen\fR being mandatory. .ie n .IP "$fscanf, $sscanf" 4 .el .IP "\f(CW$fscanf\fR, \f(CW$sscanf\fR" 4 .IX Item "$fscanf, $sscanf" Only integer formats are supported; \f(CW%e\fR, \f(CW%f\fR, \f(CW%m\fR, \f(CW%r\fR, \f(CW%v\fR, and \f(CW%z\fR are not supported. .ie n .IP "$fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal, $setup, $setuphold, $skew, $timeskew, $width" 4 .el .IP "\f(CW$fullskew\fR, \f(CW$hold\fR, \f(CW$nochange\fR, \f(CW$period\fR, \f(CW$recovery\fR, \f(CW$recrem\fR, \f(CW$removal\fR, \f(CW$setup\fR, \f(CW$setuphold\fR, \f(CW$skew\fR, \f(CW$timeskew\fR, \f(CW$width\fR" 4 .IX Item "$fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal, $setup, $setuphold, $skew, $timeskew, $width" All specify blocks and timing checks are ignored. .ie n .IP "$random" 4 .el .IP "\f(CW$random\fR" 4 .IX Item "$random" \&\f(CW$random\fR 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). .ie n .IP "$readmemb, $readmemh" 4 .el .IP "\f(CW$readmemb\fR, \f(CW$readmemh\fR" 4 .IX 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. .ie n .IP "$test$plusargs, $value$plusargs" 4 .el .IP "\f(CW$test\fR$plusargs, \f(CW$value\fR$plusargs" 4 .IX Item "$test$plusargs, $value$plusargs" Supported, but the instantiating \*(C+/SystemC testbench must call .Sp .Vb 1 \& Verilated::commandArgs(argc, argv); .Ve .Sp to register the command line before calling \f(CW$test\fR$plusargs or \&\f(CW$value\fR$plusargs. .ie n .IP "$timeformat" 4 .el .IP "\f(CW$timeformat\fR" 4 .IX 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 \&\s-1VL_TIME_MULTIPLER\s0 can be defined at compile time to move the decimal point when displaying all times, model wide. .SH "ERRORS AND WARNINGS" .IX Header "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: .PP .Vb 3 \& // verilator lint_off UNSIGNED \& if (\`DEF_THAT_IS_EQ_ZERO <= 3) $stop; \& // verilator lint_on UNSIGNED .Ve .PP Warnings may also be globally disabled by invoking Verilator with the \&\f(CW\*(C`\-Wno\-\f(CIwarning\f(CW\*(C'\fR 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. .PP List of all warnings: .IP "\s-1ALWCOMBORDER\s0" 4 .IX 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. .Sp .Vb 4 \& always_comb begin \& a = b; \& b = 1; \& end .Ve .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1ASSIGNIN\s0" 4 .IX Item "ASSIGNIN" Error that an assignment is being made to an input signal. This is almost certainly a mistake, though technically legal. .Sp .Vb 2 \& input a; \& assign a = 1\*(Aqb1; .Ve .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1ASSIGNDLY\s0" 4 .IX Item "ASSIGNDLY" Warns that you have an assignment statement with a delayed time in front of it, for example: .Sp .Vb 2 \& a <= #100 b; \& assign #100 a = b; .Ve .Sp 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. .IP "\s-1BLKANDNBLK\s0" 4 .IX Item "BLKANDNBLK" \&\s-1BLKANDNBLK\s0 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: .Sp .Vb 2 \& always @ (posedge clk) foo[0] <= ... \& always @* foo[1] = ... .Ve .Sp Simply use a different register for the flop: .Sp .Vb 3 \& always @ (posedge clk) foo_flopped[0] <= ... \& always @* foo[0] = foo_flopped[0]; \& always @* foo[1] = ... .Ve .Sp This is good coding practice anyways. .Sp It is also possible to disable this error when one of the assignments is inside a public task. .Sp Ignoring this warning may make Verilator simulations differ from other simulators. .IP "\s-1BLKSEQ\s0" 4 .IX 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 \s-1ONLY\s0 later in the same block, however this style is generally discouraged as it is error prone. .Sp .Vb 1 \& always @ (posedge clk) foo = ... .Ve .Sp Disabled by default as this is a code style warning; it will simulate correctly. .IP "\s-1BLKLOOPINIT\s0" 4 .IX 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 .Sp .Vb 5 \& always @ (posedge clk) \& if (~reset_l) begin \& for (i=0; i<\`ARRAY_SIZE; i++) begin \& array[i] = 0; // Non\-delayed for verilator \& end .Ve .Sp 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. .IP "\s-1CASEINCOMPLETE\s0" 4 .IX 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 \*(L"default: \f(CW$stop\fR;\*(R" or just \*(L"default: ;\*(R" so that any design assumption violations will be discovered in simulation. .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1CASEOVERLAP\s0" 4 .IX 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. .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1CASEX\s0" 4 .IX Item "CASEX" Warns that it is simply better style to use casez, and \f(CW\*(C`?\*(C'\fR in place of \&\f(CW\*(C`x\*(C'\fR's. See http://www.sunburst\-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1CASEWITHX\s0" 4 .IX Item "CASEWITHX" Warns that a case statement contains a constant with a \f(CW\*(C`x\*(C'\fR. Verilator is two-state so interpret such items as always false. Note a common error is to use a \f(CW\*(C`X\*(C'\fR in a case or casez statement item; often what the user instead intended is to use a casez with \f(CW\*(C`?\*(C'\fR. .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1CDCRSTLOGIC\s0" 4 .IX 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. .IP "\s-1CMPCONST\s0" 4 .IX Item "CMPCONST" Warns that you are comparing a value in a way that will always be constant. For example \*(L"X > 1\*(R" will always be true when X is a single bit wide. .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1COMBDLY\s0" 4 .IX 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 http://www.sunburst\-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf .Sp Ignoring this warning may make Verilator simulations differ from other simulators. .IP "\s-1DECLFILENAME\s0" 4 .IX 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. .Sp Disabled by default as this is a code style warning; it will simulate correctly. .IP "\s-1DEFPARAM\s0" 4 .IX Item "DEFPARAM" Warns that the \*(L"defparam\*(R" statement was deprecated in Verilog 2001 and all designs should now be using the #(...) format to specify parameters. .Sp Disabled by default as this is a code style warning; it will simulate correctly. .IP "\s-1DETECTARRAY\s0" 4 .IX 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 \s-1UNOPTFLAT\s0 warning (see below). .Sp The solution is to break the loop, as described for \s-1UNOPTFLAT\s0. .IP "\s-1ENDLABEL\s0" 4 .IX Item "ENDLABEL" Warns that a label attached to a \*(L"end\*(R"\-something statement does not match the label attached to the block start. .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1GENCLK\s0" 4 .IX 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 \s-1ALL\s0 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.) .Sp Ignoring this warning may make Verilator simulations differ from other simulators. .IP "\s-1IFDEPTH\s0" 4 .IX 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'. .Sp Disabled by default as this is a code style warning; it will simulate correctly. .IP "\s-1IMPERFECTSCH\s0" 4 .IX 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. .IP "\s-1IMPLICIT\s0" 4 .IX 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 .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1IMPURE\s0" 4 .IX 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. .Sp Ignoring this warning may make Verilator simulations differ from other simulators. .IP "\s-1INCABSPATH\s0" 4 .IX 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 +include used on the command line to specify the top include source directory. .Sp Disabled by default as this is a code style warning; it will simulate correctly. .IP "\s-1INITIALDLY\s0" 4 .IX 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 \s-1COMBDLY\s0 warning. .Sp Ignoring this warning may make Verilator simulations differ from other simulators. .IP "\s-1LITENDIAN\s0" 4 .IX 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. .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1MODDUP\s0" 4 .IX 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. .IP "\s-1MULTIDRIVEN\s0" 4 .IX 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. .Sp Ignoring this warning will only slow simulations, it will simulate correctly. .IP "\s-1MULTITOP\s0" 4 .IX 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. .Sp 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. .IP "\s-1PINMISSING\s0" 4 .IX 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 \*(L"(.\fIpin_name()\fR)\*(R". .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1PINNOCONNECT\s0" 4 .IX Item "PINNOCONNECT" Warns that a cell instantiation has a pin which is not connected to another signal. .Sp Disabled by default as this is a code style warning; it will simulate correctly. .IP "\s-1REALCVT\s0" 4 .IX Item "REALCVT" Warns that a real number is being implicitly rounded to an integer, with possible loss of precision. .IP "\s-1REDEFMACRO\s0" 4 .IX Item "REDEFMACRO" Warns that you have redefined the same macro with a different value, for example: .Sp .Vb 3 \& \`define MACRO def1 \& //... \& \`define MACRO otherdef .Ve .Sp 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: .Sp .Vb 4 \& \`define MACRO def1 \& //... \& \`undef MACRO \& \`define MACRO otherdef .Ve .IP "\s-1SELRANGE\s0" 4 .IX Item "SELRANGE" Warns that a selection index will go out of bounds: .Sp .Vb 2 \& wire vec[6:0]; \& initial out = vec[7]; // There is no 7 .Ve .Sp 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. .Sp .Vb 5 \& wire vec[6:0]; \& initial begin \& seven = 7; \& ... \& if (seven != 7) out = vec[seven]; // Never will use vec[7] .Ve .IP "\s-1STMTDLY\s0" 4 .IX Item "STMTDLY" Warns that you have a statement with a delayed time in front of it, for example: .Sp .Vb 1 \& #100 $finish; .Ve .Sp Ignoring this warning may make Verilator simulations differ from other simulators. .IP "\s-1SYMRSVDWORD\s0" 4 .IX Item "SYMRSVDWORD" Error 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 error message as you would disable warnings, but the symbol will be renamed by Verilator to avoid the conflict. .IP "\s-1SYNCASYNCNET\s0" 4 .IX 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. .Sp Disabled by default as this is a code style warning; it will simulate correctly. .IP "\s-1TASKNSVAR\s0" 4 .IX 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: .Sp .Vb 4 \& task foo; output sig; ... endtask \& always @* begin \& foo(bus_we_select_from[2]); // Will get TASKNSVAR error \& end .Ve .Sp Change this to: .Sp .Vb 5 \& reg foo_temp_out; \& always @* begin \& foo(foo_temp_out); \& bus_we_select_from[2] = foo_temp_out; \& end .Ve .Sp Verilator doesn't do this conversion for you, as some more complicated cases would result in simulator mismatches. .IP "\s-1UNDRIVEN\s0" 4 .IX 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. .Sp Disabled by default as this is a code style warning; it will simulate correctly. .IP "\s-1UNOPT\s0" 4 .IX 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. .Sp 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 \&\s-1UNOPT\s0 warning will result if \s-1AI\s0 & \s-1AO\s0 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. .Sp Ignoring this warning will only slow simulations, it will simulate correctly. .IP "\s-1UNOPTFLAT\s0" 4 .IX 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. .Sp Unlike the \s-1UNOPT\s0 warning, this occurs after netlist flattening, and indicates a more basic problem, as the less obvious case described under \&\s-1UNOPT\s0 does not apply. .Sp Often \s-1UNOPTFLAT\s0 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: .Sp .Vb 1 \& wire [2:0] x = {x[1:0],shift_in}; .Ve .Sp This statement needs to be evaluated multiple times, as a change in \&\*(L"shift_in\*(R" requires \*(L"x\*(R" to be computed 3 times before it becomes stable. This is because a change in \*(L"x\*(R" requires \*(L"x\*(R" itself to change value, which causes the warning. .Sp For significantly better performance, split this into 2 separate signals: .Sp .Vb 1 \& wire [2:0] xout = {x[1:0],shift_in}; .Ve .Sp and change all receiving logic to instead receive \*(L"xout\*(R". Alternatively, change it to .Sp .Vb 1 \& wire [2:0] x = {xin[1:0],shift_in}; .Ve .Sp and change all driving logic to instead drive \*(L"xin\*(R". .Sp 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. .Sp The most complicated \s-1UNOPTFLAT\s0 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. .Sp The \s-1UNOPTFLAT\s0 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. .Sp The \s-1UNOPTFLAT\s0 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. .Sp To assist in resolving \s-1UNOPTFLAT\s0, the option \f(CW\*(C`\-\-report\-unoptflat\*(C'\fR 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. .Sp Ignoring this warning will only slow simulations, it will simulate correctly. .IP "\s-1UNPACKED\s0" 4 .IX Item "UNPACKED" Warns that unpacked structs and unions are not supported. .Sp Ignoring this warning will make Verilator treat the structure as packed, which may make Verilator simulations differ from other simulators. .IP "\s-1UNSIGNED\s0" 4 .IX Item "UNSIGNED" Warns that you are comparing a unsigned value in a way that implies it is signed, for example \*(L"X < 0\*(R" will always be true when X is unsigned. .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1UNUSED\s0" 4 .IX 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 (\*(L"*unused*\*(R") or accessing only a single array element marks the entire signal as used. .Sp Disabled by default as this is a code style warning; it will simulate correctly. .Sp A recommended style for unused nets is to put at the bottom of a file code similar to the following: .Sp .Vb 4 \& wire _unused_ok = &{1\*(Aqb0, \& sig_not_used_a, \& sig_not_used_yet_b, // To be fixed \& 1\*(Aqb0}; .Ve .Sp The reduction \s-1AND\s0 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 \&\*(L"unused\*(R" (\-unused\-regexp) is recognized by Verilator and suppresses warnings; if using other lint tools, either teach to tool to ignore signals with \*(L"unused\*(R" 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. .IP "\s-1VARHIDDEN\s0" 4 .IX 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. .Sp Disabled by default as this is a code style warning; it will simulate correctly. .IP "\s-1WIDTH\s0" 4 .IX 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: .Sp If it's a constant 0 that's 32 bits or less, simply leave it unwidthed. Verilator considers zero to be any width needed. .Sp Concatenate leading zeros when doing arithmetic. In the statement .Sp .Vb 1 \& wire [5:0] plus_one = from[5:0] + 6\*(Aqd1 + carry[0]; .Ve .Sp The best fix, which clarifies intent and will also make all tools happy is: .Sp .Vb 1 \& wire [5:0] plus_one = from[5:0] + 6\*(Aqd1 + {5\*(Aqd0,carry[0]}; .Ve .Sp Ignoring this warning will only suppress the lint check, it will simulate correctly. .IP "\s-1WIDTHCONCAT\s0" 4 .IX 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. .Sp .Vb 1 \& wire [63:0] concat = {1,2}; .Ve .Sp An example where this is technically legal (though still bad form) is: .Sp .Vb 2 \& parameter PAR = 1; \& wire [63:0] concat = {PAR,PAR}; .Ve .Sp The correct fix is to either size the 1 (\*(L"32'h1\*(R"), or add the width to the parameter definition (\*(L"parameter [31:0]\*(R"), or add the width to the parameter usage (\*(L"{PAR[31:0],PAR[31:0]}\*(R". .PP The following describes the less obvious errors: .IP "Internal Error" 4 .IX 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. .IP "Unsupported: ...." 4 .IX Item "Unsupported: ...." This error indicates that you are using a Verilog language construct that is not yet supported in Verilator. See the Limitations chapter. .IP "Verilated model didn't converge" 4 .IX Item "Verilated model didn't converge" Verilator sometimes has to evaluate combinatorial logic multiple times, usually around code where a \s-1UNOPTFLAT\s0 warning was issued, but disabled. For example: .Sp .Vb 2 \& always @ (a) b=~a; \& always @ (b) a=b .Ve .Sp will toggle forever and thus the executable will give the didn't converge error to prevent an infinite loop. .Sp To debug this, run Verilator with \-\-profile\-cfuncs. Run make on the generated files with \*(L"OPT=\-DVL_DEBUG\*(R". Then call \fIVerilated::debug\fR\|(1) in your main.cpp. .Sp 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: .Sp .Vb 2 \& CHANGE: filename.v:1: b \& CHANGE: filename.v:2: a .Ve .SH "FAQ/FREQUENTLY ASKED QUESTIONS" .IX Header "FAQ/FREQUENTLY ASKED QUESTIONS" .IP "Does it run under Windows?" 4 .IX 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. .IP "Can you provide binaries?" 4 .IX Item "Can you provide binaries?" Verilator is available as a \s-1RPM\s0 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. .Sp 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. .IP "How can it be faster than (name-the-simulator)?" 4 .IX Item "How can it be faster than (name-the-simulator)?" Generally, the implied part of the question is \*(L"... with all of their manpower they can put into it.\*(R" .Sp 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. .Sp 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. .IP "Will Verilator output remain under my own copyright?" 4 .IX Item "Will Verilator output remain under my own copyright?" Yes, it's just like using \s-1GCC\s0 on your programs; this is why Verilator uses the \*(L"\s-1GNU\s0 *Lesser* Public License Version 3\*(R" instead of the more typical \&\*(L"\s-1GNU\s0 Public License\*(R". 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 \s-1GNU\s0 Lesser Public License. However, Verilator output (the Verilated code) only \*(L"include\*(R"s the licensed files, and so you are \s-1NOT\s0 required to release any output from Verilator. .Sp 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! .Sp One limit is that you cannot under either license release a commercial Verilog simulation product incorporating Verilator without making the source code available. .Sp 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. .IP "Why is Verilation so slow?" 4 .IX 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. .IP "How do I generate waveforms (traces) in \*(C+?" 4 .IX Item "How do I generate waveforms (traces) in ?" See the next question for tracing in SystemC mode. .Sp 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 \*(L"trace_object\->dump(time)\*(R" every time step, and finally call \*(L"trace_object\->\fIclose()\fR\*(R". For an example, see below and the test_c/sim_main.cpp file of the distribution. .Sp You also need to compile verilated_vcd_c.cpp and add it to your link, preferably by adding the dependencies in $(\s-1VK_GLOBAL_OBJS\s0) to your Makefile's link rule. This is done for you if using the Verilator \-\-exe flag. .Sp 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. .Sp Note also older versions of Verilator used the SystemPerl package and SpTraceVcdC class. This still works, but is depreciated as it requires strong coupling between the Verilator and SystemPerl versions. .Sp .Vb 10 \& #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(); \& } .Ve .IP "How do I generate waveforms (traces) in SystemC?" 4 .IX 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_sp/sc_main.cpp file of the distribution, and below. .Sp 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. .Sp 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 $(\s-1VK_GLOBAL_OBJS\s0) to your Makefile's link rule. This is done for you if using the Verilator \-\-exe flag. .Sp 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. .Sp .Vb 10 \& #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(); \& } .Ve .IP "How do I view waveforms (traces)?" 4 .IX Item "How do I view waveforms (traces)?" Verilator makes standard \s-1VCD\s0 (Value Change Dump) files. They are viewable with the public domain Dinotrace or GtkWave programs, or any of the many commercial offerings. .IP "How do I reduce the size of large waveform (trace) files?" 4 .IX 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.) .Sp 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. .Sp Also be sure you write your trace files to a local disk, instead of to a network disk. Network disks are generally far slower. .IP "How do I do coverage analysis?" 4 .IX Item "How do I do coverage analysis?" Verilator supports both block (line) coverage and user inserted functional coverage. Both require the SystemPerl package to be installed but do not require use of the SystemPerl output mode. .Sp First, run verilator with the \-\-coverage option. If you're using your own makefile, compile the model with the \s-1GCC\s0 flag \-DSP_COVERAGE (if using Verilator's, it will do this for you.) .Sp Run your tests in different directories. Each test will create a logs/coverage.pl file. .Sp After running all of your tests, the vcoverage utility (from the SystemPerl package) is executed. Vcoverage reads the logs/coverage.pl file(s), and creates an annotated source code listing showing code coverage details. .Sp For an example, after running 'make test' in the Verilator distribution, see the test_sp/logs/coverage_source directory. Grep for lines starting with '%' to see what lines Verilator believes need more coverage. .IP "Where is the translate_off command? (How do I ignore a construct?)" 4 .IX 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 \*(L"\s-1VERILATOR\s0\*(R" define for you, so just wrap the code in an ifndef region: .Sp .Vb 3 \& \`ifndef VERILATOR \& Something_Verilator_Dislikes; \& \`endif .Ve .ie n .IP "Why do I get ""unexpected `do'"" or ""unexpected `bit'"" errors?" 4 .el .IP "Why do I get ``unexpected `do''' or ``unexpected `bit''' errors?" 4 .IX 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. .Sp .Vb 3 \& \`begin_keywords "1364\-2001" \& integer bit; initial bit = 1; \& \`end_keywords .Ve .Sp If you want the whole file to be parsed as Verilog 2001, just create a file with .Sp .Vb 1 \& \`begin_keywords "1364\-2001" .Ve .Sp 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.) .IP "How do I prevent my assertions from firing during reset?" 4 .IX 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. .ie n .IP "Why do I get ""undefined reference to `\fIsc_time_stamp()\fR'""?" 4 .el .IP "Why do I get ``undefined reference to `\fIsc_time_stamp()\fR'''?" 4 .IX 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 \*(L"\s-1CONNECTING\s0 \s-1TO\s0 \*(C+\*(R" examples. .ie n .IP "Why do I get ""undefined reference to `\s-1VL_RAND_RESET_I\s0' or `Verilated::...'""?" 4 .el .IP "Why do I get ``undefined reference to `\s-1VL_RAND_RESET_I\s0' or `Verilated::...'''?" 4 .IX 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 $(\s-1VK_GLOBAL_OBJS\s0) make variable, which should be part of your Makefile's link rule. .IP "Is the \s-1PLI\s0 supported?" 4 .IX Item "Is the PLI supported?" Only somewhat. More specifically, the common PLI-ish calls \f(CW$display\fR, \&\f(CW$finish\fR, \f(CW$stop\fR, \f(CW$time\fR, \f(CW$write\fR are converted to \*(C+ equivalents. You can also use the \*(L"import \s-1DPI\s0\*(R" SystemVerilog feature to call C code (see the chapter above). There is also limited \s-1VPI\s0 access to public signals. .Sp 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 \s-1PLI\s0 interface code, and call it with $c(\*(L"{any_c++_statement}\*(R"). .IP "How do I make a Verilog module that contain a \*(C+ object?" 4 .IX Item "How do I make a Verilog module that contain a object?" You need to add the object to the structure that Verilator creates, then use \f(CW$c\fR to call a method inside your object. The test_regress/t/t_extend_class files show an example of how to do this. .IP "How do I get faster build times?" 4 .IX Item "How do I get faster build times?" Between \s-1GCC\s0 3.0 to 3.3, each compiled progressively slower, thus if you can use \s-1GCC\s0 2.95, or \s-1GCC\s0 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 \s-1GCC\s0 runs between identical source builds, even across different users. You can use the \s-1OBJCACHE\s0 environment variable to use these \s-1CC\s0 wrappers. .IP "Why do so many files need to recompile when I add a signal?" 4 .IX 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. .IP "How do I access functions/tasks in C?" 4 .IX 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 \s-1DPI\s0 chapter in the manual. .IP "How do I access signals in C?" 4 .IX Item "How do I access signals in C?" The best thing is to make a SystemVerilog \*(L"export \s-1DPI\s0 task\*(R" or function that accesses that signal, as described in the \s-1DPI\s0 chapter in the manual and \s-1DPI\s0 tutorials on the web. This will allow Verilator to better optimize the model and should be portable across simulators. .Sp 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. .Sp 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. .Sp 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.) .Sp In the \s-1SYSTEMC\s0 example above, if you had in our.v: .Sp .Vb 2 \& input clk /*verilator public*/; \& // Note the placement of the semicolon above .Ve .Sp From the sc_main.cpp file, you'd then: .Sp .Vb 3 \& #include "Vour.h" \& #include "Vour_our.h" \& cout << "clock is " << top\->v\->clk << endl; .Ve .Sp 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. .IP "Should a module be in Verilog or SystemC?" 4 .IX 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: .Sp A module with only SystemC cells below must be SystemC. .Sp A module with a mix of Verilog and SystemC cells below must be SystemC. (As Verilator cannot connect to lower-level SystemC cells.) .Sp 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.) .SH "BUGS" .IX Header "BUGS" First, check the the coding limitations section. .PP Next, try the \-\-debug switch. This will enable additional internal assertions, and may help identify the problem. .PP 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: .PP .Vb 3 \& cd test_regress \& cp \-p t/t_EXAMPLE.pl t/t_BUG.pl \& cp \-p t/t_EXAMPLE.v t/t_BUG.v .Ve .PP There are many hits on how to write a good test in the driver.pl documentation which can be seen by running: .PP .Vb 2 \& cd $VERILATOR_ROOT # Need the original distribution kit \& test_regress/driver.pl \-\-help .Ve .PP 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: .PP .Vb 6 \& 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 .Ve .PP 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. .PP Finally, report the bug using the bug tracker at . The bug will become publicly visible; if this is unacceptable, mail the bug report to \&\f(CW\*(C`wsnyder@wsnyder.org\*(C'\fR. .SH "HISTORY" .IX Header "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 \s-1CPU\s0 model of the Alpha processor and simulated in a C based environment called \s-1CCLI\s0. .PP 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. \&\s-1CCLI\s0 was still being used as the shell. .PP 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 \s-1GNU\s0 Public License.) .PP In 2001, Wilson Snyder took the kit, and added a SystemC mode, and called it Verilator2. This was the first packaged public release. .PP In 2002, Wilson Snyder created Verilator3 by rewriting Verilator from scratch in \*(C+. This added many optimizations, yielding about a 2\-5x performance gain. .PP In 2009, major SystemVerilog and \s-1DPI\s0 language support was added. .PP 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. .SH "CONTRIBUTORS" .IX Header "CONTRIBUTORS" Many people have provided ideas and other assistance with Verilator. .PP The major corporate sponsors of Verilator, by providing significant contributions of time or funds include include Cavium Networks, Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems, Nauticus Networks, and SiCortex Inc. .PP The people who have contributed major functionality are Byron Bradley, Jeremy Bennett, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers include Jeff Dutton, Ralf Karge, David Hewson, Wim Michiels, Alex Solomatnikov, Sebastien Van Cauwenberghe and Gene Weber. .PP Some of the people who have provided ideas and feedback for Verilator include: David Addison, Vasu Arasanipalai, Jens Arm, J Baxter, Jeremy Bennett, David Black, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee, Lawrence Butcher, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike Denio, John Deroo, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic, Alex Duller, Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete, Andrea Foletto, Bob Fredieu, Shankar Giri, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Thomas Hawkins, David Hewson, Jae Hossell, Ben Jackson, Iztok Jeras, Christophe Joly, Mike Kagen, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki, David Kravitz, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber, John Li, Charlie Lind, Andrew Ling, Paul Liu, Dan Lussier, Fred Ma, Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, Dominic Plunkett, Niranjan Prabhu, Usha Priyadharshini, Alberto Del Rio, Oleg Rodionov, John Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Brian Small, Alex Solomatnikov, Art Stamness, John Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Stefan Thiede, Gary Thomas, Steve Tong, Hans Van Antwerpen, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston, Joshua Wise, Johan Wouters, and Ding Xiaoliang. .PP Thanks to them, and all those we've missed including above. .SH "DISTRIBUTION" .IX Header "DISTRIBUTION" The latest version is available from . .PP Copyright 2003\-2014 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the \s-1GNU\s0 Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. .SH "AUTHORS" .IX Header "AUTHORS" When possible, please instead report bugs to . .PP Wilson Snyder .PP Major concepts by Paul Wasson and Duane Galbi. .SH "SEE ALSO" .IX Header "SEE ALSO" verilator_profcfunc, systemperl, vcoverage, make, .PP \&\*(L"verilator \-\-help\*(R" which is the source for this document, .PP and internals.txt in the distribution. verilator-3.856/.gitignore0000664000177100017500000000033012151516614015511 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-3.856/test_sc/0000775000177100017500000000000012307720634015173 5ustar wsnyderwsnyderverilator-3.856/test_sc/.gitignore0000664000177100017500000000006212111011552017142 0ustar wsnyderwsnyder*.old *.dmp *.log *.csrc *.vcd obj_* logs project verilator-3.856/test_sc/Makefile_obj0000664000177100017500000000214312306677750017476 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-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. # #***************************************************************************** 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.856/test_sc/sc_main.cpp0000664000177100017500000001062612306677750017326 0ustar wsnyderwsnyder// -*- SystemC -*- // DESCRIPTION: Verilator Example: Top level main for invoking SystemC model // // Copyright 2003-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. //==================================================================== #include #include #include #include #ifdef SYSTEMPERL # include "systemperl.h" // SystemC + SystemPerl global header # include "sp_log.h" // Logging cout to files # include "SpTraceVcd.h" # include "SpCoverage.h" #else # include "systemc.h" // SystemC global header # include "verilated_vcd_sc.h" // Tracing #endif #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(); #ifdef SYSTEMPERL sp_log_file simlog ("sim.log"); simlog.redirect_cout(); #endif // 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 #ifdef SYSTEMPERL SP_CELL (top, Vtop); SP_PIN (top, clk, clk); SP_PIN (top, fastclk, fastclk); SP_PIN (top, reset_l, reset_l); SP_PIN (top, passed, passed); SP_PIN (top, in_small, in_small); SP_PIN (top, in_quad, in_quad); SP_PIN (top, in_wide, in_wide); SP_PIN (top, out_small, out_small); SP_PIN (top, out_quad, out_quad); SP_PIN (top, out_wide, out_wide); #else 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); #endif //========== // 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"; # ifdef SYSTEMPERL SpTraceFile* tfp = new SpTraceFile; # else VerilatedVcdSc* tfp = new VerilatedVcdSc; # endif 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 && !passed && !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 a 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.856/test_sc/Makefile0000664000177100017500000000362112306677750016646 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-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. # #****************************************************************************/ 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 preproc compile run test_debug: precopy prep_dbg preproc 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) preproc: cd obj_dir ; $(MAKE) -j 1 -f ../Makefile_obj preproc 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.856/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.856/internals.html0000664000177100017500000010702512307713746016427 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 psudo-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 psudo-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 op1p to give the pointer to the AST for the "then" block, while elsesp calls op2p 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.

AstNVistor

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 provided 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 no deprecated and should 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.

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 convenition have the suffix _bad in their name, and include fails => 1 in either their compile or execute step as appropriate.

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 additonal 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 and SystemPerl tests also run the tests in the test_vcs, test_verilated and test_regress directories when using make test. This is disabled by default as SystemC/SystemPerl 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

  • The regression tests will assume that you have a version of SystemPerl to match. Typically if working on Verilator from git, also use SystemPerl from git.

  • 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 numberic, it then prints the width of the item. This field is a squence 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-2014 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.856/README.html0000664000177100017500000002155712307713746015372 0ustar wsnyderwsnyder NAME


NAME

This is the Verilator Package README file.


DISTRIBUTION

This package is Copyright 2003-2014 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.)

If you will be using SystemPerl or coverage, download and install System-Perl, http://www.veripool.org/systemperl. Note you'll need to set a SYSTEMPERL environment variable to point to the downloaded kit. Optionally also set SYSTEMPERL_INCLUDE to point to the installed headers.

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, SYSTEMC_LIBDIR, SYSTEMPERL, and SYSTEMPERL_INCLUDE 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_sp                     => Example Verilog->SystemPerl conversion
    test_vcs                    => Example Verilog->VCS conversion (test the test)
    test_verilated              => Internal tests
    test_regress                => Internal tests


LIMITATIONS

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

verilator-3.856/veripool-logo.png0000664000177100017500000000156512151516242017034 0ustar wsnyderwsnyder‰PNG  IHDR67pÇIJsRGB®Îé`PLTEÿÿÿ”“¸Îœœ €).f)œt‘p¸©ÔPOc BB½zz3-‡¢]kP ^..7½·æ%tt†¯Œ°$$k“L^Ž8Cƒ €ÀÀñ™fÿfÿ3ÌÌ33™YP·qtRNS@æØfbKGDˆH pHYs  šœtIMEÜ-—+zIDATHÇÅ–‹¶¢0 EÁ€­"ˆÁF/ýÿ¿œ¤ ˆ^pÖš9`é#›¤%“ä_H¤ßaR}lÆàkLÉØ€¨A‚ú´$Ô¨g° Hù “‹rxÏŽzƒ)ÉCÊÒjÀØ%“R.a*Ð’‚ƒ$Ó–£Y.aÖÌFB§r6ιQƒI´l`ƒrt 61;L¬Ã‹Iw‡›x›cµ]BÿøFL…òÞàÅ›´S”ü|ç j×wqnµ‹&½;–u) ó•œ4O9’š<¿“ºüz—W½Ë.»Š°‹Îp_úäs©èÔè¼ÇêÒ̱ÇCÐK¼?[_½óå+Á» ýŠ=4¹d²Œ3Ñø;ŒŠÚ½cTÞ‰‹‰1cTnBèŽ$DvyLGÓá%c/—ÿ²X6Èmذ)è Ø¸wWcz²U"VbˆU¼ÿßV`êÝìU¿bíÉ~‚4ÙìvÓaå“ùG»Û㲈etÓâí¸Sas÷v°LtüA-VüûÛU÷Ƨÿ=?í’ÿ®?…±žé·¹O±IEND®B`‚verilator-3.856/internals.pod0000664000177100017500000006532012306677750016251 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 psudo-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 psudo-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 provided 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 no deprecated and should 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 =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 convenition have the suffix C<_bad> in their name, and include C 1> in either their C or C step as appropriate. =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 additonal 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 and SystemPerl tests also run the tests in the C, C and C directories when using I. This is disabled by default as SystemC/SystemPerl 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 * The regression tests will assume that you have a version of SystemPerl to match. Typically if working on Verilator from git, also use SystemPerl from git. =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 numberic, it then prints the width of the item. This field is a squence 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-2014 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.856/test_regress/0000775000177100017500000000000012307720634016240 5ustar wsnyderwsnyderverilator-3.856/test_regress/.gitignore0000664000177100017500000000016012234175446020231 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.856/test_regress/driver.pl0000775000177100017500000015570412306677750020120 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_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_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, "nc!" => \$opt_nc, "optimize:s" => \$opt_optimize, "site!" => \$opt_site, "stop!" => \$opt_stop, "trace!" => \$opt_trace, "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_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, glob ("${dir}/t_*.pl"); } } 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, 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} ||= "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 -export-dynamic -shared -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")], # Verilator vlt => 0, 'v3' => 0, verilator_flags => ["-cc", "-Mdir $self->{obj_dir}", "-OD", # As currently disabled unless -O3 "--debug-check"], verilator_flags2 => [], 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}/vlt_coverage.pl"; $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"; $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}}); $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{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{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; } elsif ($self->{coverage} && !$Have_System_Perl) { $self->skip("Test requires SystemPerl; 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 = ('g++', @{$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{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 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(" SpCoverage::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 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 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 --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 --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_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-2014 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.856/test_regress/Makefile_obj0000664000177100017500000000364012306677750020546 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-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. # #***************************************************************************** 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) $(SP_INCLUDER) $^ > $@ $(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.856/test_regress/input.vc0000664000177100017500000000013412234175446017733 0ustar wsnyderwsnyder +librescan +libext+.v -y t -y obj_dir/ +incdir+t +incdir+../include +incdir+obj_dir/ verilator-3.856/test_regress/Makefile0000664000177100017500000000433112306677750017712 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-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. # #****************************************************************************/ 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.856/test_regress/t/0000775000177100017500000000000012307720636016505 5ustar wsnyderwsnyderverilator-3.856/test_regress/t/t_func_twocall.pl0000775000177100017500000000071712234175446022057 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_case_zx_bad.pl0000775000177100017500000000117012262644672021636 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_preproc_psl_off.pl0000775000177100017500000000134612262644672022563 0ustar wsnyderwsnyder#!/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_psl.v"); compile ( verilator_flags2 => ['-E'], verilator_make_gcc=>0, stdout_filename => $stdout_filename, ); ok(files_identical($stdout_filename, "t/$Self->{name}.out")); 1; verilator-3.856/test_regress/t/t_unopt_array.pl0000775000177100017500000000077312234175446021744 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_flag_topmodule_bad.pl0000775000177100017500000000145612234175446023207 0ustar 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.856/test_regress/t/t_unopt_combo.pl0000775000177100017500000000076612234175446021727 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_program.v0000664000177100017500000000040512234175446020667 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.856/test_regress/t/t_bitsel_struct2.v0000664000177100017500000000274712234175446022203 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.856/test_regress/t/t_var_pins_sc32.pl0000775000177100017500000000407112234175446022047 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["-sp -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}.sp", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.856/test_regress/t/t_mem_multi_io2.cpp0000664000177100017500000000355512234175446022307 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.856/test_regress/t/t_case_dupitems.v0000664000177100017500000000344712234175446022056 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.856/test_regress/t/t_func_plog.pl0000775000177100017500000000071712234175446021353 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_alw.pl0000775000177100017500000000071712234175446021013 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_sys_file_scan.pl0000775000177100017500000000112312234175446022210 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_tri_eqcase.pl0000775000177100017500000000071712234175446021516 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_rand.pl0000775000177100017500000000116112262644672021333 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_blocking.pl0000775000177100017500000000071712234175446021167 0ustar 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.856/test_regress/t/t_func_graphcirc.v0000664000177100017500000000177312234175446022206 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.856/test_regress/t/t_interface_down_gen.v0000664000177100017500000000321012253135443023027 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.856/test_regress/t/t_preproc_ifdef.pl0000775000177100017500000000071712234175446022206 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_v2k.v0000664000177100017500000000271312253135443020755 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.856/test_regress/t/t_param_concat.v0000664000177100017500000000105512234175446021651 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.856/test_regress/t/t_debug_fatalsrc_bt_bad.pl0000775000177100017500000000144012234175446023631 0ustar 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.856/test_regress/t/t_trace_cat_reopen.out0000664000177100017500000001745012234175446023067 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.856/test_regress/t/t_dist_fixme.pl0000775000177100017500000000200412234175446021521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 FIXME $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 FIXMEs: ",join(' ',sort keys %names)); } } ok(1); 1; verilator-3.856/test_regress/t/t_select_bad_msb.v0000664000177100017500000000060412234175446022147 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.856/test_regress/t/t_order_doubleloop.v0000664000177100017500000000456212234175446022567 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.856/test_regress/t/t_lint_input_eq_bad.v0000664000177100017500000000035612306677750022712 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.856/test_regress/t/t_lint_restore_bad.v0000664000177100017500000000057612234175446022550 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.856/test_regress/t/t_interface_top_bad.v0000664000177100017500000000065512253135443022651 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.856/test_regress/t/t_struct_nest.v0000664000177100017500000000201312253135443021564 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.856/test_regress/t/t_flag_wfatal.pl0000775000177100017500000000155512234175446021647 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_math_synmul.v0000664000177100017500000000532512234175446021566 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.856/test_regress/t/t_clk_latchgate.pl0000775000177100017500000000071712234175446022164 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_only.v0000664000177100017500000000033412234175446021230 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.856/test_regress/t/t_lint_realcvt_bad.pl0000775000177100017500000000141712262644672022674 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_langext_3_bad.pl0000775000177100017500000000103612234175446022064 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_mem_multidim_trace.pl0000775000177100017500000000103612262644672023235 0ustar wsnyderwsnyder#!/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 => ['--sp --trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_grey.pl0000775000177100017500000000071712234175446021360 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_assert_synth.pl0000775000177100017500000000102512262644672022121 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_lint_defparam.v0000664000177100017500000000040712234175446022027 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.856/test_regress/t/t_func_bad_width.pl0000775000177100017500000000151512234175446022334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_tri_gate_nmos.pl0000775000177100017500000000133712262644672022233 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_tri_dangle.v0000664000177100017500000000103712234175446021332 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.856/test_regress/t/t_package_abs.v0000664000177100017500000000135412234175446021444 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.856/test_regress/t/t_param_type.v0000664000177100017500000000277012234175446021370 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.856/test_regress/t/t_flag_topmodule.v0000664000177100017500000000075012234175446022224 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.856/test_regress/t/t_dpi_context.v0000664000177100017500000000233212234175446021541 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(); 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 endmodule verilator-3.856/test_regress/t/t_param_sel_range_bad.pl0000775000177100017500000000167212234175446023325 0ustar 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.856/test_regress/t/t_inst_signed.v0000664000177100017500000000334312234175446021532 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; if (sgn_wide !== 8'sh7) $stop; // Simulators differ here. if (sgn_wide !== 8'sbzzzzz111 // z-extension - NC `ifdef VERILATOR && sgn_wide !== 8'sb00000111 // 0-extension - verilator as it doesn't have Z `endif && 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.856/test_regress/t/t_mem_first.pl0000775000177100017500000000071712234175446021364 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_interface.pl0000775000177100017500000000072212253135443021325 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_types_bad.v0000664000177100017500000000260612234175446022047 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.856/test_regress/t/t_alw_dly.v0000664000177100017500000000266412234175446020664 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.856/test_regress/t/t_mem_packed.pl0000775000177100017500000000071712234175446021464 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_sys_readmem_bad_end.pl0000775000177100017500000000107412234175446023340 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify 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.856/test_regress/t/t_func_task_bad.v0000664000177100017500000000046412234175446022010 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.856/test_regress/t/t_math_repl.pl0000775000177100017500000000071712234175446021352 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_pp_pragmas.v0000664000177100017500000000241312234175446021352 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.856/test_regress/t/t_flag_werror_bad1.pl0000775000177100017500000000146012234175446022573 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_param_public.pl0000775000177100017500000000072212253135443022023 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_pp_underline_bad.v0000664000177100017500000000037512234175446022520 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.856/test_regress/t/t_flag_topmodule_inline.pl0000775000177100017500000000104312234175446023727 0ustar 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.856/test_regress/t/t_initial_dlyass.v0000664000177100017500000000103212234175446022225 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.856/test_regress/t/t_lint_always_comb_bad.v0000664000177100017500000000146212253135443023352 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.856/test_regress/t/t_select_lhs_oob2.pl0000775000177100017500000000071712234175446022445 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gate_basic.pl0000775000177100017500000000071712234175446021460 0ustar 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.856/test_regress/t/t_tri_array_bufif.v0000664000177100017500000000600012234175446022364 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.856/test_regress/t/t_flag_topmodule.pl0000775000177100017500000000104412234175446022372 0ustar 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.856/test_regress/t/t_dpi_accessors.cpp0000664000177100017500000005675712234175446022403 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.856/test_regress/t/t_order_comboloop.pl0000775000177100017500000000071712234175446022563 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_flag_topmodule_bad2.pl0000775000177100017500000000134012234175446023261 0ustar 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.856/test_regress/t/t_inst_dtree.v0000664000177100017500000000261212234175446021362 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.856/test_regress/t/t_inst_array_bad.v0000664000177100017500000000112112234175446022175 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.856/test_regress/t/t_dpi_accessors_inc.vh0000664000177100017500000000316312234175446023046 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.856/test_regress/t/t_param_mem_attr.v0000664000177100017500000000211312234175446022206 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.856/test_regress/t/t_package_ddecl.pl0000775000177100017500000000102612234175446022117 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_preproc_inc_bad.v0000664000177100017500000000034712234175446022336 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.856/test_regress/t/t_func_outp.pl0000775000177100017500000000071712234175446021401 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_endian.v0000664000177100017500000000534312234175446021477 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.856/test_regress/t/t_math_concat.v0000664000177100017500000000546512234175446021513 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.856/test_regress/t/t_enum_int.v0000664000177100017500000000461212234175446021042 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.856/test_regress/t/t_lint_blksync_loop.v0000664000177100017500000000453212234175446022751 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 ["--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.856/test_regress/t/t_sys_sformat.pl0000775000177100017500000000071712234175446021750 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_local.v0000664000177100017500000000170712234175446021170 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.856/test_regress/t/t_math_mul.pl0000775000177100017500000000071712234175446021205 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_unopt_converge_unopt_bad.pl0000775000177100017500000000125012234175446024460 0ustar 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.856/test_regress/t/t_mem_slice.v0000664000177100017500000000557112234175446021166 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 if (active_command3[3][1][2] != 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.856/test_regress/t/t_var_bad_hide.pl0000775000177100017500000000132012234175446021755 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_order_comboclkloop.v0000664000177100017500000000321512234175446023100 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.856/test_regress/t/t_inst_tree_inl0_pub1.pl0000775000177100017500000000132212234175446023235 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_gen_defparam.pl0000775000177100017500000000071712234175446022007 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_trace_public.v0000664000177100017500000000253212234175446021657 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.856/test_regress/t/t_math_clog2.pl0000775000177100017500000000071712234175446021416 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_pull01.pl0000775000177100017500000000071712234175446021372 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_pins_sc_uint_biguint.pl0000775000177100017500000000477512253135443024467 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["-sp --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}.sp", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.856/test_regress/t/t_gen_mislevel.v0000664000177100017500000000121212234175446021666 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.856/test_regress/t/t_func_under2.v0000664000177100017500000000201712234175446021433 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.856/test_regress/t/t_func_begin2.v0000664000177100017500000000150212234175446021400 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.856/test_regress/t/t_math_divw.v0000664000177100017500000001363312234175446021211 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.856/test_regress/t/t_mod_dup_bad.v0000664000177100017500000000041012234175446021451 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.856/test_regress/t/t_param_value.v0000664000177100017500000000333112234175446021515 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.856/test_regress/t/t_math_vgen.pl0000775000177100017500000000071712234175446021347 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_lsb.v0000664000177100017500000000404212253135443020624 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.856/test_regress/t/t_select_plus.pl0000775000177100017500000000071712234175446021721 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_mlog2.v0000664000177100017500000000234512234175446021260 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.856/test_regress/t/t_dpi_string_c.cpp0000664000177100017500000000237412262644701022204 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.856/test_regress/t/t_inside.v0000664000177100017500000000404112234175446020473 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.856/test_regress/t/t_lint_unused_bad.v0000664000177100017500000000160612234175446022363 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.856/test_regress/t/t_struct_notfound_bad.v0000664000177100017500000000052212234175446023266 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.856/test_regress/t/t_udp_bad.pl0000775000177100017500000000120412234175446020765 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_param_repl.v0000664000177100017500000000230212234175446021340 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.856/test_regress/t/t_func_first.pl0000775000177100017500000000071712234175446021541 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_param_concat.pl0000775000177100017500000000077412234175446022031 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_math_vgen.v0000664000177100017500000002334712234175446021202 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 //============================================================ 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.856/test_regress/t/t_math_divw.pl0000775000177100017500000000071712234175446021361 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_mem_packed_assign.v0000664000177100017500000000147312234175446022657 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.856/test_regress/t/t_package_param.pl0000775000177100017500000000072212234175446022146 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_graph.pl0000775000177100017500000000067512234175446021361 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_case_inside.v0000664000177100017500000000313312306677750021474 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.856/test_regress/t/t_hierarchy_identifier_bad.pl0000775000177100017500000000220512234175446024357 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_trace_ena_cc.pl0000775000177100017500000000145212262644672021765 0ustar wsnyderwsnyder#!/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); } ok(1); 1; verilator-3.856/test_regress/t/t_select_index.pl0000775000177100017500000000072012234175446022037 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_package.v0000664000177100017500000000255712234175446020625 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.856/test_regress/t/t_sys_sformat.v0000664000177100017500000000257112234175446021577 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 [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 $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.856/test_regress/t/t_param_while.v0000664000177100017500000000126012234175446021510 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.856/test_regress/t/t_dedupe_seq_logic.pl0000775000177100017500000000106712234175446022671 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_select_bad_tri.v0000664000177100017500000000044712234175446022171 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.856/test_regress/t/t_cover_line_sc.pl0000775000177100017500000000115712262644672022213 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_pp_lib_inc.vh0000664000177100017500000000026112234175446021466 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.856/test_regress/t/t_inst_port_array.pl0000775000177100017500000000072212234175446022612 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_vpi_unimpl.cpp0000664000177100017500000001271412262644701021721 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 Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; #if VM_TRACE VL_PRINTF("Enabling waves...\n"); 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.856/test_regress/t/t_math_equal.v0000664000177100017500000000272712234175446021351 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.856/test_regress/t/t_func_wide.pl0000775000177100017500000000071712234175446021342 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_dpi_context_noopt.pl0000775000177100017500000000111212234175446023124 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_sys_readmem_bad_digit.pl0000775000177100017500000000107412234175446023672 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify 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.856/test_regress/t/t_param_sel.pl0000775000177100017500000000071712234175446021342 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_array_partial.v0000664000177100017500000000423012234175446023107 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.856/test_regress/t/t_lint_implicit.v0000664000177100017500000000052712234175446022065 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.856/test_regress/t/t_flag_f.v0000664000177100017500000000123612234175446020441 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.856/test_regress/t/t_mem_multiwire.v0000664000177100017500000000344212306677750022110 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.856/test_regress/t/t_func_public.pl0000775000177100017500000000103012234175446021655 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_interface_mismodport_bad.pl0000775000177100017500000000130012253135443024401 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_gen_for1.v0000664000177100017500000000276512234175446020733 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.856/test_regress/t/t_bitsel_wire_array_bad.v0000664000177100017500000000076112234175446023541 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.856/test_regress/t/t_func.pl0000775000177100017500000000071712234175446020332 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_outfirst.v0000664000177100017500000000532712234175446022122 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.856/test_regress/t/t_parse_delay.pl0000775000177100017500000000072212307713445021661 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_shift.v0000664000177100017500000000532712234175446021356 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 [31:0] right; reg [31:0] left; reg [63:0] qright; reg [63:0] qleft; reg [31:0] amt; 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.856/test_regress/t/t_interface1.pl0000775000177100017500000000072712262644672021424 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_mem_multi_io3_cc.pl0000775000177100017500000000117212262644672022605 0ustar wsnyderwsnyder#!/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"], ); ok(1); 1; verilator-3.856/test_regress/t/t_enum.v0000664000177100017500000000327512253135443020166 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.856/test_regress/t/t_flag_wfatal.v0000664000177100017500000000036712234175446021476 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.856/test_regress/t/t_inst_misarray_bad.pl0000775000177100017500000000122712234175446023066 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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=> '%Error: t/t_inst_misarray_bad.v:\d+: Illegal port connection \'foo\', mismatch between port which is not an array, and expression which is an array. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_alw.v0000664000177100017500000000330612234175446020637 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.856/test_regress/t/t_vpi_var.v0000664000177100017500000000650212253135443020664 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.856/test_regress/t/t_case_write1_tasks.v0000664000177100017500000030173612234175446022646 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.856/test_regress/t/t_select_plus.v0000664000177100017500000000625412234175446021552 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'h0c000000000000000000) $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.856/test_regress/t/t_pp_lib.pl0000775000177100017500000000077612234175446020651 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_bind2.pl0000775000177100017500000000072212234175446020371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_shift.pl0000775000177100017500000000071712234175446021525 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_flag_skipidentical.v0000664000177100017500000000030312234175446023031 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.856/test_regress/t/t_case_66bits.pl0000775000177100017500000000025012234175446021477 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.856/test_regress/t/t_clk_2in.v0000664000177100017500000000703212234175446020544 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.856/test_regress/t/t_math_svl.v0000664000177100017500000000677112234175446021051 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.856/test_regress/t/t_func_begin2.pl0000775000177100017500000000104212234175446021550 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_sys_readmem.v0000664000177100017500000000371212234175446021534 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.856/test_regress/t/t_flag_libinc.v0000664000177100017500000000077012234175446021456 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.856/test_regress/t/t_case_x_bad.pl0000775000177100017500000000133012262644672021442 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_sys_file_scan.v0000664000177100017500000000173212237723527022047 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.856/test_regress/t/t_tri_ifbegin.v0000664000177100017500000000172112234175446021503 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.856/test_regress/t/t_math_equal.pl0000775000177100017500000000071712234175446021517 0ustar 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.856/test_regress/t/t_func_const_bad.v0000664000177100017500000000234412234175446022173 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.856/test_regress/t/t_case_write2.pl0000775000177100017500000000121412262644672021602 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_func_const.v0000664000177100017500000000370012234175446021362 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.856/test_regress/t/t_select_bad_range2.v0000664000177100017500000000207212234175446022545 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.856/test_regress/t/t_mem_slice.pl0000775000177100017500000000071712253135443021326 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_program.pl0000775000177100017500000000071712234175446021046 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_if.pl0000775000177100017500000000073412234175446020625 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_interface_twod.pl0000775000177100017500000000072712262644672022400 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_lint_declfilename.pl0000775000177100017500000000111212234175446023023 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_func_bad.pl0000775000177100017500000000222512253135443021126 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_cast.v0000664000177100017500000000113612253135443020146 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; 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; o = tocast_t'(4'b1); if (o != 4'b1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.856/test_regress/t/t_sv_bus_mux_demux/0000775000177100017500000000000012307720634022422 5ustar wsnyderwsnyderverilator-3.856/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_wrap.sv0000664000177100017500000000646412234175446027437 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.856/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_demux.sv0000664000177100017500000000435612234175446027606 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.856/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_mux.sv0000664000177100017500000000444212234175446027271 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.856/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_def.sv0000664000177100017500000000200212234175446027204 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.856/test_regress/t/t_var_bad_hide2.v0000664000177100017500000000067512234175446021702 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.856/test_regress/t/t_EXAMPLE.v0000664000177100017500000000455212306677750020327 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 [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'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.856/test_regress/t/t_gen_for0.pl0000775000177100017500000000071712234175446021076 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_param_no_parentheses.v0000664000177100017500000000266112234175446023423 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.856/test_regress/t/t_math_reverse.v0000664000177100017500000000411712234175446021710 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.856/test_regress/t/t_tri_various.v0000664000177100017500000001076612234175446021601 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.856/test_regress/t/t_sys_readmem_bad_addr.v0000664000177100017500000000052512234175446023333 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.856/test_regress/t/t_lint_syncasyncnet_bad.pl0000775000177100017500000000200412234175446023743 0ustar 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.856/test_regress/t/t_param_ddeep_width.pl0000775000177100017500000000103412234175446023030 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_func_crc.v0000664000177100017500000002117312234175446021007 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.856/test_regress/t/t_dpi_var.cpp0000664000177100017500000001132112262644701021154 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.856/test_regress/t/t_langext_3.v0000664000177100017500000000075412234175446021113 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.856/test_regress/t/t_math_tri.pl0000775000177100017500000000071712234175446021206 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_attr_parenstar.pl0000775000177100017500000000071712234175446022430 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_struct_notfound_bad.pl0000775000177100017500000000105412234175446023440 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_for_local.pl0000775000177100017500000000071712234175446021337 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_notunsized.v0000664000177100017500000000460012234175446022460 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.856/test_regress/t/t_mem_slice_bad.pl0000775000177100017500000000210112234175446022127 0ustar 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.856/test_regress/t/t_gen_for.v0000664000177100017500000000712612234175446020646 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; i ['--psl --sp --coverage-user'], ); execute ( check_finished=>1, ); # Allow old Perl format dump, or new binary dump file_grep ($Self->{coverage_filename}, qr/(,o=>'cover'.*,c=>2\)|o.cover.* 2\n)/); file_grep ($Self->{coverage_filename}, qr/(DefaultClock.*,c=>1\)|DefaultClock.* 1\n)/); file_grep ($Self->{coverage_filename}, qr/(ToggleLogIf.*,c=>9\)|ToggleLogIf.* 9\n)/); ok(1); 1; verilator-3.856/test_regress/t/t_display_time.pl0000775000177100017500000000157612234175446022066 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_tri_gen.v0000664000177100017500000000133312234175446020650 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.856/test_regress/t/t_interface_down_inlac.pl0000775000177100017500000000112412253135443023517 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_select_set.pl0000775000177100017500000000072012234175446021523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_index.v0000664000177100017500000000262312234175446021164 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.856/test_regress/t/t_flag_csplit.pl0000775000177100017500000000271312253135443021656 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_sv_bus_mux_demux.pl0000775000177100017500000000102612234175446022765 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_var_in_assign.pl0000775000177100017500000000071712234175446022221 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_real.pl0000775000177100017500000000071712234175446021333 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_case_x.pl0000775000177100017500000000077412262644672020647 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_param_circ_bad.v0000664000177100017500000000042612234175446022131 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.856/test_regress/t/t_func_named.pl0000775000177100017500000000072212253135443021464 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_assert_synth.v0000664000177100017500000000370312234175446021752 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.856/test_regress/t/t_langext_1.pl0000775000177100017500000000075712234175446021265 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_case_huge_sub4.v0000664000177100017500000000333412234175446022104 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.856/test_regress/t/t_array_packed_write_read.pl0000775000177100017500000000102612234175446024223 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_func_graphcirc.pl0000775000177100017500000000071712234175446022354 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_order_multidriven.v0000664000177100017500000001101512253135443022746 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.856/test_regress/t/t_lint_declfilename_bad.pl0000775000177100017500000000153112234175446023636 0ustar 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.856/test_regress/t/t_gate_unsup.pl0000775000177100017500000000110712234175446021543 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_select_bad_range.v0000664000177100017500000000063212234175446022463 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.856/test_regress/t/t_pp_lib.v0000664000177100017500000000040012234175446020460 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.856/test_regress/t/t_vpi_var.cpp0000664000177100017500000004720312262644701021206 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 Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; #if VM_TRACE VL_PRINTF("Enabling waves...\n"); 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.856/test_regress/t/t_struct_init.pl0000775000177100017500000000072312234175446021743 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_select_bad_msb.pl0000775000177100017500000000117012234175446022317 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_gen_cond_bitrange.v0000664000177100017500000000557512234175446022664 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.856/test_regress/t/t_embed1_child.v0000664000177100017500000000167712234175446021534 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.856/test_regress/t/t_gen_assign.v0000664000177100017500000000234112234175446021336 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.856/test_regress/t/t_sys_readmem_b_8.mem0000664000177100017500000000066512234175446022601 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.856/test_regress/t/t_vpi_var.pl0000775000177100017500000000145312253135443021035 0ustar 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.856/test_regress/t/t_package_param.v0000664000177100017500000000141112234175446021771 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.856/test_regress/t/t_preproc_inc_inc_bad.vh0000664000177100017500000000032312234175446023331 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.856/test_regress/t/t_mod_recurse.v0000664000177100017500000000523712253135443021531 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.856/test_regress/t/t_cover_line.v0000664000177100017500000000607712234175446021360 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.856/test_regress/t/t_math_arith.pl0000775000177100017500000000071712234175446021517 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_gate_notif1.pl0000775000177100017500000000134312262644672022454 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_var_tieout.v0000664000177100017500000000205012234175446021377 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.856/test_regress/t/t_display.pl0000775000177100017500000000253112234175446021040 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the 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.856/test_regress/t/t_lint_only.pl0000775000177100017500000000155012262644672021405 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_flag_ldflags_c.cpp0000664000177100017500000000226112262644701022442 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.856/test_regress/t/t_sys_readmem_bad_digit.v0000664000177100017500000000052712234175446023523 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.856/test_regress/t/t_mem_func.pl0000775000177100017500000000071712234175446021170 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_order_comboclkloop.pl0000775000177100017500000000072312262644672023255 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_tri_inout.cpp0000664000177100017500000000222112234175446021547 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.856/test_regress/t/t_sys_readmem_b.mem0000664000177100017500000000055012234175446022343 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.856/test_regress/t/t_var_const_bad.v0000664000177100017500000000063712234175446022033 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.856/test_regress/t/t_order.v0000664000177100017500000000565612234175446020350 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.856/test_regress/t/t_tri_pull_bad.v0000664000177100017500000000031212234175446021655 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.856/test_regress/t/t_mem_multi_io3.cpp0000664000177100017500000000124112253135443022270 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.856/test_regress/t/t_trace_off_sc.pl0000775000177100017500000000120212262644672022005 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_flag_bboxsys.v0000664000177100017500000000065712234175446021713 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.856/test_regress/t/t_inst_signed.pl0000775000177100017500000000072212234175446021701 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_alw_dly.pl0000775000177100017500000000071712234175446021032 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_port_array.v0000664000177100017500000000205712234175446022444 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.856/test_regress/t/t_dpi_accessors.pl0000775000177100017500000000130312234175446022210 0ustar 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.856/test_regress/t/t_array_packed_sysfunct.v0000664000177100017500000001445212234175446023612 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.856/test_regress/t/t_detectarray_1.pl0000775000177100017500000000077512234175446022132 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_flag_f.vc0000664000177100017500000000036312234175446020604 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.856/test_regress/t/t_vpi_unimpl.v0000664000177100017500000000154512234175446021410 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.856/test_regress/t/t_array_pattern_unpacked.v0000664000177100017500000000243712306677750023761 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{ 4'd3, 4'd2, 4'd1, 4'd0 }} }}; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.856/test_regress/t/t_cover_toggle.pl0000775000177100017500000000127012262644672022054 0ustar wsnyderwsnyder#!/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 => ['--sp --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.856/test_regress/t/t_clk_vecgen3.pl0000775000177100017500000000103312234175446021552 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_param_chain.v0000664000177100017500000000142212253135443021454 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.856/test_regress/t/t_math_cmp.pl0000775000177100017500000000071712234175446021167 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_array_bad.pl0000775000177100017500000000125612262644672022362 0ustar wsnyderwsnyder#!/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+: Port connection __pinNumber2 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.856/test_regress/t/t_repeat.v0000664000177100017500000000133212234175446020500 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.856/test_regress/t/t_interface_modport.v0000664000177100017500000000613012253135443022717 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.856/test_regress/t/t_inst_dtree_inlab.pl0000775000177100017500000000112012234175446022671 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_gated_clk_1.pl0000775000177100017500000000072212253135443021522 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_mem_packed.v0000664000177100017500000001124412234175446021310 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.856/test_regress/t/t_select_negative.pl0000775000177100017500000000071712234175446022540 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_gate_pmos.pl0000775000177100017500000000133712262644672022235 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_lint_pindup_bad.v0000664000177100017500000000063712234175446022362 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.856/test_regress/t/t_tri_gate_cond.pl0000775000177100017500000000133712262644672022202 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_case_itemwidth.v0000664000177100017500000000457712234175446022227 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.856/test_regress/t/t_lint_unused_bad.pl0000775000177100017500000000236612234175446022540 0ustar 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.856/test_regress/t/t_extend_class_c.h0000664000177100017500000000073412234175446022165 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.856/test_regress/t/t_struct_packed_write_read.v0000664000177100017500000001237412234175446024270 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.856/test_regress/t/t_dpi_shortcircuit.pl0000775000177100017500000000130412234175446022746 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_struct_packed_value_list.v0000664000177100017500000001174112234175446024307 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.856/test_regress/t/t_inst_dtree_inld.pl0000775000177100017500000000107712234175446022545 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_flag_ldflags_a.cpp0000664000177100017500000000133712262644701022443 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.856/test_regress/t/t_var_outoforder.pl0000775000177100017500000000071712234175446022437 0ustar 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.856/test_regress/t/t_dist_spdiff.pl0000775000177100017500000000126512234175446021674 0ustar 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. my $root = ".."; if (!-r "$root/.git") { $Self->skip("Not in a git repository"); } else { my $cmd = "cd $root && nodist/spdiff . $ENV{SYSTEMPERL}"; my $grep = `$cmd`; print "$grep\n"; if ($grep ne "") { $Self->error("Include mismatches SystemPerl src\n"); } } ok(1); 1; verilator-3.856/test_regress/t/t_mem.v0000664000177100017500000000274212234175446020004 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 [15:0] 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.856/test_regress/t/t_var_init.pl0000775000177100017500000000071712234175446021212 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_bitsel_struct.v0000664000177100017500000000125012234175446022105 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.856/test_regress/t/t_gen_var_bad.v0000664000177100017500000000044312234175446021451 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.856/test_regress/t/t_assert_basic.pl0000775000177100017500000000102112262644672022031 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_var_vec_sel.pl0000775000177100017500000000104212234175446021657 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_math_swap.pl0000775000177100017500000000071712234175446021362 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_param_repl.pl0000775000177100017500000000071712234175446021521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_select_unsized.v0000664000177100017500000000141512234175446023120 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.856/test_regress/t/t_bitsel_struct.pl0000775000177100017500000000072212234175446022261 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_ccall.v0000664000177100017500000000241712234175446021340 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.856/test_regress/t/t_math_concat0.v0000664000177100017500000000411312234175446021560 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.856/test_regress/t/t_param.v0000664000177100017500000000272312234175446020325 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 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.856/test_regress/t/t_sv_bus_mux_demux.v0000664000177100017500000001635112234175446022623 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.856/test_regress/t/t_assert_basic_fail.pl0000775000177100017500000000120212262644672023025 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_gen_intdot2.v0000664000177100017500000001032712234175446021440 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.856/test_regress/t/t_langext_2_bad.pl0000775000177100017500000000103612234175446022063 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_math_svl.pl0000775000177100017500000000110612234175446021205 0ustar 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.856/test_regress/t/t_interface_gen3.v0000664000177100017500000000315612253135443022074 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.856/test_regress/t/t_unroll_signed.pl0000775000177100017500000000071712234175446022243 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_cond_const.v0000664000177100017500000000245212234175446022206 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.856/test_regress/t/t_savable.v0000664000177100017500000000357312234175446020646 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; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d\n",$time, cyc); `endif 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; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.856/test_regress/t/t_var_rsvd_port.pl0000775000177100017500000000073512234175446022271 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_func_const_bad.pl0000775000177100017500000000355412234175446022350 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_for_init_bug.pl0000775000177100017500000000066412234175446022046 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify 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.856/test_regress/t/t_gen_mislevel.pl0000775000177100017500000000071712234175446022050 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_select_loop.pl0000775000177100017500000000071712234175446021707 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_rand.v0000664000177100017500000000131012234175446021153 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.856/test_regress/t/t_udp_noname.pl0000775000177100017500000000103112234175446021512 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_clk_gater.pl0000775000177100017500000000117412234175446021330 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_pp_dupdef.v0000664000177100017500000000050212234175446021164 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.856/test_regress/t/t_bitsel_const_bad.pl0000775000177100017500000000117412234175446022673 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_enum.pl0000775000177100017500000000071712234175446020343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_trace_cat_renew.pl0000775000177100017500000000151612262644672022525 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_gen_var_bad.pl0000775000177100017500000000107512234175446021624 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_param_if_blk.v0000664000177100017500000000564312253135443021631 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.856/test_regress/t/t_bench_mux4k.pl0000775000177100017500000000071712234175446021606 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_display.v0000664000177100017500000000443312234175446020672 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.856/test_regress/t/t_tri_inout.pl0000775000177100017500000000116512262644672021414 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_preproc_ifdef.v0000664000177100017500000000145412234175446022034 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.856/test_regress/t/t_func_const.pl0000775000177100017500000000071712234175446021540 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_clk_2in.cpp0000664000177100017500000000206712234175446021064 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.856/test_regress/t/t_extend_class.pl0000775000177100017500000000107712262644672022056 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_dpi_shortcircuit_c.cpp0000664000177100017500000000353212262644701023415 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.856/test_regress/t/t_math_concat.pl0000775000177100017500000000071712234175446021657 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_for_funcbound.pl0000775000177100017500000000076412234175446022232 0ustar 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.856/test_regress/t/t_gate_implicit.pl0000775000177100017500000000071712234175446022211 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_notfound_bad.v0000664000177100017500000000107212234175446022533 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.856/test_regress/t/t_bitsel_slice.v0000664000177100017500000000344412306677750021674 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.856/test_regress/t/t_assert_cover.pl0000775000177100017500000000272512262644672022102 0ustar wsnyderwsnyder#!/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 --sp --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.856/test_regress/t/t_var_escape.out0000664000177100017500000000412212234175446021672 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.856/test_regress/t/t_leak.v0000664000177100017500000000074212234175446020140 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.856/test_regress/t/t_struct_packed_sysfunct.v0000664000177100017500000000302312234175446024010 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.856/test_regress/t/t_table_fsm.v0000664000177100017500000000767212234175446021171 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.856/test_regress/t/t_display_real.v0000664000177100017500000000343212234175446021673 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.856/test_regress/t/t_dos.pl0000775000177100017500000000071712234175446020164 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_enum_overlap_bad.pl0000775000177100017500000000130612234175446022674 0ustar 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.856/test_regress/t/t_func_under2.pl0000775000177100017500000000072212234175446021605 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_array_pattern_unpacked.pl0000775000177100017500000000103112306677750024117 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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, bug355"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_width_bad.v0000664000177100017500000000074412234175446022201 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 (); // 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)); endmodule module p #(parameter WIDTH=64) (input [WIDTH-1:0] in); wire [4:0] out = in; endmodule verilator-3.856/test_regress/t/t_const_dec_mixed_bad.v0000664000177100017500000000035712234175446023163 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.856/test_regress/t/t_select_index2.v0000664000177100017500000000152012253135443021741 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.856/test_regress/t/t_var_set_link.v0000664000177100017500000000100012234175446021670 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.856/test_regress/t/t_param_mem_attr.pl0000775000177100017500000000067412234175446022371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_math_precedence.pl0000775000177100017500000000071712234175446022505 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_implicit.pl0000775000177100017500000000101212234175446022224 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_pp_misdef_bad.v0000664000177100017500000000046012234175446021775 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.856/test_regress/t/t_pipe_filter.pf0000664000177100017500000000316212234175446021665 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.856/test_regress/t/t_trace_off_cc.pl0000775000177100017500000000117612262644672021777 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_preproc.v0000664000177100017500000003703312234175446020701 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 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.856/test_regress/t/t_tri_gate.v0000664000177100017500000000205412234175446021020 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.856/test_regress/t/t_tri_select.v0000664000177100017500000000201612234175446021355 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.856/test_regress/t/t_package_enum.v0000664000177100017500000000133612234175446021643 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.856/test_regress/t/t_func_rand.cpp0000664000177100017500000000123712234175446021500 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.856/test_regress/t/t_order_wireloop.v0000664000177100017500000000043412234175446022255 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*/); wire foo; wire bar; // Oh dear. assign foo = bar; assign bar = foo; endmodule verilator-3.856/test_regress/t/t_delay_stmtdly_bad.pl0000775000177100017500000000176412234175446023066 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_func_wide_out_bad.pl0000775000177100017500000000122312234175446023030 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_math_signed2.v0000664000177100017500000000300612234175446021564 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.856/test_regress/t/t_func_twocall.v0000664000177100017500000000275212234175446021707 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.856/test_regress/t/t_bind.pl0000775000177100017500000000072212234175446020307 0ustar 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.856/test_regress/t/t_order_a.v0000664000177100017500000000311112234175446020630 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.856/test_regress/t/t_gen_cond_bitrange_bad.pl0000775000177100017500000000163512253135443023626 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_lint_always_comb_bad.pl0000775000177100017500000000127112253135443023521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_vams_wreal.pl0000775000177100017500000000071712253135443021531 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_trace_complex.out0000664000177100017500000000435012306677750022417 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Sat Mar 8 15:28:02 2014 $end $timescale 1ns $end $scope module top $end $var wire 1 0 clk $end $scope module v $end $var wire 1 0 clk $end $var wire 32 # cyc [31:0] $end $var wire 2 ' v_arrp [2:1] $end $var wire 2 ( v_arrp_arrp [2:1] $end $var wire 2 ) v_arrp_strp [1:0] $end $var wire 1 1 v_arru(1) $end $var wire 1 2 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 3 v_arru_arru(3)(1) $end $var wire 1 4 v_arru_arru(3)(2) $end $var wire 1 5 v_arru_arru(4)(1) $end $var wire 1 6 v_arru_arru(4)(2) $end $var wire 2 , v_arru_strp(3) [1:0] $end $var wire 2 - v_arru_strp(4) [1: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 7 P [31:0] $end $upscope $end $scope module p3 $end $var wire 32 8 P [31:0] $end $upscope $end $scope module unnamedblk1 $end $var wire 32 . b [31:0] $end $scope module unnamedblk2 $end $var wire 32 / a [31:0] $end $upscope $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 b00000000000000000000000000000000 # b00 $ b0000 % b00 & b00 ' b0000 ( b0000 ) b00 * b00 + b00 , b00 - b00000000000000000000000000000000 . b00000000000000000000000000000000 / 00 01 02 03 04 05 06 b00000000000000000000000000000010 7 b00000000000000000000000000000011 8 #10 b00000000000000000000000000000001 # b11 $ b1111 % b11 & b11 ' b1111 ( b1111 ) b11 * b11 + b11 , b11 - b00000000000000000000000000000101 . b00000000000000000000000000000101 / 10 #15 00 #20 b00000000000000000000000000000010 # b00 $ b0000 % b00 & b00 ' b0000 ( b0000 ) b00 * b00 + b00 , b00 - 10 #25 00 #30 b00000000000000000000000000000011 # b11 $ b1111 % b11 & b11 ' b1111 ( b1111 ) b11 * b11 + b11 , b11 - 10 #35 00 #40 b00000000000000000000000000000100 # b00 $ b0000 % b00 & b00 ' b0000 ( b0000 ) b00 * b00 + b00 , b00 - 10 #45 00 #50 b00000000000000000000000000000101 # b11 $ b1111 % b11 & b11 ' b1111 ( b1111 ) b11 * b11 + b11 , b11 - 10 #55 00 #60 b00000000000000000000000000000110 # b00 $ b0000 % b00 & b00 ' b0000 ( b0000 ) b00 * b00 + b00 , b00 - 10 verilator-3.856/test_regress/t/t_tri_gate_bufif1.pl0000775000177100017500000000134312262644672022430 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_case_write2_tasks.v0000664000177100017500000025433112234175446022645 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.856/test_regress/t/t_dedupe_seq_logic.v0000664000177100017500000000525212234175446022520 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.856/test_regress/t/t_tri_select_unsized.pl0000775000177100017500000000074512234175446023276 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_var_pins_sc_biguint.pl0000775000177100017500000000471412253135443023421 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["-sp --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}.sp", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.856/test_regress/t/t_tri_select.pl0000775000177100017500000000116512262644672021535 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_inst_wideconst.v0000664000177100017500000000220412234175446022253 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.856/test_regress/t/t_gen_inc.v0000664000177100017500000001272412234175446020631 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.856/test_regress/t/t_var_pins_sc2.pl0000775000177100017500000000411112234175446021757 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["-sp -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}.sp", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.856/test_regress/t/t_lint_defparam_bad.pl0000775000177100017500000000154512234175446023012 0ustar 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.856/test_regress/t/t_tri_inout2.pl0000775000177100017500000000066012234175446021472 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 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.856/test_regress/t/t_pp_display.pl0000775000177100017500000000160212234175446021535 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the 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.856/test_regress/t/t_trace_complex_structs.out0000664000177100017500000000617612306677750024216 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Sat Mar 8 15:28:22 2014 $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 $var wire 2 , v_arrp [2:1] $end $var wire 2 - v_arrp_arrp(3) [1:0] $end $var wire 2 . v_arrp_arrp(4) [1:0] $end $var wire 1 < v_arru(1) $end $var wire 1 = v_arru(2) $end $var wire 2 3 v_arru_arrp(3) [2:1] $end $var wire 2 4 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 A v_arru_arru(4)(2) $end $scope module p2 $end $var wire 32 B P [31:0] $end $upscope $end $scope module p3 $end $var wire 32 C P [31:0] $end $upscope $end $scope module unnamedblk1 $end $var wire 32 9 b [31:0] $end $scope module unnamedblk2 $end $var wire 32 : a [31:0] $end $upscope $end $upscope $end $scope module v_arrp_strp(3) $end $var wire 1 0 b0 $end $var wire 1 / b1 $end $upscope $end $scope module v_arrp_strp(4) $end $var wire 1 2 b0 $end $var wire 1 1 b1 $end $upscope $end $scope module v_arru_strp(3) $end $var wire 1 6 b0 $end $var wire 1 5 b1 $end $upscope $end $scope module v_arru_strp(4) $end $var wire 1 8 b0 $end $var wire 1 7 b1 $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 b00000000000000000000000000000000 # 0$ 0% 0& 0' 0( 0) 0* 0+ b00 , b00 - b00 . 0/ 00 01 02 b00 3 b00 4 05 06 07 08 b00000000000000000000000000000000 9 b00000000000000000000000000000000 : 0; 0< 0= 0> 0? 0@ 0A b00000000000000000000000000000010 B b00000000000000000000000000000011 C #10 b00000000000000000000000000000001 # 1$ 1% 1& 1' 1( 1) 1* 1+ b11 , b11 - b11 . 1/ 10 11 12 b11 3 b11 4 15 16 17 18 b00000000000000000000000000000101 9 b00000000000000000000000000000101 : 1; #15 0; #20 b00000000000000000000000000000010 # 0$ 0% 0& 0' 0( 0) 0* 0+ b00 , b00 - b00 . 0/ 00 01 02 b00 3 b00 4 05 06 07 08 1; #25 0; #30 b00000000000000000000000000000011 # 1$ 1% 1& 1' 1( 1) 1* 1+ b11 , b11 - b11 . 1/ 10 11 12 b11 3 b11 4 15 16 17 18 1; #35 0; #40 b00000000000000000000000000000100 # 0$ 0% 0& 0' 0( 0) 0* 0+ b00 , b00 - b00 . 0/ 00 01 02 b00 3 b00 4 05 06 07 08 1; #45 0; #50 b00000000000000000000000000000101 # 1$ 1% 1& 1' 1( 1) 1* 1+ b11 , b11 - b11 . 1/ 10 11 12 b11 3 b11 4 15 16 17 18 1; #55 0; #60 b00000000000000000000000000000110 # 0$ 0% 0& 0' 0( 0) 0* 0+ b00 , b00 - b00 . 0/ 00 01 02 b00 3 b00 4 05 06 07 08 1; verilator-3.856/test_regress/t/t_display_wide.pl0000775000177100017500000001053712234175446022055 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_pp_misdef_bad.pl0000775000177100017500000000117312234175446022150 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_param_named_2.v0000664000177100017500000000206312234175446021707 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.856/test_regress/t/t_func_v.pl0000775000177100017500000000072212234175446020653 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_interface2.v0000664000177100017500000000470312253135443021241 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.856/test_regress/t/t_package_twodeep.pl0000775000177100017500000000071712234175446022521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_inout.v0000664000177100017500000000105312234175446021234 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.856/test_regress/t/t_lint_width.pl0000775000177100017500000000110612262644672021540 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_order_loop_bad.pl0000775000177100017500000000143212234175446022344 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_math_signed.pl0000775000177100017500000000071412234175446021656 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_various.pl0000775000177100017500000000025212234175446021737 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.856/test_regress/t/t_lint_unused.pl0000775000177100017500000000121012234175446021715 0ustar 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.856/test_regress/t/t_math_concat64.pl0000775000177100017500000000071712234175446022031 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_pins_cc.pl0000775000177100017500000000303312234175446021657 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_gen_intdot.pl0000775000177100017500000000071712234175446021531 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_pick.pl0000775000177100017500000000072212253135443021324 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_clk_2in.pl0000775000177100017500000000114512234175446020714 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_var_bad_sv.pl0000775000177100017500000000151712234175446021504 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_dedupe_clk_gate.pl0000775000177100017500000000106712234175446022475 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_mem_multidim_Ox.pl0000775000177100017500000000102612262644672022524 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_sys_rand.pl0000775000177100017500000000071712234175446021221 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_vpi_memory.cpp0000664000177100017500000001640212262644701021723 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 Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; #if VM_TRACE VL_PRINTF("Enabling waves...\n"); 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.856/test_regress/t/t_inst_prepost.pl0000775000177100017500000000065112234175446022125 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_interface_gen2.pl0000775000177100017500000000072712262644672022256 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_inside_wild.v0000664000177100017500000000334112306677750021521 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.856/test_regress/t/t_inst_v2k__sub.vi0000664000177100017500000000101312253135443022126 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.856/test_regress/t/t_inst_recurse_bad.v0000664000177100017500000000057512234175446022543 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.856/test_regress/t/t_mem_multi_io3.v0000664000177100017500000000305512253135443021760 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.856/test_regress/t/t_for_count.v0000664000177100017500000000457412234175446021231 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.856/test_regress/t/t_dpi_context_c.cpp0000664000177100017500000000574212262644701022364 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(); } #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; } } verilator-3.856/test_regress/t/t_flag_ldflags_so.cpp0000664000177100017500000000134012262644701022636 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.856/test_regress/t/t_interface2.pl0000775000177100017500000000100312262644672021411 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_order_loop_bad.v0000664000177100017500000000153612234175446022200 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.856/test_regress/t/t_dpi_shortcircuit.v0000664000177100017500000002052712234175446022605 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.856/test_regress/t/t_attr_parenstar.v0000664000177100017500000000133412234175446022253 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.856/test_regress/t/t_tri_pullup.v0000664000177100017500000000106512234175446021422 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.856/test_regress/t/t_vpi_unimpl.pl0000775000177100017500000000113712234175446021556 0ustar 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.856/test_regress/t/t_mem_multi_ref_bad.v0000664000177100017500000000140412234175446022652 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.856/test_regress/t/t_typedef.pl0000775000177100017500000000071712234175446021037 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_assert_synth_off.pl0000775000177100017500000000121012262644672022747 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_func_tie_bad.v0000664000177100017500000000054012234175446021622 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.856/test_regress/t/t_gen_index.pl0000775000177100017500000000101112234175446021323 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_emit_constw.v0000664000177100017500000000335112234175446021556 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.856/test_regress/t/t_sv_conditional.pl0000775000177100017500000000072212234175446022406 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_param_public.v0000664000177100017500000000126012253135443021650 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 verilator-3.856/test_regress/t/t_preproc_def09.out0000664000177100017500000000255212234175446022230 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.856/test_regress/t/t_package_dimport.pl0000775000177100017500000000066712234175446022534 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_inst_tree_inl1_pub1.pl0000775000177100017500000000112512234175446023237 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_flag_skipidentical.pl0000775000177100017500000000170712234175446023213 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_alw_combdly.v0000664000177100017500000000233612234175446021521 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; 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 @ ((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 (g != 32'hfeedface) $stop; end if (cyc==7) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.856/test_regress/t/t_func_gen.pl0000775000177100017500000000071712234175446021163 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_case_x_bad.v0000664000177100017500000000064712234175446021300 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.856/test_regress/t/t_lint_incabspath_bad.pl0000775000177100017500000000157112234175446023346 0ustar 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.856/test_regress/t/t_math_svl2.v0000664000177100017500000000155112234175446021122 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.856/test_regress/t/t_var_in_assign.v0000664000177100017500000000252712234175446022051 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.856/test_regress/t/t_lint_once_bad.pl0000775000177100017500000000153612262644672022162 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_select_little.pl0000775000177100017500000000071712234175446022233 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_pp_dupdef_bad.pl0000775000177100017500000000200512234175446022143 0ustar 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.856/test_regress/t/t_tri_pull2_bad.pl0000775000177100017500000000116312234175446022115 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_math_vliw.pl0000775000177100017500000000071712234175446021371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_hierarchy_unnamed.v0000664000177100017500000000062312234175446022707 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.856/test_regress/t/t_param_bit_sel.pl0000775000177100017500000000072212234175446022174 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_realcvt_bad.v0000664000177100017500000000035412234175446022517 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.856/test_regress/t/t_func_numones.v0000664000177100017500000000202012234175446021712 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.856/test_regress/t/t_preproc_psl_on.pl0000775000177100017500000000135312262644672022423 0ustar wsnyderwsnyder#!/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_psl.v"); compile ( verilator_flags2 => ['-psl -E'], verilator_make_gcc=>0, stdout_filename => $stdout_filename, ); ok(files_identical($stdout_filename, "t/$Self->{name}.out")); 1; verilator-3.856/test_regress/t/t_inst_dtree_inlc.pl0000775000177100017500000000107712234175446022544 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_inst_dtree_inlac.pl0000775000177100017500000000112012234175446022672 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_preproc_undefineall.pl0000775000177100017500000000111512234175446023410 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_interface1_modport.v0000664000177100017500000000153212253135443023001 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 ( ifc.out_modport isub, input integer i_value ); always @* begin isub.value = i_value; end endmodule verilator-3.856/test_regress/t/t_mem_fifo.pl0000775000177100017500000000071712234175446021160 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_precedence.v0000664000177100017500000001102712234175446022330 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 `ifdef verilator wire [1:0] o3 = a ** b ** c; `else // A commercial simulator gets this wrong, so calc manually wire [1:0] o3 = pow(pow(a,b),c); `endif 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 `ifdef verilator wire [1:0] x1 = ~ a ** ~ b ** ~c; wire [1:0] x2 = a ** b * c ** d; `else wire [1:0] x1 = pow(pow(~ a, ~ b), ~c); wire [1:0] x2 = pow(a,b) * pow(c,d); `endif 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'h34b4e0b25bb03880 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.856/test_regress/t/t_bitsel_struct3.pl0000775000177100017500000000072212234175446022344 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_array_packed_write_read.v0000664000177100017500000002350712234175446024062 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.856/test_regress/t/t_dpi_display.v0000664000177100017500000000215312234175446021523 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.856/test_regress/t/t_cover_toggle.v0000664000177100017500000000603312306677750021707 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.856/test_regress/t/t_clk_gen.pl0000775000177100017500000000071712234175446021001 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_pindup_bad.pl0000775000177100017500000000174712306677750022543 0ustar 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.856/test_regress/t/t_var_init.v0000664000177100017500000000124112234175446021032 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.856/test_regress/t/t_param_type.pl0000775000177100017500000000102612234175446021532 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_case_default_bad.v0000664000177100017500000000055512234175446022453 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.856/test_regress/t/t_case_zx_bad.v0000664000177100017500000000056512234175446021471 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.856/test_regress/t/t_order_multidriven.cpp0000664000177100017500000000214312253135443023265 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.856/test_regress/t/t_flag_f__3.v0000664000177100017500000000002312234175446021013 0ustar wsnyderwsnyder`define GOT_DEF3 1 verilator-3.856/test_regress/t/t_math_clog2.v0000664000177100017500000000513712234175446021246 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.856/test_regress/t/t_preproc_psl_on.out0000664000177100017500000000261112234175446022607 0ustar wsnyderwsnyder`line 1 "t/t_preproc_psl.v" 1 `line 4 "t/t_preproc_psl.v" 0 `line 7 "t/t_preproc_psl.v" 0 /*verilator metacomment preserved*/ /*verilator metacomment also_preserved*/ `line 11 "t/t_preproc_psl.v" 0 Hello in t_preproc_psl.v `line 17 "t/t_preproc_psl.v" 0 psl default clock = (posedge clk); psl fails1: cover {cyc==10}; psl assert always cyc!=10; psl assert always cyc==3 -> mask==8'h2; psl failsx: cover {cyc==3 && mask==8'h1}; psl fails2: cover { cyc==3 && mask==8'h9}; fails3: always assert { cyc==3 && mask==8'h10 }; 29 `line 31 "t/t_preproc_psl.v" 0 psl fails_ml: assert always cyc==3 -> mask==8'h21; psl fails_mlalso: assert always cyc==3 -> mask==8'h21; 41 `line 43 "t/t_preproc_psl.v" 0 psl assert never (cyc==1 && reset_l); `line 45 "t/t_preproc_psl.v" 0 psl fails3: assert always psl cyc==3 -> mask==8'h21; `line 49 "t/t_preproc_psl.v" 0 psl assert always psl {[*]; cyc==3; psl cyc==4; cyc==6}; `line 55 "t/t_preproc_psl.v" 0 `line 57 "t/t_preproc_psl.v" 0 `line 61 "t/t_preproc_psl.v" 0 psl assert always cyc!=10; `line 65 "t/t_preproc_psl.v" 0 `psl psl assert always sig!=90; `verilog `line 71 "t/t_preproc_psl.v" 0 72 `line 74 "t/t_preproc_psl.v" 2 verilator-3.856/test_regress/t/t_langext_4_bad.pl0000775000177100017500000000103612234175446022065 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_EXAMPLE.pl0000775000177100017500000000072212234175446020466 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_initial.v0000664000177100017500000000154712234175446020661 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.856/test_regress/t/t_func_real_param.pl0000775000177100017500000000071712234175446022515 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_vams_basic.pl0000775000177100017500000000071712234175446021506 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_sys_system.v0000664000177100017500000000114012234175446021437 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.856/test_regress/t/t_interface_modport_export.pl0000775000177100017500000000103112306677750024477 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_dpi_display.pl0000775000177100017500000000151712234175446021677 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_func_bad2.v0000664000177100017500000000052712234175446021050 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.856/test_regress/t/t_initial.pl0000775000177100017500000000071712234175446021030 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_embed1.v0000664000177100017500000000621412234175446020361 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.856/test_regress/t/t_param_while.pl0000775000177100017500000000072212234175446021663 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_unoptflat_simple_3.v0000664000177100017500000000230512234175446023030 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.856/test_regress/t/t_psl_basic.v0000664000177100017500000000257012234175446021164 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 toggle; integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; // psl cover {cyc==3 || cyc==4} @ (posedge clk); // psl assert {cyc<100} @ (posedge clk) report "AssertionFalse1"; `ifdef FAILING_ASSERTIONS // psl assert {toggle} @ (posedge clk) report "AssertionShouldFail"; `endif // psl default clock = negedge clk; //FIX // psl assert always {cyc<99}; // psl cover {cyc==9} report "DefaultClock,expect=1"; // psl assert {(cyc==5)->toggle}; // psl cover {(cyc==5)->toggle} report "ToggleLogIf,expect=1"; `ifdef NOT_SUP // psl assert {toggle<->cyc[0]}; // psl cover {toggle<->cyc[0]} report "CycsLogIff,expect=10"; `endif // Test {{..}} == Sequence of sequence... // psl assert {{true}}; always @ (negedge clk) begin //if (!(cyc==5) || toggle) $write("%d: %s\n", cyc, "ToggleLogIf,expect=1"); //if (toggle&&cyc[0] || ~toggle&&~cyc[0]) $write("%d: %s\n", cyc, "CycsLogIff,expect=10"); end always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; toggle <= !cyc[0]; if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.856/test_regress/t/t_param_module.v0000664000177100017500000000231212234175446021664 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.856/test_regress/t/t_wire_types.pl0000775000177100017500000000106312234175446021564 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_inst_array_inl1.pl0000775000177100017500000000103612262644672022473 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_dpi_context.pl0000775000177100017500000000077012234175446021716 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_func_v_noinl.pl0000775000177100017500000000103612234175446022051 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_tri_inout2.v0000664000177100017500000000267312234175446021327 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.856/test_regress/t/t_math_shiftrs.pl0000775000177100017500000000071712234175446022072 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_package_verb.v0000664000177100017500000000070712234175446021636 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.856/test_regress/t/t_delay.pl0000775000177100017500000000100612234175446020465 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_dpi_string.v0000664000177100017500000000116212253135443021355 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.856/test_regress/t/t_vlt_warn.vlt0000664000177100017500000000110312234175446021410 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.856/test_regress/t/t_pipe_exit_bad.pf0000664000177100017500000000060312234175446022154 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.856/test_regress/t/t_mem_func.v0000664000177100017500000000523712234175446021021 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.856/test_regress/t/t_pp_display.v0000664000177100017500000000430612234175446021370 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.856/test_regress/t/t_math_msvc_64.pl0000775000177100017500000000101712234175446021663 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_param_value.pl0000775000177100017500000000071712234175446021673 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_mod_recurse.pl0000775000177100017500000000103112253135443021666 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_sys_readmem_bad_notfound.v0000664000177100017500000000053212234175446024253 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.856/test_regress/t/t_tri_gate.cpp0000664000177100017500000000313012234175446021331 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.856/test_regress/t/t_case_reducer.pl0000775000177100017500000000072212234175446022017 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_package_export.v0000664000177100017500000000115512234175446022217 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.856/test_regress/t/t_trace_ena.v0000664000177100017500000000125012234175446021140 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; 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 verilator-3.856/test_regress/t/t_math_imm.pl0000775000177100017500000000104612234175446021166 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_interface_mismodport_bad.v0000664000177100017500000000114712253135443024241 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.856/test_regress/t/t_tri_unconn.pl0000775000177100017500000000072212234175446021551 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gate_unsup.v0000664000177100017500000000126712234175446021401 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.856/test_regress/t/t_const_overflow_bad.v0000664000177100017500000000110112234175446023071 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.856/test_regress/t/t_gate_elim.pl0000775000177100017500000000071712234175446021325 0ustar 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.856/test_regress/t/t_func_real_param.v0000664000177100017500000000104312234175446022335 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.856/test_regress/t/t_func_lib_sub.v0000664000177100017500000000415612234175446021661 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.856/test_regress/t/t_var_pins_sc64.pl0000775000177100017500000000406412234175446022056 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["-sp -pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.856/test_regress/t/t_alw_splitord.v0000664000177100017500000000757412234175446021741 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.856/test_regress/t/t_bitsel_slice.pl0000775000177100017500000000072212306677750022041 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_repeat_bad.v0000664000177100017500000000054612234175446022342 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.856/test_regress/t/t_math_synmul_mul.v0000664000177100017500000121176612234175446022454 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.856/test_regress/t/t_tri_dangle.pl0000775000177100017500000000071712234175446021507 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_clk_vecgen1.pl0000775000177100017500000000103312234175446021550 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_func_under.pl0000775000177100017500000000072212234175446021523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_case_wild.v0000664000177100017500000000576212234175446021165 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.856/test_regress/t/t_interface1_modport.pl0000775000177100017500000000072712262644672023170 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_final.v0000664000177100017500000000111112253135443020276 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.856/test_regress/t/t_sys_file_scan_input.dat0000664000177100017500000000000612237723527023562 0ustar wsnyderwsnyder1 2 3 verilator-3.856/test_regress/t/t_math_reverse.pl0000775000177100017500000000071712234175446022063 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_unoptflat_simple_3_bad.pl0000775000177100017500000000076212234175446024014 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_param_named_2.pl0000775000177100017500000000071712234175446022064 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_dotted.v0000664000177100017500000001224512234175446021360 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.856/test_regress/t/t_param_ceil.pl0000775000177100017500000000071712234175446021473 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_enum_int.pl0000775000177100017500000000071712234175446021215 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_sys_plusargs.pl0000775000177100017500000000040312234175446022125 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.856/test_regress/t/t_unopt_bound.pl0000775000177100017500000000072212253135443021721 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_cdc_async_bad.v0000664000177100017500000000404412234175446021757 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.856/test_regress/t/t_help.pl0000775000177100017500000000123512262644672020326 0ustar wsnyderwsnyder#!/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(fails=>1, cmd=>["perl","../bin/verilator", "--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.856/test_regress/t/t_order_clkinst.v0000664000177100017500000000444512234175446022072 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.856/test_regress/t/t_func_bad2.pl0000775000177100017500000000105512234175446021216 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_sv_enum_type_methods.pl0000775000177100017500000000106012234175446023627 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_embed1_wrap.v0000664000177100017500000000455612234175446021421 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.856/test_regress/t/t_interface_down_inld.pl0000775000177100017500000000110312253135443023354 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_trace_public_sig.pl0000775000177100017500000000156512262644672022702 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_sys_time.v0000664000177100017500000000114112234175446021052 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.856/test_regress/t/t_select_plusloop.v0000664000177100017500000000340312234175446022435 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.856/test_regress/t/t_math_signed.v0000664000177100017500000001316112234175446021505 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.856/test_regress/t/t_langext_3.pl0000775000177100017500000000075512234175446021265 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_case_x.v0000664000177100017500000000237312234175446020470 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.856/test_regress/t/t_flag_topmodule_inline.v0000664000177100017500000000077712234175446023573 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.856/test_regress/t/t_flag_werror.v0000664000177100017500000000036712234175446021540 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.856/test_regress/t/t_gate_elim.v0000664000177100017500000000423312234175446021151 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.856/test_regress/t/t_display_time.v0000664000177100017500000000161112234175446021703 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.856/test_regress/t/t_func_dotted_inl2.pl0000775000177100017500000000104312262644672022615 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_lint_implicit_port.pl0000775000177100017500000000077612253135443023302 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_order_multialways.pl0000775000177100017500000000071712234175446023145 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_debug_sigsegv_bt_bad.pl0000775000177100017500000000130712234175446023503 0ustar 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.856/test_regress/t/t_interface1.v0000664000177100017500000000143312253135443021235 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.856/test_regress/t/t_gen_cond_bitrange.pl0000775000177100017500000000071712234175446023026 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_real_abs.v0000664000177100017500000000221212234175446022001 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.856/test_regress/t/t_mem_packed_bad.pl0000775000177100017500000000124212234175446022264 0ustar 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.856/test_regress/t/t_mem_multi_io.pl0000775000177100017500000000105412234175446022051 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gate_basic.v0000664000177100017500000000370512234175446021307 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.856/test_regress/t/t_math_pow.pl0000775000177100017500000000071712234175446021215 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_defparam.v0000664000177100017500000000146112234175446021633 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.856/test_regress/t/t_dpi_import.v0000664000177100017500000002046212234175446021373 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.856/test_regress/t/t_package_twodeep.v0000664000177100017500000000077712234175446022356 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 (/*AUTOARG*/ // Inputs clk ); input clk; import pkg1::*; reg [PARAM1:0] bus1; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.856/test_regress/t/t_for_funcbound.v0000664000177100017500000000262712234175446022061 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.856/test_regress/t/t_bench_synmul.pl0000775000177100017500000000126612234175446022065 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_math_synmul.v"); $Self->{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.856/test_regress/t/t_inst_dtree_inla.pl0000775000177100017500000000107712234175446022542 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_case_orig.pl0000775000177100017500000000071712234175446021332 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_preproc_def09.pl0000775000177100017500000000130212262644672022032 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_lint_blksync_bad.pl0000775000177100017500000000217312234175446022676 0ustar 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.856/test_regress/t/t_inst_wideconst.pl0000775000177100017500000000076212234175446022433 0ustar 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.856/test_regress/t/t_math_msvc_64.v0000664000177100017500000000273312234175446021520 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.856/test_regress/t/t_select_bad_range2.pl0000775000177100017500000000117412253135443022712 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_param_if_blk.pl0000775000177100017500000000072212253135443021773 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_pipe_filter.out0000664000177100017500000000202012234175446022057 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.856/test_regress/t/t_trace_cat_reopen_0000.out0000664000177100017500000000533012234175446023520 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.856/test_regress/t/t_select_index.v0000664000177100017500000000203412234175446021666 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.856/test_regress/t/t_mem_iforder.v0000664000177100017500000000411612234175446021513 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.856/test_regress/t/t_sys_readmem_bad_end.mem0000664000177100017500000000050312234175446023474 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.856/test_regress/t/t_assert_cover_off.pl0000775000177100017500000000101012262644672022716 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_func_lib.pl0000775000177100017500000000077312234175446021162 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_vpi_get.v0000664000177100017500000000351512253135443020654 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.856/test_regress/t/t_preproc_undefineall.v0000664000177100017500000000073212234175446023243 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.856/test_regress/t/t_vpi_memory.pl0000775000177100017500000000135412253135443021555 0ustar 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.856/test_regress/t/t_math_signed_wire.pl0000775000177100017500000000072212234175446022703 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_trace_cat_reopen_0100.out0000664000177100017500000000510212234175446023516 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.856/test_regress/t/t_leak.pl0000775000177100017500000000115312234175446020306 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_gen_missing.v0000664000177100017500000000246212234175446021527 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.856/test_regress/t/t_array_query.pl0000775000177100017500000000072212234175446021736 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_enumeration.v0000664000177100017500000002773012234175446021560 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.856/test_regress/t/t_dpi_dup_bad.pl0000775000177100017500000000143612234175446021630 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_clk_dpulse.pl0000775000177100017500000000071712234175446021524 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_dpi_export.v0000664000177100017500000000444412234175446021404 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.856/test_regress/t/t_math_pow.v0000664000177100017500000000421712234175446021043 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 [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 if (61'h1 ** 21'h31 != 61'h1) $stop; if (61'h2 ** 21'h10 != 61'h10000) $stop; if (61'd10 ** 21'h3 != 61'h3e8) $stop; if (61'h3 ** 21'h7 != 61'h88b) $stop; if (61'h7ab3811219 ** 21'ha6e30 != 61'h01ea58c703687e81) $stop; 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: if (p!=61'h1) $stop; 32'd05: if (p!=61'h10000) $stop; 32'd06: if (p!=61'h3e8) $stop; 32'd07: if (p!=61'h88b) $stop; 32'd08: if (p!=61'h01ea58c703687e81) $stop; 32'd09: if (p!=61'h01ea58c703687e81) $stop; default: $stop; endcase case (cyc) 32'd00: ; 32'd01: ; 32'd02: if (shifted!=61'h0000000000000001) $stop; 32'd03: if (shifted!=61'h0000000000000008) $stop; 32'd04: if (shifted!=61'h0002000000000000) $stop; 32'd05: if (shifted!=61'h0000000000010000) $stop; 32'd06: if (shifted!=61'h0000000000000008) $stop; 32'd07: if (shifted!=61'h0000000000000080) $stop; 32'd08: if (shifted!=61'h0000000000000000) $stop; 32'd09: if (shifted!=61'h0000000000000000) $stop; default: $stop; endcase end endmodule verilator-3.856/test_regress/t/t_select_lhs_oob.v0000664000177100017500000000410712234175446022207 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.856/test_regress/t/t_math_real.v0000664000177100017500000000766012234175446021166 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; 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 // 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.856/test_regress/t/t_case_genx_bad.pl0000775000177100017500000000117012262644672022136 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_tri_pullup.pl0000775000177100017500000000116512262644672021577 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_gen_assign.pl0000775000177100017500000000074112262644672021514 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_const_dec_mixed_bad.pl0000775000177100017500000000114212262644672023330 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_param_concat_bad.pl0000775000177100017500000000150312234175446022626 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_gate_implicit.v0000664000177100017500000000343712234175446022042 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.856/test_regress/t/t_dedupe_clk_gate.v0000664000177100017500000000256312234175446022326 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.856/test_regress/t/t_select_lhs_oob2.v0000664000177100017500000000621512234175446022273 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.856/test_regress/t/t_var_dotted_inl2.pl0000775000177100017500000000104212262644672022451 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_bind2.v0000664000177100017500000000407312234175446020223 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.856/test_regress/t/t_interface_down_inla.pl0000775000177100017500000000110312253135443023351 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_clk_powerdn.pl0000775000177100017500000000072212262644672021705 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_order_clkinst.pl0000775000177100017500000000105112262644672022234 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_mem_multidim.pl0000775000177100017500000000071712234175446022061 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_pipe_exit_bad.pl0000775000177100017500000000146512262644672022177 0ustar 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.856/test_regress/t/t_math_strwidth.pl0000775000177100017500000000074612262644672022265 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_xml_first.v0000664000177100017500000000145312234175446021233 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.856/test_regress/t/t_for_init_bug.v0000664000177100017500000000137612234175446021676 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.856/test_regress/t/t_lint_input_eq_bad.pl0000775000177100017500000000132412306677750023057 0ustar 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.856/test_regress/t/t_dos.v0000775000177100017500000000066512234175446020020 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.856/test_regress/t/t_var_bad_sv.v0000664000177100017500000000032612234175446021330 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.856/test_regress/t/t_inst_tree_inl1_pub0.pl0000775000177100017500000000112712234175446023240 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_flag_ldflags.v0000664000177100017500000000123712234175446021631 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.856/test_regress/t/t_order_multialways.v0000664000177100017500000000234612234175446022774 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.856/test_regress/t/t_genvar_misuse_bad.v0000664000177100017500000000051312234175446022675 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.856/test_regress/t/t_var_bad_sameas.pl0000775000177100017500000000246712234175446022332 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_gen_local.v0000664000177100017500000000116412234175446021146 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.856/test_regress/t/t_lint_repeat_bad.pl0000775000177100017500000000137212234175446022511 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_var_pins_sc_uint.pl0000775000177100017500000000472712253135443022743 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["-sp --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}.sp", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.856/test_regress/t/t_order_multidriven.pl0000775000177100017500000000120312262644672023126 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_var_life.v0000664000177100017500000000443612234175446021017 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.856/test_regress/t/t_clk_gater.v0000664000177100017500000000635512234175446021165 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.856/test_regress/t/t_math_imm2.pl0000775000177100017500000000116012234175446021245 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_select_runtime_range.v0000664000177100017500000000146312234175446023423 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; reg read; 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; end if (cyc==3) begin read = mi[index]; if (read!==1'b0) $stop; end if (cyc==4) begin index = 6'd44; end if (cyc==5) begin read = mi[index]; $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.856/test_regress/t/t_case_reducer.v0000664000177100017500000002546112234175446021655 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.856/test_regress/t/t_langext_2.pl0000775000177100017500000000076112234175446021261 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_select_param.v0000664000177100017500000000066512234175446021667 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.856/test_regress/t/t_lint_incabspath.v0000664000177100017500000000031212234175446022357 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.856/test_regress/t/t_display_signed_noopt.pl0000775000177100017500000000250512234175446023611 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_mem_slot.cpp0000664000177100017500000000235612234175446021363 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.856/test_regress/t/t_flag_nomod_bad.pl0000775000177100017500000000113012234175446022300 0ustar 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.856/test_regress/t/t_gen_for.pl0000775000177100017500000000071712234175446021016 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_interface_down_inlc.pl0000775000177100017500000000110312253135443023353 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_func_noinl.pl0000775000177100017500000000071712234175446021531 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_sv_cpu.v0000664000177100017500000000625512234175446020530 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 (500 == 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 **** wire pad [1:NUMPADS]; // GPIO Pads (PORT{A,...,R}). // ************************************************************************** // Regs and Wires, Automatics // ************************************************************************** /*AUTOWIRE*/ // ************************************************************************** // Includes (Testbench extensions) // ************************************************************************** // N/A // ************************************************************************** // Chip Instance // ************************************************************************** chip i_chip ( /*AUTOINST*/ // Inouts .pad (pad), // Inputs .clk (clk), .rst (rst)); endmodule // test // Local Variables: // verilog-library-directories:("." "t_sv_cpu_code") // End: verilator-3.856/test_regress/t/t_cdc_async_bad.pl0000775000177100017500000000216612234175446022133 0ustar 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.856/test_regress/t/t_for_break.pl0000775000177100017500000000071712234175446021331 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_misarray_bad.v0000664000177100017500000000140112234175446022707 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.856/test_regress/t/t_lint_implicit_def_bad.pl0000775000177100017500000000165112234175446023661 0ustar 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.856/test_regress/t/t_interface_gen.pl0000775000177100017500000000072712262644672022174 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_func_noinl.v0000664000177100017500000000477612234175446021371 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.856/test_regress/t/t_var_types.v0000664000177100017500000001745312234175446021247 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.856/test_regress/t/t_clk_vecgen2.pl0000775000177100017500000000103312234175446021551 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_struct_packed_sysfunct.pl0000775000177100017500000000071712234175446024170 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_ccall.pl0000775000177100017500000000071712234175446021512 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gated_clk_1.v0000664000177100017500000000271312253135443021353 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.856/test_regress/t/t_var_nonamebegin.v0000664000177100017500000000224212234175446022353 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.856/test_regress/t/t_interface_gen2.v0000664000177100017500000000312612253135443022070 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.856/test_regress/t/t_select_plusloop.pl0000775000177100017500000000071712234175446022613 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_for_loop.pl0000775000177100017500000000071712234175446021216 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_bench_mux4k.v0000664000177100017500000001065012234175446021432 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.856/test_regress/t/t_preproc_psl.v0000664000177100017500000000346012234175446021554 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 metacomment preserved /**/ /*verilator metacomment also_preserved*/ Hello in t_preproc_psl.v // Psl capitalized not relevant // Double commented ignored // psl not ok // You can't have multiple statements on one // psl line. // Inline /*cmt*/ comments not allowed inside psl comments // psl default clock = (posedge clk); // psl fails1: cover {cyc==10}; // psl assert always cyc!=10; // psl assert always cyc==3 -> mask==8'h2; // psl failsx: cover {cyc==3 && mask==8'h1}; /* psl fails2: cover { cyc==3 && mask==8'h9}; // Ignore this comment-in-between-statements (however not legal inside a statement) fails3: always assert { cyc==3 && mask==8'h10 }; */ `__LINE__ // Note the PSL statement can be on a unique line // There can also be multiple "psl" keywords per line. /* psl fails_ml: assert always cyc==3 -> mask==8'h21; psl fails_mlalso: assert always cyc==3 -> mask==8'h21; */ `__LINE__ // psl assert never (cyc==1 && reset_l); // psl fails3: assert always // cyc==3 -> mask==8'h21; // syntax_error, not_part_of_above_stmt; // We need to count { and ( when looking for ; that terminate a PSL expression // psl assert always // {[*]; cyc==3; // cyc==4; cyc==6}; // syntax_error, not_part_of_above_stmt; // However /**/ pairs can't be split as above. `ifdef NEVER // psl ifdefs have precedence; `endif // Macros are expanded... `define define_sig cyc // psl assert always `define_sig!=10; `ifdef verilator `psl psl assert always sig!=90; `verilog `endif // Did we end up right? `__LINE__ verilator-3.856/test_regress/t/t_struct_port.v0000664000177100017500000000423112234175446021611 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.856/test_regress/t/t_assert_basic_cover.pl0000775000177100017500000000150212262644672023233 0ustar wsnyderwsnyder#!/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 --sp --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.856/test_regress/t/t_var_tieout.pl0000775000177100017500000000071712234175446021560 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_param_sel_range.v0000664000177100017500000000152512234175446022343 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.856/test_regress/t/t_param_chain.pl0000775000177100017500000000072212253135443021627 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_case_dupitems.pl0000775000177100017500000000071712234175446022224 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_const_overflow_bad.pl0000775000177100017500000000153512262644672023260 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_var_local.pl0000775000177100017500000000071712234175446021341 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_bad_hide.v0000664000177100017500000000066312234175446021615 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.856/test_regress/t/t_func_bad.v0000664000177100017500000000156012253135443020756 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.856/test_regress/t/t_case_66bits.v0000664000177100017500000000071512234175446021334 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.856/test_regress/t/t_dpi_name_bad.v0000664000177100017500000000066012234175446021605 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.856/test_regress/t/t_metacmt_onoff.v0000664000177100017500000000054312234175446022044 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.856/test_regress/t/t_package_export.pl0000775000177100017500000000120012234175446022357 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_case_onehot.v0000664000177100017500000000434012234175446021511 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.856/test_regress/t/t_func_first.v0000664000177100017500000000123612234175446021365 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.856/test_regress/t/TestVpi.h0000664000177100017500000000257212306677750020271 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.856/test_regress/t/t_mod_dup_bad.pl0000775000177100017500000000124712234175446021633 0ustar 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.856/test_regress/t/t_math_const.v0000664000177100017500000001122512253135443021353 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[2] = 12; v32[2]++; if (v32[2] != 13) $stop; v32[2] = 12; ++v32[2]; if (v32[2] != 13) $stop; v32[2] = 12; v32[2]--; if (v32[2] != 11) $stop; v32[2] = 12; --v32[2]; if (v32[2] != 11) $stop; v32[2] = 12; v32[2] += 2; if (v32[2] != 14) $stop; v32[2] = 12; v32[2] -= 2; if (v32[2] != 10) $stop; v32[2] = 12; v32[2] *= 2; if (v32[2] != 24) $stop; v32[2] = 12; v32[2] /= 2; if (v32[2] != 6) $stop; v32[2] = 12; v32[2] &= 6; if (v32[2] != 4) $stop; v32[2] = 12; v32[2] |= 15; if (v32[2] != 15) $stop; v32[2] = 12; v32[2] ^= 15; if (v32[2] != 3) $stop; v32[2] = 12; v32[2] >>= 1; if (v32[2] != 6) $stop; v32[2] = 12; v32[2] <<= 1; if (v32[2] != 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.856/test_regress/t/t_dpi_var.v0000664000177100017500000000433612234175446020653 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.856/test_regress/t/t_order_wireloop.pl0000775000177100017500000000105512234175446022426 0ustar 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}, expect=> '%Error: t/t_order_wireloop.v:\d+: Wire inputs its own output, creating circular logic .wire x=x. ', ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_gen.pl0000775000177100017500000000071712234175446021026 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_unopt_converge_run_bad.pl0000775000177100017500000000114412234175446024121 0ustar 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.856/test_regress/t/t_tri_graph.v0000664000177100017500000000075212234175446021204 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.856/test_regress/t/t_sys_plusargs.v0000664000177100017500000000207712234175446021765 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.856/test_regress/t/t_clk_condflop.v0000664000177100017500000000464112234175446021663 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.856/test_regress/t/t_dpi_accessors_macros_inc.vh0000664000177100017500000000167112234175446024414 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.856/test_regress/t/t_bitsel_struct2.pl0000775000177100017500000000072212234175446022343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_emit_constw.pl0000775000177100017500000000075712234175446021736 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_blocking.v0000664000177100017500000000363212234175446021015 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.856/test_regress/t/t_hierarchy_identifier_bad.v0000664000177100017500000000210012234175446024200 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.856/test_regress/t/t_gen_cond_bitrange_bad.v0000664000177100017500000000457412234175446023470 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.856/test_regress/t/t_inst_sv.v0000664000177100017500000000300212234175446020701 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.856/test_regress/t/t_func_lib_sub.pl0000775000177100017500000000075012234175446022026 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_trace_cat_renew_0000.out0000664000177100017500000000533012234175446023350 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.856/test_regress/t/t_unroll_signed.v0000664000177100017500000000616212234175446022072 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.856/test_regress/t/t_dpi_qw.v0000664000177100017500000000155512234175446020512 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.856/test_regress/t/t_math_concat64.v0000664000177100017500000001524612234175446021663 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.856/test_regress/t/t_inst_dtree_inlad.pl0000775000177100017500000000112012234175446022673 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_mem_iforder.pl0000775000177100017500000000072412262644672021670 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_var_rsvd_port.v0000664000177100017500000000062412234175446022115 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.856/test_regress/t/t_select_little.v0000664000177100017500000000421512234175446022057 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.856/test_regress/t/t_trace_cat.v0000664000177100017500000000046212234175446021150 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.856/test_regress/t/t_dpi_var.pl0000775000177100017500000000110212234175446021010 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_unoptflat_simple.v0000664000177100017500000000111512234175446022604 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.856/test_regress/t/t_vlt_warn.pl0000775000177100017500000000112112234175446021221 0ustar 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.856/test_regress/t/t_trace_public_func.pl0000775000177100017500000000137312262644672023050 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_clk_latchgate.v0000664000177100017500000001130712234175446022010 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.856/test_regress/t/t_array_query.v0000664000177100017500000000225412234175446021567 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.856/test_regress/t/t_psl_basic.pl0000775000177100017500000000102412262644672021331 0ustar wsnyderwsnyder#!/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 => [$Self->{v3}?'--assert':($Self->{nc}?'+assert':'')], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_flag_topmod2_bad.v0000664000177100017500000000071712234175446022411 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.856/test_regress/t/t_sys_readmem.pl0000775000177100017500000000071712234175446021707 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_struct_packed_value_list.pl0000775000177100017500000000071712234175446024461 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_flag_werror_bad2.pl0000775000177100017500000000135312234175446022575 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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(-sp -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.856/test_regress/t/t_embed1_c.cpp0000664000177100017500000000770712262644701021204 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.856/test_regress/t/t_sys_plusargs_bad.v0000664000177100017500000000074412234175446022572 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.856/test_regress/t/t_param_package.v0000664000177100017500000000064212234175446021776 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.856/test_regress/t/t_param_long.v0000664000177100017500000002132112234175446021337 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.856/test_regress/t/t_func_tie_bad.pl0000775000177100017500000000113412234175446021773 0ustar 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.856/test_regress/t/t_func_lib.v0000664000177100017500000000041012234175446020775 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.856/test_regress/t/t_vpi_memory.v0000664000177100017500000000247312253135443021407 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.856/test_regress/t/t_inst_overwide.v0000664000177100017500000000212312234175446022100 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.856/test_regress/t/t_mem_first.v0000664000177100017500000000575712234175446021224 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 // lint_checking BNDMEM OFF if (np2_mem[6] !== np2_mem[7]) begin $write("Mem[6]!=Mem[7] during randomize...\n"); //$stop; // Random value, so this can happen end //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.856/test_regress/t/t_alw_split.v0000664000177100017500000000734312234175446021226 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.856/test_regress/t/t_typedef_signed.pl0000775000177100017500000000071712234175446022370 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_for_break.v0000664000177100017500000000716612234175446021165 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.856/test_regress/t/t_clk_condflop.pl0000775000177100017500000000072212262644672022033 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_inst_array_inl0.pl0000775000177100017500000000104012262644672022465 0ustar wsnyderwsnyder#!/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.856/test_regress/t/bootstrap.pl0000775000177100017500000000121712234175446021065 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.856/test_regress/t/t_func_sum.pl0000775000177100017500000000071712234175446021216 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_return.pl0000775000177100017500000000071712234175446021731 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_select_index2.pl0000775000177100017500000000102412253135443022111 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_func_public_trace.pl0000775000177100017500000000124112234175446023037 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_gen_cond_const.pl0000775000177100017500000000100012234175446022343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_var_const.pl0000775000177100017500000000071712234175446021375 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_implicit_port.v0000664000177100017500000000106412234175446023126 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)); set u (.clk(clk), .enable(~implicit_also)); endmodule module set ( input clk, output enable ); assign enable = 1'b0; endmodule module read ( input clk, input data ); endmodule verilator-3.856/test_regress/t/t_dpi_accessors.v0000664000177100017500000000453112234175446022045 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.856/test_regress/t/t_flag_language.pl0000775000177100017500000000033012234175446022142 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.856/test_regress/t/t_flag_ldflags.pl0000775000177100017500000000226612234175446022005 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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}" ." && g++ -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}" ." && g++ -fPIC -c ../../t/t_flag_ldflags_so.cpp" ." && ld -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.856/test_regress/t/t_unopt_bound.v0000664000177100017500000000120712253135443021547 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.856/test_regress/t/t_alw_split.pl0000775000177100017500000000112612234175446021370 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_langext_2.v0000664000177100017500000000216312234175446021106 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.856/test_regress/t/t_sys_readmem_h.mem0000664000177100017500000000075512234175446022360 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.856/test_regress/t/t_func_paramed.pl0000775000177100017500000000071712234175446022023 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_mnpipe.pl0000775000177100017500000000072412262644672021725 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_func_v.v0000664000177100017500000000120212234175446020474 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.856/test_regress/t/t_func_named.v0000664000177100017500000000153412253135443021315 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.856/test_regress/t/t_param_ceil.v0000664000177100017500000000175412234175446021324 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.856/test_regress/t/t_extend.pl0000775000177100017500000000072112262644672020664 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_assert_synth_parallel.pl0000775000177100017500000000133012262644672023774 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_wire_types.v0000664000177100017500000000313112234175446021411 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.856/test_regress/t/t_mem_slot.pl0000775000177100017500000000116012234175446021207 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_tri_eqcase.v0000664000177100017500000000705012234175446021342 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.856/test_regress/t/t_func_flip.pl0000775000177100017500000000071712234175446021344 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_block_redecl_bad.pl0000775000177100017500000000144212234175446023637 0ustar 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.856/test_regress/t/t_clk_gen.v0000664000177100017500000000446212234175446020631 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.856/test_regress/t/t_case_onehot.pl0000775000177100017500000000071712234175446021666 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_mem_multi_ref_bad.pl0000775000177100017500000000227412234175446023031 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_param_named.v0000664000177100017500000000213712234175446021470 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.856/test_regress/t/t_clk_condflop_nord.pl0000775000177100017500000000101112262644672023045 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_final.pl0000775000177100017500000000072212253135443020456 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_sv_enum_type_methods.v0000664000177100017500000000614112234175446023463 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.856/test_regress/t/t_math_signed2.pl0000775000177100017500000000071712234175446021743 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_struct_unpacked.v0000664000177100017500000000077412253135443022421 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.856/test_regress/t/t_gen_if.v0000664000177100017500000000212712234175446020452 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.856/test_regress/t/t_mem_slice_conc_bad.v0000664000177100017500000000466112234175446022775 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.856/test_regress/t/t_bitsel_struct3.v0000664000177100017500000000163212234175446022174 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. 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; 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 if ((a == 8'h54) && (c == 8'h43) && (d == 8'h32)) begin $write("*-* All Finished *-*\n"); $finish; end else begin $stop; end end endmodule verilator-3.856/test_regress/t/t_enum_overlap_bad.v0000664000177100017500000000043212234175446022522 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.856/test_regress/t/t_select_negative.v0000664000177100017500000000356112234175446022367 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.856/test_regress/t/t_enum_type_methods.v0000664000177100017500000000544412234175446022760 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: System Verilog test of enumerated type methods // // This code instantiates a module that uses a localparam with an enumerated // type. // // 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; simple_test_1 simple_test_1_i (/*AUTOINST*/ // Outputs .c (c), // Inputs .a (a), .b (b)); // This is a compile time only test. Immediately finish always @(posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule // **** Simple use of parameters for sizing an array **** module simple_test_1 (input a, b, output c); int myarray1 [PINID_MAX]; endmodule verilator-3.856/test_regress/t/t_struct_portsel.pl0000775000177100017500000000072212234175446022467 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_struct_array.pl0000775000177100017500000000072212234175446022115 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_svl2.pl0000775000177100017500000000071412234175446021273 0ustar 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.856/test_regress/t/t_param.pl0000775000177100017500000000071712234175446020477 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_case_huge.v0000664000177100017500000001577012234175446021156 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.856/test_regress/t/t_inst_sv.pl0000775000177100017500000000071712234175446021064 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_hierarchy_identifier.v0000664000177100017500000000205412234175446023402 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 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.856/test_regress/t/t_tri_select.cpp0000664000177100017500000000275012234175446021677 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.856/test_regress/t/t_mem.pl0000775000177100017500000000071712234175446020155 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_cover_sva_notflat.pl0000775000177100017500000000147712262644672023124 0ustar wsnyderwsnyder#!/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 --sp --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.856/test_regress/t/t_for_count.pl0000775000177100017500000000071712234175446021375 0ustar 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.856/test_regress/t/t_gen_div0.pl0000775000177100017500000000071712234175446021072 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_flag_topmod2_bad.pl0000775000177100017500000000131512234175446022555 0ustar 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.856/test_regress/t/TestSimulator.h0000664000177100017500000000510612306677750021506 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.856/test_regress/t/t_trace_cat_renew.out0000664000177100017500000001745012234175446022717 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.856/test_regress/t/t_dpi_2exp_bad.pl0000775000177100017500000000114712234175446021715 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_cover_sva_notflat.v0000664000177100017500000000215112234175446022736 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.856/test_regress/t/t_inst_mism.v0000664000177100017500000000135412234175446021226 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.856/test_regress/t/t_dpi_display_c.cpp0000664000177100017500000000235312262644701022340 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.856/test_regress/t/t_select_param.pl0000775000177100017500000000072012234175446022030 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_mod_dup_ign.v0000664000177100017500000000065412234175446021512 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.856/test_regress/t/t_interface_gen3.pl0000775000177100017500000000072712262644672022257 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_pp_dupdef.pl0000775000177100017500000000101412234175446021334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_interface_down.pl0000775000177100017500000000072712262644672022372 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_trace_complex.pl0000775000177100017500000000216412306677750022227 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_debug_sigsegv_bad.pl0000775000177100017500000000134412234175446023017 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_math_pick.v0000664000177100017500000000427112253135443021156 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.856/test_regress/t/t_gen_for_shuffle.pl0000775000177100017500000000071712234175446022532 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_pull2_bad.v0000664000177100017500000000046312234175446021746 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.856/test_regress/t/t_alw_combdly.pl0000775000177100017500000000071712234175446021673 0ustar 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.856/test_regress/t/t_typedef_port.v0000664000177100017500000000437312234175446021734 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.856/test_regress/t/t_tri_gate_bufif0.pl0000775000177100017500000000134312262644672022427 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_unopt_converge.v0000664000177100017500000000062612234175446022262 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.856/test_regress/t/t_var_bad_sameas.v0000664000177100017500000000112412234175446022146 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.856/test_regress/t/t_inside_wild.pl0000775000177100017500000000072212306677750021672 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_blksync_bad.v0000664000177100017500000000151012234175446022517 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.856/test_regress/t/t_struct_unpacked_bad.pl0000775000177100017500000000112612253135443023370 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_tri_ifbegin.pl0000775000177100017500000000067212234175446021660 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_var_in_assign_bad.v0000664000177100017500000000065712234175446022661 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.856/test_regress/t/t_case_inside.pl0000775000177100017500000000072212306677750021646 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_clk_dsp.v0000664000177100017500000000723512234175446020647 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.856/test_regress/t/t_math_trig.v0000664000177100017500000001225612234175446021205 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 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 `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.856/test_regress/t/t_preproc.out0000664000177100017500000002547112234175446021246 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] `endprotected `line 160 "t/t_preproc.v" 0 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"); 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 544 "t/t_preproc.v" 2 verilator-3.856/test_regress/t/t_func_check.pl0000775000177100017500000000076212234175446021467 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_lint_multidriven_bad.v0000664000177100017500000000130212234175446023413 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.856/test_regress/t/t_var_nonamebegin.out0000664000177100017500000000240412234175446022715 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.856/test_regress/t/t_param_bit_sel.v0000664000177100017500000000132312234175446022021 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.856/test_regress/t/t_extend.v0000664000177100017500000000332412234175446020512 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.856/test_regress/t/t_mem_twoedge.v0000664000177100017500000000512712234175446021522 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.856/test_regress/t/t_struct_unpacked_bad.v0000664000177100017500000000067112253135443023223 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.856/test_regress/t/t_interface_down_inlb.pl0000775000177100017500000000110312253135443023352 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_func_real_abs.pl0000775000177100017500000000072212234175446022156 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_trace_cat.cpp0000664000177100017500000000355312253135443021463 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.856/test_regress/t/t_package_ddecl.v0000664000177100017500000000140512234175446021747 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.856/test_regress/t/t_var_dotted_inl1.pl0000775000177100017500000000103612262644672022453 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_dist_portability.pl0000775000177100017500000000370012234175446022757 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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(); } 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)); } } 1; verilator-3.856/test_regress/t/t_assert_synth_full.pl0000775000177100017500000000132012262644672023141 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_struct_portsel.v0000664000177100017500000000425112234175446022317 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.856/test_regress/t/t_case_write1.v0000664000177100017500000000172712234175446021436 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.856/test_regress/t/t_sys_rand.v0000664000177100017500000000144312234175446021045 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.856/test_regress/t/t_unopt_converge_print_bad.pl0000775000177100017500000000125612234175446024455 0ustar 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.856/test_regress/t/t_interface_down_inlad.pl0000775000177100017500000000112412253135443023520 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_var_rsvd.pl0000775000177100017500000000071712234175446021225 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_interface_down_inlcd.pl0000775000177100017500000000112412253135443023522 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_var_escape.v0000664000177100017500000000322512234175446021333 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.856/test_regress/t/t_var_nonamebegin.pl0000775000177100017500000000145612234175446022532 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_mem_multidim.v0000664000177100017500000000564612234175446021716 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.856/test_regress/t/t_pp_circdef_bad.pl0000775000177100017500000000120212234175446022271 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_case_write2.v0000664000177100017500000000172712234175446021437 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.856/test_regress/t/t_sys_file_autoflush.pl0000775000177100017500000000114012234175446023275 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_func_range.pl0000775000177100017500000000071712234175446021506 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_assert_dup_bad.pl0000775000177100017500000000121312234175446022346 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_sys_file_basic_input.dat0000664000177100017500000000021612253135443023712 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.856/test_regress/t/t_lint_implicit_def_bad.v0000664000177100017500000000070712234175446023511 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.856/test_regress/t/t_clk_dsp.pl0000775000177100017500000000071712234175446021016 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_interface_down_inlbd.pl0000775000177100017500000000112412253135443023521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_var_bad_hide2.pl0000775000177100017500000000132012234175446022037 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_for_loop.v0000664000177100017500000000346312234175446021046 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.856/test_regress/t/t_tri_unconn.v0000664000177100017500000001051612234175446021402 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.856/test_regress/t/t_gen_missing.pl0000775000177100017500000000077412234175446021704 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_inst_dtree_inlbc.pl0000775000177100017500000000112012234175446022673 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_inst_overwide.pl0000775000177100017500000000102112234175446022245 0ustar 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(-sp -Wno-WIDTH)], verilator_make_gcc=>0, ); #No execute () ok(1); 1; verilator-3.856/test_regress/t/t_select_set.v0000664000177100017500000000216312234175446021355 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.856/test_regress/t/t_math_swap.v0000664000177100017500000001014112234175446021201 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.856/test_regress/t/t_dpi_sys_c.cpp0000664000177100017500000000244512262644701021513 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.856/test_regress/t/t_sys_time.pl0000775000177100017500000000071712234175446021233 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_udp.v0000664000177100017500000000726612234175446020024 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.856/test_regress/t/t_lint_block_redecl_bad.v0000664000177100017500000000065512234175446023473 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.856/test_regress/t/t_dpi_sys.pl0000775000177100017500000000077012234175446021050 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_interface1_modport_trace.pl0000775000177100017500000000104712306677750024344 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_init_concat.pl0000775000177100017500000000071712234175446021671 0ustar 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.856/test_regress/t/t_dpi_export.pl0000775000177100017500000000127012234175446021547 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_math_imm2.cpp0000664000177100017500000000236112234175446021415 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.856/test_regress/t/t_mem_multi_io.v0000664000177100017500000000222612234175446021702 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.856/test_regress/t/t_select_lhs_oob.pl0000775000177100017500000000072212234175446022357 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_types.pl0000775000177100017500000000106312234175446021406 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_dpi_logic_bad.v0000664000177100017500000000071212234175446021760 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.856/test_regress/t/t_math_imm.v0000664000177100017500000000615312234175446021021 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.856/test_regress/t/t_case_genx_bad.v0000664000177100017500000000056412234175446021770 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.856/test_regress/t/t_var_vec_sel.v0000664000177100017500000000117012234175446021510 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.856/test_regress/t/t_mem_multi_io3_sc.pl0000775000177100017500000000117712262644672022632 0ustar wsnyderwsnyder#!/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"], ); ok(1); 1; verilator-3.856/test_regress/t/t_func_grey.v0000664000177100017500000000273412234175446021210 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.856/test_regress/t/t_array_pattern_packed.v0000664000177100017500000001417012306677750023413 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 initial begin 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; // Doesn't seem to work for unpacked arrays in other simulators //array_simp <= '{2 { '{4 { 4'd3, 4'd2, 4'd1, 4'd0 }} } }; $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'b10}} }}; else if (cnt[30:2]== 6) array_bg <= '{cnt+0, cnt+1, cnt+2, cnt+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+0, cnt+1, cnt+2, cnt+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.856/test_regress/t/t_lint_declfilename.v0000664000177100017500000000037212234175446022661 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.856/test_regress/t/t_cover_line_sp.pl0000775000177100017500000000115712262644672022230 0ustar wsnyderwsnyder#!/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 => ['--sp --coverage-line'], ); execute ( check_finished=>1, ); # Read the input .v file and do any CHECK_COVER requests inline_checks(); ok(1); 1; verilator-3.856/test_regress/t/t_array_packed_sysfunct.pl0000775000177100017500000000071712234175446023762 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_trace_public_sig.cpp0000664000177100017500000000204212234175446023032 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.856/test_regress/t/t_lint_incabspath.pl0000775000177100017500000000112212234175446022530 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_hierarchy_unnamed.pl0000775000177100017500000000102412234175446023054 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_display_signed.pl0000775000177100017500000000237712234175446022401 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the 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.856/test_regress/t/t_unoptflat_simple_bad.pl0000775000177100017500000000076012234175446023570 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_interface_modport_inl.pl0000775000177100017500000000115212262644672023742 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_flag_f.pl0000775000177100017500000000076012234175446020613 0ustar 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.856/test_regress/t/t_preproc_inc3.vh0000664000177100017500000000070312234175446021757 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.856/test_regress/t/t_case_orig.v0000664000177100017500000001010712234175446021153 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.856/test_regress/t/t_initial_edge.v0000664000177100017500000000434412234175446021643 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.856/test_regress/t/t_enum_type_methods.pl0000775000177100017500000000072212234175446023123 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_dpi_2exp_bad.v0000664000177100017500000000076212234175446021546 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.856/test_regress/t/t_embed1.pl0000775000177100017500000000276412234175446020540 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_cast.pl0000775000177100017500000000071712234175446020331 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_set_link.pl0000775000177100017500000000071712234175446022057 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_detectarray_2.pl0000775000177100017500000000077512234175446022133 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_display_signed.v0000664000177100017500000000270012234175446022216 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.856/test_regress/t/t_inst_missing.pl0000775000177100017500000000106212262644672022102 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_dist_untracked.pl0000775000177100017500000000210412234175446022372 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_trace_public.out0000664000177100017500000000507012234175446022221 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.856/test_regress/t/t_inst_aport.pl0000775000177100017500000000103112306677750021554 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_func_dotted.v0000664000177100017500000000762412234175446021530 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.856/test_regress/t/t_var_rsvd.v0000664000177100017500000000102312234175446021043 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 // global is a 1800-2009 reserved word, but we allow it when possible. reg global; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.856/test_regress/t/t_dpi_export_c.cpp0000664000177100017500000001123512262644701022213 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.856/test_regress/t/t_clk_dpulse.v0000664000177100017500000000205212234175446021345 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.856/test_regress/t/t_enum_func.v0000664000177100017500000000235212234175446021202 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.856/test_regress/t/t_flag_f__2.vc0000664000177100017500000000012512234175446021160 0ustar wsnyderwsnyder +define+GOT_DEF1 // -DNON_DEF /* +define+NON_DEF */ +define+GOT_DEF2=1 verilator-3.856/test_regress/t/t_xml_first.pl0000775000177100017500000000121712234175446021402 0ustar 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.856/test_regress/t/t_math_mul.v0000664000177100017500000000277312234175446021040 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.856/test_regress/t/t_initial_edge_bad.pl0000775000177100017500000000125412234175446022617 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_lint_width_bad.pl0000775000177100017500000000133312262644672022350 0ustar wsnyderwsnyder#!/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 ASSIGNW expects 5 bits on the Assign RHS, but Assign RHS's VARREF 'in' generates 4 bits. %Warning-WIDTH: Use .* %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_eq.pl0000775000177100017500000000071712234175446021015 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_package.pl0000775000177100017500000000071712234175446020772 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_bitsel_const_bad.v0000664000177100017500000000073112234175446022520 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.856/test_regress/t/t_pipe_filter.pl0000775000177100017500000000143212262644672021677 0ustar 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.856/test_regress/t/t_mem_slot.v0000664000177100017500000000111612234175446021037 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.856/test_regress/t/t_math_imm2.v0000664000177100017500000000231512234175446021077 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.856/test_regress/t/t_unopt_combo_isolate.pl0000775000177100017500000000117112234175446023436 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_sv_cpu.pl0000775000177100017500000000274612234175446020702 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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. $Self->{vlt} and $Self->unsupported("Verilator unsupported"); 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"], iv_flags2 => ["-yt/t_sv_cpu_code -It/t_sv_cpu_code -Y.sv"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_display_real_noopt.pl0000775000177100017500000000262612234175446023267 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_package_export_bad.pl0000775000177100017500000000132212234175446023172 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_package_dimport.v0000664000177100017500000000303312234175446022351 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.856/test_regress/t/t_savable.pl0000775000177100017500000000132412234175446021007 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_var_const.v0000664000177100017500000000105512306677750021225 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.856/test_regress/t/t_func_public.v0000664000177100017500000001262612234175446021521 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.856/test_regress/t/t_clk_powerdn.v0000664000177100017500000000611512234175446021533 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.856/test_regress/t/t_dpi_import_c.cpp0000664000177100017500000001325512262644701022210 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.856/test_regress/t/t_math_signed_wire.v0000664000177100017500000000200212234175446022523 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.856/test_regress/t/t_gen_forif.v0000664000177100017500000000442312234175446021162 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.856/test_regress/t/t_sv_cpu_code/0000775000177100017500000000000012307720634021317 5ustar wsnyderwsnyderverilator-3.856/test_regress/t/t_sv_cpu_code/program_h.sv0000664000177100017500000000201412234175446023650 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.856/test_regress/t/t_sv_cpu_code/timescale.sv0000664000177100017500000000041112234175446023637 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.856/test_regress/t/t_sv_cpu_code/ports_h.sv0000664000177100017500000000172712234175446023362 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.856/test_regress/t/t_sv_cpu_code/pad_gnd.sv0000664000177100017500000000102112234175446023263 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.856/test_regress/t/t_sv_cpu_code/adrdec.sv0000664000177100017500000000215312234175446023120 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.856/test_regress/t/t_sv_cpu_code/ports.sv0000664000177100017500000001005012234175446023040 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 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 { logic [7:0][1:0] in; logic [7:0] dir; logic [7:0] out; struct { 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.856/test_regress/t/t_sv_cpu_code/ac_dig.sv0000664000177100017500000000622212234175446023105 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 dbus.sConnect( .id(ID), .rst(rst), .sdata(sdata), .ws(ws), .mdata(mdata), .adr(adr[1:0]), .we(we), .re(re) ); // 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.856/test_regress/t/t_sv_cpu_code/rom.sv0000664000177100017500000000147212234175446022476 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.856/test_regress/t/t_sv_cpu_code/ac.sv0000664000177100017500000000350512234175446022263 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.856/test_regress/t/t_sv_cpu_code/pinout_h.sv0000664000177100017500000000322612234175446023525 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.856/test_regress/t/t_sv_cpu_code/pads_h.sv0000664000177100017500000000535312234175446023141 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.856/test_regress/t/t_sv_cpu_code/pad_gpio.sv0000664000177100017500000000204312234175446023456 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 **** alias ana = pad; // **** 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.856/test_regress/t/t_sv_cpu_code/cpu.sv0000664000177100017500000001320512234175446022465 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 busproperty = dbus.mPreAdrDecode( 0, idec_mem_adr ); end endmodule // cpu verilator-3.856/test_regress/t/t_sv_cpu_code/chip.sv0000664000177100017500000000642212234175446022624 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 **** inout wire pad [1:NUMPADS], // **** 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.856/test_regress/t/t_sv_cpu_code/pad_vdd.sv0000664000177100017500000000101612234175446023274 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.856/test_regress/t/t_sv_cpu_code/pads_if.sv0000664000177100017500000000570312234175446023307 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.856/test_regress/t/t_sv_cpu_code/ac_ana.sv0000664000177100017500000000202612234175446023077 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.856/test_regress/t/t_sv_cpu_code/pads.sv0000664000177100017500000000457612234175446022640 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 **** inout wire pad [1:NUMPADS], // **** Inputs **** input logic clk, input logic rst ); // *************************************************************************** // Code Section // *************************************************************************** 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 .ana (padsif.ana [i]), // 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.856/test_regress/t/t_sv_cpu_code/genbus_if.sv0000664000177100017500000001474512234175446023651 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]}}; s_ws [id] = ws & {SSIZE{s_sel[id]}}; 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.856/test_regress/t/t_interface_modport.pl0000775000177100017500000000072712262644672023107 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_init_concat.v0000664000177100017500000000341712234175446021520 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.856/test_regress/t/t_assert_basic.v0000664000177100017500000000217512234175446021670 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==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...."); 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.856/test_regress/t/t_func_dotted_inl0.pl0000775000177100017500000000104112262644672022611 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_dpi_name_bad.pl0000775000177100017500000000115112234175446021752 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_tri_gate_notif0.pl0000775000177100017500000000134312262644672022453 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_flag_lib.v0000664000177100017500000000032612234175446020761 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.856/test_regress/t/t_unoptflat_simple_2_bad.pl0000775000177100017500000000133612262537143024006 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_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 12 .*%Error: Exiting due to ', ); ok(1); 1; verilator-3.856/test_regress/t/t_param_long.pl0000775000177100017500000000071712234175446021516 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_unoptflat_simple_2.v0000664000177100017500000000120712234175446023027 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.856/test_regress/t/t_func_sum.v0000664000177100017500000000362212234175446021043 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.856/test_regress/t/t_psl_basic_off.pl0000775000177100017500000000100512262644672022162 0ustar wsnyderwsnyder#!/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_psl_basic.v"); compile ( v_flags2 => [], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_bad_width.v0000664000177100017500000000065412234175446022166 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.856/test_regress/t/t_math_strwidth.v0000664000177100017500000000066212234175446022106 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.856/test_regress/t/t_dist_install.pl0000775000177100017500000000275512253135443022066 0ustar 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.856/test_regress/t/t_interface_modport_import.pl0000775000177100017500000000072212306677750024476 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_case_nest.pl0000775000177100017500000000071712234175446021343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_trace_cat_renew_0100.out0000664000177100017500000000510212234175446023346 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.856/test_regress/t/t_case_deep.pl0000775000177100017500000000104612234175446021303 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_initial_dlyass_bad.pl0000775000177100017500000000115112234175446023206 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_math_trig.pl0000775000177100017500000000071712234175446021355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_table_fsm.pl0000775000177100017500000000071712234175446021333 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_inc.pl0000775000177100017500000000071712234175446021001 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_interface_twod.v0000664000177100017500000000154212253135443022212 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.856/test_regress/t/t_math_shiftrs.v0000664000177100017500000000226412277247360021722 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.856/test_regress/t/t_vpi_get.pl0000775000177100017500000000134112253135443021020 0ustar 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.856/test_regress/t/t_struct_unpacked.pl0000775000177100017500000000072212253135443022563 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_array_pattern_packed.pl0000775000177100017500000000103112306677750023554 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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, bug355"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_missing_bad.pl0000775000177100017500000000132612262644672022713 0ustar wsnyderwsnyder#!/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:\d+: Cell pin is not connected: nc %Warning-PINNOCONNECT: Use .* %Warning-PINMISSING: t/t_inst_missing_bad.v:\d+: Cell has missing pin: missing %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.856/test_regress/t/t_preproc_inc_bad.pl0000775000177100017500000000126012234175446022502 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_trace_complex.v0000664000177100017500000000310412306677750022051 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 (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; p #(.P(2)) p2 (); p #(.P(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; 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 if (cyc == 5) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module p; parameter P = 1; endmodule verilator-3.856/test_regress/t/t_struct_init_trace.pl0000775000177100017500000000103512306677750023123 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_pipe_filter_inc.vh0000664000177100017500000000041412234175446022523 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.856/test_regress/t/t_sys_system.pl0000775000177100017500000000071712234175446021621 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_wide.v0000664000177100017500000000153112234175446021164 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.856/test_regress/t/t_var_dotted_inl0.pl0000775000177100017500000000104012262644672022445 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_math_eq.v0000664000177100017500000000347212234175446020645 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.856/test_regress/t/t_func_endian.pl0000775000177100017500000000071712234175446021650 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_overwide_bad.pl0000775000177100017500000000233312234175446023062 0ustar 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(-sp)], 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 but 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 but connection's VARREF 'outd_w73' generates 73 bits. %Warning-WIDTH: t/t_inst_overwide.v:\d+: Input port connection inw_w31 expects 31 bits but connection's VARREF 'ina_w1' generates 1 bits. %Warning-WIDTH: t/t_inst_overwide.v:\d+: Input port connection inx_w11 expects 11 bits but connection's VARREF 'inb_w61' generates 61 bits. %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.856/test_regress/t/t_clk_latch.v0000664000177100017500000000617312234175446021154 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.856/test_regress/t/t_typedef_signed.v0000664000177100017500000000371112234175446022214 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.856/test_regress/t/t_flag_csplit.v0000664000177100017500000000172512253135443021507 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.856/test_regress/t/t_interface_gen.v0000664000177100017500000000345112253135443022007 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.856/test_regress/t/t_math_div.pl0000775000177100017500000000071712234175446021172 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_initial_dlyass.pl0000775000177100017500000000077712234175446022415 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_struct_nest.pl0000775000177100017500000000102412253135443021736 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_case_huge_sub2.v0000664000177100017500000002254112234175446022103 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.856/test_regress/t/t_func_mlog2.pl0000775000177100017500000000071712234175446021432 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_outoforder.v0000664000177100017500000000237312234175446022266 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.856/test_regress/t/t_struct_init.v0000664000177100017500000000573712234175446021604 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; // 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.856/test_regress/t/t_inst_aport.v0000664000177100017500000000474012306677750021415 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.856/test_regress/t/t_rnd.v0000664000177100017500000000170412234175446020006 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.856/test_regress/t/t_gen_lsb.pl0000775000177100017500000000072212253135443020776 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_case_default_bad.pl0000775000177100017500000000111412234175446022614 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_dist_manifest.pl0000775000177100017500000000412012234175446022220 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_initial_inc.vh0000664000177100017500000000044312234175446021654 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.856/test_regress/t/t_assert_basic_off.pl0000775000177100017500000000101012262644672022661 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_inst_array_partial.pl0000775000177100017500000000071712234175446023266 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_port_bad.v0000664000177100017500000000051112234175446021660 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.856/test_regress/t/t_sys_sformat_noopt.pl0000775000177100017500000000114412234175446023162 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_interface.v0000664000177100017500000000617712253135443021166 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.856/test_regress/t/t_mem_multi_io2.v0000664000177100017500000000140712234175446021764 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.856/test_regress/t/t_pipe_filter.v0000664000177100017500000000065012234175446021524 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.856/test_regress/t/t_param_sel.v0000664000177100017500000000376612234175446021200 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.856/test_regress/t/t_interface_down.v0000664000177100017500000000261112253135443022202 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.856/test_regress/t/t_struct_packed_write_read.pl0000775000177100017500000000071712234175446024437 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_range.v0000664000177100017500000000260312234175446021331 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.856/test_regress/t/t_preproc_inc2.vh0000664000177100017500000000040012234175446021750 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.856/test_regress/t/t_inst_recurse_bad.pl0000775000177100017500000000106612234175446022710 0ustar 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.856/test_regress/t/t_typedef_port.pl0000775000177100017500000000071712234175446022103 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_tri.v0000664000177100017500000000103412234175446021026 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.856/test_regress/t/t_initial_edge.pl0000775000177100017500000000077712234175446022022 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_display_noopt.pl0000775000177100017500000000263012234175446022257 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_mem_multi_io2_cc.pl0000775000177100017500000000124112262644672022601 0ustar wsnyderwsnyder#!/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"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_preproc_psl_off.out0000664000177100017500000000215112234175446022744 0ustar wsnyderwsnyder`line 1 "t/t_preproc_psl.v" 1 `line 4 "t/t_preproc_psl.v" 0 `line 7 "t/t_preproc_psl.v" 0 /*verilator metacomment preserved*/ /*verilator metacomment also_preserved*/ `line 11 "t/t_preproc_psl.v" 0 Hello in t_preproc_psl.v `line 17 "t/t_preproc_psl.v" 0 `line 28 "t/t_preproc_psl.v" 0 `line 28 "t/t_preproc_psl.v" 0 `line 28 "t/t_preproc_psl.v" 0 `line 28 "t/t_preproc_psl.v" 0 `line 28 "t/t_preproc_psl.v" 0 29 `line 31 "t/t_preproc_psl.v" 0 `line 40 "t/t_preproc_psl.v" 0 `line 40 "t/t_preproc_psl.v" 0 `line 40 "t/t_preproc_psl.v" 0 `line 40 "t/t_preproc_psl.v" 0 `line 40 "t/t_preproc_psl.v" 0 `line 40 "t/t_preproc_psl.v" 0 41 `line 43 "t/t_preproc_psl.v" 0 `line 45 "t/t_preproc_psl.v" 0 `line 49 "t/t_preproc_psl.v" 0 `line 55 "t/t_preproc_psl.v" 0 `line 57 "t/t_preproc_psl.v" 0 `line 61 "t/t_preproc_psl.v" 0 `line 65 "t/t_preproc_psl.v" 0 `psl psl assert always sig!=90; `verilog `line 71 "t/t_preproc_psl.v" 0 72 `line 74 "t/t_preproc_psl.v" 2 verilator-3.856/test_regress/t/t_vlt_warn.v0000664000177100017500000000122412234175446021054 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.856/test_regress/t/t_lint_restore_bad.pl0000775000177100017500000000133712262644672022720 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_lint_implicit_bad.pl0000775000177100017500000000204412234175446023040 0ustar 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.856/test_regress/t/t_trace_ena_sp.pl0000775000177100017500000000123112262644672022015 0ustar wsnyderwsnyder#!/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 -sp'], ); 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.856/test_regress/t/t_gen_for0.v0000664000177100017500000000146512234175446020726 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.856/test_regress/t/t_debug_fatalsrc_bad.pl0000775000177100017500000000132512234175446023146 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_unopt_array.v0000664000177100017500000000370212234175446021566 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.856/test_regress/t/t_lint_once_bad.v0000664000177100017500000000072712234175446022007 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.856/test_regress/t/t_inst_prepost.v0000664000177100017500000000102312234175446021746 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.856/test_regress/t/t_var_types_bad.pl0000775000177100017500000000227212234175446022217 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_case_auto1.pl0000775000177100017500000000071712234175446021423 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_clk_latch_edgestyle.pl0000775000177100017500000000120212262644672023361 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_math_cond_huge.pl0000775000177100017500000000071712234175446022343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_clk_latch.pl0000775000177100017500000000105112262644672021316 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_display_wide.v0000664000177100017500000000561212234175446021702 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.856/test_regress/t/t_case_write2.out0000664000177100017500000001155712234175446022003 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.856/test_regress/t/t_lint_ifdepth_bad.v0000664000177100017500000000202712234175446022501 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.856/test_regress/t/t_param_no_parentheses.pl0000775000177100017500000000071712234175446023574 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_param_ddeep_width.v0000664000177100017500000000116312234175446022662 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.856/test_regress/t/t_case_nest.v0000664000177100017500000000713312234175446021171 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.856/test_regress/t/t_hierarchy_identifier.pl0000775000177100017500000000071712234175446023557 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/.gitattributes0000664000177100017500000000002012234175446021372 0ustar wsnyderwsnydert_dos*.pl -crlf verilator-3.856/test_regress/t/t_flag_future.pl0000775000177100017500000000110012234175446021665 0ustar 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.856/test_regress/t/t_mem_slice_bad.v0000664000177100017500000000311212234175446021761 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.856/test_regress/t/t_func_types.v0000664000177100017500000000401412234175446021377 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.856/test_regress/t/t_mem_slice_conc_bad.pl0000775000177100017500000000101112234175446023130 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_gen_for1.pl0000775000177100017500000000071712234175446021077 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_setout_bad.pl0000775000177100017500000000131212234175446022546 0ustar 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.856/test_regress/t/t_select_bad_tri.pl0000775000177100017500000000117012234175446022334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_gen_intdot2.pl0000775000177100017500000000071712234175446021613 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_dtree_inlbd.pl0000775000177100017500000000112012234175446022674 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_preproc_kwd.pl0000775000177100017500000000071712234175446021716 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_pp_pragmas.pl0000775000177100017500000000071712234175446021530 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_tri_pullup.cpp0000664000177100017500000000240412234175446021735 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.856/test_regress/t/t_var_rsvd_bad.pl0000775000177100017500000000127312234175446022031 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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{%Error-SYMRSVDWORD: t/t_var_rsvd_port.v:\d+: Symbol matches C\+\+ common word: 'bool' %Error-SYMRSVDWORD: t/t_var_rsvd_port.v:\d+: Symbol matches C\+\+ reserved word: 'switch' %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_upscope.pl0000775000177100017500000000156612234175446021711 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the 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.tag created tag with scope = top.v.b.gen[0].tag created tag with scope = top.v.b.gen[1].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.856/test_regress/t/t_param_sel_range.pl0000775000177100017500000000114512234175446022512 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_dist_cinclude.pl0000775000177100017500000000332212234175446022203 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_inst_mnpipe.v0000664000177100017500000000266712234175446021561 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.856/test_regress/t/t_trace_cat.pl0000775000177100017500000000142612262644672021325 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_unopt_combo.v0000664000177100017500000000547512234175446021560 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.856/test_regress/t/t_flag_future.v0000664000177100017500000000036712234175446021532 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.856/test_regress/t/t_vams_basic.v0000664000177100017500000000177012234175446021335 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.856/test_regress/t/t_struct_array.v0000664000177100017500000000151512234175446021745 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.856/test_regress/t/t_math_vliw.v0000664000177100017500000000551412234175446021220 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.856/test_regress/t/t_gen_missing_bad.pl0000775000177100017500000000161612234175446022506 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_genvar_misuse_bad.pl0000775000177100017500000000123212234175446023045 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_case_write1.pl0000775000177100017500000000121312262644672021600 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_case_itemwidth.pl0000775000177100017500000000071712234175446022370 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_setout_bad_noinl.pl0000775000177100017500000000136612234175446023756 0ustar 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.856/test_regress/t/t_package_abs.pl0000775000177100017500000000071712234175446021617 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_outfirst.pl0000775000177100017500000000071712234175446022271 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_div.v0000664000177100017500000000542512234175446021022 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.856/test_regress/t/t_metacmt_onoff.pl0000775000177100017500000000161212234175446022213 0ustar 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.856/test_regress/t/t_interface_down_inlbc.pl0000775000177100017500000000112412253135443023520 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_dpi_sys.v0000664000177100017500000000140112234175446020667 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.856/test_regress/t/t_gen_local.pl0000775000177100017500000000071712234175446021322 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_param_circ_bad.pl0000775000177100017500000000131312234175446022276 0ustar 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.856/test_regress/t/t_var_in_assign_bad.pl0000775000177100017500000000150612234175446023024 0ustar 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.856/test_regress/t/t_bitsel_wire_array_bad.pl0000775000177100017500000000110312234175446023701 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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=> # TBD better error message, bug509 #'.* #%Error: Exiting due to.*', ); ok(1); 1; verilator-3.856/test_regress/t/t_mem_multiwire.pl0000775000177100017500000000071712234175446022256 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_flag_nomod_bad.v0000664000177100017500000000026012234175446022132 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.856/test_regress/t/t_sys_file_basic.pl0000775000177100017500000000146612234175446022357 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_sys_plusargs_bad.pl0000775000177100017500000000140212234175446022733 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_func_types.pl0000775000177100017500000000071712234175446021556 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_defparam.pl0000775000177100017500000000111212234175446022172 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_order_doubleloop.pl0000775000177100017500000000105112262644672022731 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_func_task_bad.pl0000775000177100017500000000111612234175446022154 0ustar 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.856/test_regress/t/t_detectarray_2.v0000664000177100017500000000153212234175446021752 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.856/test_regress/t/t_func_under.v0000664000177100017500000000130112234175446021344 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.856/test_regress/t/t_assert_dup_bad.v0000664000177100017500000000063112234175446022200 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.856/test_regress/t/t_sys_readmem_bad_digit.mem0000664000177100017500000000044312234175446024031 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.856/test_regress/t/t_dpi_qw.pl0000775000177100017500000000106112234175446020653 0ustar 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.856/test_regress/t/t_var_pinsizes.cpp0000664000177100017500000000177412253135443022255 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.856/test_regress/t/t_select_loop.v0000664000177100017500000000241412234175446021532 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.856/test_regress/t/t_rnd.pl0000775000177100017500000000071712234175446020162 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_delay.v0000664000177100017500000000135012234175446020316 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.856/test_regress/t/t_flag_lib.pl0000775000177100017500000000032312234175446021127 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.856/test_regress/t/t_trace_off_sp.pl0000775000177100017500000000120212262644672022022 0ustar wsnyderwsnyder#!/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 -sp'], ); 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.856/test_regress/t/t_case_huge.pl0000775000177100017500000000127312234175446021320 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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 --profile-cfuncs"], ); 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); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_trace_ena_sc.pl0000775000177100017500000000123112262644672022000 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_lint_ifdepth_bad.pl0000775000177100017500000000151212234175446022650 0ustar 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.856/test_regress/t/t_var_life.pl0000775000177100017500000000127212234175446021163 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_func_return.v0000664000177100017500000000314012234175446021551 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.856/test_regress/t/t_param_package.pl0000775000177100017500000000072212234175446022146 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_var_notfound_bad.pl0000775000177100017500000000172512234175446022711 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_func_dotted_inl1.pl0000775000177100017500000000103712262644672022617 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_udp_lint.pl0000775000177100017500000000114312234175446021207 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_udp_noname.v0000664000177100017500000000136612234175446021354 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.856/test_regress/t/t_var_escape.pl0000775000177100017500000000173012262644672021506 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_math_cmp.v0000664000177100017500000001043612234175446021015 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.856/test_regress/t/t_math_arith.v0000664000177100017500000000756312234175446021354 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}}; 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]); $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.856/test_regress/t/t_langext_1_bad.pl0000775000177100017500000000104012234175446022055 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_enumeration.pl0000775000177100017500000000102612234175446021717 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_vpi_get.cpp0000664000177100017500000001757112262644701021202 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; unsigned 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 Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; #if VM_TRACE VL_PRINTF("Enabling waves...\n"); 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.856/test_regress/t/t_preproc.pl0000775000177100017500000000364112262644672021053 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_case_huge_sub.v0000664000177100017500000004007712234175446022025 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.856/test_regress/t/t_tri_pull01.v0000664000177100017500000000373212234175446021221 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.856/test_regress/t/t_inst_array.v0000664000177100017500000000241212234175446021373 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.856/test_regress/t/t_pp_circdef_bad.v0000664000177100017500000000061512234175446022127 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.856/test_regress/t/t_func_numones.pl0000775000177100017500000000071712234175446022076 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_bind.v0000664000177100017500000000251612234175446020141 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.856/test_regress/t/t_dpi_string.pl0000775000177100017500000000077312253135443021535 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_math_const.pl0000775000177100017500000000071712234175446021536 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_math_concat0.pl0000775000177100017500000000071712234175446021737 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_sys_readmem_bad_end.v0000664000177100017500000000055512234175446023172 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.856/test_regress/t/t_func_paramed.v0000664000177100017500000000303612234175446021647 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; i1, 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.856/test_regress/t/t_trace_complex_structs.pl0000775000177100017500000000225012306677750024012 0ustar wsnyderwsnyder#!/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'], ); 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.856/test_regress/t/t_var_pins_sc1.pl0000775000177100017500000000412512234175446021763 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["-sp -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}.sp", qr/sc_in\s> \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.856/test_regress/t/t_lint_inherit.pl0000775000177100017500000000064712234175446022071 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_mod_dup_ign.pl0000775000177100017500000000110012234175446021646 0ustar 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.856/test_regress/t/t_func_regfirst.pl0000775000177100017500000000071712234175446022237 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_assert_cover.v0000664000177100017500000000645212234175446021727 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.856/test_regress/t/t_param_named.pl0000775000177100017500000000071712234175446021643 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_check.v0000664000177100017500000000246012234175446021313 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.856/test_regress/t/t_gen_forif.pl0000775000177100017500000000075512234175446021337 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_preproc_inc4.vh0000664000177100017500000000030012234175446021751 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.856/test_regress/t/t_leak.cpp0000664000177100017500000000444112262644701020451 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.856/test_regress/t/t_trace_cat_reopen.pl0000775000177100017500000000151612262644672022675 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_langext_1.v0000664000177100017500000000204312234175446021102 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.856/test_regress/t/t_func_regfirst.v0000664000177100017500000000240712234175446022064 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.856/test_regress/t/t_sys_file_basic.v0000664000177100017500000001411412253135443022172 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; 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; // $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.856/test_regress/t/t_var_pinsizes.v0000664000177100017500000000225212253135443021730 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, obv1, obv16, // Inputs clk, i1, i8, i16, i32, i64, i65, i128, i513, 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; 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; 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; end endmodule verilator-3.856/test_regress/t/t_select_little_pack.pl0000775000177100017500000000071712234175446023231 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inside.pl0000775000177100017500000000072212234175446020646 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_param_module.pl0000775000177100017500000000074612234175446022046 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_preproc_def09.v0000664000177100017500000000341112234175446021661 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.856/test_regress/t/t_order.pl0000775000177100017500000000071712234175446020512 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_case_write1.out0000664000177100017500000001674712234175446022010 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.856/test_regress/t/t_func.v0000664000177100017500000000627312234175446020164 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; incr(vec[2],vec[0],vec[2]); // Reading/Writing past end of vector! 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.856/test_regress/t/t_parse_delay.v0000664000177100017500000000072212307713445021510 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.856/test_regress/t/t_clk_condflop_nord.v0000664000177100017500000000542112253135443022674 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; // PROPER ANSWER is 8'h11, but we are negative-testing //if (q8 != 8'h11) $stop; if (q8 != 8'h33) $stop; end if (cyc==4) begin d1 <= 1'b1; d3<=3'h4; d8<=8'h77; ena <= 1'b1; // PROPER ANSWER is 8'h11, but we are negative-testing //if (q8 != 8'h11) $stop; if (q8 != 8'h33) $stop; end if (cyc==5) begin d1 <= 1'b1; d3<=3'h0; d8<=8'h88; ena <= 1'b1; // PROPER ANSWER is 8'h44, but we are negative-testing //if (q8 != 8'h44) $stop; end if (cyc==6) begin // PROPER ANSWER is 8'h77, but we are negative-testing //if (q8 != 8'h77) $stop; end if (cyc==7) begin // PROPER ANSWER is 8'h88, but we are negative-testing //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.856/test_regress/t/t_mem_shift.pl0000775000177100017500000000113612234175446021346 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_mem_multi_io2_sc.pl0000775000177100017500000000124612262644672022626 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_lint_blksync_loop.pl0000775000177100017500000000117412234175446023121 0ustar 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.856/test_regress/t/t_math_repl.v0000664000177100017500000000543012234175446021176 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.856/test_regress/t/t_sys_readmem_bad_notfound.pl0000775000177100017500000000104512234175446024424 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify 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.856/test_regress/t/t_inst_missing_bad.v0000664000177100017500000000055512234175446022542 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 nc, input missing); initial if (ok&&nc&&missing) begin end // No unused warning endmodule verilator-3.856/test_regress/t/t_func_gen.v0000664000177100017500000000155212234175446021010 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.856/test_regress/t/t_lint_inherit.v0000664000177100017500000000170112234175446021710 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.856/test_regress/t/t_interface_inl.pl0000775000177100017500000000114212262644672022175 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_sv_conditional.v0000664000177100017500000003500112234175446022233 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.856/test_regress/t/t_trace_cat.out0000664000177100017500000001177412234175446021522 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.856/test_regress/t/t_if_deep.v0000664000177100017500000001345112234175446020620 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.856/test_regress/t/t_interface_modport_import.v0000664000177100017500000000162012306677750024323 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.856/test_regress/t/t_enum_func.pl0000775000177100017500000000071712234175446021356 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_mem_fifo.v0000664000177100017500000000527412234175446021012 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<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.856/test_regress/t/t_pp_lib_library.v0000664000177100017500000000045212234175446022213 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.856/test_regress/t/t_trace_public_func.cpp0000664000177100017500000000205012234175446023202 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.856/test_regress/t/t_typedef.v0000664000177100017500000000236112234175446020663 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.856/test_regress/t/t_for_local.v0000664000177100017500000000224712234175446021166 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.856/test_regress/t/t_interface_down_gen.pl0000775000177100017500000000122012262644672023210 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_if_deep.pl0000775000177100017500000000104612234175446020766 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_select_bad_range.pl0000775000177100017500000000133612253135443022630 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_flag_language.v0000664000177100017500000000052412234175446021776 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.856/test_regress/t/t_case_huge_sub3.v0000664000177100017500000003140212234175446022100 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.856/test_regress/t/t_gen_div0.v0000664000177100017500000000130612234175446020714 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.856/test_regress/t/t_order_b.v0000664000177100017500000000062512234175446020640 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.856/test_regress/t/t_inst_dtree_inlcd.pl0000775000177100017500000000112012234175446022675 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_vams_wreal.v0000664000177100017500000000076412253135443021362 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.856/test_regress/t/tsub/0000775000177100017500000000000012307720634017460 5ustar wsnyderwsnyderverilator-3.856/test_regress/t/tsub/t_flag_f_tsub_inc.v0000664000177100017500000000010112234175446023272 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module `define GOT_DEF5 verilator-3.856/test_regress/t/tsub/t_flag_f_tsub.v0000664000177100017500000000010112234175446022441 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module `define GOT_DEF6 verilator-3.856/test_regress/t/tsub/t_flag_f_tsub.vc0000664000177100017500000000013512234175446022613 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module +define+GOT_DEF4=1 +incdir+. t_flag_f_tsub.v verilator-3.856/test_regress/t/t_langext_4.pl0000775000177100017500000000101712234175446021256 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_extend_class.v0000664000177100017500000000226712234175446021704 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.856/test_regress/t/t_inst_mism.pl0000775000177100017500000000072212234175446021375 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_lint_syncasyncnet_bad.v0000664000177100017500000000415712234175446023605 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.856/test_regress/t/t_inst_v2k.pl0000775000177100017500000000107012234175446021127 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_unopt_combo_bad.pl0000775000177100017500000000213412234175446022524 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_mem_file.pl0000775000177100017500000000071712234175446021154 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_intdot.v0000664000177100017500000000411512234175446021354 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.856/test_regress/t/t_case_wild.pl0000775000177100017500000000071712234175446021331 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_crc.pl0000775000177100017500000000104612234175446021155 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_interface_down_inlab.pl0000775000177100017500000000112412253135443023516 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_clk_2in_vec.pl0000775000177100017500000000117512234175446021554 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_package_verb.pl0000775000177100017500000000072212234175446022004 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_mem_shift.v0000664000177100017500000000233012234175446021172 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.856/test_regress/t/t_tri_array_bufif.pl0000775000177100017500000000071712234175446022546 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_func_outp.v0000664000177100017500000000317212234175446021226 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.856/test_regress/t/t_pp_underline_bad.pl0000775000177100017500000000120012234175446022655 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_dpi_import.pl0000775000177100017500000000115712234175446021544 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_var_pins_scui.pl0000775000177100017500000000406612234175446022244 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["-sp -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}.sp", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.856/test_regress/t/t_dpi_logic_bad.pl0000775000177100017500000000124312234175446022131 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/test_regress/t/t_mem_packed_assign.pl0000775000177100017500000000072212234175446023024 0ustar 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.856/test_regress/t/t_mem_file.v0000664000177100017500000001136412234175446021003 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.856/test_regress/t/t_lint_unused.v0000664000177100017500000000241112234175446021550 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.856/test_regress/t/t_inst_tree_inl0_pub0.pl0000775000177100017500000000113112234175446023232 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.856/test_regress/t/t_lint_setout_bad.v0000664000177100017500000000107512234175446022403 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.856/test_regress/t/t_var_const_bad.pl0000775000177100017500000000116312234175446022177 0ustar 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.856/test_regress/t/t_order_comboloop.v0000664000177100017500000000241212234175446022404 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.856/test_regress/t/t_clk_vecgen1.v0000664000177100017500000000537712234175446021416 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.856/test_regress/t/t_cover_line_cc.pl0000775000177100017500000000115712262644672022173 0ustar wsnyderwsnyder#!/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(); ok(1); 1; verilator-3.856/test_regress/t/t_flag_bboxsys.pl0000775000177100017500000000104712234175446022056 0ustar 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.856/test_regress/t/t_math_cond_huge.v0000664000177100017500000005001612234175446022167 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.856/test_regress/t/t_func_wide_out_bad.v0000664000177100017500000000147012234175446022663 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.856/test_regress/t/t_dpi_qw_c.cpp0000664000177100017500000000217212234175446021325 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.856/test_regress/t/t_func_plog.v0000664000177100017500000000446012234175446021201 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.856/test_regress/t/t_sys_readmem_bad_addr.mem0000664000177100017500000000045212234175446023643 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.856/test_regress/t/t_repeat.pl0000775000177100017500000000071712234175446020657 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_select_little_pack.v0000664000177100017500000000113612234175446023054 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.856/test_regress/t/t_case_auto1.v0000664000177100017500000000451712234175446021254 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.856/test_regress/t/t_interface_top_bad.pl0000775000177100017500000000122712262644672023027 0ustar wsnyderwsnyder#!/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.856/test_regress/t/t_package_enum.pl0000775000177100017500000000072212234175446022012 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_gen_for_shuffle.v0000664000177100017500000000344712234175446022364 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.856/test_regress/t/t_select_runtime_range.pl0000775000177100017500000000072012234175446023567 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.856/test_regress/t/t_inst_tree.v0000664000177100017500000000465012234175446021222 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.856/test_regress/t/t_inst_notunsized.pl0000775000177100017500000000077012234175446022635 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.856/verilator.pdf0000664000177100017500000137016212307720633016242 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.34) >> endobj 72 0 obj (18 LANGUAGE EXTENSIONS) endobj 73 0 obj << /S /GoTo /D (section.35) >> endobj 76 0 obj (19 LANGUAGE LIMITATIONS) endobj 77 0 obj << /S /GoTo /D (section.54) >> endobj 80 0 obj (20 ERRORS AND WARNINGS) endobj 81 0 obj << /S /GoTo /D (section.55) >> endobj 84 0 obj (21 FAQ/FREQUENTLY ASKED QUESTIONS) endobj 85 0 obj << /S /GoTo /D (section.56) >> endobj 88 0 obj (22 BUGS) endobj 89 0 obj << /S /GoTo /D (section.57) >> endobj 92 0 obj (23 HISTORY) endobj 93 0 obj << /S /GoTo /D (section.58) >> endobj 96 0 obj (24 CONTRIBUTORS) endobj 97 0 obj << /S /GoTo /D (section.59) >> endobj 100 0 obj (25 DISTRIBUTION) endobj 101 0 obj << /S /GoTo /D (section.60) >> endobj 104 0 obj (26 AUTHORS) endobj 105 0 obj << /S /GoTo /D (section.61) >> endobj 108 0 obj (27 SEE ALSO) endobj 109 0 obj << /S /GoTo /D [110 0 R /Fit ] >> endobj 112 0 obj << /Length 205 /Filter /FlateDecode >> stream xÚ-1nÃ0 EwŸ‚£4ˆ)Q²:h†¬Ú¡èP iÀˆǨ‘Û‡¶³øÞÿÔ®6ížPF&‰P€%`WRŒ˜> 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 620 /Filter /FlateDecode >> stream xÚ}TMoÜ ¼ï¯àTaEëðc8:^vKºþ¨í]%Ms¨šTª”4j©¿}޳iÜž@0ofœ ‹Ó5dÌ¥ÎHÆo ¤L5Ë¥I­Sl¸aW|ŸXÅo¿ß}I€?%Kà8yL–Ji®R›™äz8?]+qÄ£@¤FÄQ6õàë¡È…?qK0˜U "g_ïWׂÝàÖ9©r–ý>ï™2y*qvÇúÅÇÅYt.-*mä‹ucmªU>Ê>üHš¾ÅAð§_dTº#£‚á9R;@²t2ãuQy<€É¹ŒE ' ×_ÖMÛ‡>YJ'@ÎcaW¾/»Ð¡©n2§þ‚Zºè%ùfWajèo ßU®:Ã/± Ëæå²·Ñ_ pï­ !¼¿(ªvëI«<9¡‰¿ðåŽ,Cî8¸9Í|†£¿ì_•oy´†K1cÅÍ™¯Ë÷xÖ¡ÞPù;L¯ ŸŠÂH¦tÌq6Glë°õ€Î RÍÈ‚ÀíLp_ïÃ!µ¦¦ØeÂr©çب;»öå0Yš£% \š9Qùÿú)>°Ba^ù¬ E$«Ð!¶t„MWTÕÄðùuëd΋¸]â >Ü“æŸE&VmÀ!6?Øì_Zš´ö¾ ëP]‘jéW»®Øó$jGѱ3¢âþYÑ(\Á\BÙ˜Q÷ýlSµa{$/ñ)H®f{Ì”ò:lÐÚk×coH¡~e³½‘Á¶¨7»Ã)6Ïý=D®¢^ÅÅ¢[Ñ™û]Û6‡W:ÄVÏp¢4};¯ÿY )[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 421 /Filter /FlateDecode >> stream xÚu“AoÜ …ïþá–aÃÑ›x7N·¶Öà6Q”C”´R¥DU£JýûŒ7J÷†`Þ÷Þ °MÕf–œv,}g µ4¬ÖNú€,=²[þExäß^~<Ý à¿ÅðŸ´xgˆ†£ôÖ‰»tµÙ¡zÃAPÒi`ª0·>µ}й²jSõ«ÊGŠÁ«!JP5{x®nï{¤£+¦$ÏþÌ…Ï ]-5­žX¬ŽÕ6'×áCrç½4XWðÒ*~húýÔÔ|ßÒµÓ^SœØ }¤~‚ÕÈqî‚øÔ–ô'@øàÐ}î’Ž7"Xžh ]žÌD¸€PˆZb;Ž7Œ±ðšþ¢,¾ Ð5oƾë÷3Ë(Ï_eAaíHâùï¸Ùíq¢Qr¸›?µ3Þp:‹iéj´Ü†•¾µ.äí”3P7¹³«°T^v1 ãâ©éíØ÷‚¥Þ”úü Æn;¥yÚ8ÚsnÕÁÅ9Ì JO k¬æ®^³pE0dJ—ÅÁý¡þäPAl—ËmqȸHÞÿ€(èŸ,”ÓÛþ w½ endstream endobj 155 0 obj << /Type /Page /Contents 156 0 R /Resources 154 0 R /MediaBox [0 0 612 792] /Parent 118 0 R /Annots [ 136 0 R 145 0 R 146 0 R 147 0 R 148 0 R 149 0 R 150 0 R 151 0 R 152 0 R 153 0 R ] >> 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.34) >> >> 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.35) >> >> 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.54) >> >> 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.55) >> >> 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.56) >> >> 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.57) >> >> endobj 150 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 484.218 233.567 493.085] /A << /S /GoTo /D (section.58) >> >> endobj 151 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 450.347 225.571 459.215] /A << /S /GoTo /D (section.59) >> >> endobj 152 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 416.477 195.981 425.344] /A << /S /GoTo /D (section.60) >> >> 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.61) >> >> 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 1629 /Filter /FlateDecode >> stream xÚÅÛnÛ6ôÝ_!ôe2ÓºP²´·Ôs‹IšÕn‘" EflµºM¤âzÃþ}çðP²¸]=ì‰ä!ÏýÊ—‹Áø•X1‹C/´–ëyŒ[/dQì[‹¥ukF¾-š,O†®­†#×®`Ó G¾ÏmŸEA8¼[¼¿ò=:žÀå XŽãØgï†^d¿~9»Z ¾oÏß_^8|D*ƒÙbðÇÀ<Çr{a|æ:+-·w޵„«7–Ãü8²6úaaùá„y°Ë­ùà÷ÁKÔÊ‹,—3Ÿ‡ÞN­0Š÷'$“ 2PöÕÙåŒ80„c|l2á?a„é2­JTïqèMlA·ú-Þ>×øÕŠpÒ!’Áû¥ 'ª¢›éÉÉx¾•JS’ëPŒsðŽQÃ3jÌ?^½½žŸÏ/Ü}_8,vÃC}µ.ª/°G£µ@ióñ‘‡ë²8¾óøQ?ndÿÌû4¥Ým…xµÏ£T£ªÌ·àr'Ž‘¯&¿Ç›óö¨sžöyD|ãóßfóé»óëÅùÛ«ÿÁ×NûÐà’ul¹-1–ÕZÈìÏä>þäNY):ÜëëDãgU“äpïÒeÏSG=R ù „ü)œ#Ç®ó¶ãU†ü|«eÑ\åé1 Sv 탴â~d'åÒlh‘E’çfÛÞK¡h_=Ðú ÿìrþ„м]%Íøz~aàR‚0‚@r;#i«c‚B*Ÿš:gZgxÕì¯Éè9ÁÒ®(@rÎísS@2I¸dx$Ýû¢Î…25DfRkuüÆ—V>GˆnX'2ØØý—(ñ<’Áó<£²–ê«®vKºØdjM»:i’Äj 4:`ìãúz:=¥Ý4YŠ2tØ‹šÑÍÅøj:ÚsÓрР':U-·ò4Vˆî§sF·Ú”°6"YJÚ*,{øRÖ:0Eš}r|Žúàõaü ÷ÚvØyFbÈeÊÀuô ÝJW›$#bî#(Y÷}%BRhïR0Y¡1:J¸ÙàE‚ÜèÉCÕt£š$ÍÊøaü@ùy…* }ð%Äãª}\".’L¶¡2ô¤jUÝ¢†xÀ*xÌD0Žl¶¦͈U³ÆÛ“®ú°7m2'0qG:1 f®û¨4ôµ§v z\Úh‡01¹…°ºuCöI…ÓCê´ñ ñ6ë,EM@¯ j”.ßÍuN‘bâ{ÓdŠ|‡Qáîº<ÉP˜D“ ç0§@†è"«ÁÊtro¿“Ç8oyÝXµVªþu<Þl6 ›N­Q…­r¦Ã©Yé ®ã1Æ;C†êÀÈóà ,t~®±6xKÒ9Esè4Ã=rÚÒ¾OUê€JMÄAç”JÐ’àT6Ї;Î-Ô[Ú¡…$”„@y¦ˆu¼ôÂŽžIj²Œ¦Ã;]0Ðz7Gèf|•R%Tѳ„¸”ʠ´@hÛ:´r:ÆÉ­¡ë› À±BÇèédf§esŠÊä±j yÄ£€XãLVPSCÝÁ`’CIódJKŸxÐÆG”ÉœòÔ¡ÏŒ W`Zéë:‚ÈAHÅ9bíçmceI ¨/ÏÛ yzR#d›SáQ|i«ÌÈçM–çDÌÔé†ÊBTG#IU›äÏ!Ôߣ¬uI¢×+a:$8¿°6MûK[ÔÄc©“iSîOê¾ýbvsvy}1ëçvÏnfÓ÷8”½`?à£ÝßÈ¥¿‘ïîþFØÍèo{ô7úñx· Ðò»[1E;ü… Y³ h÷ŒÙÉNü'L „|Ýçð´G„scfãÌån÷ñ0ôI?* 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 229.316 null] >> endobj 158 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F31 162 0 R /F32 163 0 R >> /ProcSet [ /PDF /Text ] >> endobj 166 0 obj << /Length 1653 /Filter /FlateDecode >> stream xÚ­X[oÛ6~ϯÐCdxRuµ%À ÐÄI×ÂÙ²Æ-0Á K´ÃE–4‘Jã¿ÃCR–ËIº¾ØºßùÎýPgó“÷—nhÄv<òFÆ|i¸žgÆØÙQìó̸5¿ "ß$5Í“kòåš%\ÔË÷Ó·£p4¸›~é;ÏááHˆv9Žc~ø2ð"óã׫‹ßçb¿oÞ|½º‚§ á/rr1?ù÷Ä…}Žá¶d|ÛuÆFº>¹½sŒ ^}6Û#ã;.\þhl{p•7'žœ ­|·«UÙa£(²,I ]Xn‡B'òćø9X<3¿22°B/4¿ ÕË•¼‘«ÅÕwÊïåÕ’æ îñçšOœŒ–…\ aA;`h¹®‡a—ç8îëÈÕ?Aø&?Õ‘ã¼ÌàfÃ8Y bÙK\Ô&ò‡Ñ‡ø9ÄÿƒÃž\ïÇ8ˆ}oæ`…¶çÅ»D,+aŒÔ"Ñ ŽÌ‹"Yh $ÏÕ.AD×d‡ô˜†—˼ab PŠbÏ3/1L¦(2^“dÍæ’“zOλŒ²*O6="‹òÉbðÖŠƒ 2Ïò$}X`…z’û›â¡(¿+½ß14ž¼IAÆ1Ô¦@âMÌ¡Ô(ì-.kªª¬9Éäƒ<)V¸>Y)[-I›š°C2¨v†pS‘¬Ñëàî‘Âþx$uM³6ûÄKQ€y© Û“zƒÐ‡\x~9ûðñF ȤÆ4úùp(_—ë ¤+LX'–­”;–ZÖ:y Ký“¦°Ó ã±yåŠw+§l°mTðwÐài†û±gžç¥Xš>ÈJ’¡3׉¶VZ—ŒÑBE}R$ù†Ñ7¦;ÚMR–,0¸0¶ë„Ž9o ²§2«HJ—T;·U Q„íZ€ïVè1+§kÊ•ø¼,+áaG¤^_¤ê#œëtãtM‡OZÂ. 5 üÝÅÊ í'•Vk{k$$,x"Ïß”%ÝG ÔWâñrµBñÅ£jûRâ¾³aÂ¥Ï8^ßÌÞ‹÷7ßf*E™vý[À‹ŒÔ,-k¸…¡"ر£¼ ì¥üÿ›ÑÄ"{–ÚaÓÉcRŸÞþ:Aw$yCNïÐC±yCTˆT5©ê2%Œé0Ì ïŠcy—‘E#rÛuö¬/V"Qꌯ­ôÕ¹6ŽÆ}Ûz/V‹šÏŽ€Rîä-šë¢³Ž¥¦#@!9˜€-?&ÕBò:…ê´Ã!×Y~L9%³lPÅTM1KqÓöЂ)Ç#¬–I“s M­aÛ&âV Ç¡9•˶-d»Ž—**’𑾏ÊN00!Âà ƒ ¢×Ý-l"oŒ¯f]Y¼&j¶Ã~=¿cLXÓšÒ†Åd;~ôEJ–Jƒ¢µÇpæÙñX¿ao¯UèàŠ¼·YŠºäÃQünðÕee¾L9£(¹.m39b>hâe E×¶ õ¨/eÍŸÍ?üžª.\4ë…,:ÝŠ£FlßcbòDtKQô˜ê¨:®RŒõm³† iÃÑâ}Eì²3±œªÎsá)©U²8HÇÔÒB;¾ÐÞúE>• `ª¡àõÍA=–?Kä/­²…6Õ—¦h<2û·#¶yùqz&/h.KÒ# ô×%º‹ÿv;Œ,`ðäH'I{zØ=ÉEz»!˜g*'æý@Â%})ði’ÑúTOüSZ“¸mv+#IÞï‘£E*GúL%»u(r,º„’Xé“ ¤f{#K5ž#†ž2>]N/®ç¿©MRº‘à>@~8ÁQµûÁ[•ÀºŸV¢µ2-îé‚Ê¢ÎèZuÍîÄ»lŠ”·ç,-Ž…Î^ÐbûAOÒB [Ž™mgØ-Ûáq]f®¸MÐo+k6í;à„•âA™C•ÌP«\ü¶lO ÇOû³êl:ûtÖ‰ç*= ÈZ™‹C:Muà—äöÕ³¦‹ÃçJkŠÑ6_Æ“"Kêì5­XÇ!°—§vùñãtx ·w¶mÃÌ?e.ºEö5‚>œµýMºõX$‚«¹U˜yÕ—gØf þbïÖkÏe½g²««i{&ƒÇƪ¶ÙYçpF*Å«H7/vý«ëC‡Äê^~DØôcòHœÉ¯Œ»_+GŽíÆaù‘ 6ÐÕ‡ÄÿŒ¹“ endstream endobj 165 0 obj << /Type /Page /Contents 166 0 R /Resources 164 0 R /MediaBox [0 0 612 792] /Parent 118 0 R >> endobj 167 0 obj << /D [165 0 R /XYZ 121.4 736.262 null] >> endobj 164 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 170 0 obj << /Length 1658 /Filter /FlateDecode >> stream xÚ•Xmo›Hþž_Á·bE¸¼T«RÛ$wW5iïì´:UU…aíîXÊ‚÷×ßìì.Æ8ͧ€Ù™g^Ÿ™ÍÛåÙË+'0âiº¡±\ŽëN}cæ†Ó(öŒef|5?O"Ï$5Í“‰c6Ë1<ÔËó|Ó›FA8ù¶|ÿòʳ{z\/€/†-Uø eÛ¶ù柉™Ü^_Þ,…¼g.n¯¯áW@øWh9»\žý½7ì©GÆ=, /œM]xÊÅÙßgo…WžÓ÷Ê÷¦žaM}o&²¬ëŒ‚˜sx"©t®Þ½?ú‘y#Þ“‚È3l­þ¶MÕ6êyõЉg©Ä…#`Œå8Ó84XÁ2«ªÉZ褈`ÎÅKê@Ôsüؼé&ÿ‚TEJq4“b* øœ3ñrO”#ižpNø° %³*ZòPH@J¢ØuÍ ”/_('Z®À·yKË&ô¿7/¸üe͆çY¡/WTÉqºåw´²Ð M“|bù30þ‚òd•+Dq ÌÛÈ7q£#÷/P‚©ëÆ )”Hç%khò©ûAÒ;°;tãÈükS Ó“dƒ&~´á£ijC{X…q¿’†²rØ¿žþ“n~¨„‘z-‹¤L÷êžR5Wg°ìÄ9+'MCj( úÇ\*ìÀB©íS«ªhNHÚ i Åkœ›Gõ½¦¥Ž8Š`Th·ú¡ï'™ÕAŸ­4gé•‘<Ù©š†¸¢O{ËÅá.×( Ëý!¨dº) 4·l 5², õW¹.Çùj×®[j±ÿ0M«J»)¡ªŠ]·%éX£Yéº-S¥bΛ¤!Ú ßÝ fþz‹ÕŽWÃVS'ºšžÆ‡±.t”…¥'à3X«­ŽÅ¢âºLIéz§Tïª}è|s-iS“–ò0'[¢Ê¨bus •§È‚p&ÖÌóÑcêà-¹´¥’¶üÜŠn$b0›Á Â0?uܹð 0°ƒ" \/~¦k¿ÁŠXª˜=æ)+€{2Á!„åêè{’çºì»YÖü¨Y«),QœœÖ´jF€a˜ÉAxbˆ©iyzzy‡Ck „o¦{툷[é0–R\´Àˆvº…6šXq %pAVífƒý☯d=‰qÕ%_2,®t,Û\ÄØµg®yY&XašÉ>->({’š[Ó®r*zÖöÁÁΚW*D)ËŽ-èÀžub!c—0Öy‚¹ ¼|>Ð{J‘Ã`=ŽÖíÍÇOË+!ýáÍr‚'[IбË[Ã~£ó ‡0j`‡…ˆŒ¨Jõä|WÌ‚]츬ÔâÝ£©ÿXEuZÅ'Rç£ZºÄ *ŽízŠÄÚUCphò­¶¥°‰”ŸÅ Í6OÖÁ9Rlå0"ä¡9‡éÝtkÀ®då®8JÞ¹Ù¶åÚŽKÐ}%3>´¡ÅVŠå’“ßÙHO510 ’xÓ•C›d^Í1ð~´î“-‡”k©H•ûé E°i w7ŠºæhT7ü/H÷¥3Ä(ªÝ W„Ô[`?XI]';}OÚä´ Ìëämq´ ßÓLî9] Žõý!ZO|ŽÏƒh=›²½ƒGxBáILY›u›Šú££l<Ú x#޶µú.j„ŸR/‰6=ž2)$˜è¡Ó®³ó]l}IÎG;ív¾MÄN,yò¶Ì`•dWªV—ɹ‡:1Þ mY³<·Ð]Ö–z‹Ì«ºBZ¶¤™Àb/Ô% åtSP³k~x&IªhöÛ#ƒz®ì&0ÝŠu÷HÈ>„BUmÿ›ÊÎ^ÓáÕ›¨ ]ÅF°ÆæætU'Ã7îó­<èÄ&z,*/À¢hÀ“z¡o9q_f ‘À×GÓvž àÚ}™¡|!uÍjk.¯@œ'µ\Åæ;V¼fœ¤.»6Ò×”V»nE[ÈõE§÷ñ¼-ïJv¯r'ö¶¡{Üïy˜¾À­p.Äð b Ç`Û5ÉŒ)‘5û°TJÙž ¾ä½Öè öþ)ãx³fD±4êðŠÚ­ÈêÔ±Æãœ><†åEÓØu%J ÿ§õ?âTOo endstream endobj 169 0 obj << /Type /Page /Contents 170 0 R /Resources 168 0 R /MediaBox [0 0 612 792] /Parent 118 0 R >> endobj 171 0 obj << /D [169 0 R /XYZ 121.4 736.262 null] >> endobj 168 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 174 0 obj << /Length 2051 /Filter /FlateDecode >> stream xÚµXëܶÿ~…/Õâ,žøÐ 0 8‰]$p ¤wm$Ë[q÷Tk¥»·ú¿w†C½îä$nëwKRÃá<3ä—wW7oyäe,‹EìÝí<.S^"b–fһ˽ýlR雦(õ†ûÝ&à~ ƒfH©|ÉÒ(Þü|÷íÍ[Îøˆ4fRI/$l ÃÐý·Hý?ÿý/oþzw‹Û®ÞÜ]ýrÅ.ôøxºdÂ'¾°LÀhu±ñz¡Éd_ü‚hõüv*ÄÖ¸ðKˆ£‘£Í à<áÄj™Ä³re ­Á¢Ä>d€Eœhú™`g CØeÑ1ÑÎúÖÊàèÖOzÁäü`*ÙéÈW@E‚yÃPý!T âEÐ,°S)åß‘µ % ±m›‡SZ†Ä¬†Pf×—.óIl»Šc!Íiƒ îy¶ÿŠN¦É'fú5—±‚• 8t×Î(j¶+…È ÅTº5ÎŽh…³Cþã?áüdNÃðórÎ>g.>ó2œ£”‰ì÷›Ý SS¿ÔÕ¾×{‡°mਛü9^§^C„çOZ¯vqÔv^*}pûAtSµÝ/V’7|š‰kjBÎFœ¦`±hq^ÅÞ"^!R ! NŽº+î‹.k„Ÿ¸L:ਓ8Z›­Øä°÷ï°-€-l$¢‚#kK»ïRÕÔYÜ¥gq{p»Uéü×'jƒy†Ç-RW.Çño;~i‘+gÖ#Ÿ'H7ˆ Ba‘ãÿ«ÔÔ@¥]±CÄT4ôu{i;s8¡ñÁê ÍG¤ÈãSùý„ÐÒ"Ž×cCaù**NZhж†Æ»¶«tnÆUììǬ±[–)–ÓêýŒ©«l8$hoÝ:VÈÄwW,%2lY±j›ÜTÛåÛ€ÃÍÙž†]î½fê Àê³”†Ùsáèê.®=÷‡«GÆS7#¢Üìt_v½Þ ‡6…îÖ0å‰ÿ¼7û¢zÿÓ‹ûgä»v¢·Þ¦'pCŠÁ]È"A_âááù?D%̬ endstream endobj 173 0 obj << /Type /Page /Contents 174 0 R /Resources 172 0 R /MediaBox [0 0 612 792] /Parent 179 0 R >> endobj 175 0 obj << /D [173 0 R /XYZ 121.4 736.262 null] >> endobj 18 0 obj << /D [173 0 R /XYZ 122.4 635.349 null] >> endobj 172 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R /F29 144 0 R /F33 176 0 R /F11 177 0 R /F34 178 0 R >> /ProcSet [ /PDF /Text ] >> endobj 182 0 obj << /Length 2413 /Filter /FlateDecode >> stream xÚ­YYo7~ׯyè<í¾äÉ–$ðÚ^KÙ<$·ÕÍ™!ÔÇ„d[š,ö¿odOÜd`_4Åb‘,V}u°õêæâÅÛ0]•~™EÙêf» £ÈOVy”ùE¯nšÕoÞ¿ÖEì %Ûjzf½ ½µÞÄqâÅ~‘fë?n~~ñ6fûDEæÇI¼ x–Aà½ü¼Ž ïÝ/ÿxóáæ—]¼¹¹øó"¹`N§Ç~䫺»øí`ÕÀÔÏ«ÀËbuO‚Ý*Îr?ª]]_üóâ^#*ç×Hr?²UV~ç¬Ä‡Á«j8W5ó³ tšþûVìdÿåNñ¦÷ƒj4¯93SøYê–H½ÞDQäUüs}ÔFth´ÉrÃŽ§ê¡×Fµyã$ñî÷²FƒìyZà·ðD-âD؃ãx~±¢ôs0„=zèÛã‚zQè‡Yæ„N§€äj‡…Eñj†~™¦,cöš¤ž‰Ä¶Ì¸Ã¥âx¿Žr¬A³Ró¬ø÷–5çI%êa×Ë¿Dã¯7I^z¿î+#¾ÒFŠE4ZW0 p½Û´èŸ#£pŠÁ ÑU=ÎY“eàzgW¸—m‹ ÌgÊÀÀànH|%`=öÃ9ô$à+T:ͽWG–§áݪ´Y€OXf³Äû2Œ³d–eJ7|0— þÉ3?Í&È SÛ# 9`{d•o‰1ë»(+ý ^ô]{úÈšV ÈI`e”»3«¾YÂMà‡SÌžœ oCÔ³V‚£F?Ófg1¸)?ÈPWà! 7ý=ˆÒJk¡ÌÒñ‰_BÐnÂÔ/–ÓW·-zû7ðx Áôœgd_·c#4®‘ýŽ…­uB:ú [7ˆÓŠ<Ä0HƒŸ¶ƒVäHxæôB4b)tEí{GAài¶SvÚVck˜;;Æ\i8½»cI£E»µüÊa슱˜…l\õ ¡­¤Xxý†šK;Fl•Õ¶\C§b(×$„BÇŸë‹cÎTHÙLUnªâ=ŒÊ5°ê¸|׊Áëð)["R¨%b4XÐ$Dœ˜§ŸÄ*LµWö•:žWñ–P‰^ŸÚÏ®º›”ƒèí(ÛÆí)¾-úl'ä&{ŸÍÕÛ÷/1)½»^cûy˜ÍÀ¯”¥:6ô‹Ð"1´-ªß€®Q–=þ–`¹WüSý ÿÊ»d¸ƒh@u ñºHìD/TeÜ&ÎPÓÍÁ³‘…c”¥Ùá˜yêúiµçúñ nñT†¯Ù ¼ÄöOWß"²ã.¸ÁÞ*«°°­Z=œ^˜º¶Ò¾™1ß•Qëæ‰{óà^ ÒuEU‹]:<¿¹}£¾¥b[`‘ªmGï 2òšÁöý8¯x¨bJ¦\`ûÍ<ºRëÑî ›ÐµÔõãÚJõ°§}¯#®^_}¾¾yÿñÝOWœ4Ïìf¦~H> endobj 183 0 obj << /D [181 0 R /XYZ 121.4 736.262 null] >> endobj 180 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F33 176 0 R /F34 178 0 R >> /ProcSet [ /PDF /Text ] >> endobj 186 0 obj << /Length 2422 /Filter /FlateDecode >> stream xÚ­YYsÜ6~ׯ˜Jå“x(ÞG%µUŠWÎnÊvv£‰_’T "¡”8¤B–µ¿~û‡3¢½Ù$O  ÑÇ× ð›íÅå«0]•~™EÙj{· £ÈOVy”ùE¯¶õê'ïݺˆ=Ý›F­CoXoB¯ƒF¿ÞÄqâÅ~‘fë_¶ß]¾ŠƒÙ:Q‘ùq¯^#…iAxW?¬£ÂûöÇ7×o·78íâz{ñÛE|Á*œvý0ÈWÕáâ§_‚U Cß­?.‹Õ#1Vq–û´šÕÍÅ¿/¾ÁcDåüIîÇA¶ÊŠÂO✅¨ÕîXÖ“3G¡_†ÅjÆ~™Ì»ÅC­^o’4ñ´„¿ÞAám÷Æ2õ ðTOÜéu=V4/õô]ƒA}µL±ë ðj]3·’%ÌÀ_ݪÛF[aÖïqaÝ«ņónB5MYÆGìúû5°ª¾ÛæEeé A¬Ü£%:S3Éš¦yâæ^õuÕ‘8µ–áÆÌ «˜–¿îÌIË™y´jÆZKï¶G¿ÐpNu¿Y’Õ€æÁabØJ?pËýX ã4Ó²G)Ëäslì{N",Æ#`<â—¤;Æ#-ÂñˆÍóxDš‹Glc<â÷ÍÍ;\‚T° #‡hœsˆÂqÇza9«V÷ÐÀ$òÂkµeúƒr®±×Öü‡Épܽ¶—DÅwí´ñvܳãí" ÈlÃÓ¢˜'DÉ3ÕD˜rzrh¾„äQbXE`¡VÆgLj&\AzÃJ¬pµ{ÙÇPÈðn€-c[ $Ä\ÆŒedkÅ“H¹³ÖQ¤˜DÊÂÅH wF‰„†¤žŸƒ(­Àç .(8t¿Ó2®DI8[¡ü$‰\êüzaÜÏ“Ò14t(¯{° kE©_Ä™cýÛBLnŠÒ£PB8dÆÀø %´ œBƒ?bÒ ïFâ¥2?q‰*cÐHR@ÌœsPyãA–!$Ò-aŸîyNwÇ ýÈ.d²˜1ÙWAà B/BøÃ0å%ÉÃT#YE™Æ¥ 64âb;yffkÁÉ¿± ‰’²œÇ€—.ƒdâ—PŒlB EéÜ#f¡vz 1ÝÔ#¾^;Š¢ÒBà ÐÊAh¨Ð¼¼êfÇ‚å!€¢B òƒ&1ëgp‘È• 4|‘yÝð|ÅÍÐívÍCnïT¬K¡6ZÝö§TÆþ.½=w]ª”5RZœÓøüØ:W¸Y«š'kìÄÃÞ&ŽËêÇÚ„;¦…ƒTN)G1_~T…˜™Nv,Áþ5%™Ë)¨.ÙB“Š›ZѱöÜ«º²t’rÝÄ ;nÞ¼ÅÆKæfUvúàXI{{3ßC-‡)bo{ÕVx̽–¤‹Ž‹ß¾Âo!PéþêæZòõtJ@s‹‡ë86Š…ûÕ/á–l!<\ñ0]hº^‹»çÇMA¸×WfEÁ\Áг# z¡+I‘˜Ž­ùmÔLªºÑÕn¡Ûédoü¶sÎÊ„Êçr°~Q N”ê`ÁŠkÉR>¬®ôKgBè·Mà&Ñt¬XžšaÏĉã©Ú›¸[)e%z€´ˆþ¼” R…umÍøÐf©~8*™ÂmdGÐ’”Ñå¨ñØ›aЭ‹¶I£Ô`y{yfþC³Çëï@h™ÝÆ¡;@®ÁZRñ} ¨µ±˜³À›#!ÃR šá+¾_°ï#eØ«[ûc-$³>·C÷ÀMº›Ñ,}x±h]*˺WÒ—úàƒÖޮ妱y*R$+ŠêNœÚò€+‚‡gL€ $RóÞO>»ÚÀ`Û‰8´ÕØûKw…qz—_ˆuœò‘xn¶_Oaû×¼1þâÒ1\°0áÑ`ÂÄ–Ã LœLQü±P–5Šv 8éSµHÅî’ª;º'_ºž¸3ËØ5Â#V†Öy²AùŽÜc1:ƒt$¥ä¤,¶Ø)ñš~®—®½|Nå,½&fèjÍŽ|L{§~̆כcŠ”üGhK•Ün—êm7à*Y†¡•̬‹¤ã :ó­73dÄ1°,önM‹“ a{–¥AëÞ¨¨±Á(=U6.XgÈsž_`ýÇ=ÁG†Åmg3ÙóyP*öºÒÆoœdàN;ÈØ2:O‘0vêȰW51¸åÇ·ßÿkûêõÂÐVVÁ(—‘ZsLÐ4,ö«¿â—,ò¤—ç4&ơĴ€Æcã*ÛZ“÷Ü7¾j]}UßNå·¨Z£bòÌEÿwå—}¢ò“ÚóOÔ~lwàJö>ÿ——z×¢ t÷#5ØžÂz>žÅ…!e )þ¸kÎØhçY–…a–ÒÝN®MQ¸Ýë0>Î4Ëz³bD eSÏEÇËTí´Èî¯Ú<31dLïNñrA€Z5éåªzãâ+*Ó _S.¢2Áw !QòE&eï…ŸÁ3L1dÚKªœˆ|᳕SÌÖÔºçÇÓÄsÌh#¿†K«l¢ª`)I„æ®nÉ#— Ïînd¥4‹gE>+Îéwœ©cW¢Á€4Ôp Rµr\̶’½£*“tˆ%ò8»´€Ÿ["߸@è]xH ¿,ËO½@œ¼fDi6ÙÛºÐ8J(ÿ»Y@â ¡ð¨cò‡¤&øcYˆW_{h'±î” 2>kþÃô‚Þ’£òD +~\ŧ-]“¾0Òð3L¸ã¯âÏiä΄ä×È»1²SÝ æÁñã{‰}±ü| ·|Û<·’ §B|±;p]m~„ K'5Ü!nTtxmqzޫם¹q*®<ðâû¸´æ'F©CPv$+@¿tÿj ÷sè¿¥Îñà endstream endobj 185 0 obj << /Type /Page /Contents 186 0 R /Resources 184 0 R /MediaBox [0 0 612 792] /Parent 179 0 R >> endobj 187 0 obj << /D [185 0 R /XYZ 121.4 736.262 null] >> endobj 184 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 190 0 obj << /Length 2292 /Filter /FlateDecode >> stream xÚ¥XIsä¶¾ëWtÍ%lÇMÜ™‰R5žÅ‰+v%#ÅÛ•‚H¨—.’åTþ{ÞÆ¥[œñ8¹4àmxˇþêæâòŠ6™›Å~¼¹¹Û(ßwÃMâÇnš››bóƒóý6 ÓÚRo•ÓowÊi`ÐnwA:›Fñö§›o.ßÞ‚ŸÆnyDpÌó<çÕû­Ÿ:_ÿãÛ·ßÝ\㱋·7.ìó6j’¸ÊK6yuñÃOÞ¦€¥o6ždéæ‘6V› N\Fåæúâï_=7#LÜÀ‹7qšºa°¶?€ÖQæôÃNW2:êƽA»¢ÔéÐNƒ»Û]äûÎ+ÞV5ÛŸ8ÅPÊ9[w½®ÑªÞêÞLEöG/LkxϹ0p˜±SÊÍ¢ˆÕ|ØF‘£K=ŒJtìlKßÀÉ›º³ð,x®ùó\œY(ü%St-ÇmYòhoú‘óÀ‡™uètuí ªó„àN*GnžGHß ÿ’È©ô=ò1OµPmm+]–O;+bÊÒîg}aKarÛÙ¦–s· }ê4ƒ¬>4b'…ʆVs<~Ï䢩`AÛš§xÑ+.îì¾Öh»Ÿ9{vi Ó¾!7yâ& 4uù„£t”×ÜËÞ;²¦ØóùÔ!Éȇ5…Q~®&Ð@MÐB+ }çæ`…aetÝ-Î/UYõQT’€‘#ê–¤;Êð ˜×ptàäN¾=ï´rü¾nðücÍdQ8;`€²xqQ¼¯6t³-¯œÈ팩G2øôiæ·r ­É}°õ¼à…àܽÍÁ#1d{$ô0öM ÉTñ&4™øâÄVÇ–Lx@¢bÍÉ$Ü ýК‰±áå#­é†²—³Ýšžù(Ö䑨_8&·B<)Ù­““€¾E¿Äj ` Ñq+,Ì~ŒÕ\}È$`VrÀ6÷ä:¤0K¨U­ÎM‡ñgÎí0R×Ý¿bV¦88à«ùSA !ÇŒ°0¡5Gðä®î9eÞÜñ—£]B쉋]o+$å R¥*43‡Å ƒé{Z‡/Áõ’¾¦OŽ)ƒÒ³rGÁ­[I[ §_LÛðÉǃ-͘-£Nî”’Ô!±UÞâÀb™²¿˜ÛlÿKÿ;‘­×lÛK…ažxωs„[ímnxÖÓíZ!Ec÷)IçdàEê¿TÉ/ÀÒÝ)ZSÝQáN¼ÎþT \1GÈX¢ý¥×ðäZu¨Ô¸ƒˆÔƒfåÄ'X9Õj3FëÇžsù…„æØU|åó˜ýgƒïCÏ|qÉß¼©ªYc8wÔ¶•%-{§ÀÉÐaàH·`\Á§¤KP:ú”Hg%y Ȇ›gÝHÏ­ æ®tоÙï)j°Q¿§ÎRŠÂôÔQZºûûWßvãvéÔ­ÙÛŽ± l›ÃR`øðòŸ-àÏÎÝ àÏNÍ—Îñ£çGàÀÀÂ9pÆš¶Ë1$ˆÍ Šš¸Ì·ó¶Ö·h ­ÁP[V¤bvûÐÀØ{¹¹¹×mÏDIH¤KÁJ€såkɸœB«w¨<绦%ô°MC\èGæa'‚G+7¤[svEÄx¡¾)¨‡ÎµïªìšÑß~„¥ëñÂa¿îøèSŽïý}®Ë±©CÇ`” ð4-.¤ß 5 æltž,``%Îë¡%„I>y2ŒC.#ÈXX}”Ï*9rÙ’ú=†/{@ä‘k@Ž5QëÀ•7üíú¯IvN‰À©PMª_8›«8æÎLŸxnÈK²í…úþØ•k…æ¢VBp÷æg]"Ç ¿r¨ÂÃÒ]SJK—†«D_XƒhîÍ\k¨Ã3ªÆZRHo×<^Ÿ‘zê:Q@ øT÷^”84ôÅs§ɼ>A›/þ o3µ|E.¼‹ VÁž<ò./ñ™9à+ÌŽ'aó{^ɾ†J¦rÐŒÈÇ„‚IyÿrMÙgÌóæÃ‡ÿΟò««ì?<PAÌV/¬Êï¿4? Éé¯Ô‹—kézn÷{bÚîø 8ó¶éäQú=ÖlÓÍž{Á0e7åôØÿà*N²„Š©ÖÚ±ûñ› ö|ýúõø&­Ž€/oí„"Çgèçv½ÂÜûÏ+¶×‰rB òÂA¼¥×8B¥8†‰-eU!ZL OÈP}SAdçØz½U€úx0õÜ»b:îSýíþ·âòe3}7à—öÇž‰›„S‘+ c˜r…•ïCñ7þiM»$pU|L»Ýÿ¯^׿‚ŽWÔË\å«Y?¸æ`•#h¨øµø´ög±ÇáI‰™:L$ qœ:;&q ±êp/(¹x¡Ä€J(V=“ΟÏá¼Ë‘¯îËæ–€4Íè½ΨgßÇ6“pÊ.¨ÊÚ)ËSÈ*…(ö<à´ZE‡Hm†67#7ºR>Ö¬¦Ú¤»–¼¶ûáè0˜wv<n1 xüŽk/®¦‡’M˜;œ+)ÏÐäc‰ÿ<>G\~ºjþ7üS=)ˆÜ$MÆV˜› ƒ(†N9¡>¤ƒ7žKonœš¼(„¬ÂÙaâz±?k)öžò uB³‹B7… ´œßÿO endstream endobj 189 0 obj << /Type /Page /Contents 190 0 R /Resources 188 0 R /MediaBox [0 0 612 792] /Parent 179 0 R >> endobj 191 0 obj << /D [189 0 R /XYZ 121.4 736.262 null] >> endobj 188 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F34 178 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 194 0 obj << /Length 2316 /Filter /FlateDecode >> stream xÚÝYYoäÆ~ׯèÅlH³y ìz¥Å‰“XŠÀ6’Ù3"Ì!Çu5‰ÉÊyÌÓTW‹ÕU_Íywõõ­Šw¹—'A²»?ìTxÑ. /ËÃÝ}¹ûÑùaŸ…ŽéªZï•3ì]å´@t{7 #'ô²8Ùÿ|ÿí×·¡¿Ðd‰FáÎg1<æû¾óöû}9þþç›ïîï𱫛û«_¯Èù;5½=ô”ŸîŠÓÕ?û»¶¾Ýù^˜g»'<íÂ$õ êÝÝÕß®Þá1‚üÅ1’,ó¢0e~òƒ¸4=Öƒ[ëæ8ê£㜹òÒ|²û“®G‘Z¹ÉMÀAYºsUìåËÞ™ÚàŸ ÍœáÑ01½ V©3´Ì}€ŸÌ‘±7¥e÷´˜Ê‹§GÓ0õ“F]/ìsGúœÂô}Õ™itjy5¯=Î jôðXpNW)/c>Ã=ÚÅÑÂî(Oû8vÈ´yÂŒh®¦Ã äµ “ÈUy_ÿ8Y$œÀ÷ÕŠ s!–ù¾»e“• ÃP¤€“_3£íÖ*¸ž†±Q¬ämc}Ë ÀJ÷ˆé^\YéÂOÕð("ø:gÝ U1Öºc¶ø’hóy0M_µÝŠýÞÈ£öcWµcÏŒ7‚Àp­PE »@•y $„ÁÛIÕœx™¯]Øž°¬£”=Z]35CE *9ǹCç ^¦3MaOÔ²G¦“­]ÚŸYkQÁƒè%VÎ'½LÈu옄z²Á²ÆúÈt…®ÍR§mê s:S´§“iJ²D µ9êB¤Š–l.Eå(šk@¯Of ¡³1a“ëðW£‹‘èÛ±+d“!Ó#è•"è!—ހĹ3àgýPËš'z­pË¿¦¬†Õãp†=g{Œ¥pg6së¬+pE‘iÌ¿`ˆÌåiÙÐv%™Å”h¸­ËRˆ3”Ÿs‡ù" VKx¦©—¥‰Åç¿̱jþù‹¹ œžPï¦S.×òŒ·wS9·{¨üv(Kp@‰Úpª>CL ÷A G…r¼äE` F”¦¯ŽM/¥„- ’2™’w¶’R…©÷ª”ÌW)É5гßÖ?¶c]òÆ”{¸ÀÜcøøá, i™ –ùNƒMóåÑ€KØ€ß)ñÀO'7‡úÅÌtüìÆöÂôðhŸµI„4•UøÝrä±$áÿâ ÔÌÎ «¡a>†ƒ)Tò<Ãýuwés¾6778î‘ý»9–á777¼šzBdUý3ï?$À/÷°xXó¦4èÛÆ¼Ù ¢Ô‹ül º ­ ¦—<°2[Z2xköÅ)$ʼÔV8y/¦á¹b%(âX}¢Änx …†§‡Œ¦Š7°û õvf[C FyêÜaÝ£}-jÝ÷¿gbr/+Ù?@]ÁòK:Ý”º+WõGT]ÛKV£ eh+fˆÀÓcUK\Ý÷ËðEŽnx­ëJ‹ôÁ޾ù†…  œ§;ÓCUC ¥\€óêðSOgwèÌVX¦gæ¨|¯;ƒþˆT•Ö”67É”sÓp±œ¯«4 û®=ÒOÏ”æa<2)„<¢TÙ'kÃÁ®y/Äè@™ 7Z* ×¥¶4¦sèhU }…®§½£é!0ÓÜbìØá);èª]Ô½–:!.'=ˆcžíþ€‘ ËÆÐv[f~¤An0]£k¢Gâ8j‚¬Ÿ=‹ˆqÿÄ_C./ùY=-˜ƒn‡“ÑÄ\;ùÅ2s€óÁ…A”ò˜üëic Ö¸Ù´îd€ «'-ã¢ñæMéAP~c-˜>¬TH‘a±)ö„õNöaµõÂÅDÓü6½î7Ô¶•ã*A÷²³'\ù¦Úõ‡ ½Ð)£©ò#zÅ—ªà’O‚Ü*p©ïY¼™J¦)•Ý6•pƒR‰æ7XH!)y„ääK’瀥ùgž`Q®§mŽábÊ1le~äø›IUõ°(˜2,R'àUÂ0¿ŽR kCP˜OóÈ]¿€ž:É?Í©Žò9‹3ÆE·5{þV°†JRóiÞ¿0—RüËÈл7¯«…]· ž\˜‘°Ãr„ÇβX¿H™q`¡²å_B9XÚ¡9ˆœ¥RúêX¬Ó½ùÊcÞ_ÆálVý–wEwL¾»ãï¢&ªP«Äy4«åÂÄ»þ¥prpE Wñ(Š`Ô¢»h¿ö}ìÿ¦Zk>¿r„ø`¸d_,4³Ï¦LvêľóêÄ#ïò5Ÿä+1ÕL¦áœ5`1_îx6Â)[}“tÇó™‹Kw§éýYÄ{÷Ô’ Œ ›–îTaï>׿4½eç;éJ»ZfÁó³áîB×ÔQV}ÅŸ¦`zó_÷vcWÐçæ˜ò©gãžã{~®;”Ñxd%~B¸è¯Û‰‘íé[b J» 64~G$¢ççi&À5Åܨ˜U5}E·}¤Þe`÷ÌÜz·švmˆ¶>kpÀ"¤Ã+¾¶£¯eRB§¯j(m±¡’^Ìž{ÞçÜbA–ʬ!QÙ@”0³0^x¿hšÆc®œê%êÄîÓU-©{gìÀ4ÕP÷àñ—ŽïÚÁÞ2n×—Äor¹yQi_yy}K=lSy*L¾ ÌŠëÿ3.³Lp‰ Äë<=2Ëgp„z Hz„ û HàM€œ¤Y.ŽF1vá«ïÌ…0ÓÛ}BÕíÓî­Ç„ÅX„!^cÌÞœyþšÀ½\pdÉP´DÅ€í`ôrûOˆòí?/ÿ> endobj 195 0 obj << /D [193 0 R /XYZ 121.4 736.262 null] >> endobj 192 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F34 178 0 R /F33 176 0 R /F31 162 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 198 0 obj << /Length 2162 /Filter /FlateDecode >> stream xÚ­XYܸ~Ÿ_ÑX,°êõ´,ê’<øŽãžŽ÷a½Ô-v³:z%µgAþ{ê«"5¯Û@^D²X$ë>ôt{ñø¥JV…_¤aºÚV* ýx•…©ŸÑj[­~òÞ­óÈÓ½©ËµòÆõFyMúõ&Šb/òó$]ÿ¼ýáñË(˜Ýæ©ÅÑ*;:÷äí:̽Wÿxóâ/Ûk»x±½øõB^°RÓ둯‚lµo.~ú9XU´õÃ*ð£"_Ý2b³ŠÒÌiV¯®/þ~ñô÷lÄ™é*Ís?Ž2!b{£×›8 ¼÷A×vÞ” èNû®Åj,M+€ÇÝFÓhÙr{cöë0óndYöö>sl»^W²;;º—ukwºÃG;µ!¡¶®¦‰Ù¥ü"I„þ'­%5LRïÛwk¥ ôëÄûö}Fseá]oñÿí6ÿ#·¦®e¶£!§g¯×§ºÜ à€[3ÞÓ Ðp²'”·7¦Ã}0}×:q-1òaM·•½AíÀr÷|1£°˜éqÆ~AzÜ(‚…öøû LŽÕNШ}ÂNü"V‚ýö ]ªbfÇ#„й­tßêb]2jî‘úIµ£îËýh>¬E:@xõü©L mwË»o__=Yç±·ýëÛN(N›%Ì%DŽÝËd˼‡Ôg m hÐÃ`ºÖ§âػֳ¬‡NfV4»ñk…¹?'NAMvÆŠUzw>ÊÒ 2:ËpfÁFXx=tÆ!tÏt€#s`]Êð vQbqê‰?ÒÈžø·Xp$ÜxêãìôŽL˜€¿<”}*<Œ¤V–\ê‘¿Ó˜xú73^bšÁÊ[Ù„}ÿ2Œ>ÀX»˜ •)G]ß'¨$ ½ÉYº³ÅɈßêå-søèªª¡ íw‹î2hÝ&ùâI”dÞ-˜ëú_@rÉ?HêIy$³‰(LTì½æ0ÃÖM‚¯åÀ´ÁËáNNï{R‰aùá £“+¤"b$˧úσî‡?ˆv$ÞþÖ Örð´¤13Cv põU&}£ëÓ—Yôs3PÄcâG‹ŽnÈÞÊ£ó2˜&dǾlœ—’,‰?Õ 65|žhk”›×6‹Æ3ÌÜWièrheúŽTêgqü€£).lîò¾Jnæ°©ô‰|ñ÷ÄĹŸG…£æ"Ó=JÞE= è-eÇy+-¼VëŠ1#¢n›æ6µÐ¶<ÎÓr”Q2mîYð„úúåóÛþÙ"£ì[Ó-@ÒÝHÔkD¢<¤û幦$¾l Ä fïZ™±ÙZƽÜÂäå/–ô#ÓîI–¤LúTéÿÖù&T~®þ:ooÌÎŒ›Á4_šS­Bã<¸Whž§Þ3D -%å}c¯¿6 ’掹D¼®FjûFÐçv/§¸rÊQ0IBä ¹x¢M«Š¥X£)k¦Èš¼ˆª4 ¨ðƒ²â€ÒC]wÐé-¯CIø?#NL›îe¯Ö’ùkYŽ6Ömƒnyðv'££¯m„ÏêÌvÈx³æ§ûEÚŽ÷cJ0’K»~,]†cx+c)ÃÑÖ' mçšù¿„›).á8+úb/ÁB¨Ž©ê£ ÷d„î˜SFa°l‹¤NÁúúnuóLܦ‘Tmy„+[‘œåy³úJ­M«7Í: ‰¹qÁqÒØW*ülxŠ ?üØœ·p™sË5žÍA˜Ð›D¹‘˜í*~ V˜þÖ²FS ‡e4©’ÙGõÒà((íç“…tK {¢('¥Þʤ³ö¬V@á5kF¤”;Aš ~,ÊJÊšJ,œbó‰Qø€”sÖ‰5HتGz{˜¸hÝÌ ‹¶ŽëÎ ¾–$¶;+(Ø¡óHÇ €RüœëJp{=¼­¥‹î:S‘$Dο"¡ŸWšÄÞUÙÝë“Ö†Ë%ª¹V*B8 ‹M"ž NÍãyæyîÌò &™QŸÒêŸäR%ƒ$1Ì„Z™Û¸Ôß‘\YþquFŠ1j]V2c•ÒµÌæ“«3‚iÀ'ß±;Ký¹I?£®ùÛ6Ú¹pÍ)=˽CIîj>“JŸ·v8LmôÅæ ÇQ4rÀ©aæ«:{cQÀCSr6§ ^NÎÜ7¢´ .ÜËO+DL`W°é{æ “M\ÚÕÁ³Iƒiª¾¼¤»zþ’úBŠX¯®—–¢€•9ÅK;,†¬ÔÕÃtÿ¤Tð€4‘ ’Ý7]}†!öˆ¡_ÖεhíÞaÿ© y49êÎæîhJ9+?L Ðœ:¤¹CšïËav1{ÖM»è;ˆYh#LM’"+<|sBìÔj3Íež½çT‡±ÌÚüü‘g d. ¬Q¸ÿ•m³ ÿûò@ýý's^è;›ö‰ÅôC©(œA±coz¡¦ ¶ÝV#E1uk@ 㞬ÅOûÖ€ˆK2 †” â»i®?ÑåVa³„¼¨ômËòÈ—€p±s±Ðq‡Ô.òÅØžZ,o¸IrC±¬êö~I 9àxÁüêùZϧײ,‡eé [‘²›0yƒÈ¸KœlB¥žzÓB4£Œî/^ßÕƒ"ù]#/Ÿ}cm Ž®r¢í%¬àн ¢æÛ,–Ƀäµ9aÜX ‹-{G§ˆ¼é½ûgz)ÄÄ% Xòµð›+Õf×SR.&\¬‰Z¤R›ý¬c]µ´iïž1?ü§ˆ<ùÉÂánft>ËœÜø*‰¨5¡V3 ü<³ÿT•rqÿ \° endstream endobj 197 0 obj << /Type /Page /Contents 198 0 R /Resources 196 0 R /MediaBox [0 0 612 792] /Parent 179 0 R >> endobj 199 0 obj << /D [197 0 R /XYZ 121.4 736.262 null] >> endobj 196 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F34 178 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 202 0 obj << /Length 1912 /Filter /FlateDecode >> stream xÚ•XYsÛ6~÷¯Ð䉚˜I€×ô)iÒN;ã^q›é´MB2jŠT ÒG}w± J²ÙÆ~q,°»ßžÐ»Ë³7_Åéªe–d«ËÍ*N¡Vy’‰¢”«Ëfõ[ð˺L[­ã`\‡qÐÃ`X‡Rª@Š"ÍÖ\~ûæ+Ý“™J®"º#…cQoZ'EðõϾ»üˆÇÎ>\žý}]´ŠgîRÄQ¾ªwg¿ý­Øúv Y«;G¸[É, ŒÚÕdzÏÞ¡IùD¬(„’9‰ð{”¤mÕm§j«Y`ut"•")•—÷¶j'¦:'L !‹bÆ)(^ñÛu¨Ê(°]ß¡z;ZØô3Š®È‘ªÒ3B©½©¦v [Ä$¬¦íoP¦(Sð|¦Iéx8fu¿ÛW£¹2­´|gÆkõãµfÚ±_ƒ"AßZšW]ƒü@«,J)Ä¢LS⤫¡5ÚÙ[·x·¬é;KÐohÇ» øF[ý H…³„‰e”Áý¥È3ö¯×­¹‚+’@߯,£2‘ʼn׈.sdù êÒ-0.?s‰y<Ó!–Šbyê÷O]›Í‚Q€5 €“îf´p£id¯}(M8haÐÀŽŠ@#ÉM“Éê†8Sãà÷Hª®1Ý–¦;²f3µÚ 0h–ßlÑ÷Õnß:¯ýNÌ{tœa“GúÊT¤™‡ä~öcO`PË< ½ÑƒîjÐI7ੲȃ¶wjõ7Dbºne*b•ü;%²df'®HÀ±²'v~”ãDzp(€,Íãà»~Ô$ù#ÚÄ¿GÛ€[ÂN:«·©ÌÐ>К!zª¡¡ªzk}0E"ÎF;{”Lû-…Í‹ÀÌ"34¡RÁ{J ö@…_qKA‡K ööó–e@ÀBm û4xŠÍ|Ü›EþòZ×õ7, Iî-+‚ÛÑ„½MÈŒ$ë­é!!øã (œÓ´aÕº~¤A=èjäû+¸(ø e07œÆý4ŠÙŸ‚ñW¼»‡˜R2 v•Ï…0©ZÛÓèW+/¤’,n…ŸÖàÛ¶4í÷(9G>­»êªeò¶ Še ÝŽ×À5èmˆ†f)ø,åêÖØÑÔ^å†p›!~lð+V)¸p,€) É)–d€³¶fÛÑ":2®9Žª§ïønKJ«G®Ž›‡F`DipÉj¦%lq‰*çnWtaB߇öÁ2uÇçŸÒ,¡4uvÚ³á=쳋 2¸¸xÿO÷ }˜-“²ícWåð+ú6šs~×`šè0(0Ý9WK(.0ûYðr•fœÆñ$Ul쪛5ýøÂ®~ð‹£®QˆóEç1;°Åpš!¶uMÎ^ÐœŠ´ƒSË÷ÝìJsl±+qL‚´>¾“´ëà ºÇsÏ3‘z™~x¦>]k”°ˆ¢B‹ƒ5\ɃuáÒmù4Ü<`OsjœáœÖøãÞÞ¥5nàhi¬†­±¦¦àøícCp†|„½ì8Åýú¢1ÃBÿ"¡òsåCšÊ:þÔÐl-¥ò.ÎÓ“T~hT$—µRŽXtÕŽGÎÝÝ¡ï&‡E[pì¿ÀAidÒ$ $P­ˆÒà­Ë£°¹Õ(oàt®8¹3žÊ§Ÿgß·Uír`Ybï*xMŒ×®"ÃÊo‰¼3EMRQ"{ª=6&*NƒW^“?á–WÌÁÒY [¾îÒ¡kŽ×£§ |>¸ <•4”>†ÎgÃ_ ø7Ô8w…eúª ©&ÄéÁ8ÙC‘qõÑ_Ä •»á ì­*žwÆòÙUÖ  ÿŸBsÜû‚ï¼Ó¹6w©Î4-Ôø>l[îK– Åå⯠lI!‰6á~Ðhªû…xÈ”ˆéØïó.D,EœþW¿îÃóé ·ÔÓä˜ÍéŽkpкúuGÏ#^ÒôZbŠº­¬Õ”NÒãþîèºYËÚ<6Je‰Ù£ó"l!›ïMg3õÌdü®¢æZ¦{ÿÚl}ŸÖšêqøÊɼB׳pç*å«—ÊkoÌ>„Š:WSWí3eÿ ›'A§uC± ™ý=•/ òÚî *|¸î÷~„NŒÇô½®'n`êò"9j…\9‡%³!jñÚ~jM‹‡|‡ƒ^ª"NCìHQÃó“fP²ŸaEqïB÷íÓ…”¾âa©‰Uúù½ÓkHEPôºmÀã+>7ö™à³íúÁw­³S,üMrz‰Oš|èodr ?_ìðûè™"ÜÀ·–;ó7}ne³ðäÙÑ;¶Ñí $’/j@-?-}Nq³cñ\É#¨I†iç‡Nö©Ö| ‚˜;I/ÜŸØÑvž•ûS"O9ÿäøl±ãRþñ ~¼ˆ{K–SÄ4 ìÐ-7™V¼‰‘ Qf:(:$3ûAøÙÆô®‰S)òX²¥(Š‚Äˆÿçá¿^‚S^ endstream endobj 201 0 obj << /Type /Page /Contents 202 0 R /Resources 200 0 R /MediaBox [0 0 612 792] /Parent 204 0 R >> endobj 203 0 obj << /D [201 0 R /XYZ 121.4 736.262 null] >> endobj 200 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F34 178 0 R /F31 162 0 R /F33 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 207 0 obj << /Length 2402 /Filter /FlateDecode >> stream xÚ¥YÝoä¶÷_±ðKµI$K¢>Ñ¢@ïrI  ;ÍC¸m §•6eßæ¯ï|Q«õêp1ú²‡äp8ó›!÷ÍÝÕÍ7Qº)ƒ2‹³ÍÝý&Šã Ùäq¥ÚÜÕ›_¼ÿn 噡iõ6òìÖ¼ˆaë+•x*(ÒlûÛÝw7ߨp1O\dJÔ&ä9R†¡÷·qá}ûÓ¿ß}w‹Ã®ÞÝ]ý~\¸‰æÕU…ù¦Ú_ýò[¸©¡ë»M¨²Ø<“à~£²<ˆj7·Wÿ¹zƒÛˆË‹mdE$*güDÍäL.HâØiÙl³oþжé;7ÚkÍÀã^˜)HŠdãGiþQ¦=ný¤H½Î˜ÚÔÁÖ/aÓï:½kÍÈ=ýÀߺ\ÍŸñ°õÁ>¦j~ URɈ…VãW[?•÷ÜØGîµæ$棪°?Š‚2MY/7ÄX´¦²¦æÖNLfžà ÍSçA#í'/à™×öx–Ïøc† &º¶Ø$ôènM½åö`wIL‚~æÞt{°¿!KÖj^hC©‘ÛU³,õîÇrß¶¦«iãÀ¹§# A[³›šîaMÍ ×UIvj2ÍÀ–Â#›©¤ôÆ~*aV=(ŸÃ¬ÜEË ÿ‰-6¢“ÕFvê°b,³×‡(2òÐþ^–^zš’¶Ç¨TèëdK1K6‘ ØŸÏâÅ“  3˜ "&rÓ‹çGKÏWÊæ¸þÛÊ\y'¥0M5Y:˹Ò8(`1ýûJœùI„±’@“]ÞÎQrá° ö/K¯Óû-î•lñe7FU§[æ.T£önjZËdsÏòÓˆÞ@¬_Ã8…èWIè}mîõÔÚQæïY×YžŠ= ÿÈçCóÃùt½eÆyàãYÕŸ?¦Åô]ï÷Cm¿jQ—Ø«¶ðóü P¨ãŠmç¹Ö0,R' Ëÿ¿>E2tiþ@¸0![C’£ Ò‡ÌG­{þ’~°Ó ýóL·˜Z (Ò¤Ž/õš¿*5Ý^Bg g8èѬ WªÄÄýÔÖLc ó ì(F 7&Cx~„9y@‚­ëØmAüÈ4»•BM9¦Û^Žq_uzýd“õÇCÛØ•$•A^̵;Z3®† äâBŸçœzTXx4¿e]T„/´<3ƒêp¸ б…ç:äìyÐÍâúy:•y?³¯ùóöË/׎—À1 Dd>‡Ž \î‹Ø¨™KÊL{<9ÃÇ‘§À|sâL²<G›g–^.ÿÜ´-S;I;Ô¨£9a‚¼¶«¸û(˜ß™‚à÷SWqÖÅOØO]­‡#ÖSh¥¢ðþ%ýº®I€*1’ãSßè-µ0sÓÑ™@‹U>­ jZ]‘Ç&‹c[A¦÷ïo“+wÞ¨\®\% OUAÙ–äu!ŒûýaQ6@ðV)BDuÀ _&.ž±Ò³ø¬wìê…ÕX§‘y&¶bah‰]¸ˆ<4d‘!ë³Q©7˜½n:àŸ<¬”B.í•Ì ]NƒtÛš–[{½ZzÊ=âqX·EÞO’PÒò2ð‰;£ÐO[¨´p¸}š?vhžJhÐhö]É<¤&|Ë‘‡ÙQw• Ö´ý™ W)(Ðß¾E"‡ò^1‡æ†æfüí?ÿ`Æ¨ÂØqÕê¦@&†Ò?äÏè*ä³ÐÌ8µ"ÓtÌ;ÔŠ† ØÕXBUCnð±Ùƒ{¶GðÆß³ôd/GÈ}|(ÔÕ}x]Eôr{~…a>®],B¤j®“F ÊAž²«ÈAççEÎ ¹u†ÜÐtØ"½„’ ¢ûÙ„\Oo"ïí§PŸgpv…êÔ.ƒ›A~¹ôº1ègù |LG°QssŠÐšá¬<—pÜU¸Çªñ{÷*+œ÷+ðw®Ž`i/ŠhüS.F€ÿÒdEË  n¾È]OˆæÐ‚n²60œo®˜ó^Cá1È•2¤Œl¾*î5e+ Û~¹=9Îõ{ wwUä9R8+#èúÖ£ˆœî•µÁ3\¡à\œ¼Tòi›BZlËcÑh÷}o©¶Žei¦È>@aR Û—‘çx£,y ³åQS+¸ܦsr²Ìhºq¹âj½q‰PÊPR’'Þ¢·éƦôÐüq®ó@‡ I¯BGäyñ'¡#Š<þt„ñyÑf¡E‰\¢H±1CgL Nea|VÆË²0>+ ㋲—YMŽ#P²'Ëû˜Þü¨÷bõѸ=(©*@ MŠ…ÇD0µ°ì‘y]åêW\½Ç,ù“W¦7šï2Iz¨Y7Œj@¢K:ºm´\JøZ ĵ[Ëßq¢§‘Yz-F‘𡛆¶ˆb_9ìì™Yòª»‡¬wħ_LR¸S8O|nj@‡'ŒÃ Ì_¼†ÝžÃ8*_äÞímÿ–M‡÷…¹7 ¯`8‡¾BÝ‚Ø-óûDUvÊ+$ÛÅAå ¤ÔÏjçp³Jç›UcEÍg wtYô`°—:÷\W¤ÅIÈïBHŒÕ{>F<(d€a­Ñ(¦ø ‡Ä%\T|óÔRv%ïáx¾öÞaüášcB&“I/}¹ä3+!&O·£D9L*© |Ð0ãôºkÙ/K(ú²º Ä«ý@¥ŸŠDt™Û#¢D#»ëy4ÆI$^¢HÅ<’ã7DB$r!á¶ÿ¯•cb"{zV6ôœàBI¨ø6‡bœŸAÝÁ'²pqÈÎU¬?ï&®¤ •óˆdá¾`ÍJ?¸P¼>Ÿ­éä]zí2b¹vá[ 0¡”$ç[%†lNÞC÷Ötêy±mì‰Y”/±Ð†œDß™1b~{[Þ5®£ÝÓfxøùʯ¼²ŸOè)%åœÃë#bÆ›(UAôÇ%$Š‚'Š”ûgçZø0 endstream endobj 206 0 obj << /Type /Page /Contents 207 0 R /Resources 205 0 R /MediaBox [0 0 612 792] /Parent 204 0 R >> endobj 208 0 obj << /D [206 0 R /XYZ 121.4 736.262 null] >> endobj 205 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F34 178 0 R /F11 177 0 R /F33 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 211 0 obj << /Length 2329 /Filter /FlateDecode >> stream xÚYëoÜÆÿ®¿â  1i’Ë'Z¨]»hà$m¤$â@à‘{w„ù¸rIKÎ_ßy-'3µÕ/âììîììÌo{zuwõòmor/OÂds·ßaèE›4L¼,W›»jó«óó6SŽê¦Øθu§bغJEŽò²8Ùþv÷íË·Ê_È ³ÄS‘Úø,#†m¾ï;ûqfÎ?~úîÍ÷w·¸íêÍÝÕ®Xço‚ùtå~º)Û«_ó7L}»ñ=•g›ZØnT’z!PÍæöêßW¯ðaþÙ5’,ó"•² ïý0>ÕqMéîêÃTw[Â}H÷ „‘—ûÉÆ b/xóíië‚⺬ßû*ÒFaèÜ~2£n_ó îNÓh^öÓˆ_æõ{þ]ŒzÀrÆcÑ1;‰ù»«í†‡ºÒL™c?5ӓѼՔ÷¤:ؿۆ)kfpƒÀËã˜uݱª#Zúÿh ç©4¢óTªœ¢«˜ˆƒðPYä o™Ñ)¸ï#÷CßÚ劉鄧“ðb¨Œ·uã$r~9ÚƒJØs»ºÓrÒC=yn<ê5­¯—þAçÀþñ¶„þB\1Ö}‡*ƒ1ê‘gm¦ ˆƒºã/ÜÁ AF@VI]w^6­˜zb¯Tì3!Ø\@$Ñ…æ kÎÓêìùXˆÖå“%'Æ?ð̧`í,<å1T/pîÎX^?AºÅxöÿ‚‚ç òH%— ÇT`˜˜yy1h&L[4 bŒy¦d~ÖÒb6éqDC­„Lž“ñ‡ƒ©‰r§ÑF86x¦à!B“ÝÌ€ÃG]È2 Õå*Þ€ë4œwõrÎCmE¡Þó¶]!Œ îà¸Ü ¦ꦙÀ,{XÜÌ™uÂu¨Órëô%$Kœ¹ŽvÑ£ ¦ NÕÑbwœyl–L]nãÜéÛÍý9j@/¿Íàðæy§u¥%‰Ì9F? ¬†ºÕ|¢‘Œq.-#:‘Y (sB€³…µ8¥£Ë˜îŠV(6jn­N®s׬µôç ^ÒÀXQ=P­?À¼ÁëÝÜ2$Ŷs-h–]DxQšÛÐøËJ@¤^ev߀tÿ\˜k'óÒ¿~IÖõ‡(TÎa4œC˜®ÑR`|â©‘+¯òÉw3Ìä†~~V—Ö:;wfÜ¢“S"(Vn?Àsây„~+mj(Æ=³Ô=dÃæÐéôÃ5%=§É$;à‡5Ÿ#8TD°Œ–yX[*J=–*ä €{óº·U: ;ÕmýûS¯Ù²R`/@`éÄ×»ÂÔåµr¡¶ª`ã ;=@û÷‰—²´·p*z2r16ÌÛ565ÀŸÕºE˜£'¿–Ôåéøî€ÊÿÞýïûQVŒÇÚØ]ÔIA_oÎ)Œ*t<ÂŒµúQ—ÓXì¶ã²Î9fÙ¥„yà)@ÌÜÑøjE±†s[ÿÉMÖù-Ã4¸Òzä‰GÑe@¼†šMÌÆ6dlLQÝŽlFŠæA4¿—y`&@RòHð„õ¶¶Ûj,ð®>‹¡Ä¶œž›†~õ½ÙJXPæSi“Â̧¸d¹kjÑìÒŒ¼„Á†°\PG@îÅmh¦$Íp1¶ aÑ€NF&æTûî0¼ãѳçY²ú9ä×®`S„Ÿ<(窥%)é ð†“HWóo5˼Ôõjóä9a&¦Ÿ†R–^ Ù<3Õ·ð,Ds}Uêúá$4õ¨¹VsñOXÞ´kêßšièüÓH1?ÊÊŠ«ÑŸa”§òÁ¤CëRú‘“RØÈ™ˆ7ASeFYÁ 0wüÜú0ÿ ÆlHæ§b¬Ýµª°«›zä [>ÏJ¦ù:ë¼é8àCxüëö§b0’}ßù\MeH/>œ¸HfT$CȺóöV…‹Uêܤ#›~õA¢>tÚ•ˆÇq­Stä]Ë!–«¸80Pů¶·ºÀL@m‚d¯0·Á)"K yâíN†ó¤ÚÄS4kžBaÙBØó|Eü:wqì«$uì·ïè—•ÄB X³ü žËdI™¤sg äDuÓâòìOÒì¢ü‘¿ø†L9‚F•,¨kjúñuj IΨØê¯^\-ç4R^”AÎð¤V^@E€f6CÞDö_ÿSÌhˆ endstream endobj 210 0 obj << /Type /Page /Contents 211 0 R /Resources 209 0 R /MediaBox [0 0 612 792] /Parent 204 0 R >> endobj 212 0 obj << /D [210 0 R /XYZ 121.4 736.262 null] >> endobj 209 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F34 178 0 R /F11 177 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 215 0 obj << /Length 1886 /Filter /FlateDecode >> stream xÚµksÛDð{~…?Ê™ZÖé-èt¦Ð†ZˆÉ—–ñ(Ò99Ð Ý)Iaøïìã$Ë®Cßt·»··ïÝÓ›³õ…ˆ™›Å~¼ØìÂ÷Ýp‘ø±›fÁbS.Þ9WË4pd¯ª|)³\ §…E¿\AènÅËŸ7߬/oÆÇOc7ƒ…Ç<"8æyžóòÇ¥Ÿ:_ýôÝëï7—xììõæì·3tÞBL·®ð’EQŸ½ûÙ[”€úfá¹A–.^qâú°ª—g?œ}ñ±aâ^¼ˆÓÔ ƒ„…x%‹*ï¥ÉAˆ¼ªx¡ÕM“W#´)yQ·Ë|Ê¡tÃu¥ w¹ CßÙÜ* ¾W##3ô ®2§}ïÁœ;¯ÛΨZýÖËj%VB¸Y±9°õ“ÌQ;üZ10‰‰›Û¼´hÞ¯Ïïаä%Óö dÏ×¼+Ú.®e³ôÇh{¼)íuM¥ÕÜ z~lÕC«Ç’èö”Ĭvèû£Ú¡LüJá•B,F²Å5: RŽŽñ‡”KP9<Æú!ë·18_?C÷DÎз“ö5·#7˜;˜º#€,¨`øŒM~]É’7Êð÷^™[NlOd¨¿ÜÎ/ÎùÚåTñ³Y¬®üÐÍ VW"sE곘ï=?êe‡qã´½Y Èå†Y„ûÄ!r£8e¯L \†ËošVSúâ®ÐŒÚ‘À"q~úþÍÛÍÅ·/1Ù7 ºG«ç=ºQc\Ùö€TMQ ¥´;ˬhŒ[W¬~Û=CE<2þ Ÿ¸ Œ5`hйžs·Œb¸\¡é5£UÃ(r!æìÃPp4#b¢ Îp¤&ղ˛FZ²vxÚe'Dž®Ã$Öt°FóâÕAìh;ˆ¥ÊÜgØ“­Bw•2†“àp#‘–w5n†Ê¨®²|Ž…ÐH|ÝËüWfJ>’9þHæ;‹—¯Qá$tò²TXp9Ö\Ð¥HÀŸ¯ú¼»]¦¡s ¯ÞløæI ÀvÇ_v ,ÐN\ƒYèµéÛæÓ Šƒ5ß•zìvè‹%»p¹Ö¬Q¡rC`ój¿¸«¸´—Ó4±á˜ñ;·ÏIUg¬,Fq©€lH"2MÄÎ=ÅÎè8n­ÆPu·2½´'(ùà«¥‰¢D8—Ôo¿AŸh>^çˆøÀˆ[Yu–EÃèšÉÁ÷wEÔƒh«Ÿñîz0\ò ¤-„ã-ƒ¶jB«½‘L®šõ’åaàe³ù⺨˜Dèãr†v±#æ..m•‰œ;%ï)oÊ- pHuá E‰ ŽH®b©s7޼äC^cŽ=bm‚ùl» Œv²)ÛSYÀød#Ul• ¶Ÿùd»m‡›AK‹ÇœF¤ÚÓÕ00gÒ c¦!Ž ¦ñ·¯.xOVCH×Ûcû|àM–@åWAèzI|hkϬļéxn&h_'boUäGÎjÓ•;»|Ãß+³¥.†q¾/mµBÖ[DˆAxgãž6êêàFÛ(íø•AðËFöÓ¸£*…@².ÆÛ¹‡ß=Âñf—³ÅGF»'bñH+à Æ²÷é/ö-^çKhðw˾®ä§Z»Í˜×4ŒƒöaŽxbr,­S•§, ÁxbSr74PZªÅ+j\ÌŒ¿Sþ6-g&Yl!ª»±ÀhîyUŒ'xË]z1"¡m‹Á®{³Ç\z ‹¼R¿[’Öò¼Â®3Ò¼’š¨&"H«(r~bûHJc“˜‡UŽWˆ}¦‹y„'›xS?~*Ñ37Ê‘„3鈋ðÝ,™êÅ‹q™K­m=Ž“šl›½ ´˜y·{ÏðÞŽB¸°m€¸Àq›ìÂÜ4 ­SJ~¡mp‰SàñÔ[Ž‘§›âw­*¹„èügjŒ&hÎï½Èƒ*©mÉ)nóþœ—;UÁÐ^ËHƒþ µ‰ýQ‰»šÂ„»“| ÕŸŸ  V»m'¼{§HŒýM`~>ô­sÕlá(?Ç7qä9ë5#8iHÒˆaHC²5lXÀpˆjµúï¥)ž"̹i»ŽÅ^ØÆŽŒžb²÷‡u÷¶¦9 ‚ï¿vÉ4PÛºõxÒñØ+'&çcêGÍÍÌvÜBH8?8ì—ÔŠ'¾è.¨ÒÖìËÚÈúKÞÀ‹¦‡´ñ]ŒF­AÚ”¦‡¼íX~TG}b¥»ôL…éößËÿ–ÇœêSj„£Á§Õ(þ™&7ú‰š|IË*`+f‰a7PicAÇÙlþ·ß:0Ÿj£ {ºm˜zj¹ðV7Ía?þ£ë%²{øs»å7<ÈêšÃmXDШDºenšZE4þ_û (i6ø endstream endobj 214 0 obj << /Type /Page /Contents 215 0 R /Resources 213 0 R /MediaBox [0 0 612 792] /Parent 204 0 R >> endobj 216 0 obj << /D [214 0 R /XYZ 121.4 736.262 null] >> endobj 213 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F33 176 0 R /F31 162 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 219 0 obj << /Length 2204 /Filter /FlateDecode >> stream xÚX[³ã4~?¿"Å ÊΉ±ä{íÓÀ »CTÁɰ@MéØJâ—`ÙçÅßnuËqf ¼$R«ÕRw}‘?ßß|ö¥L6EP¤*Ýì©To2•ymöÕæñý6„êFo¥·;)z Û]Å" ò$Ýþ´ÿê³/£p!GåiÅÑ&$ l ÃP¼ün«rñŸ·_¿þf‡Ûn^ïo~¹‘Ànä|zÈ0Û”íÍ?…› –¾Ú„ATä›GÇØn¢4 ŒšÍÝÍ·7Ÿ£ªø@4σ8Êè ;û@÷¼ÒWÅA¦›L‚"&Æ»óv—4eýcÅÆ‚¢y*îžíhZ4Ø#vö踔‰FwÇI 1Œ§Áo³§~j*â»'¹´`:}ߘêßÛ],Á¼¿LõÃ6I…nL‡&iËØ÷'?†*ÁëƒÎ;)ƒ"I貋³S)d‚k Ãä“`»KT&ö§ÚÒjë¾Ãq(<͚Ɣ£©ˆz¿… Ï4®ÌAOÍx‹³\Ô#QÍSmGÞ{è”}{Öc½[»à}ÝÀ^ÐÅF‘x¬ÇA§Of ¢­[d™=öƒ ÈOWÝÍŽ’Pö KN‰”xÀrŠy_0"ã%$B„…òˆ®8ì²4ù5^òŸ;0Ú§%ªOÇÈ…fžæþ”àt‡T7‹›E‹-Y¨0ÿó‹I$RzžU É ÐAK&bó#nÆþ¼kHJTScVl“¦Ašd^:ðwº5kæ‰e%òÊ<ÿ;Ä”*(7œ Mêî<4œˆ  ”½Ç¸˜Tê…¢íÞ>žtG´¾ó¤þL”Æ<àvÓUƒ)ªvK öÃv"Í@DNÕ]”e¢?àîNÊòD _+„ÅüNÚÈ!_‚’=s-/œBw‘¬qÁµäâ8\‹- @`®Ä‹Þ>µ~â8™%výHƒÉš “C–нsÙ‚Éå43wÆT†oDZ T;•õPù+ÚúرÏöìšçµk“G!‚ÀëK º4—Ä_¢¿ª xĸÕH"?‚áZZA‘uw¤IÉn4¼Öóÿ‰ Þͦó¥é¢`Þâ£ê¦¡ÑÑtfÐ#ïÕUUcúÕÍó^ûýÝ»=¢ 5ýWPž€qR\kÈ1ä`ˆ‘F|ŒÐMÄênír9Wœ`†®œRTèq¸~®"ñ¦£U7𑉆õtššêc)«w¶¤+ª¯˜„*¹Z~A+ÎmÖ%Íüûƒ®e®Š„ éEã"¨E·Nv56fõU^xõ+š¹hÃASw?»;ð¼îÀ01¤Š7"L­…áQEHXÀ¥÷\$ïp–öµ&áì»[àâÚ²ç½?»z;߸ðÃ!‡) m? %sŒz8RÚ€ ¥<ãÙý„ ¥‰x[ó„æô©Ë´`DŠtX˜¬ 'òIJ/½ßè·xŸQÈE³%ø|*õ )ljhBP¥ø§Б däòk,‡gÓùd¢µÚU“I7nàºÁ|L’®ó_Š~Ò0I.q%ñ8«;biµo[€ &a·@ 18Á¥t!LZPQc<"W 3î0ÿZhzk\7ô§P·fÃG*­Ø5­$0ËÆØäH4Ý4tÞÄ= ¨¦Ô…u—Æ0k7´fžL9aüÿýd¼«ÌÒýJGýy4÷4P?McW D‘úƒþû€ÆSÇT£]¯ÈA2Ђ+Ýðß\,ÚX"UÆ`‚Tì[oM8@Ä…`yÒíÙó\´]ö° לF§põƒKcˆÄzäÜXeø©e^(¤ƒÅbä à•ë7^IrÀeÇzàùU‰ŠáåðÖGuøq,¶ÕÍjZ·®Ê¹ÌDNn9íbÔ…“­ý=ÄÞ-µZ÷ÔúåâÜ£³Lêö<ôŒáL°Œa¢^°n™@½’\µwÃ9ÜZèWó€Úê§ï„çÀæEɰ X_ã5ƒ\^ãõ;ˆ@T1Î Ø0a…MÕ{XFj&2éå‰_=-­¸ÛQÆÁuº‚[At#IÓ”1âHÜ dÑ%]!Ù—5|¢9*Wr@êÃ' ønŠá&E¤n‰ -.é&  ’ðFb¾K…É 0±ƒÂãE•9¹x ®v ˜¨>þ‰x €ÇºZÍV… Bˆvþ‚ë=çgÖ|…wÊhØ(y?‰…>dapåx$Ü»Çu˜ñÁ0ä„f.fáÏ»œéÑKòÖ —_ÇÅt{Áš 9e®Â±PI ;ni¢ýâìh˜xGÃCÞþøb红ïü‹³ñíìÕã¶Ç‹h_¦>νÄ·‡©í_½¸xíKçRQq‚Å,sšá©üc üXÄ–ä@ÿg]"ãÜGºÍî.Ó`8N(Åã9½­mœÃgÍkî-ÛTØ;$a/ú~§)¿–q„)"E¼´Ç†šœBƒã²zíú仜ž O»Ÿ°èäq$^¹L`XxOÿßã†/^‘D—‘/¸6gµ‡·>˜C×”åÝŸâ5.˜ÉÜde5YðÈwÏø’Ú<Â.øÂ@X4W BMácø]„¯XÿÀÒÐ×þN]e[âgŒ¿DU(w÷5äHs„þƒ ðâ³466ŽÝåÇO7”üúF"")—+¹Ô$Å7è+×+Ç.ÚÃp~”ÐaiìšY>ì4ûi¤¯.÷Ñ–ß½]ûÒ§‚tþòü ‡õÏi*»þbðNGÇwÆÎNeµïÑÝžêØÇ`¶…g­íý7ÌçEçÔ7”xeA[oÀÊ`GE'ÉÔùþ?ä-$™ endstream endobj 218 0 obj << /Type /Page /Contents 219 0 R /Resources 217 0 R /MediaBox [0 0 612 792] /Parent 204 0 R >> endobj 220 0 obj << /D [218 0 R /XYZ 121.4 736.262 null] >> endobj 217 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F34 178 0 R /F31 162 0 R /F33 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 223 0 obj << /Length 1759 /Filter /FlateDecode >> stream xÚ­XKsÛ6¾ûWp|"“!ð5=t’Æé$Mí4’“C’-B§|¨ i9ÿ¾»X&e¦u¦½Äbìî·/èåúìùkZ©—FAd­· OXqyIÊ­un}¶?: ·¥*ÊÌavç¸ÌnàC9.çÂæ^FÎ×õÛ篹?9'H" nùtFÛ|ß·_|p‚Äþõú÷‹Ëõ ·]¬Ïþ:cÀç[l¼{Ì­Muöù«oå°ôÖò=ž&ÖQ3Vb/€¯ÒZýqöÕÒjDIâ “_ü ìkÕ”¥»iúÚá(C‚‹ÉÎØ÷Â8ä.'LíæÐçÌT®½(æ–ËB/Äÿ!S²ü¦ }»–2—¹ç¸"ìÕÁqƒØ–›â‹Ï…l‘¬¹—Ä[ewE…¦é+³Ùî^“n`gÐB³¥$Crs iÑI•uES·4ïöYGwTbd2g¡6 ¢Ë˜—†!‰N¶!…°WEãÜÎʶ!¬_¾ûíÝÕÕû7—oÖ´tÄ“3UõÎ#Í@pá¥~× I'0´]¥Qh—a0(´]ÖÉJÖÝ÷``‘X†Ág@b C2ƒÁ`ðÙ ¸ÙLæ0À‚†F#šÃ±ÎœXÔ8úvFÓ)X0Ý6j¸8ë–°˜òƒÔ]C〞ž,ã%/¦¥0ÕŒÿ ¶p ÂÕ·2w•ÜÉ»Ãn ó¢`ÀMaðHü¹çžcF^̾ƒ]šÞc‰Eì€,,ÀÐ-àÆìªúK¢15ã±èöD}bvÖ9}üLçSÈ C±ÏÆA³€Sw5WsÔY5"ãÝUÖmк{-àÖ²¤¯¶?”l \>®/¯W¯ óðkn¿’Û¬/»aSCãù“ž xr®Yp€®ƒKîTtS?öù9Íó¢ÍnJ•ßËþ#~á~\€ud¼Guµoðìc‹öKH}ü¸utP‘g7íœÚB>{¬¢Þ”}Žúi†MS£ìzJzHD¬j$ Wu( DhVh› ,t_ãºF™ˆúâ‡þª¨€¦æahüP•4u?zÀÊ›ÝÛ…°aÜ‹6Ä ªVÊÁÇN+4ó°þ,dd†®pãVð19Bϳ֌8ÔWh}›ÑËâFeêšA«ÏìõP7`¹¢„”÷ä-@Ñîá†}¬9p× U>š Ëš‹@@„4%ÁÛÒØÞ`nÅÂIQC¾%‹¡ÚP]Q\× ¡ÃÔ‰¥¼uôí˜4V%UÆ\ñ “1˜£lÍîbW7ÊÔŒÀ¾l:CèH sí6+¤ª5P̺†>½ÅDL‡°4 å]z<]JÇð™Œuù®0L³¸ž^ø>ûá+æy> =ü{–¾Õ ¹XeLƒe‘Îg“½QàEl §ŒGÂE¥>¸m‰O›î~òÏ"1¨ùÔO€–: ƒ“üûÉGÌ @þ% 3⿨1ヽc_ïry”b݉MÝi1âdšo‘ucâßìl; ÜpФnµD1í'œ ÕœH5ææRWv˜™Ò“/ÏÍ<À'r*€¯GÚR©F¹ Î* φcRA9ÎvKIÖe‰‹y û…Ü•ò‰ÂV™Œ#”÷yw’ÓòÄ2D®Ô“±"éYVÓ¨…Ÿqc”†öz‰Go4ãNÖ’ô<µ¡±t*¨jÁn°8¼{”¾é‰UKK[ÕTD¼-(;L‹Š´jÔviC Ï ÷Xäæ(…e 5óMo Dy—U‡R.„ÕIÏä~"¸.¯0®®/¯Þ¯_¿{±^@%…x Ç7å¢O0pŠ LObÛw½’Kú ¢GxDBÝ]ìTÅðØƒ ‰E#íWc·'D ½úŸuƒ~s¬‰0ë7ˆÍ 6E*ú4ÁÖRK|w!ëXF¤ã(Bo¬‰Ð×ùpŽ9¹) %œ¶˜?9nÈ!æ9-ÍÜåÔ[3µë§8±ÄÈ2£šf³PŸ ׆ôññhR †½EîLv¤‰äDÀ—ŦË>±/ÁtDZ7OEc¤ÍÕoxxÔMG{Ìe±V^°?˜™ëf)¹5^<"C/†ê: ÂWTHfšñ…ll¾ñHúÉ3ä×Çöîƒe1ýi^ÝãŸÀ. qÐ>ÿuý ÷Q endstream endobj 222 0 obj << /Type /Page /Contents 223 0 R /Resources 221 0 R /MediaBox [0 0 612 792] /Parent 204 0 R >> endobj 224 0 obj << /D [222 0 R /XYZ 121.4 736.262 null] >> endobj 221 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F34 178 0 R /F31 162 0 R /F33 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 227 0 obj << /Length 1857 /Filter /FlateDecode >> stream xÚXKs›H¾ûWP>¡*‹{%“’±WÂT’ÚÂÒØ¦(ŽÿývO/‰¬\ÄLwÏtÏô×N££g†­xšç˜Ž=(†ij–21Íõ˜m”/êÍÈe*/’4j5jƒb4fÌR™æÚÎè[ôéÃÓ;û˜®£1‹):íaÃ2]×ÕérdºêÇë ?ŒV¸ìÈŽ¾`§+Fãi†>QÖÛ£/ßteªOŠ®1ÏU^„áVaÎD3a”*«£¿NaM4¦;ŠãºšÅ&Ä<)ãû”ƶ¥«qšÒ M²‘9Áƒá¬ài\ñ M^0ظȒ솺…ƒó²Ä;ÀËxäå (£mC¹ÍÚz5T¼2Ï þB]’A #Ç©¼àò¯:cÒ2—›4+ÀhÇ5¡Š™‹ôºˆáªåbì8«wÀ+Ÿ(“C”ý›Ð{AVƒe'iu–YÐ ÂH6’2s®fš=ø²H¹Ÿúµ¯‚u'·D~úH&ôööiìÁÓ`6`X½¯¢(ZȇaÊ6Š9m*Åmw “~wj ªâtâŠÄå-E㬦h7¢ht*ê—Â8¤h™8ž5 =°îR [ðĶ&²†Q#HÜéŒQY×" Ñu,Éó¨ 'ë¶Á Ï[ò­Žv²®“7È¢½î:ãKj‰MæÈb¨/ó 1þ…I·ð7°¢×÷4Mr«Å>9\EƒÊ¦~ÛÛ"ìÓi”ÛUs›¢]®»ôްq6MxíŒ µ¿Óm|¼kuv½#®¶Ynßc’:á?e’ßì”êâcÌ¡âcÌîvI(ï§M1¢éuØ]X[¶)aËêçPû‚ò*§çqÿ:Q½Âë›/Ðîó`öö:Ÿ!ƒ^ãsˆŽ¦ÕaM«óv^ûícn¡ÿA ^¦®ºªM{‘ Ð{à´ß5ª?m¾ê¦ýs—eòˆï@ØRoéÿ¡™ñ>³‡X|ϹÔHK>FR}ßò]–|ß½ qC~Â焳"Oƒ^ýNôð‰—…ßqÅI/ñ¹ãµy\‘}"7(øs¯E€”¾¤P.ü_Dĺmþ»¾r²¹ëoŇ™{ïä÷\Á7Ø­0¯wÁ "ŒªêÂèHŽ]¿ÛN¨õZÓÙéC­¨J²¡J‡ÁˆØàù'åÒ˜$‰´¸”ÀEÖ`ŠŸÝCxdU€zgk.ºFKpÿ‰×ñë¿ ¤ î¤@OÿyBˆž˜|]Ò’RÚ ¶:Ž›3†ïùÀ¿7‘þap'”> endobj 228 0 obj << /D [226 0 R /XYZ 121.4 736.262 null] >> endobj 225 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F34 178 0 R >> /ProcSet [ /PDF /Text ] >> endobj 232 0 obj << /Length 2539 /Filter /FlateDecode >> stream xÚ•Ymã¶þ¾¿Â8X-²V$Šzk Ip 6@´·i®H‚‚¶h[¨,9”t߯ï¼Q~Ym³÷a—Cr4gžÒ_?Þ|þmœ.ʰÌT¶xÜ,b¥B½ÈUe²x¬¿ÿº+’Àºº1wq0Ü-ã ÂÝ-“DIX¤ÙÝoßþmÉQE&:YD,#…Ï¢( ¾úç*‚ï~úáíïð³›·7¿ßÄÀ-âiõ$Œ£|±Þßüò[´¨`êûE&e±x"Æý"ÉòPÕ,ÞÝüãæëçÛÐy˜DÙ"+ŠP'9+±·=hêÀøv=ÔîTXîïê펩¦ÛÖk&Ÿê¦aê×(ÑΆwË4Ê¡£Ò?–¦ïëmûåØÖ¿öšmIß™¶êöõG8,#‹Âh·™¸YÀ{a'm ›l+a{;0)Æãgaá9µw¢r/ê}ûáÞ˽ÙÀ({Ѧs<È‹×íöÅõuPËNÖ 0ȯ,l0œ4IÃR³"°S•ë`ìI’çg&“xpèÓ(åfÁ5îFfØÜÄ‘;OH›çA«aÛ[[1uDžntÜãC@: Zœ÷øEª[aÚÚÖ:3€Îí™ñ6úq_ _â²;ƒQY`Íù¸³[0VÏÇ ³nlybk‡ž‡ T59±Î’:"ÌûŠwàë-xt»Fw×Z?õ–Yñ|g޽?öƒÝßÂZª,ƒêâ×(à/æA‰Óú8k°>ãÚž*däVåt^ÑÝ`…ë`Æ:öðþ( K<Ô€Y‡¦¶4ñÔ6Gf )É\ie…Ûn€°"çiWOeÂþ2×õà…q,³rŸˆ~O¦[Š¢!E¢"* ¦×my ‡^Ë$$ÄG ˆ(xhë¡6 óL¨ÜsŸP¿mØì´—ÿÊ$oW!pCE:n#nƶXfš!«æÅfó„­¶ OÇ%òR£Üil×êÚV q%¬1fƒ†Ù@éÌ+Ÿ£Ò8N©À@ŽÉ~0ƒåé]×0Bã8Ë€C¯–Õi{ô n óB¢èFJ·„ûçÀŒŽw¶a¤&ëÅ·«x>B¢"÷L`ˆvF’J኿Êùµ¨àîArĸTW¹Ðׇƒ$@,w­ëþ:§I–°+vâM´Å«I‰±–©Jƒ/¹]G_ø:ÿÈ4OæØ3ÓßÑMÉ 1n‰S¥ŠtÜ*;;2®ì¶¦/`˜íbõ†¹PÛˆ59Såµ¢Î6ò·Óç1ïd9÷……¢åÏ&¯Îk9ġñ>ÇtªùƈvQ‡/—Ñ8_Ù›Afίbžg™%µ@U‹×¶‚ ”ƹ™w)ŸAûüÖÊ©L¡ŠXà †`€˜s£"Tj*}ÄfðG‡Y™z¶ÕÅvØeÏC<·í¼+3¼óf™)0´OC1KûyWc©þëAÚž[’‚Ä–ËA+;8¼ñ®ºRMõ1Æ}·ª²˜E,ß;rÓR˜B°}/Fº¬U˜É ~“9‰!Å&“)#‰óîî±¾*Ø&r“ƒ"cqU¨óüS3]ú’à`X’°k޼DÝrë|áGX£¨æç«]=Tw£I¯™Ê‚ÆŸêaÇÛ+JÍørw§'–rb6½"Å;”¼T~aW.ü@I5´£ê‡JV|š/®eÈ…(Ûö£›Dáœ;BUÀ9è?;Á$L‹bÊ"—«—óŒ*Tqi3çW„ɧÖ³ŸÆÂM¿î*%S&|G¾ŸÄŠª>tªÈb¬Aø±xà\-ÜÀIZyƒ»<: )ÓÓå(öw34t_Ëwë®=Û¢—ÝûôGª^Ôv|ÛÔ…_¨šÚòônƒâ)Üi-xnoœÌQâÔXÉ<ºðIœÔX6õ^®§(ÜS·kgÿK)\aî¡'‘gPwfÏXÒf°|“a e€ŒrÏ,ó³íßi{Ð1­\[HB[aèHžIžÑã@c÷=÷(8‰z!/ì}Í×4þÂÍèèçŒÔÚð|Å—0Â÷™O¸£,"ú2ܲb̪vs!C~J/Üÿ+4V…z¥JŽ øü®#GÀñîj¾©é}(2ÛÙ|«O'‡jÚ9ЧóÀ k_å­Lóûà>ÍXÍÞZ°òã›–æ‡#tŸ¦^9ƒ‹#î–¸ƒÜ9;yo’š­|6`½çÕ>ƒåÐbÄ&‘,<€ñû¤O#½¿­í—s[ Ö/Pd6‰œ+%p”ÁgG.s8ÃÂÀÆÔ”c†ku[W ËÚuxïÇ™‹' -Ï&ˆ60‘Æon™ƒ±8:Çøè,UÌ…÷ œ0«¾kFª%`”£¬5{Ž4ÿ43oŽv£°Z"ÕC<ðåröÕÚl­ü°P·ý`ý ÿü€E ¾›Lá&Oÿ¢K(w›$̱ÔEXâ~qé5ú9åî( endstream endobj 231 0 obj << /Type /Page /Contents 232 0 R /Resources 230 0 R /MediaBox [0 0 612 792] /Parent 229 0 R >> endobj 233 0 obj << /D [231 0 R /XYZ 121.4 736.262 null] >> endobj 230 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F35 234 0 R /F34 178 0 R >> /ProcSet [ /PDF /Text ] >> endobj 237 0 obj << /Length 1111 /Filter /FlateDecode >> stream xÚ•VëoÛ6ÿî¿BóLN#Z/KrÒH M‘6Yâ9º" %&æ*‰žDÛ †þïãñ(?R Í>éx¼çïÔÛI§?öÖ #?²&÷–çû$´b?"É0°&™õÅžö’ÀfÏiϳeÏñl¡ˆªçAh$D½¯“ýqàîØñ=—Dnh¹h#Rj®ëÚ£Ïg¯.F Øï^½BbôyôîÉùå'0ÔM:w<¥éZÞ&ž€xnl¥EçËW×ÊÔÕË%Á0±ÖZ°°‚(&¾¢rë¦ó{ç-$æ'–’ ŒümfQ’0ˆ·Qy{QE‘‰*Š÷£z“k©ÀI‡hèVCô[žc>©(Õ¥‰EZâ‡<_ŠDÍ‹»‚‚w^’t±ø”µåeš/3Kw*– T‘y·­2ϤW¬Ò.r*Yö*¼4á”—€Ú†A«‡ÔàÚšžSÓ‡‡êzu„‡t‡ÍÊ ŒÇ´GÝjñ¾Û©žzÖñ1ØUm]Ð2;«jˆ\m¢0=û¤-IuhR,8ÅOÉÖHL7ýôLy=çMËß_0,ð¥C{r m2‡Kˆb7µÆ¥ó†­@ƒæ”i¨ï{MA3–3É6Ê­Q±G.Á–1¦;® Äï?mÆg»Åi›úó{µ(ÜÐ~‚­ý^Ö’æ9Ëàì,j)*”¸¯DT­ÐM™Zܵi—ÀÚŤÕLÙ3—³¥Dv) Akü.h%ѥ؆Ã>0\Ua&«¨äåCxõS-Y›P÷R{–È»¾ú°5AXÕÆJ¦“‡5+ð‹®…Y¯hµ¹“s³|¿qyüÂuË¢2Ã6]Ÿ_œMÀËë»ëËËÉiAå¼/E=6«XÕ” ¿¦uöžÝÔ©µ¶®Î&ïO¦ ®Œ›þŒ—ÇÀ‰—öÌ'¬1å5ÀfÒ¯–æç£XÂ\a1‘s)ñÑ Í ¦šˆ½ôµZm­C‚Î-< žãºr€vÒt󞨗åöhæ·ðv¿$s|{N読=DÍ G·æàL ˜ê…PfŽË2ƒ½¼'Þ3Rdÿu§^à.òÅR•Þx$=' cûæGãó‹ÑME*¹¹eëÌpjòݲÝ7uÉXV|ºfVôì©›Z¦® Çôy¨'7C¯aNå¦`@bZ1ýúü¬¨>š×¦Jæy3 Éÿ­Ž Õ4\ÚÌþÞß—øêÆ Q¿qN×¢ßm~ÿíç¾á endstream endobj 236 0 obj << /Type /Page /Contents 237 0 R /Resources 235 0 R /MediaBox [0 0 612 792] /Parent 229 0 R >> endobj 238 0 obj << /D [236 0 R /XYZ 121.4 736.262 null] >> endobj 22 0 obj << /D [236 0 R /XYZ 122.4 698.4 null] >> endobj 235 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 241 0 obj << /Length 1239 /Filter /FlateDecode >> stream xÚVëoÛ6ÿî¿BÈ TbFõrR K]±¬Ýìe Ú"`dÚVMI®qýó»ãQñ–O$Ç{þîŽo'½ó:C6ŒüÈ™Ìîû,pb?bÉP8“©óÙ½ë'ÂUU¦eŸ»MÀÝ6U Dà –„Qÿëäýùðvå$ ÂÄñHF Ï<ÏsGŸ®n?þ6·Âß'£Ûk:Œ>®ÿšüúáwÖMzß{^{¶I0îÅNš÷>õœ)\½w<&†‰³6Œ¹#¢˜ù°Óθ÷Gï-:'ø®Q`‚GN”$,1™–NûƒÐÝòñÛÃ4«P=ˆpΆaH,¹\*b|³ëŒÖ»²­X¾Ü({!ø‚Vp“ñ0 ‘_¼ÐÛ¶)!œ~ä¹Y‘êvª¦x⮤eªf²Õ R ~¾Ê´¢sÕv;YØg:+–$®Âlµ^¨3 Ä‘[ƒE—ë¾»vßÖÎ/žª‡"W²FŽ#±A“Ðeéj…»ˆÀ˜Ô² µY(º—ƒ]—”–yNz€LW¬?üĽÇè”-ÑSY·ÔuI¤u•5VÍ=Áà“Ò>¼^ÏÒWø¯­®úì¨#5qÏÕk­ àõ‚äÑeVÐjÂëñ=c˜ʰ½¶¯TÚdeÁ ͼSørNÊ®ÐaTl¥V5]T­U•5¶¼v‘| R;æž…÷ù]i0ñb >[º5.pçª!b´²mVíÿjÊ;¥uI¶þ]VzVñ lQBy=]ø¶À9Æþ9÷Õ Y‘Õ‹—úó§’Zo[PÐhÁóºBßâÀ}D ¸ªiTE„-pK˜ËŠ9Ñ%ÑnåÒD¦Ã=^5%ÝMKËjÐc!d5‘feE¤ ¾.[@}%îd¡ c(ƒíËÑÞT+ZDvä[Èb®j"d ­ë {€¦ƒl›2—M–š@ ï´e*g¸šÊ­­ôºQ«Í |w¬,‘ 7ªnRÚÎÿeµ9fðA à®›*{l±`^„—åU?d¾ÒŠQ’ý:9Aäc–A|°8ÛIÃ÷& ´4Q¼?i ã°Ä±˄҅UXïZt±ÎrèhÖf“û]ÿ$!Êú“é¹gt.Ó¦­ T875B:tù†»Òì… _â3¥bÒaZ"wêôX"º~ѱî°íµÙß›7£7´ýÙÔ¥áæž™óû󲜚©d+˜68ñR½ÄŽxI/CƒøØF ?ð^â¯!ôÜós"]ë2µ³ók¥¾·€¶ÎÛVL2lEf™IM }ùI¨é:R¯åÆJþeköª„á7WÏv¡ÈçÎn܈÷ÝxTs„9²¿x¯´ÜØ7ÞÉa÷;¡ˆóÌô2{RµÆà ÚÀ¾ ¸´a6,ÇÒ€éziBëô!—&V…åÿ•ÚŸì…žÜဆO[œ¯u«ŠÄRÒP—æõ<=³±]H‹–ÓSYÍŸLÍù#Þ€>ÞÏÙ}'Ôôâ…ÙïÄU5¯Q›Ü ß äîåÑVš>¤[„™> endobj 242 0 obj << /D [240 0 R /XYZ 121.4 736.262 null] >> endobj 26 0 obj << /D [240 0 R /XYZ 122.4 398.249 null] >> endobj 239 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R >> /ProcSet [ /PDF /Text ] >> endobj 245 0 obj << /Length 1283 /Filter /FlateDecode >> stream xÚWmsÚFþίPSItzGÂw†PÜ’Á6ê8“f˜Cœ‚Té{:ýïÝ»=p5S¦_ÐÞÞÞ¾>»w|œµÌkÛ׺¤Ûq:ÚìQ³‡xZàtHØuµÙRûªß·CWgEœÐ¶­ó¶aëEÛp]OwIèwÚßfŸÌkתë =âù¡f¡ŽŽY–¥z7ãÑ@œuõé—élpÓÇÅàaÐÿ}6¼»ÊZƒYëÏ– §-Í>øäÛ ´hÓúúÍÒ–°õI³ˆÛ µ½Ühn' P‰6mýÖú(‚síºSG:][ë„!ñÜ]ãYÞ6|Çׯð“²=÷Ù¶øÃò­7 ñ[„þ~üÀÓM…¦ãy0áBHóLˆåïOtØDTà™aÛ¤ëûËÆOQ²Ç¢D[£¬á[71ŠÝ[‘D¯«Ìä‚%Íxº:­Œ¢Êf›ûUœ°£·?Ücaá4gËË˧Œ_Çi\®Ä¦P‚q ñ¿ðSFó’ÓBžB¶2:íÏo§•û°þ»Éú’%Œ+óÁ©‡”aϱTlc0‹tíàT€ŒHœl î®’'ÐF- àFÂ@{øð³<ý¥í„z¶ÅEœBˆI–béÖ€gJ<Ù©*1hˆRÕõºz%FñùZ€>µ¹Ørd§™"h‰ßœMfG·p«P\¨9¸É Êãô©)ÁåKÉÙ;J$Qj†6¥)ò&ã‘Ö÷•„ë%Ç…2…‹”Éàx_4Å©HG­Õ_1$Ö1¿TàÞwM‰gÏy&¢•]2˜ G½™HàÝd>¹»›]™9å+“gæ~%ج`æ®*¹§¥ Ž¿ªSC*êƽٯW÷âšRfÌEœ^^¶83·™ÈÁCÞ‹´©ð‹­JókÄ+S[XL ’˜ó„a"Ù3Ýä €ˆ‘3Ó·;jŸ© ÎCÐF©˜$»sƒ›­Xzˆ,Ô•ƒQ&뾓¬‚Ÿ”ÝÓ§ucÜLª8y¾åu UrýscŒ–ÊÿÅ÷ù2.þ«ÈxŒ±È£:‚z$Z¤ý|4©fD7È—ÝÜ ýB©L„ÔÈ,óy^°¼È"•uãdù–@ÆÏL³hÎ/%²ãl[d‹ÚŽN“j˜d¸S®ã)yùʤÂ.°#uÁó'åv„ !ð‚OŒËñ!7òm¡Î©â [Í7`”½:”¥”5Ìn°›Ð•×ç›D¾l=âФÂñTÕDò©:§¯`aíâl["¼U‡ö1_!eȼE ŸÈ‹K¹/¸õ¥‡Ÿeg+Q5£l“ljÚù™@ÝеºÔŒïêûx¼ÿÉf}\Ì…ƒóÞhDhâÎÔDˆYFRÓ†Æ)É«f[ãLöR9æ-˜Fé©*›Ö±]åê6ã )uW¸m†¯@+è«C5²î´Vâþ† l¼àb×ö;:-^D‘äeÓAÜ<€žt©pe©YŠF’øêšD´ÈXÈÿ¸œ¯TÈöhøñçá¤érJ⚈5á ƒ—SÙäÞ¨÷&~Z) V==Ù’©¡«ºÚR,"ôºÄj~85;Ýx˜_z¿L¯Œœ¯ F×e=ä§wïàFÿ¹»È@úmñ©i»ž4ê;ÄV<ɇQÓ¥\HT.`l[>ñlœï®ÓEŽSýkø‰Iz endstream endobj 244 0 obj << /Type /Page /Contents 245 0 R /Resources 243 0 R /MediaBox [0 0 612 792] /Parent 229 0 R >> endobj 246 0 obj << /D [244 0 R /XYZ 121.4 736.262 null] >> endobj 243 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 249 0 obj << /Length 1968 /Filter /FlateDecode >> stream xÚXYsÜ6~ׯ˜rín8 ÅûðVdo”8+[ÙhâÔn’RAÌ "‚´¤üú틜Ct•ŸØhîF÷× ¾Yž]\ùñ,wó$HfËõÌ7š¥Aâfy8[®f¿:çYèèÖ”jî;Ý|á; í|†‘ºYœÌ_þpqz‡rÒÈ“t汌 ¶yžç¼ùöÃÛïß_þôïw¾C¡óþÜü¸|÷þÝÿ.ñ¬å»›(òìÛåÙŸg>Èðfþ¨Yèú^:+ª³_÷f+˜úaæ¹ažÍia5 “Ô €*g·gÿ9{ó“,s£0eõ.ë«Q7ó sÙ¶G¤5O´}Í„éÄZÿ@d๹ŸÌ`›¥â¶DÆAì¸.n}¾ïæq̳Íýw+Ó^|lС}ËBô\LI5Ý+9Ý1³ÛŠºVUB5}·ë;^§ìɲ·_Í„~RÕ®Ô¯¿Ð¶ïuY6lÞ/M[®¦,\ð|Ó·î§×Ák}Ä8"“7Ȉœ¿­q`jc·_ꂟ´*Ëg ”óù"Š"ç]Ñô_µ`UÎý|¾é:Ý2£ùÍ C&{kê ’¾£˜ó^=̃ÔѰ&*5Ou Ï­ä 2Ñmej݈ðgÜÑ£%î|‘úž³ÜêZ´{r\‰z¶SÞ²À/èV§Àu[Uo´e†éøûhP¤Tß5Õ˜ˆ‚œB“«¢6Íš¿pñV±ÞY—U¼ÕzœGÄjÛÝY”½cĪ.º¦}žRÞÔ'qµ2¶kÍ}ß™¦æÐ#wᔪ"Îå[²™¹a”xí >Š€²=xø/Á#I<’ty0‚ÇI$yCi±È+ R)O‡x±w@±$öœ+óÄëh#bÒc1d6 }Ù1m„·ÅSûl6Õ®=¸ËÅÔå 7j!.Bî¾F«óÃ>Èc¼¿èI¯˜ ºáKÉ'{óqîÀ|^s?øèJ=?Æb‚,kÔ˜µ¿i9²™R\1¥Ä&nz`ø•e0„‚%Rû±<áw£:=µÝJ¹z…2õ°WÎK¼¿3qšWÒå¸jãàݩأ¹®áa\"UwÎÉÉ <<$=:„Êòú¨™V­x¦rGÊï ³]4®WR‰«ÆvXúpCsZj‰‹m΄ë Á±0‰‡¬ùkèÖìȽ4jš~üù+i¤ U  Î=3¸ö¯ôZAŒƒW‚˜qرSšû i1Ú­xÃЋ ½Å® —7;jó—`Nu}K÷Š4õ8ˆ>Ô@êRkd/¡mÙŠX)z5õ=Ýd‹ŠÖ‰Skì‡ÁLL%ª˜Ë–¿ÔšÀ¢“€±Ì-Æ2*3LªŽws¤…VXéXn1äpµ)`žHX­d={âBMƒ´ ™t¿™¸‰ýµ„˜ºÔD›ð€ˆõ°¡ÕÂú4áìÖ¨û’KfNÝÇ9Ïuw5÷}ß¹¼xÔd€Þ7X×`þöúíúeJש€ÛãD·$.ˆ43€X¼EÌW|wË ˆä :'¯ÿE³™Ì²ÃÈ%0;|EÖP/Ò§ªÜhE™‚À\šZ šføî aÁ‰p(›Ìå6’²õ`—¬ 2GM;óÀzQ‘ñÁèLêËrçÞJõXð§:‘{r=R3ä|¨$ÙO›ØÑTÂb2•æ¹ã#ºR¬Ø—¾›`½æ‡… DÉ7( :Äàóky(á» á`ÜÝ]^_»êKIG¡ˆè9V€³0˜òÔ~÷U„Å`‘ÆàŠ£ yÝ›VU²1ž)Õj^»S­°0mx‘ìåî‘uÛóÉò=`¸Ô0áÏB Ÿ9–Iý¤‹žËŽt¸ ÷AΜHŸ|i,’Ì'ÇŒ9Hë^ú¹¸"®A~½•üß`ÂÊ,·Ã öveO#@½V¡JÐ;ß?ç;~Üš¡Øã1MM¾ªo_|?Si¢nf;yÊòHñ;™6•LM·"#ZG Ÿ2QÔâÔàÌ,§(fÎÞ‡`šŽ~×r_¸c_Z~L#”¿ÌÈS « …lÇ-ŸW˜€ØC‡e¿’–,£7^dC.G9þyB]ƒ‚¦Y|áaõ·ñÕ\ЧžŒ8ävУ—÷ƒŸf.> endobj 250 0 obj << /D [248 0 R /XYZ 121.4 736.262 null] >> endobj 30 0 obj << /D [248 0 R /XYZ 122.4 488.178 null] >> endobj 247 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R >> /ProcSet [ /PDF /Text ] >> endobj 253 0 obj << /Length 2102 /Filter /FlateDecode >> stream xÚXmÛÆþ~¿B8 (…˜4ßEèÇÍ5ì\R_ipXQ+i{+Rå’>_‚ü÷ÌÛRÔ…v~¹›]ÎÎÌÎ<ó²úòîêåMR,ÖѺLËÅÝn‘¤i”/ViUëlq·]üüsYeîŒUË$è—a´@tË0Ëò ‹ª¢\þ|÷ÍË›,žÈÉÒ,*Ó|³Œ5‹ã8¸yóö«÷È~õÕÝÕ¯ø/’Qk%ñjQ¯~ú9^láÓ7‹8ÊÖÕâ‘‹¬\E)Pvñþêû«/?a~YUQž­Xõíww½oÓë`q’ªÙ5ÍS¦?0uº^õ¦¾Ž–ažÁ·Zuö‰¿õÍ„SG¡:íÛ;^Ôªab³ Ó*–ƒÚ>Wr\Âç¡^¦«à€¾€û„I­‹‚-–ó}¯ÅÉu{<«yÑ›£vLŠH à’÷7Ë®÷ê=]7áýpç0`}gj ^¨¬QÎ4{º_¾ ¾6ûƒ×Òž@´ù®ß6sf94¹ Pc ntüte×HÆÁQᕞxqÐö„/«`3ôÌ»¯kþx¾ìú ‰*–V0éµvÎ|XŠgakh¶d:·ÿo–¯?,éhÌÞ䨷f8kQÎü¢1BÅ:Øjgö×É:xeÁÿ xƒeYö„™@—´`U·'CÎ"øC§Oɶëyã2°°Áßu·k»£jj}alÉÆ/ŒP†¾v9a‚lY'ÌóCú¬Õv4rgËTÐ[f>ÌìºÔc>¼r½>¾æÅ¿ã,·–T »ŒwÞ4²'±Ö^= à º~?‹"Í1씅˯!@æC¯%] º‹øÍÅÏ£U¸°fөΠ2\.k¦A³÷½•/¦|ÇHãb745Â\äôÕ3µí$Üs¦³ ³ñʯØ|J3íÉE€$B7•O$cpèɤ¯‚·(OëK¬£jµ†j>ó÷ׯ™;‹€'cÚ lðJy$ã;rdõìLÊ4×?8„¥ÍÐ%`wt%§Ê>—Ê#ÚÜ {7çÕµÉè9¬½÷’¯<\k¶º×T‘ /¤˜ÌX_ÐÇ„¹l‚9  sÀ›~œªšäíÚÖ9ÓóäÍË^ø@ ^<k‘JÏ…·»¡iÈ^\œq…+g¸„[% ÂM¬=(DyžfoE㮫á®9ä%úf%Þv½ÙCÞ2çNëíF‘æüÌø„SèˆU"’É ,[Å*ø‘ó”@ô_0—/@†»S×rr‡ª« fUŒÐn<¤XÑw£6òˆr¿“·f,{2Ú TÓö÷¤ø“´Ùpm4— ïZr>”t2šøKòÌñ޲®eÊ §ii…k¤IðnÑ×ü᢫Ñ–—·Ë*îý3–ü”]@-Pr{SÚ ä@A8ç†Ú(‹CšæÙáÿâŒ6\ðÔ‚ÙþöÝÞ¨½ 0}ã ì#[þ¦µ¡R4Ë‹¶áÿm”wRÎñÞu‘.úöúR!üEœ°ÚC³©íó-§±!¾m{™FF[pqnß”À\»€|޼ǑFÂ4j8‘HöU&ÇÎüÇ”þVpn–ÆRœÀ¡cQëxs7t‚M`ï©j7Ò¬è»À ¬ÀX7Á>ƒ8©ÒX|ñ£2´­H¼ˆj?Wà”gçº>Ä£íþLƒDˆM‹sÚÖØ½(q‹Â'.0<ú÷Bžö¨w½š8 ¶Ú@øó1Ö;ÞÒF<t;ª•µìïa7Û#á¶yª5 ‹H®Þ¸EîBâõ_0A>Z[ncÄ<2!2˜2NdŸx2¤"ÚÃõª¸ þ14r…D ÛI§Ú¡?á Ê@¿ÚÏß‚C¸Çãäo¼v&¹€W¡‰'pİåE¯'‹1é‘ý‘ ¤ÆÇÁ£ ¬ÒLñAE¾B2¢¸¬O°<¶NÌøD,ü¼Â.¤*/™­Ç~üÜ¥3úGBJš•Á¶m°‘¥¿“Õ ñŒÛV÷L^$ÔÐ1H?4”ŒÂ⃔Â#«óÓ‹£|¤ˆÆ!D.û‹FÝiǤ)´k­e$¯1”ïñê_ä¦yvλŒº˜wÙ_ä“d²4óJˆ[•ùšíüõÔéùø[t¤Áþd t”—/Áиßñ[Kã TS/«í°ÕüyG/l¢Ð‰ÅØêÍüËÌk»¯éVІè#¨¨Öi6U*Rͼ2Ž4i³4‰ ð SÝ Xù«ŸßKà¸~7˜faèj9¤sh‹$ȬˆsÇóú¼zæsòŽ™IZ@ûô÷¿kOLXýê=‘ÔÇF/ÌtóQècXæŸwÐ u㯟 Ó¯™T}¸ÿÀýäþØn«‹p¿&Ë Y½¦·í£î¼.dõ™†~阻Œûÿ-Àé²L?¡ÿ¹nÎ#Âñ€¢¶žy4ãùO}Å*ZÅ9ÀgU•D/Íý‹¿I~Ž endstream endobj 252 0 obj << /Type /Page /Contents 253 0 R /Resources 251 0 R /MediaBox [0 0 612 792] /Parent 255 0 R >> endobj 254 0 obj << /D [252 0 R /XYZ 121.4 736.262 null] >> endobj 34 0 obj << /D [252 0 R /XYZ 122.4 336.957 null] >> endobj 251 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 258 0 obj << /Length 1650 /Filter /FlateDecode >> stream xÚXÛrÛ6}÷WpüDMBš÷KûËv«Œí¤µ’N'Éx(”“C€¶ÕLþ½»DSŠ«}®{=g±Ôéüèä ÔN#/2æ¥ázž±ÙIêóÂø`¾Ÿ$¾I:Ze×Ë5 º‰åûéÛIM>Í_Ÿ\øÎHŽ¥¶ëŽá:pÍqóüúýìω—˜o®¯Î¯çxñè|~ôåÈ…£Žáú}Ûub#¯>|rŒ¶^Ží§‰ñ Ö†Å6ʯŒ›£?ŽNàH”$vàÇÊŠ t„IÃ}Óâ­ÔlbAy©æ´á‚d…š°R¹iç­>ž5zË^éóBÉ1($„ÿ¢ãáŽãáØ©–ïØAì){¾¶)éã7›cPA¾ë»žkžœL¬Ð Í9kÕ "¸O*5½YƒõTMJ » "a¹®†á¶ì¯òn–¯nï1…ly[³¢¯È7×1ž“¦ƒÎKö@ºÖA#mdÚI×dFê¹rw+úÖ>gŠXN:‘Q=a­ 5ý'”5; á/džÐWœéXÿ¿@ßÞ¢g-Åܹ®ãyƒãgogÚ׺ePc™kÇ–áUµ˜… G^e´›ÿ,J鬩hC8*NRÏôªu5æ}û¤»ì›\PɶCäßTìA4 ‚d?…Ë¢ësÁ:¾ãmÊŽ|é%>­´c½@3з®ù}¿Ul±Á_× ¦Ç"[TÚË鋊Ç$9AoKÇíJ¥¯q²WË ( H+Šö)šwYN”#[yù+»'#†ÉÑ’4¤Ó@ÅyÎ ½óÑ  ÅYåÁÔ}ÞǼÈmñ‘OÓ€ˆK'ʯi%óžßil²ZÒEF¯cœÓf©-X‘üŽl°@(Þ=Ì.2Á• [ÎßÀ:傿[¢ñ´¼µ~çw¸ëo¸«ˆ nÕ…®,¸ýÑñƒJmû¦Xeú~ž5êÆŠCl5©ÕZW‰eÃ:R\Ȧ(J@ ã=‚!Œã`ˆÇ[PcµË ç’/…ÊÓ½œÈ²:TAýò¹ Ø¥Ô›-ùíý³»•÷ò½L×â‚´¤)H#aCÎϱàïøù¶#GvdË2ðœlÚÖ}»ÀìÄþHþœÖD#«n5zÊ&~G[‹‚€,H÷Ï^­…Pž³‹Ý"p•Ý‘'Ë¥Ù RZþ”ƒ««³ïýX;q:Ã.ž-»¬]_¼íl£ ç3>R(:Bv2¾£q¼=Ö!ì{U ¢û®o)ys½Jv7A"½Ü0¨–gÅ8V·`„¾.[”뫉D? ©‡ºÏÉŽ’UCf?€ÊÿúJƒ¦ %ü‚my$y?ªòšY9- öô ×-û@vX |uyig»ÝÀ%]tY·Vì¥Üªz"§â˜ ú1e‹Ï$üÀô³]LÏ™'xËHAAêwBO.¼ÄpÛ"o+Û¬¹Þ¨Ëv‡.ÛwG]6HGñ½tÝâ¿9}=}5ñ=súûùly: Ì mO³èM‹ï „‚8¾ê$è‰(p(áj#S?y–#V‚¸€E xh:ºèÕ³Š+€+à[­&‚éÅ*C”އo†\*;¦^-°Ô «½¥ðÏÑDGÄ_‰VHÈ{q Ý’‚<ôÆp¾i'"PÑ*¤‹—ºæ1Ò‡¡ùyã—õÑñÂN~=lfäX^saÇùpïØÞgí ¿;àêÕ[C Tž#]ÝÃâ Vjª:™œ.TNp" €–Ù’Õ0$‚ Ç[ÅÒ#¼Æôö“Å¿ÂB Í!ûÊëP Urä¢LÓ¨Å/™þ|+Æõyvnï«5 0±Ã(Pšnþ¾™Ÿ_MÃëæHXH.¾íï8r7ÀÃF‚F´T¿Zòíìzzùîì\ë¶7/g§gÀ2u‘ï EÃd–"•°±¥t^#UN‘%B&4Qü‰þ`ÿÇ:˜p¾ `=´k5Íù°Q¡Ëúøøð‰ˆ«c†I3|4c蔽»Kæm 4èŠ:VB<oQ# c­v3µP2ë+-ªžÙñ¶ØÜ”ÿ/àÄeßiù‹=6ã  a ÒPzúÇBl>÷%Q2¾õ´øB(ú¹¡oÇn@Kí$I”l/Üü?ñ/_ÿ˜‚ endstream endobj 257 0 obj << /Type /Page /Contents 258 0 R /Resources 256 0 R /MediaBox [0 0 612 792] /Parent 255 0 R >> endobj 259 0 obj << /D [257 0 R /XYZ 121.4 736.262 null] >> endobj 38 0 obj << /D [257 0 R /XYZ 122.4 267.214 null] >> endobj 256 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 262 0 obj << /Length 1988 /Filter /FlateDecode >> stream xÚXYsÛ6~÷¯Ðä%ÔLÄàýX+NâNb·–ê¶“d2”[œR¤Â#©§ÓÿÞ]삇L7vž¸X,€ÅâÛ‹§ë“—¯…?‹í8Ál}3RÚÞ,”ÅîlÎ>X×óȵT•åÉ\XÍ|!¬ˆj¾p]ÏríÈæŸÖ?¿|í:ƒ}dÛBÎÚB8°Ìqëìâúüj.#ëòâýÙÅžœ­O¾œuf¢;ßµ…ζû“ŸœY S?ÏÛ£Ù7-¸Ÿ¹AhãþùluòëÉ)^DÆ÷.D‘í¹!i±úsµ>{¿üüÓÕÜ•Öò-©=º¾ôìØ f áÛ±G«^©C¥¶I£R{¾ðCÇú­V)\>ô­²Èï ¬ì†8æˆw积࢚—Õô-ʆ„kÕðV«Ã|ÆPÛì£ãzŠ›""©¶h«]¶@Uá² !ìØ÷I±Fm›¶Ò¢Â*’½¦«eõ„µÁÅwDóžpä]ݨý’¸eZ?°Ö;RSXæÛ­8$UC¬ä¦QÕÑlšÔ;^XôSêæÙfñmÛÿ•cßJ3°jSVw4$ý‘Ú•à¨oc¸Eh±TBŸçûä/¼›zNc<¿Z)$ºKÒIuSe›¶ÉÊnë¹Â:¿áSáI†ª¤*<Ð „·`T%Ö·,ωjPyM”ô=@«¦Íæk#q¨J~iÞNh²â–O1[ÃÓ-LÕMÒæ¼]yÀ+$9€n¾õKˆ×;Òw[Ⱦ%À£ÉöL}t|tO0ô,­nJ#rïò®õ ã@Mî¿-÷‡,W)ì!lò§‘.:‡žôÇ~¸üãϯßý„Îøfõ8gœp `IÓŒLCc˜ó“[žlvÚR‚;)bUêK ðKY ¤i¾? I]„õf¹¤Éo;UkÓfy 9éŸ;¶cïr`±}©IUŽXô <€¿fIßg‹C³«T’>ûþkã×8¿X¾ûíÕÙãÞÈõ=ã)~| ¿šæÉ@ ܇Gí*IV õƲµ¶ÆÖÞÑp×Ñ~4î+ŒYNØ)A&ã%ûêÄ–öÑ@w °¬ˆº©Ê=Q }z7„ÁÀ õXŸŽW6fסãƒ(t¼ i¬nBçiŒ¬¤6nÝûß b•Uçšà§DWÛ`Heôðå—ôò/³b›·©z2b8É=0‘0€‰å`"‡A‚CÀ߯ƒñÇà&ý’ù›úe4‚`l'<—mª6s"z¢ ÓˆÐGô M§GOz"ß (FOÔ8Òé )*„/`@S#ÁØRáÙˆ#Ø•qSOÇ‘tCå5¢!X2 zDI?´h…:´”—aD×DÊà3ü Æ}–oŸ˜~9»z÷=@‰‡S "rT_ _ã'Ä€×cìH¿§ý‹®*ªœÖ ’¢zÉó„©—$—w ÝÖæ™ÓÉl€q_úFEJ4Õ+°¶;=¤Ó‘g«%³„}•D(Ö¨’QQ#¹ÎD¢ô\ôð•Á%¾øÚ4 #¥Ÿvâ\~uÑPÆÁÈ8y¿ Ñ…KP¬K¶ÌÔ}Ç(Öò€[oˆ[ëqû÷ëc•WŠ“p’×å0ì!ÒLÎû>6]> VS¯º¦>ꮄNüúŽYF/Cw¸¸³Qy»8€ööp ŠaXð„cÂï8UXVÛ—h¹`äS0,oèË…Nx߉`’]Æw)à‡.ÇPyA»dd$M­ Š37"z­¤V C ŒaJ¾fUYì•I+(øuîcÓ•%›œ—꾿,¡¶à4zä™È2¢ãÓô’ åúšE11-Ígø®I1~—b€J¸¼ê t.9' +£ÿËmÃŽ"&¬î¼•BÛDã0òXn¼QÅâ=\±<ºâ¸Ö ûêóÛË÷O)Pa‘iå܉ Ë1|åÞò~:”]Ýå U]£w.Wf›q¿ 5þïØ0L¹–ÖÎsu¡é Ùw¶8„ãTÝ<§ìqñ«5@â(¥#kœ°CàAŠâRú1ÛÂì‚izEƒMR«<+ø€JMbå¶RuMÑ% ëGÇÏ볫shø °¯/¯>Ÿž_<2|âkzŽcì%¢ã¢»Æy¨ ’KòFUEÒd_1ó‹§KÞŽléˆcÐ"k“º^ô°^ ¼Àzoš1=ËXÒÛФÀ ¦L–ªM{{ÛˆB†nßr\ÇçMÚÙ> endobj 263 0 obj << /D [261 0 R /XYZ 121.4 736.262 null] >> endobj 260 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 266 0 obj << /Length 1523 /Filter /FlateDecode >> stream xÚWmoÛ6þž_¡u&·5#JÔ‹Óµ@›5[‹¾l`h C‘h›^\‰² ûï»ãQ¶ì8E?ñHÏÝ=w¤^LON/xèLØ$ò#g:w¸ï3áÄ~Ä’IàLsç£{5JW6ªHGÜÕ£1wkšÑ8„°$ŒFŸ§¯O/o`Çæ%ã‘ ÎaŸçyîùûwï^žO_½û÷îô=ç¡•“—Ó“¯'¶yß‚ ÷b'+O>~öœ>½v<LgcK'ˆbæƒT8—'¼¸ë•ˆYàEN”$L1aÊå<í pÈ…[¯´ª«´(niÞ®`L\™©O^ dN«©ÕÎê —]#iA«ÒJŸ¼Ð»1vå¼î?ïB¨ë†–6#0Ÿ¶½½r¥ ™ÃfÎFcÁ÷•Æx€OcÎÙ$ s»¬»Á$¾[Õˆ ÛãhÒ‡ °Ã5§m]«ª‰) +Ìiƒ;Æ=Ú°Å6è~øó-}3ÐaA/% ˴ɳÚžƒ#à×£0tÓÎéðDI™ï]BùÚb7“¬n™iFìòÈ" DäcBǾ`HèXÇb@2~H²("’EqO²rJ ëÖÊýtç7kdªe‹“Ç[Úi•Û…lµ" ã_H’çµµa"†+º¶j…\#dAÓÒF±ë·n-?ï¨X0]•ˆDE1; ÿ¥´%(ÈVÏ2*ä\a°ëæ–>©ê@÷FiR$?`%µ*òŸ´\r{&”ë„Ó‘ÏçA ÏFád>®¤ùä›R@ŠH-óÇX &`ݸQÔÛRÅì¶(v Ÿ³(žôŽ 9Åô.ù[MVÞÐ&{#îZdz‰åoà§#(¸[šìéZb6œdÂÕ ˆ&û™Ø(œžû6½QíâL×4®š>>™ýrÌAî%ÌO¢ïs3/HzÕÙìù›7,%Ó[Ž >FL¡‘_; FN 5x Eü¨ÒÒŠ! è!鯋m©Z»ÔR x0a/öcIµü)TucèŸÁ,ˆ!ùºV6¿´vÑT è «Æ¬Û¶aJtÏ´sU¢n Ú|Ï[™u:½>¤®åîtx8I%æªk5Í6Òw*êpõü›€0tB¸Ï{7SÛÖÖ^¡Y.ðA~g m#ûQUYÑå°9ôC÷×5ö4d'D'gËg¸,&îé)}ÿMÎU…Õˆ(ÂÄrSwÚ|9ÒRöxpî3SçFã8‰ƒ­õ‹¦.Iº¢ûÄÜAfîY?è­¸2ÑD¥‡ =ÁæŠÄÚî+<©juZieÓŠºj˺¯…C»ë¢S•ŽÄL[ÍIÌÝÝâ¸ô”8ÄÖóî¤ÊîƒÜl …sØNÕ$R½ª”ú1¥!ãke :¹@Ò«µÍƒ„v`ïMtcníÔF¨^÷úªm»>xq| y½D«k1{ð€qÿ®;Ë„´êu[ êay^w׆Xò±E0'„·æò´†6ª]²cÙ0Û­Å639˜áFHliÃ7>höïaNÀ ì(_ßÒøÓ.•ª¯^¾uí¥‘ºkª# Â(%p Œ\†ÇßZšàëv?EäÊãýÅ2ÕÙÒœÊEĴ壹ؘۥËÛVËò¼7)û. oÜŠ~o÷Ç"ªª±1vÛ…´Yd^¶Ln?­‡1¾/L¶~e~†ÛϰSËž7‹O°3È]¬Ýp²²”å5‘¸B`í1¶mÀVe%-i¯¨-D‰?`ƒmÿ”z왼ÇèøY#[i&³‚` êr¾³z)ûš¯w¼Zuú(ÞÍRõ„Ƙü@!Ãc0lg‹Z_¨ Ê¡§õ÷„]Íw-;{ ÏhàÞQ;ñÁµ»uÛÙ¾Ûœò.…´…ÛO÷ˆ^7Ú>m†æ£>Þ‡}ˆÐÌ~¾ëÃÓÔw»•7{<á‡Ý{ åg.úìdEÝy-ż–Æþ„%IB'øqÿú?wõã endstream endobj 265 0 obj << /Type /Page /Contents 266 0 R /Resources 264 0 R /MediaBox [0 0 612 792] /Parent 255 0 R >> endobj 267 0 obj << /D [265 0 R /XYZ 121.4 736.262 null] >> endobj 42 0 obj << /D [265 0 R /XYZ 122.4 649.641 null] >> endobj 264 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F33 176 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 270 0 obj << /Length 1687 /Filter /FlateDecode >> stream xÚ…ioÓHô{……´ÂÄõÌ8¶Ã±¤ÑcÛ°Bn›12[O¦39#»ð+’¬üÖd…fôoü>LðË—üïQÿdé{sî‹oÌnúû*ÿ˲òÏNôÓ1†}#Ã}“äÖJÑ{>™†r»‡‡,õöÛ¤±†&ÕùØW¦m˜äÅ þ“ô°ºLsPžžõ*.u’2”ð¸vÀ8¢¦÷ã“'cÆ.{ï’ºÖµçyŸD?ñ‰œC =»ÎÊ$Gùc@OGª×sdJ«§ÎŠ6Oš¬ÜŒ™‹ô2»gDË­i7[ë¤mV[Ç|OŠ]n¥¦F×åc뺶ÀVWh”î²ü¡6îçK‡ppôµ= „+µïŽ3ƒº5ªÎ ´7à›q‘›Tšø ƒHØÒ·UÖ4ºdþÄòºÀº¾ÇÄ.7o&3~•%×¹®eÖLßl­¹A¾[¬úŽ­0$%msíA„fû »‘iG34ÉsL<ŸEª<Ézó GÚF\0U¡›­•ÏÔᎋ«bO`gÎ= Cè~Üâù‰{k‰!cð -j…Ä1vóÿ+ƒiÐI&£GÃ^‰0¡TP+‘{¦#MÇÿm•ì Ývǘ¤D¯Þñâê®n <ྫ›Íž^\ç,}…¼ÕOá¬Â·qÙp8›="p4”xè»±³`¥VèˆÚã´”±#O¡Ä¼ê ð„´íVH–Ôâüì ††0t—çÔVÜ«OWËãÓÅH†ƒ$¥¼(úÕä’!äY†Ù"AÞÊ‹n8ñF’ÿ‘êŒ19¤ftÎxÊ„ˆR³#dº„—W‹o§çGÞ{Œ^R#å¼7e—·›±Fžf•^5ùÏÂŒì¥l…œ0’C»àE©›<«¯o€ Z‹ZršF÷òš%hÜ%räÖIa¡]VR£G8yH¶—Jˆèˆ.Ç*Ð@ Òä6k¶Lb™cwmr[÷?é° ¥ïŽ» g',r9U‰õ º¬.²²æŒ¤îÑÀÁe ÒsË~5`¡ÍzˆàÔ7Xáq$z™3WN•ìEX=·Yª”6rŽÖFMÉoÍã»ð°lE®RÓ0`…#Ä Gµ¦"¢^}»¦¬}liMÅÿ›¼Ó¨‰±©¶,Sô3s”ŒÅˆÁ_|9+ÍB_£eJ!€Ô¶`aüV¼·c7ùñ¾­ÄF¶Fh+ñ…ÔŒ?X3-uÍØÅYkÙ¸°Æ<¦Õè²â ÿqXÔN[딫âæ«f½aê:ƒä çí TÞw‰ç˜”j8jÆÐˆD 4 »¶Cõ5‰‹U7:<6×6Øá?U2.׺ïW JG3ª:ÜlkЂܢª8ŒÞWÙÙº‚â)¡—`¿ 2—­.4¯m‹«î¬«GÙ´yÊËJ§íÊnÙœªÖ¦*’²Ã^ó ¦ýME‰"ÃU&¢ŠdSfM‹þøŸ¡bð€A€åóÆoôU÷†ÞJÐé¼!~2<‚_ À‡Ka»³Tqþ>­Áýh…­#êÞ _TfS%EAQ üÀ=¡^FIM—¿u²ÂŽÉÔYÑ«a``ÓßïwFÂ]7PF…¶†U'”{^Ò™w÷™x>v!íÔÈ ãÊtèºGà»é⑽@Á6Ýh`sè >e©p—u¹©² Ý»GŠôê®4»ú®žš²›r Íf† >[—j¯´9s¶1xÇØûõxdáØkÁ ö=Õ 0º -úk:.’n"ðý æIøtO^#Í2)Zf f‘ØZK­N‚3º8ÝÇq |ê ¤u[®èšdic>îâ3-nHµ§¶±Ñ˜æK]L[y7ψKD±Õ…÷ÿ8Ž™UÆÝsú?5Ž× endstream endobj 269 0 obj << /Type /Page /Contents 270 0 R /Resources 268 0 R /MediaBox [0 0 612 792] /Parent 255 0 R >> endobj 271 0 obj << /D [269 0 R /XYZ 121.4 736.262 null] >> endobj 46 0 obj << /D [269 0 R /XYZ 122.4 459.991 null] >> endobj 50 0 obj << /D [269 0 R /XYZ 122.4 260.603 null] >> endobj 273 0 obj << /D [269 0 R /XYZ 122.4 127.142 null] >> endobj 268 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R /F36 272 0 R >> /ProcSet [ /PDF /Text ] >> endobj 276 0 obj << /Length 1111 /Filter /FlateDecode >> stream xÚíVKoÛ8¾ûWÙ+!¶"в zhžHv»‰ÑKS´D'DõZ‰jb,úß;£¡ÛТ{݇Ãyp†ßÌðt19¾ds+q“ЭÅÊb¾ïVä‡nœpk‘YŸíONÌmÙ¨\8ÌÖÎŒÙ3ã<°¹ÏCçËâÝñ%÷¶ípæ†,°<²Á8èyžgŸ_ß\œ-P—Ûo?¶ÿººyûþýõ‡+b^X\Ü\:Œ1û­ãGöÙñï¼¹wþñ†î&‹É?ö=‹mnÍ]æEVZL>ñ¬ ŽÞYžË“Øzê ‹‡‘ë•[·“¿'§>g;׎]/ެ0ŽÝ€GtyUÔUÏý¹}w˜ÐfÕa6ÊT«ª$Ž*µ| mD–wWeÝé1¡éÀ¬{k½LÛ~ó"·ÄÈO0t¸>dÄG¾¹^©´¹“ ŠRlî†ÉŒ17™ÏIôU¦Ú:k¼Ð:8|&µ#ò:lßÐrø|`nÇÌêO·Bc}`lêãÕ^®7ó,ËL‹ö+!eqñí˜À=n‹•ÆpÏߢVåÙ 2ìRyRyNi#…–Ʊî<ä†Õ¬ºæþþ¼Vî# <)ýHÇúÑÈÕM¥+`]×Î I¢ºÞc;ÔTôî9P-Q«ŽPòÚ”Ê6æ|ÏMXhâg&]Ïõ ¦Fñ¤÷¤÷‘²ŸéO&Ó—˜ƒ¦* ®È§ýˆÛmz_Uºi]ÓÉ7}âFqB7€V‰‰æöíºÕ² zá$ •z|‰„m;‚&ìBÐ\ƒŸN 0Šp.3¬…(0¯„ñØ«ª)„6§­PD>ßm»J~O¿Å@¥(ú(‡ý`D ÃTA/c¯iHøÈƒ´& AÀ6õÚºÎ, cûfªãY×J"-Ùlž‹fÖª‡ù>t é°¾PàáâcnhWöñô|D6ëv êC0–¦„í%$ M1(MUP`ð]kΗ›Ù¦Ât´Ì©Œ±Ö,ŸoÞ1¼*Ö7PÖ»cŒŒ1ThÏ +R|s˜ ɘ¦ÐÎú• sU âÈ*†tR'C^oX!‚ex <†%‚ŽB2©(IR‚Êîó‚ŒM1Tƒ ¨¨–ÎÚjãuMc'Úz›ž‹ý3GØàv…=z gGG¯ÿëËiÑÂtî?}£ë–¹Jo¥>­ª|ô×ÑOó^»dQïE~ì°õ ZªÍoè~ J¨|2à7Ñ­Ÿ )¡Nþÿ§ã—>‹b7ôa$nǤå'Ã_úp•ž endstream endobj 275 0 obj << /Type /Page /Contents 276 0 R /Resources 274 0 R /MediaBox [0 0 612 792] /Parent 255 0 R >> endobj 277 0 obj << /D [275 0 R /XYZ 121.4 736.262 null] >> endobj 278 0 obj << /D [275 0 R /XYZ 122.4 399.639 null] >> endobj 274 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F36 272 0 R >> /ProcSet [ /PDF /Text ] >> endobj 281 0 obj << /Length 1620 /Filter /FlateDecode >> stream xÚWmÓ8þ¾¿"ê!‘"šÆIš¤œtì ,:n·â  Uš¸[‹$.±Ó¥ÿþfXë|ßw/®o/ϸ6t?ÜŽƒÔ}ÿúöå»w×7¯Éx}³¸¼½3ÆÜ—ã qÏ/ÉþÙŸù®áÃp»³ËÅÙ·3þ}‡í£=æ'N^}úâ; ½u|/œ§Î£™X9aœx´Jçî쟳WxüõÃŽB/d±§©… Ï¿kÞÔãÉ,˜¹K)KjmÚe)üŽëW`Æâ¾_’‘ýIøá< |oM§$Ni£+Dº‘X¯95T~_e¢öòͦÃ"ŒJþœ:;DI¶O‹ýªú…MHÿdCûý!ê¼l N>ʶÁÝß_l„·¡Àj˜7ŸÍh‰9µ9±!z›•-ÿ¥“¾o0ú€¹Y‰ØfZl‘ ¼Ü!v,ã8à²Ô¢U[çZÈšzm]p¤"K3 ®ÄƒÏËL)o<‰Â¹»X EV¡ê§šV§ìLYm Žeɇνl5ák\ñ9§·÷@Knxf‘Õ¶±OðhZÓ\Èg‹‰›l´õVáéÛR‹Mi“N‡€Ðÿ'•óßN%ÎyñŠ3EŸÆÇ =]8Ò.²¡¯–›É_D ôôC??CŒ©€ž!ä@n±ê,vˆr#:S_É„±à·ÇèeH¡œ+Å•5ÔôŽ: в²÷¸5ž“Ô¡ýQ赨O"¸§‘»øû9õ„‚éQ¸û†~[AÒ‰;ÀPâf4Cå’(aÍD§´ã×ÈäYÚ1lyVÌ,dÍÉÜ*Q?PÓê øÑÀͬ)ÈÜ!¦¨k;pµ-KpæÄ9[ró™u Jš Š¶´å<1Ä=z-2Í ëƒ.̳Á¯dÃO\R†™‘eÄߘáSi·ïp˜Ò>¦à³ÆÞ«…^7JÆœõÔFÔ»ïYµ1E±a ZMX¦éÂFÉ·¨¿¼¤îh@Ì÷´FìÏuVÙÖ¨hõˆæ-é¦ ¤†…,ª­xÃëÜž…öÂb©¨Ip`ƒô5r× eY“c„k ÑrÄ´ ]…ÅfâfÖ ÅOû*Kà\ÓRCaÜïñ@ÌB̈05)DáóCI³*{(‰ýûY•my,·v·²m"ý­ªˆ´7ùõlô¹Àþˆ/MÀˆ°ÕEŠêG¹ãüÔï$Ü8¨Éj0Àƹ$å‡ìPøFøU J˜œÄú@ËxØ ¥Ðx­$pÈ@‡C§Râ&4e fÁûªâ‡¢¡.m8jþ+º©¶Ò ]«µ i¶êX\QÝnŠŒUF`Ñu:k€—¼…s/JìËžX’ÌÜ ¡6ð2ó6H"ÀdÞÃä¿·Á¯Eô3ÿHÀ‚FY-j„¶U9tŸ´5äugõP|ì¨> endobj 282 0 obj << /D [280 0 R /XYZ 121.4 736.262 null] >> endobj 283 0 obj << /D [280 0 R /XYZ 122.4 202.633 null] >> endobj 279 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F36 272 0 R >> /ProcSet [ /PDF /Text ] >> endobj 287 0 obj << /Length 1466 /Filter /FlateDecode >> stream xÚ¥Ù’ÓFðÝ_¡Újk­F·Iå¼^0Å•µ‹<Ek¼žBW$yJñïéžÉò®È&•«¯éékºÛOד³ Z3gy‘µÞZÜóœÀнÈIf¾µN­÷ìøLÖ*6g­=嬠¶§¾0ßIÂÈþ¸~qvá»C=>w"X.éà>œs]—//ó5žõÙÛKÛKØ›g—O^½Z¾~FÄåëõâòÂæœ³'¶³ù‚èÜÐ=»„Çë&‹õäÏ ý®Å{«}‡»±µÉ'ï?ºV ¬–ëø³ÄúªsËbÇ(³V“ß&OÑ}?²8wfaèü’Ä ü˜l‡[Á„8dó²°}üÖážl_lZU á(˜®5õáþà®@zÑŒ5ûª(aeÝ6DZ. „vŽÂh"hÈ‘(wz;3{xþm!•£úx ¾Ú4F¨Oí3Ñ–5:„.PtÈ…ÍAí)Ä ½Å&Û§ª¸BÔg‘e X³)éRIx!riމ"¥\?È$rH¦g€šî˜¶I[öY‡HÖÄhKÕö#anŒ(µX*1t¸ÊšÊJ~y•i«S}ûL•WMqóaq‡N”Ä\¨þØ$â ¡µ§¡²(™éü„4†³‚2„­Iaª0ä´R›Oè4V:–ù/cÆ«BµJdtä^ªš*Cõâ;ž:YïTcÔš/E¡ûé)âJ¨âô6û÷ƒâÄ0þÈ0œI,E䦅½•7ê~: ²Í \öUeAX-ù36„<"¤ÏŸ‘ß© &Gh.ùN¤¾ hßÈžD@sýL¶ ÞöÏ”dJúÖR¤©b[Ö¹@™ÓñÀÃÊáÝj7Ú¼1ˆÍH¢p"4Z³È(·# µ˜Z#BÓŠVæ’Z', ¤4ùÊ/¶~Z“s¤²/¥#G"r¤‹Ä¿.ìÑÅlé^¬«ã/}‘ç:3‡íìŒC&LõÑ[ƒ|ŒC!ÄD­püÕP0+¼Y·žÇÐXèO¹h³õÃJ]ÎÐfªÛº_ù¢.óU§¿\6þ¡wʺղºÉÁKÁVýG˶ {?6,`'H<ùIh¯·(üqÇOl‰«íEçðð°"9[BÝ#ù™f˜ð@k×Sª{ëÄ$;:¾¦ªÁ´­îD©ŽIW†ä6Þ™¿!Ú·Ò}ßô¬®5Ž5'¼º«ÒaUSŠ)½œ™¦¥[£ŽÑ!-Ó£ÓÆðZ¶ûºÕyùƒädÖÈ»2Ôëþ£Êë†c?îì¯ ®¤¤áEÓW)½?à–¶ja¬Š:%ú¶~yYËnðõÝÏ1}áh-Âbž9IÀo¬DÏ¡êi ð²)3­álB±*‰=Ö MK"ù‚¤¦÷é;crh•hˆÑì»™,ÑQ¯¡‹9†H½G²„Q/+QC&¢*¦£k¬<º×BWTµÜÀ¶ôÛ8Ö,®×YÛ´)ññ5tî¾Dw×ÝúܕƴCçX£‘×S ¡M™WŠ6*Dó²i U•)§P¿}Þ´òÞ»Ååòå¼aýæòmÛoÖg´²É³ÎL?ŠØW=Qö™A?÷k[ÑV_*¬(4;ŸáV¢ÝYd¥ÞüP""±­Àr˰øâ»ìĘ„1{^"]Û)õü“µÞÚ€¦£…‰–óŠêŠô÷Òš’`^jSxÄ?ö]e@:Kð¡&ðhAnˆ6XO݉~BK¢ÀqeΓ…QÖ# zï ¸‹W€¥Ý}‡bç|Pàx-†xd¾§ Ä|Y÷ „Ä´·Ç°·±Ñ[¸Ùß—À‡Š4aÍΔ°ŠÒè3; !&O)É륨UmÒt°#Á ±/ô¤öÕxü1“PÙŸ3Ó R‰Îãò«ÿãè1'NäYÓ0vfù¯æ÷ÿ‘â: endstream endobj 286 0 obj << /Type /Page /Contents 287 0 R /Resources 285 0 R /MediaBox [0 0 612 792] /Parent 284 0 R >> endobj 288 0 obj << /D [286 0 R /XYZ 121.4 736.262 null] >> endobj 289 0 obj << /D [286 0 R /XYZ 122.4 682.004 null] >> endobj 290 0 obj << /D [286 0 R /XYZ 122.4 217.301 null] >> endobj 285 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F36 272 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 293 0 obj << /Length 2120 /Filter /FlateDecode >> stream xÚXYoãF~÷¯ÐBÍûÈ`;3±³ŽwV`‘E¶$Â<6iä¿o]-Q³Oꮪ®®®úê Þ­.nîÜp–ÚiäE³ÕvæzžÌb/²“ÔŸ­ŠÙ/Ö§yâ[ª+«lîZý|áZ-,ºùÂ÷Ë·“0šÿ¶úñæÎwÆzœÈv̯gƒ·Ü]s(6CϾ¯ ðJkÞäm}ÈúrS)›à%37€7Gžx ì0ˆFpÇH=A@à„ˆß!ižð]DZê»v`nl§¾ø÷(^caŽø¾ÇÁW`8ž¥‡†$Áh&eøãZOè4Õ½0±*ë²W³ô°ÑªgÆiE&€u6“VûR›[Ì"\µsÀÀ³æ}Ùh¶@Q<¯§‚¤>guÙḑH=ÍÃTÁC%Q¢ègÍN±Dm2¢>j9•5 J€¨KD" ®¬;݃’ø÷-Óðƒµ.w `•7mØ'ÛÆvHËÔeÓWÈ@p[–ç *°é¤6OeÆäE¤€¯e…d”@ªñQƒîy·a¶*˜ >Ëó´gH]Ω‚"f…à¨#atA)¾*ÚFü?hq¬/¯ò¿ÌéWN=tÙ®ÎDcÁHÅ(åC­Êa%ñÛ]!’àq(yî{÷kÐwcÀŠæEÖðoYS!ãë˜^”¿:¾EªÉãndm»¶>?«8]ÆÇ6™¦„qÑß2z÷ …©Ä€ù#ÄM8½ßg¨Ò‹8T¸È1ƒì6¨ÿ…×œŠ°ø„u7À\+áÙUÅ›¦me]«¢ÌzUÉÁCײŽzÊŽ—’n`à5F>Ŭ¥:?i.FÊZßpÕ½ƒáâíªŽeÀ³AÅÕ8JîÁ*G%ŽdjÕï…Nø‡Ý ÿ°ÉçTa¡~hÝ·] û±ˆñ 7=£Aí@Éâç:Y×O=ŒÛ™”:\4¤œ×ÆôªÓðËÛׇÔçžWyÕÒµ\£DM±Sørêj>Ç é”‰Ç¶å kŽ1íÇzhO=FR p=RtÀsDñL]K s·Å‡ú‘J7Ã/Á å»v€*ªD¼¯SµbŸ»Ô`YŒúhG)Œ £ñcæÄVÏ$Μ £ÏòH¿nÚ9&#•þ¶ÙZjŽnkYõJ÷ ‰tÃîQÚT(,R%PO* y%ç ŒJ‰2E‹“¢>YƒîÛ^qì$Rž8&kq]ößJŒýëN€"R*eJág¤wUñ*«ž‘™¡3_´¹„j%ojä §I n3E”"m,ÍDu–/¦]€Ê»&ü.JÚ«V…¤q/Žy1ž+ÊN¡o‘Þ©­)°ÈÂÌÑ}7äýЩ…L:îhÒñ‚Ö‰»ÿ11 Åv¤F æT+†jRÚ®ÿUmGªÝµIT/ö)?ñè ô×ÂKc;rüs·qàÀF­`Ì”qª!Å·¤:´ÃEʆÛá×`©ã©œUöüÛ Œ’`õûPv܌ᴑÛñ­Q]Ï\•‡¦èá=QI?l%3ˆC»…Q£Â›ã@Þ1‘Æõ1Òš…xü†2XɸÍÇÁ)?b3DÄ<Ž—4 w¢¦:R­‡ªg"8kª„7T–p4¥b8Tê|þ?J&þóO&üæIí IÇQ…o¥[SQÛÿñ•Î÷RÉ/5Á8Î3HS¬ :’ŸÌÙg¸yQ:h©µ¬ë¬{$Vqâ-̈*ÚÈeÈ|î`¬7'GS"nËíI¦Wçþ”„°iB ÐeA":&í¸õ‡¦RÁêü g‡tV›•ªe+sÍRÔUnå·74‘Aéù¢_óÈoÊêdƒù¢%°%œ• Š|Dß\‰ï™2ƒf¾=¸ø Ýà†6|\Ÿ_Ó©˘¸¹!ÀçæêéT<‘‹³1æa™¯·@^wÅÕÍ›)³úŽát¡€žÒä;RzTøÌ´b½=´ŸÊ”œ.~ä!,ôë ÷rûâìMÕòú‰ïÒ)_­ð»CãH  YòšFænËF¤ú0ÙÊ y)¾%ƒ#׎첉”øžù¯ï ÝiQ endstream endobj 292 0 obj << /Type /Page /Contents 293 0 R /Resources 291 0 R /MediaBox [0 0 612 792] /Parent 284 0 R >> endobj 294 0 obj << /D [292 0 R /XYZ 121.4 736.262 null] >> endobj 295 0 obj << /D [292 0 R /XYZ 122.4 682.004 null] >> endobj 54 0 obj << /D [292 0 R /XYZ 122.4 629.544 null] >> endobj 296 0 obj << /D [292 0 R /XYZ 122.4 298.403 null] >> endobj 291 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F36 272 0 R /F28 142 0 R /F11 177 0 R /F31 162 0 R /F14 297 0 R >> /ProcSet [ /PDF /Text ] >> endobj 300 0 obj << /Length 1826 /Filter /FlateDecode >> stream xÚ…ÉnÛFô¥ˆ&9\Sô êÀ‰ÓÚuI`0äHš–‹ÂEŽý÷¾e†"eº¹ˆ3o›·Ï½¾9;ã‹ÄNB/\Ül®çÙþ"òB;NÄâ&_|´n—±°d£ŠtéZÝråZ5,šåJßv„ËÏ7oÏßg$Ç‘DÉÂan|ŽãXë?–^l]]_#»°ÖWï>\\¾Ân.®Þ£ ³_oξž¹Àé,ÜAa»N´ÈʳŸE¨· ÇI¼¸'Âr!ÂÈö`U,®Ï~?{† wl˜/lᆋ0Žm_D¬V{wØ«»CZôh–\®Ï·?£ jåºvLz°7uS¦ÒÖ/ü\r›ól +;8©Š^~rç°s_°€°wg9÷ªº ’?»5ÌÌToôé/Yá›r…_=Ór6%m!·²áC cŸ3É”œ-KyÖÒ¼”ÏHŸ•çØ xŒµ Y«9Ö^ µ…zè[ÐÜ÷!a¢Q°]¶pu°Ãhvâ Á>É>$„Eþ÷2ÏVÛï÷Ë$SÝt-‚<+kê¶E²eu¹W…ª¶L²|–ÕÉœAY ü‘•K{ ú»ÖÍNµŒQZàVV²I‹â·”%­áZBWó·é+¦Ð¯æŠGר¼›X5Ò»±•òöRUXý7Þ¶m'K^§U΋}S“¹yŸIf^?ΨLc$o»¦)R‘•!E¯È|ªÆ_ªÊë%øâ¾µêPr‰Ëš¯Ù¯^b¼šv Y=ˆ$k~ÀŸº lÓï™DßgØ’* )rõÉB6’dtLvu-[ ˆÀ€H†}éU‘óÒø†ÎÖJÝï@/ЊºŸóVWpœ¿í6?4¾ '^ GiñzuЃŒÜÕmÇ«c”"Ô€3“lCìy¤ç çвp=hgŒõÖ%×¥ tî—ÙÐzµÕ>&„1†7¬·c£ÈN!&i[ÖC˜l†æV•”ŸøÙéF¨8 ó},úfH‘XüÚ«wú˜Ø„aZ™Øø[ŒªYð¤®ÍLµ¨/ ‹æ´”Z¥nW÷ÛÝ\†µ%ƒËýØŽ%8fá ˆ.SR…ñÃÙˆáìÆl'ÏDViÇÐüÐ'µ–Î],Â.ƺvqHû|”³|ùEŸëZÿ,I‘Sžn.ûÀ8Æññ²w‚‡X¡×Â@'Lªã y:hSq®õFUÔLuz€ÔÓ”×Ú×}·ïuÊãm‡É8)F¡ï#ô=nFqã‚FÕI1©1!CAª¬èsyÎ7¥nÇuKÎò.1v=ìZYlV¹ìd¦TÈ”DÑÐDKÄèCè ”k‘©Eì'&­#S1¸*!ðpƒÌ÷ÁTW x‰((Q(ûá"Ÿ¯.³pTQ£ÛRDÇž‰ˆ´hk^iƒx#sE&¡˜šÙ:#÷]ú¹o”c4ÜVûbž”´Ù 3$7ÝÄh8Óy| Û¾<½cŸº©•®ÜÉ•šì§w™àòS7ã¤5Á'\°f‰ëéyæ’»BXï׫kb\óþu0¸û‹ö‰9žW¾~^«Œo˜“¢…“ùÀ/3'm.[µ­Z¦¼WÝŽÁÛ,ÃØÅá£éü”ç˜1€9vzÀ ~¶ØZEÓMuAÉ—NbQ{SÔݰÚ(¬-£P3×Ò& ÛI‡OÝ(±áïѯ  43UCløÖU%¨¡çáî8RÍ·5jŠIlÂø“Þù‚û”4ƒ•~BCjxyQeªUÜlbâD\Ïñ¿îU‡¡¦&lÑ¿©íŽÞ=€Êœ½šQ¡å2çnúx6ü“›ˆçé„öàõ‰Ò¾_s¹"x(S$N9ÐõðÀÀ ÎóC#Å·6uQð»ÃɇPJ”4'! _•¸2ˆ±¥y¼ïÁ3ÈW¸‚9œ÷ë—º'ÿ1vGô†#];Y®í_þ¾ËÕl¤«¬Íîh¾BB|ǕڮNI°LUeg˜•꓈ÜÖ}sw÷êò2+èÑú?Á GKÏÜý÷9¦`íŒ8ö3Ä¡‘O&Jf„©XÿÑó+¼ã5 endstream endobj 299 0 obj << /Type /Page /Contents 300 0 R /Resources 298 0 R /MediaBox [0 0 612 792] /Parent 284 0 R >> endobj 301 0 obj << /D [299 0 R /XYZ 121.4 736.262 null] >> endobj 58 0 obj << /D [299 0 R /XYZ 122.4 624.777 null] >> endobj 302 0 obj << /D [299 0 R /XYZ 122.4 286.2 null] >> endobj 298 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R /F36 272 0 R >> /ProcSet [ /PDF /Text ] >> endobj 305 0 obj << /Length 1841 /Filter /FlateDecode >> stream xÚíXmoÜ6 þž_qè—ø†žjK²eƾ¥K1´ØzëdAêžu­~¹Ù¾¤ù÷#EÉñ%Nš†ýdŠ¢(Š/(?[<9ŠâYƲ„'³åzqÎäLñ„¥™˜-‹ÙIð~žŠ@·¦ÌçQÐÏQÐÑÎBÈ@°4Næ§Ë×OŽD8Òùbq< IE”À²0 ƒçoß¿úõ—§óTËã·oHËÑñO/ß¡–ƒ—˃¿"X΢ÁÁ¢PÍVÕÁÉi8+`êõ,d"Kg—V°š‰D1T9{wðóÁ³;N•¤)“B‘IGxªNÁ3”y»Ñ–ŽƒBwfSw4¸šó4hv‡eI‚—s®‚¼FnOœ¾!É|×7UÞkõ禣ù]gê 1«ü.Ô„B–º{ gypynV¨õœä·;Ú uhbÕy¥;ôœpE,ÇÚ34kàÜIÁVÛ-Qn²˜«¦Úš‚§‰ojâ¯Û¦º¡ÉÛJ£‹y 'lMþÑéäÁF׺…ó4ôªšóEœž¦}ò£ÜìÚ³U™wîXõ‰Q®ðtI&dÂ1n#!w4µYÄŠC¿úÒ”Å*o ? ©Ão‰ð‚‡ØEÁ‡”®4χ æ.T¥ @rBBø6•é¡Cƒý#bPÑæ5Ì 9aëtKYÞUL®i­b1œÄêÂ>uXHˆ-ÅÔÞØ`¨0x 7PM“¼'®{Ûœ!Vn«µ¿!\¿B—ƒñ|7»RïÝ«â:€ÊôäåUçQx»k)| ö¥… 8*ÂE¿Ø•ÜÎVÅYªç<´øÚ:QÍðÖ¹¿÷>ÁD ø`1´÷_ì ‘œÆ/Á!pÓ†o3é<.£DAb±µÂb-hóÙ=ea4êhtxœÑ«nJ!¨¸†=œ¥‡]á‘ÂêEÌ›c_ŠÛ$@ЇBßÔã«9J÷€PðpàþDj}ÀµðÌ}èCq }0ã¡xúàë^}4Ð/õ gëtèZÜîi@)lyƩۃ>²Q+vŒÏöLù~âÞ5È¢¿‰WaHÚ §Gñ‚Ñþ —ÙΧܫ¥@èÀZºß cQº-F ٚ™r½UŽï…éwœ³ah²É÷|¬GÏ¥’]))ÔøÒÄéVoìCô.Vû0Ü·ù 6ü‡ Ժʾ6lÿÆ-NX&ÄtÇÆ•OÂë® Òÿg)é3…Äl6"—’9H;ü{Ccüó——IzUBA4e¡5ž{Ù[íNï§Íí.Í¡b:Aûc‘àø¶DÂÿœÜÀÐÿ´ŒúëCôõï>˜µSóc´‹ê‚ƒVníþ‚Z DÎ4ÒFö½!"³GÄÑ“ü"F±`*ÂF‚%ʹî'÷øoÕ^³O endstream endobj 304 0 obj << /Type /Page /Contents 305 0 R /Resources 303 0 R /MediaBox [0 0 612 792] /Parent 284 0 R >> endobj 306 0 obj << /D [304 0 R /XYZ 121.4 736.262 null] >> endobj 62 0 obj << /D [304 0 R /XYZ 122.4 658.982 null] >> endobj 303 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F31 162 0 R /F29 144 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 309 0 obj << /Length 1640 /Filter /FlateDecode >> stream xÚµX[sÓF~ϯPd¨…¤Õu:LJ`Â¥$ðL²‘Ööº­Dâßsö)¶ëP:¥/ñ¹íÙoÏmWyr~ôèY;¹—'aâœ/œ ½ÈIÃÄËr᜗Î÷ý,®êt%gÛÏæÛÑÍæBD®ð²8™}:ñè™ð·ý¤©—™ã“ …u¾ï»/_?w< 3÷ù zîÙ9ú?~ý…ÇoŸ²ôÝ›7¼EÍ9z?:9?úr€;ß & üÔ)꣟|§Õ Ç÷Dž9×Ö°vD’z!P•svôçÑdSûû"†¸*E•[ª¢‚e=lb¨G4ìX²v 8±•6=„펲ɽ, î.›ø[eÿ/e†b¿lÂ0ä²AjZ‰ –´€ ¢ö¶lÛ*›ÈO¹lPq[6Èõ+¶¿äÂXêæâ3Æ\m®1wmWšC©ÁŒÙ(_ª¦Ä©«ÕÏc Ê.´E[¯u¥:N¡îTÑë¯v, Þ/ ö!3ì:"p(ÐøK»mÆm¾™bB{¶1P¸˜fȵø¾\g¾w®ÿKž£,ÛÏs”¥îãÇ¿Îæ¹OÍ`~%íš»Vö­íÜ8L܇i›§€?Œ‰Ò ïÒÖŠ$EKM«núqýý+ôÜÞ/ÚÌÛÆ¦(ŠÀ\u]Û œdG’½Ä!6Šu³h'Ú Í禵©kF!8\µ½åâ‘óGåÐè~¤i(un–1 ¨1,Š+;Oò--NŸ‹¾‡5•ì äW¨N|÷Jc²FÆ:ï³dá®& f´Á8˜žý—íüz¥' e `¯¡Þ=ßXêf*¬~_@EÔr0ÞjÔ§“žÍÌ.§º…,{€ÒÖë« ám¡Œ;Õ4Ë}kiOúyæÉ(íÚ% lôkV`ð‚Ù­júnÀÝ «mk¸'XMÓ«»T C!´ Ó_-Œnâª.™]wºíto“ÉÃFõH/vG‰õøeP;&Þˆž:9ß§|uÈÊ´|€½{ð{¬á8Џi ïýN)žkpԵ͡­î~=Àaàn´"moÊjCÒ},¡íëbè:¾’I&QÝH[tÖ-¾ÚÉÉ›ìÞæ¿ 0wR¤¥á‹æpaà;Å ¬çòP!Oþí˜Zrpzez¾-_ÓT7*GyC<ô µǑà ç§!b}ÿçi„ߘöAøÃ§½)õº¢`Émòà}D?‹¡ªˆbàY´uÕ/IÅÀZw zÑN…Bcg²_ì0/G¯­=â ˆâÁv­4ÝöøÜÞò±o—ÊN%º®á­*áÅ·«Dªµ[Û/D4¿¼¸xvúòäââ–yúxrpÇãïrhF×þßµ»[maû†ÖJž^ö^´ÔVK‘„êˆ1b/¸jCŽWÊhv ˆ³®èí‹KÄî±™ÜÌ5Ì­ï­·'ànÄ©q˜ð¡Úº¶)z0Ôf@ Q²c‘,KUbO±»ÆþU0õH…1­F3ú¹xw½Ø‘3˜CéÙØIåðJ@ÜôôMex0‰ÂýŠ(¥ñ…E …oøÙÐð@@ã–lm\V­á¥ïm¨Ø{U›ÝÍbȱìÁU_~ÍWcߟf{·Äøñ‚Ôx9j:úØA`Ÿó·ìÐ÷¤™—„P ™—fKÄãÿ6þ†æØ endstream endobj 308 0 obj << /Type /Page /Contents 309 0 R /Resources 307 0 R /MediaBox [0 0 612 792] /Parent 284 0 R >> endobj 310 0 obj << /D [308 0 R /XYZ 121.4 736.262 null] >> endobj 66 0 obj << /D [308 0 R /XYZ 122.4 698.4 null] >> endobj 311 0 obj << /D [308 0 R /XYZ 122.4 643.25 null] >> endobj 312 0 obj << /D [308 0 R /XYZ 122.4 549.157 null] >> endobj 313 0 obj << /D [308 0 R /XYZ 122.4 467.018 null] >> endobj 314 0 obj << /D [308 0 R /XYZ 122.4 289.239 null] >> endobj 315 0 obj << /D [308 0 R /XYZ 122.4 147.988 null] >> endobj 307 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F36 272 0 R >> /ProcSet [ /PDF /Text ] >> endobj 318 0 obj << /Length 1991 /Filter /FlateDecode >> stream xÚ•XësÛ6 ÿž¿ÂçOò-–õ–¼»ËÖîѵ]פÝíÚÝŽ‘è˜=\RJæÿ~ÊVªÞº/1 ˆÇ`¾¿¹Øü¦‹­¿Í¢lq³[„Qä'‹<Êüb/nªÅïýªˆ=©U-V¡×¯Ö¡×ÁB¯Öqœx±_¤Ùꯛ›ãà\OžûEX,Òæ ÷òêõOï®VQáýô5ÄÞõ ê¿zý ‰WoŸ1õÝ›7¿½Å“Ô~ñüæâÓEê‚E8ûa/ÊæâÃ_Á¢‚£‹À·ÅâÑ26‹8ËýVõâúâ÷‹ï¿pÛ¬(ü$ÎÉÒ«W×dÁAh£Ú;Ú(Cו­¸­eEÄGÕïiµüDi-Ú»AÜI"½_…aˆÚ–´ïôYÃ"¾9ñûxa0z ÷Û†l:§GöÀ;hid»ŠrG€% ž¾xª9Ô²A.3D+¥ª/qzòŸ¯>qÚ­Ö ¬ÓLª[·èî.ù“ÀQ@ØáÏ#šOºwË^ƒ£˜U´Qµ5$ŠÏÙ‘-ÂÐߦi„އÛÅ[¿Hèv×ÃЛ7×/A2Oa{€‚ŠN÷$< ÊB˜NÏW?$Aæí†~Ð’Öhk§ïi‡áK‚Ô»µ÷6¬H¯”–eñÄÓ¾C§ZI¡+âÍAÛ‹?ŒR×GÓË>–FÇGX"KÄHÝ«®åïªví‚j‘é F ·’Àëvô Nðiõ SŽö&mÞç&,û=äÃ(M‹è ƒAI"’A8ž²£¬e?ʳò¡ßÛµÓS2½¨äH Ìn¥M%!AK%zW&ª¥ÚqáAÚJK(0pÑ\¾ÿaK+*¶d]TÖ0èW:0P~%ªÙÃ%£m~†S¶ P†ÊÕ°€M+›=£Ó'ßx£;bÁ¯Ðýðüš‰ÜRAÅ$¥ÀàÒáKñ$¸ì!Wày ¦§„~B Hžxæ`kN:uu}¤ È[´æÊ±áÖÈžˆˆ>ÝÀ›^5r}«EK¡ÜƒVê¹ûäés;¿ ïa䕃֌"ÖB u-­B—IX5à0CT2)XTxåeéãÍ€¶T;"¢‹|á½U“¿µ¶é%ñ›òjĵ˹¢²”¤[0ïÌ: ¤N5 -Ã_Õ–šÎ,¶Ú£=ËÕª•Nï@Ò¿@ÉHySjÖr!TN:F‹ ¶h& |6W_ŒT&Ÿ!>ÒpyoÝìG”ct¬Ì·«uø¡B²$u ü# }h¬JbË%š²ZµÂ¸_Œ5'8JVr'†º§SÝAMÎ\·¬;ë3›·÷·®H$FGw-!™¥áEØ…—®9í}K݉zWYŠ—Ù;'Yo1;í»>à–#(0…;•ä4áWLDŸ·Þx„hüºD)ô’$ÞšÛ\8™ BV<@}7ÓÁA¶uèdèC À„Ý¥•#n¦!Ýb‘GÛ¯Kª8‡þH£"(nÛ®§=…RÛ³Ÿ¿}nhi–ì¡¥yà]Õ5‘G8à­õ2,&eÈL?+S¤5¸L?—G§”d„0”¤¸…iZ¡a$B¿=­Ê£Õ3£íTð‹É °íXÖ뤈\oͼ‡†R¶’›˜ ›‡¡U=«æM¾š+ï3ÏÉ Tç ã{!û œ€6ÞÚîÆ{&qDCéżlÙPËñäH¼ÚøN¢—ë4…A§ŸS‘“Št­%EŠsìq/]K?b휂tZj®¤Ã`QÅÕ—›  3‰Ú÷}*‚Éåÿþa§ã¶d›äáÀ-e»ÝÈʵå^þJÍÆÊëS¯nåãJ×%w]¾0M™'½»Í,¶Û!=0AÆ­b×uׂGÈâuC'óV{k(?8pTi¡™ošø1Áµå;«EÕ ›¯™Øí tÄ5ÅÕùÌÎÒ0j@²q_ñ¸z\öÉùlO)ñŸó=‚°uƒjäFÁ±eõt>™±Ÿ>Œ„{QZŠÖ¹6ËÍÆÛî`Ž|ºj„¿ñ#%,`~^Ò‰Su.2lx?ÂX'ë¿KŠœß§qlD[ïÆMŸÓÆò‰Ã¡V4·v:±ÄvI ü¸°È`sÇJ©rlH–<­¢Â’_Îôø.Ýl¿à÷êÉTš8ƒ\ S,0e­Ñ¸‚ßÌÎò{‰8œæX;‡œYL䩃ˆ&èM—¡™LP²B‹¢0`œl¨‘ýQaëA RHjZ£•4nãνíè–3Qd\Œ¦–!‰Z<š`2 [3ëZ$턵ŒÞÈí‡YØF‹åT+ÄÀ_€<€£ñ1E'¥k=S *haål¿ÁoÿÅÀLtÀСyÄR.ŠãôŸmÇÿ:$#j/¯¦Ø'Ôºã1¨‘ãS›:ÿàë')ør­î­·•Å7|–צ㕵/Qeä¶’ág ÝøÓ`‹Õ¶Yú]Âu:­èUÇgßñxD>Žs2+kgGXzZO‡,ï8õ~¦ÁÔ*äÇÂS8KIVí–´ Àâd2Ým¤Yìé ­ÀéÇ ÜµÆ9íóÂÏ"0>ýÜýw/ÎÜÿ×þßxNa endstream endobj 317 0 obj << /Type /Page /Contents 318 0 R /Resources 316 0 R /MediaBox [0 0 612 792] /Parent 322 0 R >> endobj 319 0 obj << /D [317 0 R /XYZ 121.4 736.262 null] >> endobj 320 0 obj << /D [317 0 R /XYZ 122.4 615.266 null] >> endobj 321 0 obj << /D [317 0 R /XYZ 122.4 294.688 null] >> endobj 316 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F36 272 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 325 0 obj << /Length 2368 /Filter /FlateDecode >> stream xÚÍYmoÜ6þî_±MDÛz‰zGÐia.Œ4»‡;¤KK\[ˆVÚê¥vz¸ÿÞy8¤¤Ý(iîÛ}ÒpH‡3ϼp÷ûë“ç~´ÊÜ,ñêz»ò…pÃU"b7Í‚Õu±zëüsŽjËJ®}§_o|§!¢]o‚ t7âõ»ëŸ^œÞLŽžë‡ÙÊc~Jû<Ïs._½þñ—Wk‘:?žABàœýëúìõÕÅϯ¯ æäìúä÷Ÿöy+Ô&p}/Y廓·ï¼UAS?­<7ÈÒÕƒ^¸[qâ ¢ªÕÕÉ?N¾ÇµDºòC7c1Ý+NS7 ’™Nþ¤Sà³Nqr¤Ó‘‰¼éí&IÈb®ïmÊ•Üvk¼äA çà¦i‚\®x–ÎŽ _ÑYþ‚‡7£ß27ÎF7_^¼þ_Ýœdθ´õæn¦¹ÉÍ4`7›€ú9e7{ìfÒ{ô´Çž¦µ’?3O{sOÓÔg<Í "4 ÆÓaO3”‚0…§é䜭gFg‡ÉôÕΦ鹳‰?sv˜hg³£iåÿ‰£UÛ’$®;álq \Ÿ2¿g,½† • !ŽÁ mJº=”UÅT«Æ{1CÖ¬3ŸÏ«ïUÍ”¢@ØÐªUÅ)/F'c;Y“_k9îÞúF‡ÝÇ—ö7ˆ{iÂk» `šDvÑdëC»KƒàÈ0¯â™3Ô…j«²V<œÊ¾ZÁÜÑëDk[ÅTÓÈÈ{*¨m<]šï^Ú¢"à ,#ÃS‘ÑEHæqÁâÞƒLJ„.]úˆGÈ^&DÔ±õ°Gá ¿™S@ El ¦\ùmÛ옪›v§Ë7ÑFÓdÒÔKùôí)*/írªöŒ…Ǿ|Býcÿ=/FÄ›«Ë%ÍùRº íaô‘™C’™Ã¶¡€½õ¡Ì:U0Ž/¬µÃ‰·º´ÛéÛ²g‚TÌ)IÔck{4F6ÐöŸÿj¤èqYs©ÇQ(õà}BuJ ½{€/Å÷ÓüS\‘ˆ¥¨>„xêfÙü09Æu]\áå"Ú3 œp¡&„‘À1Ö"hƒ`N ˜œìNµÃ= «(´•iuQêN&ï«ÌT°¾ç#tO{$V0)+0slÃŒÏû£M{=Ý”¯ Ö§Œ¤K› ODGuŠ’SÁ½©8jÿÀȹ¡*ÌoÍÞíËJˆ¡Ðw.!tð=4øÀËTiZ3OÆÁ@šóuI©J‡´°¡Fß Å(ÐRèÓ·²¬L{8/Á#“ÜDS”Áo$ðó30¢)IœgŠw«ZÇc`(&,¡æš‰ M›B@™(ÜyŒïÉ¡•óµ»Í‘’SAà<óy–OÌá‚_n¦q#? Üħ—›ÈÜ4MMžØþ¥8o˜ endstream endobj 324 0 obj << /Type /Page /Contents 325 0 R /Resources 323 0 R /MediaBox [0 0 612 792] /Parent 322 0 R >> endobj 326 0 obj << /D [324 0 R /XYZ 121.4 736.262 null] >> endobj 70 0 obj << /D [324 0 R /XYZ 122.4 698.4 null] >> endobj 323 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F29 144 0 R /F34 178 0 R >> /ProcSet [ /PDF /Text ] >> endobj 329 0 obj << /Length 1537 /Filter /FlateDecode >> stream xÚåXmoÛ6þž_¡/Ãä4V$Q¯Ø§´M‹]ƒÅ^°¡-RZ¢m!zqE©nþýîx'ÕöŒ5 lh¿XÇãñx÷ÜCšäãùÉù3/´R'üÈš/-Ï÷ÀŠýÈIRaÍsë}3I„­Ú¢”Ïî&SÏn@h'S![8IMÞÍ_ž?îŽßw/H-—|x Œs]×~uñúùï?±Ÿ_¢a_þ1¿|={qõz†nN.ç'N<çZÞp<7¶²êäÍ;×Ê¡ë¥å:"M¬­1¬,ÅŽRiÍN~;yü÷´‚ØndEIâ"¦ ¶E·†bß®Šº¨0¨¾"ŶȻµ3™†aº“×´Ô­€OˆD§ê\£Äu¡©W7ôý)üD¦-jôÞ±AH#òbU ªÍd ª|)R?AL ¯©ç9iRܺ“u.Ûœð{ë†nÑý¬©}­ÑUl«¬xëŠ@备Œ5$˜dš ô*Ÿî`5õ'¬¦è|žó}ÖL„oÄÕÊ•º]”˜¦og¨º»m`6AÞö…NxälÆÙrˆz J:©­¬¢åö‚¬WE}p“±™´šÞ‘^7}™ï!ãbU7­âž%ÈL>N îie-Ë{]hçò3Y)ÂQjúžŸ¾ìf$ tþc×ù"W 1vcôŒñszþð’è{Ý©*»]+™s¾€= š#™åÝ„À Ä¥* ô¯WØôÑŸ:êè7¬i¨M¤¡fß~?¦Ý¬¨Ï$=CpŽƒË(IìŠRÎÙ‰F8¶Å°¥$ÖÔì>þ¦”)tm†"G°¬`ê$ú4Ô"VÐôݦÇAAj;kÒ!ýJ…k[k,B Çi`?UzStj׌­ ŒÇ%iLkŒIïÅQÜ•ÌÚæŒ8Á›¨4Û”|‹á6íw +uÓÆ0ßžèF‹è€ùD‹X-à{@‹Xìî±`NÄ 2 LÈ´€V®vX‘DÂ~J…ð˜»N˜ bÄâÿO ð,°¦í±ûAâ'¡a~÷bzF†`Ë„Œ‚AÞ5Óx@‚ `à¸oì&j „Ô ®‚½0ŽÄûuÔPdð-þFŠjóÀ#‡÷Ý"M‰ð¥ÝH ìùL hQYA`Œ¦Â¥£êdY’@'M s$¥±$Ì8"ô ÄÂéªM©*>$CM}ô¬:röj>Á&¤ý-æØÆ@ÈÎ?, &¾Á0Aó-<ÌDHóûÝ‚¢=¶ ¸¢fþÃ-ÈôŒlÃ~IJ Ù•<”¨EݦȠãÌx§B Êx„L¨à „úÛ• æsÅ_àâŠbûWfÓSc[˜¥Òxô£¸`Îø† Ø6+ÍÛ¢•Ò@qO=ãõ¿Y‘âã$ÜÛB.hƒ #Ç/­}ð@ë4˾ÎQ}†QÅŽÀ¹7‰€²RÉZµÿú 3ûs6¿üõæòúÅ««çÜ8ˆÒ¾½7öŒu7·O®_7·³9¾¡\\cÉæÔ‹ëÙípÈ?Ðì>×`Áp}ÖJóÈö(´b<8ç=ɹZʨíZÕÖ²^õæ ÀÈ[·—¸îôôá°Iùb’Föüêz kV~ÿaFíZ„Ç,ÄW w%½º>Û»½ $F•¤W ƒ>Aº€m˾ ¤(,˜zdÌ ¾ Þ›m©?~6ßáí{\KpÁ”mÓ×ùÀØjS”õÞ{W6˜ð­’Ÿš¼P8±Xð¿óù4ŸH†GÑ¿¤¡J endstream endobj 328 0 obj << /Type /Page /Contents 329 0 R /Resources 327 0 R /MediaBox [0 0 612 792] /Parent 322 0 R >> endobj 330 0 obj << /D [328 0 R /XYZ 121.4 736.262 null] >> endobj 327 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 333 0 obj << /Length 2175 /Filter /FlateDecode >> stream xÚ¥]sÛÆñ]¿‚“‡tLŸP73u)u&‘ÝŠn;“dèx$oà˜;ÀŒòë»{»  3±GO¸Û½Ý»ýÞÅ·«‹Ëë0~±Œ–³ÕvF‘ŸÌ²héçE<[mf?{ÿ™ç±'ªÄ<ôÚù"ô4,Ì|ljûyºœÿºúáò:|¢(ðä˜Ä#Ì.ïÇ×7ßx=rïû+ä{Wÿ[]Ýܾ}ws‹l.®V¿]„@ÌÂÓkb? ²YY_üük0Ûê‡YàÇE>;ºƒõ,^f~«jv{ñ¯‹oQ¬¨x"Ö2Ïý$ÎèI?ÍãˆäjµY—ºù%ˆ“É2ÒI”øE°œ-ÂÔOá¨W¨q‚H”céY Õ¨fGÛVþÞÒª;0d/-šÓx r‚Çh¦¯õ|  µGÕ–xfO{Ñl˜™‘‚™(þ K_0\‚<((g†~‘²Nj²@/zgD«tÓë.±>)d¤ÍÅI#…déc}ê?Uâ’Hn‡B%KïN¸Ý=íZM߃!U”ÒZRo²<;¥f@‰‡2ÒlŶ•†—ôùhl+ëríûþ|‘y=&ª8ôÜ™È[­&´7º>ÊãáõhÝȶ3%\«ù»—´¨„mé\‘$š]'vLXùĞŧH– ­$7„Çî‰ä#ð¸s’;Õ¬É'Žs Ñfc_N½¿7ý­Ó 3V( Ô–¾n$­Žä£’"ß>zÖg;Êå‹Qä7Ô_…ÖŽ¼Q÷kÙˆ»J¾¸üÌhü`Q-I˜övOÂ펫v¨´‘e%z/Gš©f£JÑJ†îåSZe Öñ]gâ݉¯t Ç:ož4€‹ß"Ý àkÄyÅÒÖH§êÜÓUw ]"Tÿ@ø­f:˜ÆyLg(PŠù¾Aô‹F3gQž/c `ކñªõGoç°ý%Hƒ¾ðáJ«ª|]>HoµØlÜ Üš>ÀŸ¢ë%시4€Ó5Íé°mÁ:%­[UŸ™€¬²>\ÂëâÀ»Æô†²#^þ.êC%ÿÆ¥(æþԇľûq‘Fß4J=r´µ¡¸&Ì®‰@°fyöÈWSÖ<*T-F_جËêž¶ßô,xÿ—á­xÑÚ¼šR±¨ŽâÁ®·[:ÿú âÚù_èíÜ 8lª{§ääÄÍÆïKù÷o¯@j¹–ÂT¯&¢m‡~ ‘;Ò&Eà=rôu/¢DÛu×µ¼=ªªbžNËvšÁ(ªÜ1ê9ÜúŽ’nrçð»FTˆÛ7g¾V²ärÓUäW)ä‹j§ ¤Ò½2 <«k ~‡ah#ë”㥠E‚KmŒ,[ÞT”³Kôÿ{:Éùx/ðÆOJÇ>d§‡``<îðvÊT…Ï‘SÑK=JÒÀ; 6—kTVxo±/û«¥3¢²šWôÙÑë¸ ˜ÚHÆR‘MNé`{^¼ýéýÕ¿¯¯Þ¬nßüsÒíñyÂ`ô¾¤áØAqPí — –w-Å#+#Œîµ|²¯- 9WƒÙA o¨LàÔÏ®5aŒ€Ê»¾ -þìÚsËVá:ˆùtÉ=^² ”¶u çJ})] @Ø#Å Ýë®ÚŒh¡zG å~€–ä*T¡]7è>kNïÐ.+V~F—·ü…>Wƒq½w}-¬¶ºªœxGŠAÓ¹ÈÓ[õ˜Khêuˆkža§*ÃseÑ#7[àvï Ÿhã ÿ„"Éçc6 {rC^;´>Âû®¾«°=7áüšìôLJ èv_h²/ŠÝ<Ë^ùÉ^ÅS{g{l¯œìŀ϶ʭ²­ ˆ ¬'`o.häBbVp6#VI×¼ÂZ •LÎ?£\‰3¤ˆÒ ý;LœŠ¥ ¥'X„µäfà/ÔÄypš9²¢X’ö½WÑ«­êR#ôh(ž¡&ŠÂcŸí#íyΠ´Ïº¦,ˆÎù${†;D‘×îû@„ÍØí#…ƒc& aÀbÄNK¬êø­©XÒæÔÐ |ÿæt¹if× ˆϘL‰äÂQâš|\à(€Á‡ ~2bŸÚüãh6`²mW1¥&7ïÒ5Çß®j|ZWñ8âh ó ì{7ááQ]óslÕtjœ×ÖyiBñ•Š]#+0r$a>)7?àð@*ýGÈ’xÂôãô× j …äF·Ì„F"Kwt͆Ü8ØuwuÙé–Û‚¢ý\Ý`Óˆš²,4ññÀñ–K? ²þwñOCò¨§nš¤~Ÿ~>­×ß½[­×\ÓØOãå€+|?HÂþ¤°ôÚ7_ ˆo’–¦©¬–ˆ>Òö+ÿ+:NŠ:YDAáƒgŽƒ¼Ÿ:#ˆÔ‡E 27¬÷i§~O™Š÷X¥pÕÂPGÝ-ll×ÿЈÀý™oˆpO&ÀsF*˜™Ãž½=µžKZqÉØ³qæ8Èž™’¬Æt ™–º|Ìpªµ_øSÀUNÌF]µacµý@¤ËÎHýOu‚¢M-R»¬£F_ýxF¡J¨ìãk JcøÎHZ÷œþN…‘³^~Êz¤¢qÚëŸF™j4 8oJBï¿Îe8›ON›ô½ì‰/¸S I‰êÏ@ÂS+E®‡K#mWµTÓÐ×]xnÞ½_]ÿøI­óhÔÀ'¶-ý.ܟذâq¥{ˆ$–çÀ~RRaå¿¶$7veáØ­Ywú@Ûsr T)ZÒOÞa8 ¿>ÿ@xæÛ+—&ÂhÜ<Ñ@ûY˜@ð~žçÄ".ú¿åÿÏ~<[ endstream endobj 332 0 obj << /Type /Page /Contents 333 0 R /Resources 331 0 R /MediaBox [0 0 612 792] /Parent 322 0 R >> endobj 334 0 obj << /D [332 0 R /XYZ 121.4 736.262 null] >> endobj 331 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F33 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 337 0 obj << /Length 1332 /Filter /FlateDecode >> stream xÚÅWmoÛF þî_!ô“lÔ²¤Ók‡K±$HÑ9[ã½mœís"DÖe:9nþýÈ#eËŽºf[‡ú‹x<’G>Ç—óëÙ`rÄNîåI˜8³•„¡9i˜xY.œÙÒyïþ6Ì„«ê¢”ÃÀm†ãÀÕ@Ôñ‘+¼,N†go&gÂïØ Cß ¢ÜñÉFžïûîÛ“éù¯'Ã0sÏOÑ‚pOÿ˜N¯..§Whfp:ü9@Ïw‚7 üÔY¬ï?úζÞ8¾'òÌÙZÁµ#’Ô *«Á/ƒ×–ºa%™†ÂI²Ì‹DJNÕêf8ŽÃØ5÷eѬ-&#ú>PÈn£kbF—²Q×Ò˜â¦Z«ª1#˜|‡®Ãñã ðò8&ó“ iMuæ›[&îK¹P¨OK½:Ú7jv‹….uE,9תïYnå£!¡Ø÷¹º)*+ø^g‡÷Á}~ð žèÅ^’¥¬—ÞLßÓõ{£× ÃÆpaD™•À:ªZòf×¼y”¯cȳ<;aìåþ“ŒµWƉ»-Ê’(²¯Qu%Ëò‘x62"í 1/5™»@ñ»vSZ±”c2ÌÖô}Á½88‰7\l‡aêê¾Ì«ŠID\4T#[Ñ›rIE>V´q òæµ’w$X4bšVxïF× É`ò¥)2ƒW\ÈÝÊé÷ÍìÄ´sÃöv-C}ÂÛ^”›eQÝ´É­M[ú°î¾iVÿ_‰ú¹vðyÐ:°ØêÿæÐü}Áÿ‡ón G±—Ao>L±ÑÃP„"PÒ%ø ÌæZð…àd:¦òÜKó¸:ksÓs$tâG­ÌhÒ×TòØ‹`üuKñÇÂÈy‰½!Ü$ò²%¬x©%qm•˺²¹Œµ2FÞ°òÊö$ ¤­ÊGZØ'CJ+]B‡KÛ>W¸ ½†Ä±EíõAFe/ŒŸiÕg”¦_Ï Ï€$ß©±ªR‘çŒôHq»1v¢Ž…¹;Ht qÒŒ!휛#¤ð¬÷UÜW†ºV˜jÇõ¡µ3¸O¾“Uƒ=*!~2{¢´;÷Jîó×Fâ÷“G&/a7‰\ÂUß“¬-™F.PðŽ– M6dAXwíÒj‡DÚ(໵¤ö¸âŠq5´’5«5›º²U€&*þÖ={¶'[³¾{¡û†‡7'Y”[A 4rl[ ¤f…I£ÉîH®+\Ðó# ¢}Â銶4[ÚoWÈ;,ìYhƒ~Ùç*&<Õ1T¢íƒ*á F†’uY` ¸Ø·Ú$kÑGrÞöZ 7†:*yRG¸¿ó¾­Ô `…Â=fÆØã«ú$×÷¥ú§O¨‡ýɸ„“›kþFö¿ö¿¤§W<ë¯.:½þýäÝôbz~`ˆËÆ8þ%‹ýÉ…^ò¨¯”Ú¿ÛØ'côVáÌ£¿/«ã*ƒûÜGýÅ G_Îþ ƒ p9:˦fohéˆß9eÜ ±  ùQ‚B‡~bŸËÖýYª¢iq`ìý’íêöàÞD–Õ’;ØŠû ý•Frç8î·EŒÏø®ïýñ¸¸¬áöŸ‚u©Z­¡‡sEAßyÂKƒÈ‹w²Èoÿ{ÿ5|!V endstream endobj 336 0 obj << /Type /Page /Contents 337 0 R /Resources 335 0 R /MediaBox [0 0 612 792] /Parent 322 0 R >> endobj 338 0 obj << /D [336 0 R /XYZ 121.4 736.262 null] >> endobj 335 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F29 144 0 R /F34 178 0 R >> /ProcSet [ /PDF /Text ] >> endobj 341 0 obj << /Length 2202 /Filter /FlateDecode >> stream xÚåkÛ6òûþ ;9]kõ¶Œ—æ’\ŠCÚC¶÷@[,¸×KD–\QZgûë;/êáU’+/‡~1Ér8ïÊß\_\½ ÓÕÎßeQ¶º¾[…Qä'«m”ùù.^]—«½­óØÓ­©Ô:ôºõ&ô˜´ëM'^ìçi¶þùúÛ«Wq0¡E&»UÀ4ÂÎAàýãùÛ×?<_G¹÷ú%Rˆ½—ÿ¹~ùöÝ›ïÞ¾C2/¯/~¹á\° nb? ¶«âpñãÏÁªÔ·«ÀwùêD«8Ûú̪ջ‹^|ƒbE»'beyî'ñ–Yºzö°Ž#¬kP³nnL]™ZßtʾvÅ’Í4%þ.ÈV›0õw “úÁê’…15«Eñò®¯‹Î4¤KФò°N3OµFÝVšq¥þ)ˆ“ÚŒ§¬HÀцG‹f8®7ÑÖÓ…¹{ä­Ý½~zoŒ÷‚ Mú»4e¦…‹]äÙû¦¯Jž×M‡“лâ¹§Ê:)2†8Ôé^·n—5–×=¨Å_o²(ð®ïð ðô#/àdè•= SÀLè°ȘùU3ÉænQÚeéLU¼ÐtÑw¢RX‡5Ï"9̈){6à¸åašmyU©v/ÄHöþ€¿¢¡–À!7mAê$‰¼Wë\¬Ž”òÞ€˜v&KƲ€©ÚÃÖmȺ…ñ„×4íûKtÎ@ÄE< 3U—#ÈòTøª<}b™Fb¼·Ýl'.ïØ·úkÔ6]ôÈ; U³GÀ¼Õw`êºÐK¦Pµ3ë™[[ñÁ¾³¦÷?M†H€À鬮î|Ž·Yèn†€X”~"xýme ZZý¤ÁÃ:K#°o8«»NKÐ* GSûîrj\´zo,l¿‚ŽÆ“iEؽ_Rcp»x6ui ÕÍõanöèÖ úv1%ñhÆ|®Ôx…”mÚÝ«Ž!/x(J¥æå•¸hµ*ù Sk:ÙI¼!Œœzªêe‰þ?Á;Þ1„ãÁëO¦ªD¿•m\ $ œ*(FAUḯDŸlnÐ饤W¸º=+'{7A_¡@|€GŒF ÇMqCÁ×=»òGoxSƒUI!yÈRÂØ[Sïq96˜¦· €ä €réãGrÝFJŠ3¹ê$Öì¹oÍáá3”KU´µ.X8»‘•©@~ét‚éêÊÕÖÿ%Ÿ„³„h~΂a(Q@vx—0–|XPaQñ©IiGdË£$RÀ1îÏÀ©:¬7¼YÊ 1!Éæc%5Š=Þƒ+¼'‰\åAˆK@8.ª”ÙØ(àQÅÀ_}5¿à’k¥ósDñ‘`( |ªªtK…6½ïåpgC%„©Ë.Ù¤ÒÁbL‘¸R²Yñ@•\Cø-3Œ˜ Ã?Nît(»Äê˜ãöš;èYŽWG¦#D#glÁê sÁ,Dä{,AÿÕ%#zÃÁG7€tWgJMêúֵޔá9à45(‰÷|¬Ú1W¶ÅÚÞîûƒfc‚²¢,™¢,rš…ÀÔŒ"}!F‘ îAdjð˜N˜]ËÐÌx‚KF6¶­>›ÿ9í~äÍ\kyßœ¡–•( zÂ!À˜C˜Œ -gd}Nkƒ†pCÅ%¨P•;Ï%ß^‰«ë½ÆÌƒ¸',Ðý Ú÷êªïš„mÁK.²óNª>k¢l©nx¿T½þ-é&yB @œÃ¹ÕeH–ðxk:Ú“Ž B‡(‚Å4¥âiXóâP!>ƒÜìËÒ$çsEhf±ª+ýBÜNÇ©÷wéh‘)é—œÑN,eðTJÔºSöéã®Ø«ì×̈ô½AêböüÐQYNå0W‹Á>¸”?Ø\û¨ÚVMbŽ’;Œq´¹5RõžvnZ)+¯u­[ȃø@Çnc z®+ ˜dŒª¡Q³Œ à*õ‰ù5x0ÅdƒýPs´œHh¯k7³‰Fpa§k¹]Ù³»œ°J]}"3&;ïíw×<_3qxäÕ÷ªÞ“2É¥g¤VØrþÒ=Ájw¬Ò3:ÒŽóé;uZT`½—Ò߬çTi]KÏ­*”ÝiOê»Þà,ÿ‹†jz®ãCäÔjì‚¶â8[ׯn¹3ÄÉA-Å(@¤©¤ KAh÷'™Í»&¸Ít÷<£ž™§®}Z Eî©>ßOeŸí§†^ûôJK‚i““WØÝ&Aèšw€¼à¡páÃËÁepÁ¯41´]“¨K& †‘·jð©^b¬>³õ\:ò‰ÊÔ\ÊÐ&²Ñ—¾÷T§¤+Uè/D7mùÇŠ#2ÒØÊdzVþL9|%êÅj×j»&š» ‚jn{9Bù\•*¥ Ú/ñŠ vbè_‘/±O8ýNFþ6ÌÜgó?/\½õ·ãwu]îõM–X •d~§nç_>GŠ‹} 9áwúè¿õÇÿ?^•yU8õªpú QÃw¦|Æ ‘Ç[Gÿ ?å_áV>Õ⮊¾Óÿ(Dó6êW6º/ê‚ÑöÓ‘O#">7iA²v0Í\ æyp L«ÉcùÙÿ øy]—¹ü¹s:ν½aµœÖÀCgL7lÎÉU[ °8ן0Áù“Õ&Mü<‹„îo¡ßû¤ endstream endobj 340 0 obj << /Type /Page /Contents 341 0 R /Resources 339 0 R /MediaBox [0 0 612 792] /Parent 322 0 R >> endobj 342 0 obj << /D [340 0 R /XYZ 121.4 736.262 null] >> endobj 339 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 345 0 obj << /Length 2200 /Filter /FlateDecode >> stream xÚ¥XYä¶~Ÿ_Ñ00ÛØÑHÔÖ'Æð‘dÇyñŽÄîfVG[¢f2ùõ©Kêîµo°/­b‘,«¾:ØŸß_Ý~¥›2(3mîw›Hë Ùä: Š2ÞÜ×›ŸÕ?¶E¬ìà³”ßÞDªbØÞÄq¢â H³í/÷ßÞ~‡grtT™Î7!ˈJ؆¡úîõßüôz« õÍW(!VßÝ}wG¼Þ‰º¿ûñ‡7(ïê«û«_¯"n¢E­8ˆÂ|SµW?ÿnj˜úvqYlžia»‰³<Ð@5›7W»úï§ËßÜ/+Š ‰sÖíö³§m¬ù†¾Ç{2Çé±qÕCÛÃP«zjìg·|Í sé$(Ãls¥N2–÷ÓhëíMÊì¼Ì•aʃ»£<æÞxÛÚn«s´-²|Ïk]W» f…{°¿'âÐOœØõž‰GZ$+\׸”ýÁ47Q”iÊʾ Ópê;ŽpѰPã‘7Vàb÷6Œ“Ê4Í Ï ö×ÉŽÞÖ°)’åhŸµ3ž9_ð§B-sU[¶].rLU-çѵPÂÙµÐ:ÎwÉÉ++º›É÷­ñnV1+ÕhýÈ”?8¡Œ÷ƒ{œÐ8|>€µe‰°.LŠŒªïP_o\7 éæ À€Á!'º}gšñB?bIç©úçøVk«Ön°•wO(ÐŽxYª×ÍØó4\‰Líæýp=&Z1*è9ò¾ ÎM£ëöLÒ½xêtÖ•D?;_᱇€±|7 ˜‹ ýŸÁ1VUÑQá컎¿›Á¢¯p}g-À#R5˜ ËŠ9n sÜ V:f¹î8yfÕ¶jÌ~ïeŽ&¼˜pÄ(yˆ™++`:L)Ò Oa :þ¾!O~Á̇ãLÒg6 H";¿›wÃ.C¢BÕï.¶ð¹ìؾAS$¹º'ðâô3Š12 ‹‰Ðhå‹~q‘«(ˆ˜0]-Ð8ÐL÷]óò'̉b(#XtäI„ïm÷[r¦êžY”lÀÄ æÁû@Þ‘ãöJýX‰–ÅX~cÈ‘ù¬$çàØXˆœ¬èzþ6}·'…‘GvûhÌ?"÷éÿ­avÂ3×àp–íÏÃ3HS0$êNf8¡!%xÎç½\ƒ©"ÓtÏß3g‚µœ•ö“¨«žg@'s¥þ³óølIäI9/xvµ?¬É‰ƒòTðÿ²b$ðv^.+<%T)7¯PBªË˜^¢G—)Ý¿§°ßæÖX=5“ãÄë/þÊä…,yðTb"‰3]fªÝbDÂô˹|˃i´»©aÚ‰œd8s% zFLÖä˜ÃÌ)°3­ŽàïÓŒ'/â®ÿ^`ŽPžd KplË·âYr*|ljs9/=«a#säºvØ™Ê2ËðNç¶G i9ñ¼þN—p:NƒXLIôåL7š ¢…{ä B‘äR†<0›ƒ5#äôDXª;,c:S{ÛÙ³µ&_ e'ÌmŸJ`ÆY'¬¹þ¡2èÕµ~áÔèt©@Q"Ó)d4‹‰^˜O—ĕΘr]…zóQ0žF³q„Ìô<ÖˆÍ8IçoôCkºjÕÎ"ÞJ.ÃÊ%MJ'¤¢Ld¤€ÿã4&B¨Y÷Þ°÷ 0¹æt“G’•€@5¹ÌæÑR­$´ÂÃÃÝÔUR¹qr)f|ÇË>9Û:‚»ºý'²¤ŸEK‘_1+£cµÃ‚“æ F©>ÖÈ™ÀYhà v¦È¥® Yƒm¡$—ØO¸^£H; ý´?ð’k±ñ.XÓRŠ{â=ZõÇ´à|1N)p¿üë3fÛÉjF%N\×n„h–9{·•2£Gê.ìÜ“ëº2ŠÕkYnÍžÐí? v?@PÜú[ÿPÝÃùYÆ'Æ*úŸÚg¨Åî\®ùkÿm ÝØ.ä˜ ¼ðÐcNü`ø~éFóˆŠé¢njIÝÄ3"sº.wÞ@ì&? –g玟÷ÑÃÙfC¸˜c  ;G^èdËY¿Š¡[ MѲ)Tü˜QÍÒ#õ¯iôLa3J°§ä>ÌLÚ|\JLëèá`øT_¼}qz‘‚Ò¯°¨EôÌc}ø¶¡¤5`ÉBlÿVîrù²$œÚ4/é†ÚWÛ¢-é>ü=bolÇø@ef|äø`58|'¤6B„@/™7A„¶òÛÃaˆð㇯\l¢$ˆ¡_Ü9ÞÙ?(Ñéè^è”,—PJ ©~–PÞ»>x&Žƒp ˆÿ·ñô`wø6žYDbÀpyaûHé¥A˜ƒÕÙûQŽCH–AQ|§DÏÿüþ.;ð endstream endobj 344 0 obj << /Type /Page /Contents 345 0 R /Resources 343 0 R /MediaBox [0 0 612 792] /Parent 348 0 R >> endobj 346 0 obj << /D [344 0 R /XYZ 121.4 736.262 null] >> endobj 74 0 obj << /D [344 0 R /XYZ 122.4 296.642 null] >> endobj 347 0 obj << /D [344 0 R /XYZ 122.4 127.142 null] >> endobj 343 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 177 0 R /F33 176 0 R /F28 142 0 R /F36 272 0 R >> /ProcSet [ /PDF /Text ] >> endobj 351 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è¥ñhp9ysü*ôwä"õFAâø$CŒáœïûîÛ“³×NAê¾~‰B÷í韧¼âdFîäô¯³s”wðrrðϾ#6j…žð'[\\úN[oß Ç©sc—N8J¼f…s~ð÷Á³ï¼o”¦^&¤Û•’mW«f0ŒÂØ­®hlŠ&Q-|~5'B!Ëy'çÊ “hìž¶D–ESѬÑK|`WÈÖJ•<ž¯ËjÕ¬´â°"“_¨FÏKš?¯–+]¨ áã˜T½A¹UWäOÈv¥\ªbMžDš E¸Ù~®‰†oÂѼ 'WU,AƒÇì<±c¤Hxi:Àê¥ G,n$ê±û”†O~ìßÂYq»k"ÿFÃ- ¿Òp÷„îÙsưï¢ÉBÃ5a»7º(hV« ¬ÒµŠ–kÞ_¨’f&*áq&,…ËlVŽúŒf³¼’†X lÙÆVK¾Ê˜'Æ€ ðµ•Æçoi°lrÃn¹G®]Ê>Þ!$ÒB‚Öa”š0òs¢”ý¤O~C¼Ð‚L Ë9-o‰×èË;à­¨TÑÉv##öošܽ1…­6qþÃ4.‰"ˆÜ5n'ï”GaŒRHc³ÚZ3€![>µM TI›˜¦eUb@ ²ÈLÑ’©úŠÆ[fÚz ¤{¤Â‡Fí)?"å) L&—•ñ® -ÂÀ=~xrþð˜æÆ¦0nS ï {åIT`Í´§il+ʳZå]¦ˆ¶ÔMCÎÃÃY«?묉¢[µý{l~2Bò•+…"u!8ÄØý%×Í Ð…5´o‚¶2°JµDg*"ïƒDƒ!Rx|º&>z _[kòºÝ6¾lõªP|T/Káp†YYµ}ïÊ!rÀ@Gdª$0«J¢rm.Ò^5Œ}Í=!–$Õ9xЄ! Üø4ó£f$”à@eR.R¹Ç¨8rHãá ôÇ^‘úÏt™÷`2AIŠ~¦xR¬›û»Rݲn‡3¸à»ÚÃøVÖsÅšÛ@î µ­ G÷ž'Ù¬ºlZYf̹’íâ'ú¢j[…qŸÕUÓ ZÕ²Î!€.þà#’ˆ±÷JÕ ®hþ‡m¢±¸o$å¬H4ö-Î wsaACá(8re­å¬PÞqè»W] YW•Ì*KÕJSޝZbê˜Û0B”NÑÔÁ;¶Gè‰"ßý½Bnƒ ŒµÉ.°Žµ •}L¸M2 “˜oœ—Ó&åhJ•åšO¥qb3´™lêWpïå|¨V4¹ŸˆŒ‹»¦ÆÐFÁʰBÁ©»ÙÒ˜”H™Q®@¥d–Öòæp8¡mÌj øŒK2íK²Ê$¤úE§ Ã Æ •cÜP·ri`Æ¿.½YŸKlfË,S«À¹%Ðfˆ¼¸ÅÓ;H¡i6à ]æX¸÷Ûp¦²N«h5Wªrò5/í¤® Í£s{šÒ…u 7 TïM±ÉO c00«Á§d‹OmzL@Ҡצü²Mb 2ØÂkrY›>RÖ6ÙÑÖ÷÷´…%E‘¿Q˜~™™*Š3 }½øbOœuÆÿ'õ×K+°OÝm‘asô4Õ{ ËÈJ‚j`´‰b÷ ^‹š|NŸ½?™N¿{ùtúÇËÉtJ‚€Iç½ÍÁ¦7žïx–Ï=¢É(ÑrÕ'߇y gµ¢/\˜ÚWÑ\•îá\™T˜ׇDá Ç$øÈ\—Ô"B{âÐŒ+©Åýt§¬ÁÞ6rP\]u¥÷ye}„o7Œü1êƒ$k,Z ‹aÀAQiøÌæé¶QX¿ñà’sÅ,,ðÒŠ_ÜnaM‚;¸¬&ɦ'HÜnØ÷jŽŸ#wÖa'þ¾ ‚{ßw@øÆh™$ìÃÍœÌbê #ª¡Ë¢`ä7tHmó¶€zAM¶óÍ ßm2Üh¾b>ÝÑ j‘wÊzDíYÛÚRX÷Eæ©ùž )µ«Ž&—qÂÈlZI\·³ÂlÂ[U«ê¥.7»Žö ¤aS’}%é3ŒVóCáѺ*1¹£Øôƒ|ƒùú&ôuMüYˆ ÌN;J:á~¡›vÿ»÷º$ßpÔdÃ)ƒ¿mתXÑŒ­Å7æjÖÍ!çæ?Ñ-½**É­9ôKï°=ª@K|ìwD;‡A‰wÔòÛòˆ$ü˜4)èsËCoR™f±Vß6—ÜÚ:"Áÿgœaz‘à‹BûÇË¿GB¾ endstream endobj 350 0 obj << /Type /Page /Contents 351 0 R /Resources 349 0 R /MediaBox [0 0 612 792] /Parent 348 0 R >> endobj 352 0 obj << /D [350 0 R /XYZ 121.4 736.262 null] >> endobj 353 0 obj << /D [350 0 R /XYZ 122.4 502.687 null] >> endobj 354 0 obj << /D [350 0 R /XYZ 122.4 430.18 null] >> endobj 355 0 obj << /D [350 0 R /XYZ 122.4 168.714 null] >> endobj 349 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F36 272 0 R >> /ProcSet [ /PDF /Text ] >> endobj 358 0 obj << /Length 1979 /Filter /FlateDecode >> stream xÚ¥XKÛ6¾ï¯PЋ ¬½‡=l€´Ý MÑÆ)´9p%ÚV£‡KJÝn~}çE[Þ:MÐ^¬ág¾yÐ/6WÏ¿2¯ ª<νÍÖ‹â8H½"΃²J¼Mãýêÿ²*_›¶S«ÈŸVëÈ0«u’¤~”Y¾ú°yõüÛ$\ȉ£2Èã YFTÁ¾0 ý×·o¾{w»ŠKÿ»—(!ñ_ßýp·Á#nWeêoî~|óå]½Ü\ýq€Ð‹Žj%A^Ý_ýú!ô˜zå…AR•Þ-ì½$/‚¨Î{{õÓÕ ¼_’{QTYŸ.˜—e&+÷ZMõ*‰ü½¶|“3‹„Þ:3Ò/Z£¬üÖâ·ôÇÃÔöí'Ýðp;&t³ÓLY=Øvjÿ\Å…/¬ßÂ,ü-L²ñÀã{eü‡¶ín°ÁjG¡71÷¡í:¦Ô4éþ ìi”M#ÞïÀ&à;L{82S¿Ñõ„ƒ ¸í°c>)ŒD‡¦gi®“þýŒwžxº­P 3,Óvöj¨E¾ØAMí8Xf±ÂxÞ=l¡Ëã i­ºïÀ`ÔUfœ‡†ÑBª#ð:°:)Wøû@xæhô[”)Ëx;™¹žf£ÑCEæ+Ä»tûï~«Ê‡î©Ò?À z@“MŽeç[g4“•UЬú$´ 4D±5Ê·,—´ü܆™4<¤`—ŸK„ª>³g.îW;´B þøÛë%ß‹eVÍ„mûÞiÀàhtƒÇ¹KèÃ%Kûâ^²/¬åF/ì¤e¥r«.aÀ6;Ü 9äO²B=æ…ÿ°o¥8Œà6ŠN„¥Ó^MLíô  !ŽãqÐnõÙÝevË_ÅkŽ·cîÖŒ=S÷ÝHûØ; üú"€zÕ0€ ¶èm–£aÖ,­ð ÕYUÜe1ò{1—e&¥ší+ø*| ZÀŽ5_›¶×_Æ={l4@x”ƒ1]}#é •$ã b k§û1nyßiáÀ_ûÈCå÷¨¼EªEâ+nñnø8Œ˜½h;©éÿ%ò8bëÂ!hÅŸ •}ÀŸ‘t -ai†´ÉàŒÑ±ÓÙþí8›߈±•†þ÷ãñ$Íg‘ƒ$1ô÷Ê^Œï¥†1Ür«•„&ŽÑ—1¨or39±ãêv€2¥:Iâ<{?ïD‚ ênn­´U‘;y RЧùúÈàë_Œõ…1#Ræ>ý ½cBžl†¶ Šxï]#aÒNN‹,„:×”i-e"d Þ777<ÀCðûìæ†ñŒ‚)ï%\© e+dc…Å/Übh”îÍÍógNìÃ^L ºÙæòu,‚EL¨Ã¯ÂO‚'£tº`¢Ì#³ç5 ˜Yî‡zÅ•§¸¼[ÿ…iÖ’ßp ƒ¹›xQÓB¯‘€NèrdpR;ï<…S_ç)©D·×.2/æÈ“ñy‚,ß÷üa×Rµë´ -ý(PÒ2¶ª³šr~î[‘"êÐãŽ5çæFvŸp!f¤Ëá<.nëÐ5ÌE–L‡€´3lºPO0,’Ôèà>o)—sjÏsÊ 9Æ^´i±â jà`Fñð=à(ðX'SP‘TGÙ %‘`žá& ˜Oå"7wr©b`h0öK•ºYöaÀX­?ßM†Tqö×Ú)‚ûÐJÿÈñºÎÓ 0L˜ACim·¼ô(eq0 ïX‰·ÅÑl©Â¤QqÚˆýA˜…d !v?ÎÝÅÞ²V QâíxsF«žyÚ˜Ñ`¯ÿNú•uH8 x‘ŠäpÀh•…©ËØÏNpþnÏ{$:#ÄkzÄ+2â0ûGMúë£6­%Sõ\åe™uˆ‰Ÿ¤e&ßâOÚŒçØŒ–µ¢ˆÍǸ±Ìâ² óM vËòÀoˆËà.SÂV¨0¨/X1«2ÿ…ì4ó0¸BïvXWèT·<ì ©‡m‘¨m郪ßÌìZÉ|£'mú–:?Js˱˜I•¾\?ta(…ßJpqPï%þ"Øõ.4 à·ÓQ¥ëÏ ¶–Î:8Šæä>yË y2ŒÄ“vSV%Œœàl õ£‘y¯N%ž×Q±<KÁ¿xáÐCãéYŧ'¥{ž!á|k(cV® Æ×p×qk#néÔECŠâ÷dwT/»"Ù1¨ÏÝö‰>\úì¥[ôîKÝU|CTAÀ¯¬Š²à›‘š¶K%’w?®gDEî``í¡7à²f„#õ(È3œ¿#|©KŠÄÖïnài¯­ ¢Üï3 ëBý•§ÓƒÁ¤§qŒB’¿pñÄÙм™æÃ©€ láf×Ì’z×—ÇÕy{½¨sh¥àBž€Îyåþ:¯Ø-«Ã¡kI×Xtã\¦ µéÚº•æ<~’‡`ÕîØ=ž×I|ðønÃk2êZÔ;ÃËŒ x—½ö,3¹QâLdP£_ŒÒkÜXbÒÉrrò$DR^HîÇNzê¢x‘Ÿ=öR¢+þ C~ëôìÔcÁåšøÏ·N« ,K’¦î/¹¿d© endstream endobj 357 0 obj << /Type /Page /Contents 358 0 R /Resources 356 0 R /MediaBox [0 0 612 792] /Parent 348 0 R >> endobj 359 0 obj << /D [357 0 R /XYZ 121.4 736.262 null] >> endobj 360 0 obj << /D [357 0 R /XYZ 122.4 682.004 null] >> endobj 361 0 obj << /D [357 0 R /XYZ 122.4 587.911 null] >> endobj 362 0 obj << /D [357 0 R /XYZ 122.4 481.862 null] >> endobj 363 0 obj << /D [357 0 R /XYZ 122.4 411.679 null] >> endobj 356 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F36 272 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 366 0 obj << /Length 1782 /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‘fÓóW§/âðàžHAå“î%œ ÃP¼>óòïóiTˆ—Ïñ†X¼¾øíbŽ,ΧE"æ¿¿¹ÄûNžÏOþ=‘pA8‘;±â@†ùd±9yÿ1œÔ°õjqYLn<áfgyÔL.Oþ„iÈNÊ‚sòxpÁÖ8/„';²IœY˜ tp—Ïä™0–¾ïèƒà7¤Ïwx¦pY–—µjuo¦Át–æ±øÕ ©o¼ùÉ öp,rq…«[äž‹Z±–Þtô4žLêt»P$碹áàOv„¬,ïêì^5ú«ªwZ¢g2Žƒ<ÉŽíüUYƒò³"¡¬è¼²œ#"Î2ÑšŽP»X@,Æ"™'“’…Pù$—àu)Ñ-HðZ%|[ÙN/ í-Ñ, _n•S÷ÝH|l*6]T„@‰–âÆ[”—âÝŒ}tèË, ¢l磟G¼˜ƒÊ ¤«XgÝ®ˆ:¨%5M¢ì ªxûáÁ­õ®¿ÖµrÃQ¿ántçÝ·¦5ZÂ)E4Â(ý2l*Å ™ì 1Ë£ ”1›##A}$ƒ ª­®Ep·Ö†0j 6ËAcQâ$ÏÌÌïÕ¶oA ÝšŽ²ªRÔûÓwDzAŸ\¬28ú8NZ>ìz¦q(˜ $߸€30›Ðn„NÚ¸ Š„HçÓ2VŸ^´(É·.Dj¨¡É«}VBD¶Þ(”–#¬3¢…pHel³õvÍ|4¸®êxå:Û/ºÞ*>ª©ê¦åÌÏ…áûð$¦F‰?zônÓo}bÛ7MMµ¢}4f£«­¹ >‰Ãa)q•˜¢z·çÃÎvcÜ€g0òz„X!(ÑA‰”ˆ’Œ²ŠÆÚtývëÉØNÕ CÅåR{ÃŒ» àrÆUAГ'hÕ'´¯¾D% Ï!æY <™tÍòÚó9oùszÕnv]{¹YÒ^·æ›¡¸lÔø(„ ¡4ÆÔ`üÅÚ‡×,Rß=•=SóF£Ô{"‚ŸÐÓzHIÉ}(ñ mûû%ø½ût]5=ßó˜>h—³‘èžÉúåhxåÍÅêúè.0º!ý)èÁÉÕd ê ÷2Æö®1°Z§âô”°o÷ \)_Rv´-Áš¿4 ô@}é”m±qHñ€LS{‘ƒ37˜ìŽ Hþé“jÏpKJqŠˆSºlްäÒËo…Ú CÅ ¡©ûñ˜þwÀŸöþæøÎ÷qúóõÐ×YéÅi£ÑÐ*U«½ã9Büx¥[µKÇ æ¤âqö&Øôyj´:’ñE!gÝqÊõ ò®ˆ&Ù0úˆH¹üÀŽŸ;s\ §aƬ™pÙ·‹Nûbã/h™¦«Üg‡Î‰%®@Ë™í·×ŠX¥dµC§soÝÙ‡VÈ(äi½°®x–=¬ó~¾f弞¦8ži*žz]ù±4p„±ª.l¸±ºë†q4ív$XÕð0ó^šÞ2‰[apJr>ûûìÞ¬8#þDßѰ?î¾çô¦H$³AOváÀØiq`vôtÊ'°ªo•”#d`oŽ"ÜS*Aø}P-F’ùšy˜Þ;#Æ;Œ<øfááX"Eiéýˆ;~xEÀQ_ô›Þ-ûÆ$q¨ð‡Z¢e èU[ëÝh(ŸýàvK§*hú±Z°(«Æ\aöáx9ÍÑûc¤_þ¥½uü¤·Å•â‚]ƒx AêÍÅðÀÉÖ<ƒÇyw}¿¸{•Ï»7V}gfã3>¼ p6 ±»¯2ó5¿··­1-EÀnàÃ9oE¸( %AŸ¿ú!>{KÜRöZ¾lk ;ª­½vIyï\°·xÊô´¨Mû°SásËo?ÐTŠŸ÷ñä ÃþFÁK•,ão^`x„J9Öæø’EȽ¸ÀùKDêË–³iñMqWˆgû‹‘t_«5˜£S­–UßtG}e]Q{> endobj 367 0 obj << /D [365 0 R /XYZ 121.4 736.262 null] >> endobj 368 0 obj << /D [365 0 R /XYZ 122.4 579.4 null] >> endobj 369 0 obj << /D [365 0 R /XYZ 122.4 245.206 null] >> endobj 364 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F11 177 0 R /F36 272 0 R >> /ProcSet [ /PDF /Text ] >> endobj 372 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Ç ‹ý"Íf/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 371 0 obj << /Type /Page /Contents 372 0 R /Resources 370 0 R /MediaBox [0 0 612 792] /Parent 348 0 R >> endobj 373 0 obj << /D [371 0 R /XYZ 121.4 736.262 null] >> endobj 374 0 obj << /D [371 0 R /XYZ 122.4 682.004 null] >> endobj 375 0 obj << /D [371 0 R /XYZ 122.4 561.677 null] >> endobj 376 0 obj << /D [371 0 R /XYZ 122.4 469.907 null] >> endobj 377 0 obj << /D [371 0 R /XYZ 122.4 373.489 null] >> endobj 378 0 obj << /D [371 0 R /XYZ 122.4 303.306 null] >> endobj 379 0 obj << /D [371 0 R /XYZ 122.4 209.213 null] >> endobj 370 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F36 272 0 R >> /ProcSet [ /PDF /Text ] >> endobj 382 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î¾æýŤn; endstream endobj 381 0 obj << /Type /Page /Contents 382 0 R /Resources 380 0 R /MediaBox [0 0 612 792] /Parent 348 0 R >> endobj 383 0 obj << /D [381 0 R /XYZ 121.4 736.262 null] >> endobj 384 0 obj << /D [381 0 R /XYZ 122.4 682.004 null] >> endobj 385 0 obj << /D [381 0 R /XYZ 122.4 538.152 null] >> endobj 380 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F36 272 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 388 0 obj << /Length 1660 /Filter /FlateDecode >> stream xÚ­XK“Û6 ¾ûWè°3‘gÖŠ^Öã¸yÎfÚ4íº½$9нæ¬)ÅÝþú([wâéÅAÄã#úÕjöò]´ôÊ ÌâÌ[m½(ŽƒÔËã,(ÊÄ[UÞgÿ¯y‘øR«ZÌ#¿Ÿ/"¿BÏI’úIP,³ù×Õ‡—ï’ðDOAç^H:¢Ö…aèÿróñýŸ7ó¸ðß¿E ‰ÿËí¯·+Üâf^¤þêö·w¨oöv5û6‹@AèE£YI…¹·ifŸ¿†^S¼0HÊÂ;XÁÆK²<ˆª½»Ùï³Wè_\þà_VAšäd[¥ŒX×’œ˜#Nƒ2̼E´ Ê”„ß°0˜žù¦½ld‹îôy¹ß@lÄ<ÎýG’YÏ0Ë #+¢º¶fµ¥o¿“¤a]w°&÷7¨öy¬%òU{O,6›õ)C_Á»ZʼnÚ|„à,¢((—Ë©û‹8-N<Ê1ÕÈR½‘õ–iƒßŒ0ª’Á|‘F™¿Ú»ð¸›`™M×4ä%N‘çH1‚,½×.ùÊh»Þíi¸ÖR<œ3Z´èwÃ.}e?†0üíÐâ.¬êZQ«Þ¥f9˜ÛN³øÝ£±Va|„âùîž$DUIÞ‘ò„j¬q–ÇæDsr4çÔöŒl@ ùx@‰NW& äM`º¡¼˜¦¨_†Ó[’]$yfÝúýÛk$ ’‚ɗ~#РG’m»ž¸ªÝÔƒÓ0´{ÁPBÛ+â ­O—ö4únE´5±;M ¯x‘á/XÒ²öýž2¢Ï¥š²Õ m…xKSÿµ0’J‡rNB!¢s3N7¢·Fï¤!†ÐN¸vqèhfh³¢Ó½¬~ž“Ìådž&¤ÞŠÍÅ©±¡%`Dd= Ûj´Å\ÃDœq>ìéG¹ƒêwDÝËVj8µ¬ ½ ª·¹áк}0Hœq÷iàß³bˆPc"ÃvZX0®1ÆÓCtC'øÄ'ÊaÀ™špÌfõD>â ûÁ‚ «iìÎXM lJ[ÑPyL}eцE—^|èöZuÊdquAm¯‰ZõÍVËüYò#Ò÷‰õѹ‰Ëˆr„Ó‡4Þ yá¿0,£™ßCѱ¹¶\žŸŒ-4OÔÚ€“¸‘z\Üwô/(l‡ºuž /ÙxqôÌóæËÚrôFÎ^hÑ\vbnÐ(Ì©a4³:àL/:wÎ[N{¯¾/ŸKÁTÐuþ>ãØ›^£â‹¬¿#YªX†öcìç„}â¹– ±©±ßW2>'Œ~öm'úQìÑÕ¾–Ãrì:`5&ÞE„U¿ùtË5Ç“zqZ!®ÐóAÀ!Ü-·Š=hÏËê$K|j×gÖ°Z­1{ɳ³7ài>(}aÁ>6À=—´„*KUΖղ¤#†|J*Ô8‘4E=‘n©r—Ň#ܶß‹š†u™@«ÅšíÁ7L#.XºyzTŸô3Žu‰Uñ=Э-ŸÏU¤í>Vø¨qS] ›«µ²÷bæjw†½;»VŽL©u§Ý` WYí_Â$m•ÙaXàq¥ÚmwÈ€6CûÐv6«­câUÕÊ]×;Œ6N£i'Á¹oÚ¶‚HWlPÝzÊÃþpçX`gï-á!8º½£{¼{ŽSC»8׎ʬ³Ü›@œÁh8'ÝÓµ+Ïmd\nà°‡'ž½çÊÌMËJŽù¡­“²©1vtÙÙrÛr™¹Fˆ­V²­ ÛÞÛ–­'Îî¤Ûä•ôÕb,•¨ QÌ´qÕ°r‚;2mXRèûÁUœs)û.C:N!·cH½~ažê8ð&ÏQ:âve·Í,ÏÄ=“‡¢AÃZ™ž7ù>_bÓ­ð¹Æ,t´5@›4¢ÝÐÓ¤8WÆXœÜFÔ’ý?ØY;LœðvgxøÓM@¶vø±£ÝdÎIJèè/•q Ï£þ±Ožú¨á<7==„pHMb^j–á‡+N·¬ÇtÄ Æ ÷˜Üæ˜åxéÿ!a³ [kÎeÃá&¡‡{jÝu³HWwÌX–Å^Î0êÎqÌj:6I f£ÑR_|3ž–Y}¬dψ8Ú⢇¶¸?<xÒÓKܵ$ÐüIhƧ ϸý“7™q‚ÙéïEË$È£Ô[,‹ Hù´pÿ#ý ãÿíÌ endstream endobj 387 0 obj << /Type /Page /Contents 388 0 R /Resources 386 0 R /MediaBox [0 0 612 792] /Parent 390 0 R >> endobj 389 0 obj << /D [387 0 R /XYZ 121.4 736.262 null] >> endobj 386 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 393 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 394 0 obj << /D [392 0 R /XYZ 121.4 736.262 null] >> endobj 78 0 obj << /D [392 0 R /XYZ 122.4 280.955 null] >> endobj 391 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 397 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–ÀI6´¢i‰Ü4ª¢ý\¡š{Dº¢$E"t'>ð`ÎæJ[ 4Eß©CG“§Z¿òhŽÆFo ªl+s"[a¸ÕfNyƒ§–¥¢@l!Ý)Š™öç  @ãp{s3rÄîÁ#ö²t`Pgd:Öß •rNwÞȶ#&ÐIÚ7(ðˆ2Lˆ¼&0yéL.‰%±Éç7‡ŽïÙ?¾ÿùâýí›ËÛ zK]D`ÈÒ`ŒøòÈÓeQYmÆ’”Ñ!ÖþŽþj›Ü^—cèÂÙeF\FÃ'' á‰&¦•ãNþh* ¿ö’>¸é6z¯›òŒ 6çC ?ñ†|â'ÜÎ38Aë­ÔÊ HU/Û/Õø¨?)Û*3)ð~êëÐÂÍZuDdøì’h0H%š\f%]×ß±œSQ§Ÿöäl…œGryGÚ#š2U½e3I 2}ÊcÀxÐ5ÞeäðJè…öZ D· Qpv”ÄS=2büÞð;§ëzÂÉg9‘§ „ð<áÍéz½­UCY9òÌ›‘Þ,HŒ¤T­“>PíaI¦mûÃX"30þ;Zž¤µ3Jð²{.t„aΩ¦y_u)¸!4ØLô-Oqkž1×ùÝÝõÕêzõ²°»l¥S7!‡†œ[Ì•I¤´¦«FU“ë8@r"׉j,EÖûƒ9Œâ4f¡È$pÜ™‘ج¬d£ä¢é2©} QKÄI—=¡Ùřɓ·;C“ùwµÌ©dãb)¶YùRLåyÙ,:ÉF†cŠÔ¯×Öÿñxµzs㤑ýÛ¿’ÿµ„q_ €25 '𘡴­kŽÏ€‹Ü€“NŒ—úÎK ¡¥ÉبÂÜ.+#^ñÐ5ŒÅÌWrÙ@n”i›Øî3{êj_Š×/M¬¨ï °¾‚¦úŸæ’ï\ªýoÈôݰ¯n0E&n ÅNOžz¿ÀìY׋KÓhdò£ëû°Ps†”iÞe87[ذ¬i»Cñ7U Õ  ZËŽFU£z°±×¹LÉ“S½´(PôP3ÉhÀx€z«jšBÆÂ§ë¦§ŠÆáãÀ×­Škóèþq“JsÕ {.í '‚i|L(“œð‼¸ù >ÀV0¼0G ³H¨JRжíªk’&R2T‚ÑF£Ž 6¨ÑF†ñq’ô*ù™vt/ ërÒס‹þþÙþ¿†ŽjzÈ$ÏäY^h~Gxö•¨E£ëdÌŒ ?e`z-Žº}Ãï<èÝ{Wj™´Ôˆ-”"„.ì¿Aôüôa¨i6H=³îîÛZä1Ké¯]õêbTþÂ%Tû¹<âsæÇá\ƒF à>º¡»Wð°­ …¼|Âë¿Þp‘RpÉ}§¡k8òÙxrÑ74¢þ8IBŒ±ÙÔÕï$$LSÀ©ŒÐg!·ÃÞàIÖÅWF–ƒÎÔg1àfPo:£ÐíÿøJàcP endstream endobj 396 0 obj << /Type /Page /Contents 397 0 R /Resources 395 0 R /MediaBox [0 0 612 792] /Parent 390 0 R >> endobj 398 0 obj << /D [396 0 R /XYZ 121.4 736.262 null] >> endobj 395 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F37 399 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 402 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ñÿú¿£R:Ý endstream endobj 401 0 obj << /Type /Page /Contents 402 0 R /Resources 400 0 R /MediaBox [0 0 612 792] /Parent 390 0 R >> endobj 403 0 obj << /D [401 0 R /XYZ 121.4 736.262 null] >> endobj 400 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F29 144 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 406 0 obj << /Length 2471 /Filter /FlateDecode >> stream xÚåksÛ6ò»…&ýjÆ¢ù~\gîÆÏÔ™ÄNmåÒ›¶“EHæ„@Æqýíbe³mÒ×/âX,û^èdyptádzÜÍ“ ™-×3?Üh–‰›åálYÌ~vþ=ÏBGª²sßéæ ßiPóEFNèfq2ÿuùúè"ôFt‚Às£<žyD#ð`ŸçyÎùÍÍ<Èœë›[Ü:ÇWgDèÃÜ÷}çøæêˆ_½ºEšç˃ÿø@Ä›ùk¡ë{élUüü«7+`éõÌsÃ<›=Äz&©TÍn~<8Á;ù³;&YæFaJüßžÿDרG¹¹—Ì~ìúq@¸PB5z¾ˆ|ÏéîEGPi¿¼¢Ëz[=|7_Àµe×IÅ‹Êá±’L¥¥o¯yb%´üíà wDS°ˆý=ÞB׋S+âM°ïûnû£lˆô¶+>¥]OŽ}7ʺ_&èÆne„—Ú/’4vn¥djÁwi‘›˜6ÝwÝöGG®î›»^énQH]nwÕÖG[±%)}tÚ×uÙlôíÕ{0W~žç'­îÚæãÅLHßÁ ]w²!Äc?¿@nÂÁJ:) ÞÏÂn Yð²æí°‘bÛ{Îïo”XŒm=—R”¹~þ‡1ó‰MáÄ¡Éß&\œÞÜ.ß\¿º<ýÚ€ÁŽœ;¿xA¼*V8Èè¾p2òží$£ Õ†˜ÓÈiCVmÓöÚ’ ãvKX /ÙñV©jÆ×‘´¾VmMs-T ‡4S–²Ue-Ô#ÙJÙlûNSB¾òÉœ… škûi´RRtFË8"Ó¸%$©²!¬-e¾‚›ªìXËúOÕÜŸ¾}wz}u»üöjÝ’„‚%=š8ØÓ@(Ië έ ³Æ¡ åÏópª^ÒЄŽÝê(Øñ!¨M>(fS5øC\L).ÂFöô]Šp§Ôv·±‚”_X’/lÀ{{¸I<¡ÿœ®¼$³þ <*Öša9‡òpÄ2ê]õ =Ü›€&ð›ã úhªåö®ìõ¡,$™,„2)üÛ™ë·'goæyâüçÛ«’ÐK¬%{Æ’S²dÜU}ž³†¼Ôˆ Y±Z†IÒ,ìošZZÁà$&Ð ÁP&:Q\aT#î]Ù`™ANwUkŒƒÄ‰é>Œ÷z1eËädùg¹á¬d– #jš4Ž—Çl8³ï{ˆÂ èJÀ¿"zàg‚ Cª±¯€n û 3W)T”Žñ˜vŠoŠtq86 ã’0Õ´(½8ŠØè–ˆýh+ˆ 8Hû‡Ø Ë5aòíª žAù`»l \’ãt¿ö;œb¾*?±iQB<¥x#]bXëû¸Ê•,Ù’êh³©©LpAЧi›Å3…šõ=…r|_ÚZq=ànÖW|j9™ÄªvSbª h|VRhª^ür°º³lc¦YD^ö;íšFÐúÒ×öiø"`ôtÐiPNÂÛ«šÿÛׯNŽ©1 þ¨1[X&~'†Þà^´ qigÍfðiˆ1H4jpjdÅeÛ0Í¢„üJF¡Ê!–)¢ìöMz7Ðÿê”~v~úæâòÍùÕñÛó¿Ö³ÀÃÌ7! &jŠCEo2NÆ|6X‚…‰ß•Pææ/™T#jÉë­)e¤n^vLÕzµ=•1AXQ…6`6OHƒ:½0óœ­ ÈF˜’_ XÒ¥i€2|Qå¸ðʼázôÆ‚›òa w€ X¼²ÁP’ÅÎ’8ó˜3{'Äã“xR§˜TÈL }ß=ëh«Ú¦ÑK#:ê>.^ÐUF`÷m_“ÐR#4’Ð`¦2éÅg<1ÖÞƒ²[á=ƒ„ºTÓXQ‹å9‹Gš)ÊQzæ;ß8 i)Ô8ñË{Ûƒí;ÚМyXL³´¸k£ZVL12¾A2Î!TfGJs1T—úIÞŒ}K6Õ:—Uusغ))L7;²•<´ˆ\¿/>rUÞ©¡ø'T[ª){YìŠÐ‘ï•ZÜU¶)¸qQȵ01ÛÐÒ¶3(¹·à¬ ׄ+¾Ÿ:z4¥)=À¿g¶º§ê~eF4±2몯«Ç†tñ‹±ã›ã·¥³L0µa€ è&Dý‚Pž¾¤¶Õ4($¤ó• 3J}ö¦`µÛ M@6ñ …t›â›K5å*”«XƒW‚š–ƒžWô½~ÞÔ}šûÅ‹=×uáãã3Nl*)Á ¡'8‚ת\³}H$zߘÂÿCc²ÅýÙùòütIötsü-Eþ¹}ýÊm?yϲ6,BŽ ŸÍIô¦jµs›môRïµW­Ã4ëøÀ`‘|¶“œ+Úˆ^ð!N¾ˆ’˜)D#¨¸²öÆ©õ2¡ª­(biZANsÛ|Äèm;ØäS2þ3äøAC¬æØz7…‰~Ö)öµr‚qcUy†¡Ô|ûf+¨uA6©uÈ0!÷«Ž`:.#v3,6rr/çÄt dÆ„I˜Ù¤’cÀÇ€m¹~ä3Œ¤W½Rš(K˜`aBPÓ.Þ_]¿[^¼9F±,Qo1È€ãn(P)9Äø†ÈA€¼ð¨ÎWÔõ¡[q;¿£õ¡æ4¯Vèˆ0b#´œ4棢¸ƒQd2,mfÔmÕwT o ÑgÂv¤Â9Žc½R%Û/ß|xÚ»q¼¸©kçn–eÄWØäþzQü endstream endobj 405 0 obj << /Type /Page /Contents 406 0 R /Resources 404 0 R /MediaBox [0 0 612 792] /Parent 390 0 R >> endobj 407 0 obj << /D [405 0 R /XYZ 121.4 736.262 null] >> endobj 404 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F32 163 0 R /F11 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 410 0 obj << /Length 2239 /Filter /FlateDecode >> stream xÚåX[wãÆ ~÷¯ÐÉËR‹âU—öÉë•§Ž³µµÝ‡lNJ‰#kŽG¤–C®â_|–¼»û$8F¿ nöÃâöòæo¯Ž4nƒ#MĨ„²{vÃZâÄÙXýPd†Iµ0?¨BUt‹üë¹·jjÞ`‚ÄËŒ-#®åè¡ucY0ш°Œ—kçÒ)l9õý¾ˆyÎøºDž'±W(•CN"ABÿêë0MIƒÆ™DÖUdÝ/@ì=í.F<0}ù ×¼7Õzo”ÈÖ;%ÇãåâÕ5¥ËÂŽòüuѧ<²è F§À-9*ýš°MYwÛ _Åp¨Nå'^t¶—éàD T*oÖŠañpµ)«]V¶GÑ„àœéœ¬¸+-TžÎœŸµÉÖl}‚Qp7 Öà:@Å’ÌÎï ÞjK²c´µbasRÊ’-âgt×áƒ.nn8½–•3›Úê\Hõ©©%-.¿ÿ~|ÿD§í.‰¥ÈØe¥xE‘¿ch_é]V=ñB{:CHJþ[ÙT¼ê±|¹ˆ§k® €ތÏAüXŠYfK8ºê3yY¬¥°!ž¥Ö•\ûädFJP8IŒX^ðª,Ô9CyY¼©Y‚åó]èÁy®­™éx¬Oʆÿ¶tÆAÚ†|œ–Nlí²6jÜ¢µ2Vd¬ä8k uT I‘™£ìÄJH6U¹c¨$7ULòÌ7ê}QÊÊþ×µóúêýâÃòÇWÏ$Jñ¤7c½aP«z~!‰TX:Ï9»8ú?Öäl¸›E :Wûz pÆyz\ApÐíþç Jõ¦×N ^¢ÙÜÚhêŽ@„#•+Åêž~táä,“Ý̪#Õzmßê+™XJKšñ’ â©K Tl½iÄV ‡ ÈRoxÅBˆäÔè@9™÷¦¯õy¯m¶2mIé*; ÌÕ&sþu%Á¶ý•KpœNæ±'z¯ÛúÖv[N˜‘¥«ü\þ*j‰lîËIÿÃ2ÑÿÔæu]ÏõÏwW‹ËåýåŸH_ò¥¤oÒf¶m8ãjÈÊÍ ÑÄÛu%ž×Ú2ëwd+‹Øs¹‚î¹¥Kž£9H9°‡~ 7z2= Ês2™ÛKEÅÛ2ØÕ\,ÚtŒtÅ¿{q+†_¾ü”+³4ò–Îã 8)é@H„ØþJK41½õ(Ù¸5³|3B²—ñÒc% /ê¦*\‹É¼ãÔ{£×ºvF;b Ö¢ÍmGÏn€r/Iª6Fv^Œ&@é^ý÷•tÔÙ«ü5‘ws}y½|}Ô…mÇ„nºâ QÉi!Yq½g¿;2 ­sXem¨æŒ@¡ëS!bIŠù«–æà:'lSE]NŸmøåM×ñ¹ÜhV£6ôÉÔÜ+PÉ™zŸ¶ÚHõà"6á×ìGõíœ;ãö>L—+\¥mÀÁcö\4–Õc¯‚‹Ä&rÅ´½"ÍrÅnr±¼€¥8OAÜt#åÛ„TœÅn”IG›™îуøÆ²wxpIޤäyÚ! E]÷5¨ÎUDxâ_—äsiµ’†pÆke MÛt‹¤Ñ`T&(—ž¥0=tRÏ[¨ò”6.Úœº5W X|ßßXi$kD<à2°º'“ã·°ÐÇå/ÐøÓõÝâí˜w6Ôu6î½&^ÔSüÅÅèç£W…¶6Ü!FÞu¶vB€ë“`šëè¦>reZr„*䉎rñ…öÛºÞÿe<>þW:–+!—ŽÒøÎ¹Õø'§ÿç?#¤]Yûx·øOE-ü¦ªEQû‘ P&ˆÌ>âÆ˜MS¬9‚N¶™È0TBA“Ï9Ëá†;ã·Ü@wÃEù».ÈêwývÜÀ•Ú¨ŠºSåjäÄãO<›†®ÙAPÉ&Ç6ë ·›¸"ÐM¥ÄeŽXJ·Âu(ß&óøå „]JÛN¢å¶Ô5±xÌú¿–YéšXùJ‹ÊýÔÿÑ w{yñîþÃp>¡²F?b¦‹’ù‘×±BMÒÀûg7=‹1̨"Û)Þm¿˜áUæÍòFËÞ6„̾Ïê­û80•¾ ÈÊ áâ²@Àó Òc©³#@÷Zº•Ë4úçFòIl|€–'æäÜ5ÿµÎëš( ùÞßr ÷…¢vßÔ».ˆ/‘;vÓwyDct+…â0qr5ŸLT)DU;1ƒÖí2!žó½ËjÊ‚'ÞÆ]J÷%r»Ïeè›4²£¬dù͇N¨¦±? “Á(žQlE¬h·ßûÿò+vÍ endstream endobj 409 0 obj << /Type /Page /Contents 410 0 R /Resources 408 0 R /MediaBox [0 0 612 792] /Parent 390 0 R >> endobj 411 0 obj << /D [409 0 R /XYZ 121.4 736.262 null] >> endobj 408 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F32 163 0 R >> /ProcSet [ /PDF /Text ] >> endobj 414 0 obj << /Length 2152 /Filter /FlateDecode >> stream xÚÝXKsÛF¾ëW°rY°V„ñ±{²-ÙÅ”Me%&©”ãÚCrÊx0x„¥üúí×€ ‚x­k{zzzzº¿éîÁ›ÍÕ«w~<ËÜ, ’Ùf7óƒÀfi¸Ë,œm¶³OÎOóeèèÆjî;Ý|á;5Í|†‘ºË8™Þ|ÿê]èôçFY<óXGàÁ:ÏóœÛûûy°tîîp}è¼^ß°¢Ÿç¾ï;¯ï×+P¾~ÿ€:¯n7W¿]ù Ä›ùƒi¡ë{é,/¯>}öf[˜ú~æ¹a¶œH°œ…Iê@³‡«ÿ\½ùó£Ô ½d–,—n¦láé :ý;Ú¦›_½Ø«’Äiu_l™~œ/‚ÔÑ<è[½½2U‘@ìüÓTyÑoG̯+æt™Ê버SÊÂÄ)L%3]ÍKÚ#l¦äf÷„ž€Ó,|ßÍ☭eUà¿®>²ÿ (¬089b°Ûºor‘ÝšFç]Ý%!´€/ßpÇ7È~…‚$+„ÔÅ"%¤ê Ò7Q6áØÅ k!º¸c6嵃æôv¡J¨T\*½,´ŽJ…íW‘ßX4$4ïnn~üáÛ®ÏmÓpnö‡BÁi~J)ƒ=E$TqþœP$nepAÑbnORÛ¸ûŽ•ÈkêâšA¡¡ïÅÒ$Ϊc¾tR *L»‚WÔÝE]íµ ¡émÿ()^ bþTÀž>·í|}ìLiþP’^¾šÎÇH¼èÖŸ7éœÎ©âçJ=ï‚®¿Úä§ÑäGÎËa½¹{YÖæœÀx¦ìÀ7×?_áç øÍ5‘(Ù§”¯ðÄA²©6íHˆ“ZË;Uµ©°‡ Ø…àœ‚}”E˜ô+Á-¤•DrdÀ.…îéYŸJò9¤Æ7¢Í2§Ž K‰áÐ×X¢ ¨;æO#TzÚü²n´€!oôtŨyžó†Jº”S£Ž‚H5àowñ ˆì{8¼ðó$Úï¤}ò¨ûát}éÀü!ßæt5‰Ãå©3æqpFs]“šè¥¾gVÃm Uè¨D}w¹ŒðAÂxã1µQC0ÕP‚×±,b@Ó†\’z¶Ãm;¶uÑã¥Ä¤“IË8e¤ØW´}£…Ç®Jó àÀ£Ë¦f¤ÄˆRźúÊüÖ‹ˆ-ÏHKºýËÏT`U U'J »¹CˆŸL‹мdüÃ%l7PŒ †¦lZšÉíF® Øx\ÝŽX1a(¿jg‹ß¯Ÿ}€Á^è­íÒ²}W— séæ( J^öIã‡Õúãêáaµ~ÿòÏqÈ•ã _óð‰¢øçWyhûU+-˜‘÷Ôé`¸9ç¡Ý VT&@š–—/ ívrAbq=YFùN¾öVèЈ;løaƒ"ùybÐÒ¶\²pV˜Ã=¤;®C‘7nª²ÑÇ7ÛÌ H-û0Fû#½ªQr«"ÏF–¬œêÃËc7ú¸ÆS*¨z àº£aâ;|õº0{´µ¾ú/Rp'0B8‹Ï^üûîëŸ8þ6ï³ó Xß½½[¯oßn^þ‘ƒ¢H9"®uC4‘²e8µ0d6Ý„Ñ|(;F‚ÃÈâåsŽ-}‰¸›$5—ì |pßü·øB;óãÐMýh·ÁÍìÇö8²Ÿ÷ÿJÈfš endstream endobj 413 0 obj << /Type /Page /Contents 414 0 R /Resources 412 0 R /MediaBox [0 0 612 792] /Parent 416 0 R >> endobj 415 0 obj << /D [413 0 R /XYZ 121.4 736.262 null] >> endobj 412 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 419 0 obj << /Length 1474 /Filter /FlateDecode >> stream xÚµWYoÜ6~÷¯PÑ>HHVu+A{$ˆtw‘4H”–¸6QItDÉG}g8Ô¶Œ¸Eû"ÎAÉoŽ^­_³Ä)ü" SgµvXú±“…©Ÿ‘³ªœ/îG/\ÑÉš{Ìí½s7‹¢Øü £!{¹­©IO˜ý<?#{r{’åüýâèìÍü_¤·A̤÷è ¨JÌ-m¬\#niάk¢.¬ßÔÐï×* [,Žú‡ØÛÜÈÎBq-Ê/é‹àÛË)Ðd+{‰%Ü …û"ñëveëà=KðI!™FÓ:8¶ŠÆì‡ ™Þh{eŸW€ ª‰áZè³D‚D Så€ZKlþµ Íç#¼º¼"fDñwŸÆ3Õ‹Ñ9 XO©ÆêJ®…ž‚Œvx“ÜnR%f!$9æÐ1¶Ö³æµÆÃÅèðK¨ FÊÉV I±ÒáJ÷ð®6¤ÄË¢´2ùyÓnu¡¹ÎÁŸ8)/K1>{àÛð´W=â«-ˆ÷Â.Ú »û¡Ú¢w0¦éµêH*nE9ŒõFu»V¬jjåÿ!|..À•8ËXL÷§jqÐï„x6iò‘'IÚôÒaÇÔO£-³Ç3É®`.eT\l2ê 4¦B! ™€´A•æÚfãTKS?‹ŠýÚ»\®NÞ{Eê~þQ‹¶zi:¶zi¶íQÙô(Æ¥(á4è^šfó6¢ ÛŸmçT¢6ËEÓç°— ù˜„(Ywjk&3áhÔ=ö}Ч˜€qkzç–ÅŸ¡5'8ÇBêË—Oí!Þ^´ª£G1HÆÒÄûEU½¢eþ´P!e/Þ-{ ÒҴ̈ X›c§ASކ(|Ê:š²]7›,RªÓOíj—ŸOË'ØÏ~2Míâä‰ïÞ¼ëÌ= ØR_Gaêê»U“®á}‰ÒK¡÷&?{F|'´è®Çð@‰ÁWu–ã­%M€‡éè Ôê‡GÈÌ2<ÂDJSûÂëAû uE,d¨{¢M\¨Œ¡ÊÎ8¦¡TÍ•¬ÍÏpÑØç±2/)q’°@¦’šãŸŠaèü›Õv:”e~1]ÖM³˜îü;³s|d7lt¢HV¸ç¦Ö³tlV§ü…+©àE Ú¹ÐnÕ¨±áôýw7P“wØüé( é[ïñ¦Em!YöTˆYù‹!| ?Ïs²‘$ãŸóßDî endstream endobj 418 0 obj << /Type /Page /Contents 419 0 R /Resources 417 0 R /MediaBox [0 0 612 792] /Parent 416 0 R >> endobj 420 0 obj << /D [418 0 R /XYZ 121.4 736.262 null] >> endobj 417 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 423 0 obj << /Length 2086 /Filter /FlateDecode >> stream xÚåkoÛFò»…>]©ƒEó)J¨Ò8…Û;ùÎVi`¬¤•´0*—Œ­þú΋”(3×ýØ/ÚáìÌìì¼W¯Woýx0u§ã`2¢áÝ kLiCh«B¤Q޵ÜÀSWûºâ½MYdrWi„D:œcÈMzb#/òr†&¤078à&·•V˜<Œ›ç`\&ãìE€D¨Q i«‚qJˆt&%·TåIÚZ¬›£ÔÕJÁ¾4ìgJ™uµ»D8ääF$tšnÏòŽå`²ât·¡y/Åëç=”kÈ H`}&ÔÏUÄ'=¨iQä¼Åxl³ðY¡¹ÿ%Ó…d¡ï†I Q AæÉ˜ÂŽƒØÙÅ+†S# w¬ëÊ‘q9šòš¸ûLš>)ìœÈ÷Ý?y]ê-T$†1ÉÆ]8{ã²¶Oú…[B<<`~ >awEü8‰«+–ør¡­uœhcô©!…PVIçŽ:KÃÐàà—ù8êØ*`Òïw*ßêóÚS_këRo[S?`Ð>ruõê/Úpܱ¡HGÑpB]±ézNc£¡‘øhl>ìÛseEG}ü;¾+ŒÚȃ:]p³ù7Õƒ+!¨X¶?S,9¿i„hÄ«/¹º(a³E¦ÊŠR7¢2¨‚{¼u €YAb­eKYÝ?ß±ôTºS;9ÒxV§2›b3Ê_4&9¡Ágª¢¸Óö«[È»ù›»›÷×ó¯l'Cvä7‹!Í€•Î|² +õ a#̹þŒFǾN$E]®ôªÀJ>82:u¤4Á2%Ž;È—žÃÚ™»='ï³5+ê…Í<ˆ ´¼Úün_ñŒœ©Gš‡p[ñÒÞà}½LÍŠÂÁw8HB'-Ôºe¢)²ËžoS9P•¥ú⨠9s¬ÄäZU>6a'EBLÙL!MÃh‡˜lJÃÿm&¢wóÛÿ.þ|,‡^Ò4_€ÖµTÁ+ç9BP(lUÖ+|q„ˆÅ¾|2óEâ`ÀR‰sÒ÷øôNžUÈRòÚfû"ĈOšq\š5Oôà–VK1îîX[š\aÃK6o" Þ7MGœ”Áp*p Iiªéíű—龸šá[ Þ0‡0TPl}6E-¬ƒ²µá•ƒ ! .y2EHñ’I˜Õ©°¸¦e p„¯ó&G„­—'¬­åqD4ëÞ±¨K#gvÉkë0€ox!oàšó€ v1Í8Cù‹_Õ)co»Œ<áøÞÿ·áWÚ“±º‘+GwÕêQü5¾?“£’ßòÒØ5‰ø!´ú2jÍÀl‘¶F0 Í'QZìùS?à Ӟ‰CÇ%¡d%aä±IQ„:A¹ìyj7…a‚¯])EÇ`N…‰3»áïð2£ÿ¯–'9½KCjÆšyè©ÂÏøbÿÁ¶àµ*Z”¶49ö£D NÉS2q¸OȤùù±Nö’ë–ÒŒ_>_Í£wÄ!E•ÝÃ÷U©S"þàÎÔ£¿B(Föý'µª,K”]Ât“©|ÕJR'VŠ'Qâ½­ïtn‰xÍ«ÓrhVÜËÆcP½¦òNLÒwǤçI‡8é •Ù§Â†EGÆ€„k}ö®ÔÒ¤æ·vœî´Hé\øf- °,ÿñqR齄¯§u~&§[K^À›m¡ÓÈlúf§ž·?HÉ´àòEZž´EœM.ÿoûL¾Ð>#nŸ?ÝÄ`p†fØüÏÊÿãÿº¿ȶàç endstream endobj 422 0 obj << /Type /Page /Contents 423 0 R /Resources 421 0 R /MediaBox [0 0 612 792] /Parent 416 0 R >> endobj 424 0 obj << /D [422 0 R /XYZ 121.4 736.262 null] >> endobj 421 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 427 0 obj << /Length 2395 /Filter /FlateDecode >> stream xÚ­YYÜ6~Ÿ_ј—¨iEuÅØ‡ 6^$ì]»³~p ƒ£fwQK‘òx²Øÿ¾U¬¢Ž± ìõ2M‹d±Ž¯ª8ßïo¾}g›*¬ò$ßì›8IB±)’<,«t³?lÞß–i zÝÈmØí.:ôÛ]šŠ Ë,ß~ØÿôíË4ší“$Q(ªlÑIë¢( ~xóf›”Áë7oq}Ü¿ú3mônÇqpÿæÕ°ù«¿¼Å=o~Øßü~Ã&Ñ&EKÃ8*6õåæý‡hs€©Ÿ6Q˜VåæÑ1^6i^„ ŒšÍÛ›¿Ý|wLª/e(Ò‚äûåÕë¿î_þ|¿­ò`O×Y¨%aå›]œ…• %ïP-²o È_=K‹£<8 ŠIýšî¢hªîZcû¡¶wÛmtW«/úiu×owôÛñsÝî@aªÖ¿F©PÞRŸZÙ‡f ÚìPt¸ù.ŽÃ*ËHPùШC¸Ý•)Ü ·¹7pc<¢˜TÝÖÍpP†¾$ýÔ`œîrm”õûÔ Hßxg‘§ä'tXʇ½Øî²¤ ´%΋DGxZ“øaÜ1*ƒ®mžpTÁHÑà*{«ë¡adO¤ÁÈÏ¢ q¡¤Ï 34V_ý>Œ [$[-­»/Pp»Î\ãÜo ²¼ˆYe°ßh¼…È9‰lÎÝРqªd?jÜVÉVñäp¥_çð«/×¾Ãó>mÑH„àZüçP 5‘`ÜË#þáu8gçY«zZÎé]‘mÍ’ü; ǤÕ1‡H´Ò*úÈgÝžhüÔ0““æL8ž2Ì/m£Ûò9yÅ.|0,¢ùwHÛ¦z&È#݆­²6–>@ÂL‚6f»Èö@èö Ñ‰Áîf5X0–²àÒõ.þDð ,pD0hä‚[VE Q9R³ QÆÐšî ! +ñ\- óClÕ½öªƒ‘‡öànC¯Xv Û¯ Ýv–L ¯èä€KKýÇÄöôÕ¢/çŒw(ÖÏpò=.ÙÓ j[DÈ9 |4?Ò›î„ú@2A-j¿±4Bqh§{RŠÐÜé >i¼ì£óöåþ+73O§àesàfg8ŸéS²<ý[²‚5­P=Äk«j­ä×pf¿{ÐÖÙ,ÍùÍ'‘ñ‹ñ‹A„€zENªtB¥£P†"f:x0ßq®ŒgÉ%ôÈ6»lqÒ}Ôè€Y’ï“ï¢4üL?¢Ÿ|~ÃÔqP«ö£nÿùb%yíÖØS\ÅQ`hÕE‘ÚˆÔ*vHÒ* £SÌLHDõi›elBєжph ë¯>`‘Ã*Ty,(l€&釴&Ûo©[¢ß¾Ñ횺{õû ­DÜ~¾ÅALBŠ9±†|5|ð•‡GO 0ó‘"æ0AÍ&`½gM„˜¿*ŒT;;®3Óé˜M1€¾1à#‹›§‚ntº f—œÈÀgjŽŒ¾ÝÚ^iàí¢îš—îéDcç$øZÂ÷z¿DŒèzâńšóhóäÅ<ÉdJE,¹6NÍNÍWäÈå;%̉jFo„¤/-}Œ2Èæ ¨à‹˜ÂS ®þ㘢,“?ójø– ÖjY6­•þDÙè ¦8ã®G®8Q’÷!ö1gBX Ä·! µsjn“ˆƒœçA¤“`ŵýçÿGºu€„Úû¯•·¤<˜8ô^uðáU7‹‚Iu° ™·SQs ÒÝ®ùõ;m1*DåQ”K 3Ò ÛÍÀR`í¡Ðt½]³›ë⹊ ¡ª¯íÜ,DEG#ß<¸sáÛŸÀþä É¡'ªíåAcfsÕ¢SFH'u¶´Ã,%v½ƒv®ˆ€WóšG –[EobŒyg®ãT0r( ñ,“ÒWýT#¯T:{j—ÎðA˜]³ €0¶|P3쬤=`ç|3÷ £T;GJ-êöf^ØtTªjË|C¶\­¿äÊ"Ÿ;ÈËáû¤ZEÍ6”¬¾ýöÅ"ÌûîB.#[¢È†ÄsþÀ»>ÏðÎ¥]» “ØÖ ï™g}âp`ÑÉ.¨`_«Ñ$¶·"Éé"q•2ëP»"/™‘0/¡b=£q¨^»6Æ®wC†ñ…»Òšyw-Æ®HnÏ`Úõ%´‹æöÌ‚¡ˆ/Ve÷y(1QSëÅÖ\ö]àtF¹D´LBôÆê'cÛ +˱bEŸh–]æ—˜Dî[d3uõyZäó4M’8”•#pÌB3 7±{ q¡‰U +œ/ésÖÙÕÐ Ð3C#ÉA74FC'eƆFòÔó:,Þj(} ­ wD²$ùa1êiÈBÙu­xŽú´©œ]Z§ Ô|"¨±B6>ÂIGËè—¦Ì=z”ùÈ…´ç±²«¢d²<0xË»-µáãÉðØœó3ÔZ d:H^êã2¥›¥ùš.禋€!bѹ¯¼ ¾’™¼ìiîŠ LO"-H/@ƒÜØ5Tå yáwÄBªƒI|=¤vôY—ÄUjð¯¿FIq !¹Ú5rµG¸ûJeV¥a"Æ…XÝ»#=˜à… µ'a‘—KmâcÊ­Û¼Ù¨Un4>tqÄÜÃT˜á… ÞÅãÑõ0 >¦×˜ˆÄ‰«$®Ÿ½·‰Ña8\Y"*-+±ž|O½¼" AUãÒOÌ%'H×0hÉé=4F·p .¹ÅÔ¼-øÙo»+¾"‚s¾Ujâ ‹¥‹÷e–Uì¿…¤Õo3?HÍ­5+¦ÊâPÄ¥_aüKžús¦Jª<„®zy_~Ûr~l¥nVë~<µ]?{åó=Ú•Aûòœ‹ZÌŠ³H<{=1wËt;­w|…ãSz{耰¹H")ã, ‹X€аò¯÷Yáÿ[ð/º¸}ü endstream endobj 426 0 obj << /Type /Page /Contents 427 0 R /Resources 425 0 R /MediaBox [0 0 612 792] /Parent 416 0 R >> endobj 428 0 obj << /D [426 0 R /XYZ 121.4 736.262 null] >> endobj 425 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F33 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 431 0 obj << /Length 2322 /Filter /FlateDecode >> stream xÚÝXKsä¶¾ëWLéå¸$Šï!½Éam­wåT)‰${]åu©0C̵$1áÃZ9•ÿž~3”©Š³Çœ4ÍF£ûën|swrñ]˜. ¿È¢lq·]„Qä'‹U”ùy/îÊÅÏÞË<ötk*µ ½~yzíò<Ž/öó4[þr÷ýÅwqp$'Š?)ÒEÀ2¢öAཽ¹YF¹÷·›[Ü{o®/YЇe†Þ››ë+~ýîež¼½;ùçIB‚E8ªûa°Zlꓟ %,}¿ü¸ÈÄX/âlåG0ª·'ÿ8ùÏ¿;c–ç~¯X¿®ÿ¾,2ïÍ2޼oÿúö’O4±L”øE-ÎÃÔÏ“‚·}@Ó¨¶éø0ýƒêy44{µYF+ïžV—LíúvØô¬š’O>4Æ: ªÕÇœ,ñÁý^ “(‹$Lp4 "j8²MõÄ£°Õ]ç6k@ Áe€Ú=“ÙÕ5ÇÁFmFfŸ =rE-ûlÛÂ.AXtø't¤ÿóÒn¿·PuÆ­È8º=[ƒa•€! ¬*“Ù¥ÑKtO ÚÖq5‚>¸[Baœƒ ¬ùõV™í‹ãÊÈ•·ã?šƒZ3;tj‡€ùTµq€ðHq†ÀÆ1pœѨ?Ž÷ú2¸¡$,~¿Âöžüaò1ˆÒîzètyÞêþ¼Ÿè•±^ƒ48ý Ysbýê(!%O=2|Õf®Ä°Œdò2Zà.QÔ!©mG˜„©®t­IxÏ„ZµŸ:ò"3˜V;yt´+*?Ý ¹åÒtj]¹$¶>ìRoÕPI¦RcäˆL(ÍÈPñÚÆÒ —Ú%DV¹ÐFÛr¾–ØîŸ#Å4rX&FN_âåùÞ CÄX²„z+`.°$lÅ|rЧ„|  ý wu¸MØ)G¦cÆÞò|?ôL ðÝÖœ¾ûÓìV8yŠAÆÿ?¶Ñ,F×FÍø_¶¸ÀóÖV•E¥Á„_KYv ÕP•á $l‘ä#i”z÷CƒNpoñÈŸ–xá¥?ý+Dâ«upFj…Aâ§€ùÏÈ=.÷- H½g¦lOº¿_Ÿa…˜ÞÅÿñÎòw-ÊmÍg¸°q!(õï×3ÈwÂ1“¢˜÷Žî$H¼V—PÃ`àT*Q¤Sa†” `I¯¸#å7ÝÚŽ¹j­dcï‚cð€½מç5¤y YQ"bP>fç°„öÛæŠÎ# RL‹ ¦õ¦Ö¹yÊ)†§lJåàI•V%ƒLø´¸¹U¦Éî¤È[%5ÌìtO,]}Æ*n´m¡¾â±ÙâË ÍÅb(5.Ј¦Ž‰b I:»¦tŸ`M£kL(YƧCZ­v˜P_Ò¬Qµˆ>=àôéœÊˆÐç€,g”Nˆ#;È ”lwùЖÖt—<~–Øp6I úµ°»¢J°pRiP¢J#². ”f´•6JS.6è&qÖ3Tت£J#ð´9°öZIÝ}à=Þ3%¬Œ4Ç ‰Rtæ^$LŒÊ›桚…ê!˜à-ÌÆ=7)Ãdœd®€6²ûÖ0¦'‡cÞS»‰•½0¶v ¾)I»ÀÐ1òÐ{ÏÎ*ÝNê4æù‘«±ö¨†uW¦çp_© EéØ*u<¥äe”RaÙ/.ÃQ´…ñ£ÔX©”>Ǻ±îa@Èäþ"%Yê±·RÔ»:‰0—à×¢÷l°™Ø·jW«NJ|ú › óú°ëþpµùã2Þܼ¿º¼|{ýUçØÅÜÅAuX1Cûîm‡† Y¦ä9ÀÈiTïLs¡ÉXH«,Q¥ó$š‘_”zSIg…SÅ«ÜK·­©ð ¹RÓZó‰—°% 2A™$XÑ¥#Eñt*)Ô¦™K«±‘Ç«Ãy¥ XuÅ|µ¤þÁ T¹ðñàD«˜Ûù× \ ÖæœùÁ0òÇQá«¥œ?Ïíi§a$Š`eçäØØï‹£Î ¥cY)È ½À”>h€Ù%M§ìíl©*© c¸ êòô°Ó6Ó\ݤHÚ°¿”úÿ£Øý#áúáêòîýÿ¥Ñ*hÇHÅÙZ”F+¨`þ>ÊM`‚f¦Ü·¦-ÇDiw˜©r‰1Á[au‘0(»÷­Y´{åÛÖ ì:Îߟ?gÅ·Ó 6˜ÔnÅÐ ¨†’q¾…Ðù w V˜¨ãìxL° ßc0´†îqïèÑ'݃ªk¹ßn4UÄÔNà8ìŠB$GCr Õ„ô½Ø3»×;\:<1ávË,œÀi§íz·m,ÉwתLxžÚ¾-ôr-"ÏÍø"·Ç' ‰°Ú@Ý,©RrÍ‘Žîõð¼ƒwì¼<ßV5ó_Ͼv¢éW€¯ý«ŽGr«ìYÉŽ”€×1Ù8Þ8âïÚôB!ßfð[R8ÏùHO¼ óDaú3¹†$¤çŽt•ŠÓá¹øÝŒQQSêV`ËíãžÎuŒbP.ߟ<”x¡ôJ >óBÓþ­m6€͈Õ1Jy?}O+í¸XÜ?Ôº7zÂI¼«f‚¢ˆf ™ž!ÐÔÔ¦±¿ @ ÂÏóœÕHs÷ÿ2Fcô endstream endobj 430 0 obj << /Type /Page /Contents 431 0 R /Resources 429 0 R /MediaBox [0 0 612 792] /Parent 416 0 R >> endobj 432 0 obj << /D [430 0 R /XYZ 121.4 736.262 null] >> endobj 429 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 177 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 435 0 obj << /Length 1617 /Filter /FlateDecode >> stream xÚµW_sÛ6 ϧÐõ¥ò-VEQ’¥öz·ôß–^/í·}Èr;Úbl^%Ñ#¥ºY¯ûìʱsj›—å!„@@àøÙüèÑ+–eTæI̯–$QÌ’<*JÌ«à2ü0)x(ªÅ„…ÝdÊB „™L9OCY>¹š¿~ôŠÇ{z’$ŽÒ2 bÒ‘Ä Çqøòü|’áÛó ”çáÉÙ Rôq OÎÏNAùÙo¨óèåüèï#Jâ€íLã‹gÁ²9º¼Šƒ ¶^qÄË"غƒMÀóY”UG=C9Û÷±(#ÆË /Š(å3²p«ŒœL³$ /³Çñ‘›º·it¹õ›OqIÃkãâÐìý…–üaÅKaÌÍe|õ„¢tíiÊ¢‚ó`šdQûxÏ×’b³˜L!TÒvôùgÌÓ/Ç­íZ-1ŽkÚZÖÂ(Ü—–ªÅÝNÂ2 ½¼h+"¶ª®=«¶š¨F|£ràûv6èÚë]‹Í5ßøkìcÿöûñsê ï×ìaAþöó('dÐéªÕFµ+ð/OÂn­,Q[tO˜v·EÑBJ·õ Q¶ßlŒ´v–H°°VC¼‘M$Ýò Þ-™å¡êî*µªÁ}-:éå´1 åk­â+0"Ï’rß³$ò`Ê€‡,ôìãé‹ùïÏßž=?™”y8 ÈN â‘z!¼ÜF—@ª[‹Ž¨…°²"R·´nUÕ­‰4}-È,Ô×ĸH\è&kœ†‚6–º]‚“-9ŠúŒW"7µ‚-5\°Þ Ñ¢õPÊSÆ¢2ËÈVÕV²“¦Q¤Š— ™M¦y’„§-ñí*§„ò,1é¡‘ú¬4ÆÜÒ÷†ÈÞ¡^]d…W讳ã¶YUÁù«rÏaZbº*DbðZú J49õµïÊ?¬úGVÌ4›ÝÊÛµîëêötA§ éw #ÝŠþí›ëseIõ]Éh¤ŽÂK6;,›½:Îù®8ÉÓ½†ºdÇ æïxE¨öqÒ¨È/¢ÙÔ‰¶ki$až:;¨¸Ö-ı®=&Õr%ê1³¸ƒ0­Ö¤Áv;ä[†×Ú4pŽýÐÆ¬Ý#LCr÷ÝÉùûìÉXvÜ?zN a½©s@Å„tôáòH¸˜`¿¥‚¼0Dc’Õ jØ  ‹pHáäáš=À`aa³Ø°+ðªº#é!Âñ´¿ý¡}NÑ›Ž…ˆBÊC*‰–·j@B$!pÏ™´÷Šö’3éÎ>0xšì+û ¾³¯ðöãŽÚÞŠ•³ÔÙðõâÅÉ9]~ &0¾=p…u Ô¦ÙÝF­ëZc&o]×ÁT­> endobj 436 0 obj << /D [434 0 R /XYZ 121.4 736.262 null] >> endobj 433 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 439 0 obj << /Length 2520 /Filter /FlateDecode >> stream xÚYY“Û6~Ÿ_¡šS‰Eóé­­”cdíñ1²S©8µ…¡ 1I( éYí¯ß¾HIcÆë—Ðh4š}|ÝÀü¸ºxôôíg_ž±žªÓè8ôøôG‰H¾|ýfõÏÅ3<àÃË?»úñý‹KP IboµÓ ³—Š|ìÇÀÁÃÉôõƒ4áOÈü¦aîеý¤Oje¿ÜO[Ì’`ˆŠ$úV3Q«ý·ãUCQŒt8Ðÿ|ž§–Î@°ÉvŠøÝ;`»3þZ·­Új´A–y×Z9Ùµ“í·]gë©ï: :¶€z'ÙÒk1Ô5Çy’åâ7X(9¾Ö2¥ÌÁÁ¹ÂHévª“=h„öž ˆ`­1l’ Ð#Ó ;åTàÙ:UO†ˆ|Ð1¡ x…' „~dzÀK%¼óéOO®_\=†x L…ázªÖþçÇ¡o§lôµ‘+å€G~œdj±È23ˆO–øHCÒ( …È;Ò"$ o@ –9R8¦8ùVÐ6Jýd)Ÿù ã%ò(wÀ¶¦ã_JpôÍšá/ñ~5ÍÚÎ1ÁÚXð²F‰_°r¨K¬ÿF…¨¥¦iK"ˆã§‡í¤ø/LNA×mßíûŽÇd;Û#žÒrä)·\šˆ§ÄUï FÎEm¾2¥³­Ýˆ´¦íaû”ã¾ÿžÁQp 5VÐsÉ?Vj`£ï›2ý¶´í8µ…c¯±Ã’n­€ó0lDV}·³ÎŸðØb´láG™öS%: GlÏÈœ~6kÍ>»5 d&èÿ÷ÙýêOˆƒßècàWq¥™§`™!Éã2ý¼{óŠ›aÿ :ª¿¹zÈÓçäîµuê!G.×UXÙS²jî6Àçj/¢-˜I„µ0dÝþc²²ýÓ|TymÍ”[TþpzŽu8™WGj5òå^[™-•ú®’•Úòû-Eð1µr²¼6mç Ąީx?oÆ NO)mZªüI£“@œv`Òmoª5Éž¸.(ì˜|z&4‰0Y㎹ ±Rug»ys«…JvBJ¿ÿa¾È¥ßTZµ“KƒÒ©²; âD‚XbŸý¡Ý¶ £jJ}^%â®-v%I þ·ûJ­­ugjª Øvè¿zÈ#^ãÐæ%¨¥TÏ‘ ”90M9ͤG.¡ÃEE¤R¿0MÚ †¤CC”"ÎÈ8B®¥÷¤RnP„ŽêàKŽÅm;]íyAš(Ü¡Z^ÄšÎKšƒWÏ7}…ñ‡”;j:Ü'ü”¯AØ §t‚Jh?ãG὇Gã>»9Æ/o¡÷ÍÀõ—Æ«r@1®; öX˜¸QêŽÇÐ&+¶c ”Ó¨ºhMâzB+ìѾå^hh*š$bÖC_@‡Wï+£¹Úà|¯\Ç#2DY)¹N@%&;õÒ÷!@²(zÑKVÅL'20¼pX«fÏIŠî•â2ÕÎpl“Ó¸³O¼ýP| '¥8ÕtþåDóùÊbúDÐI€×kíJµæhI¼Ô%[¦aÞ,¥ob ŠÇß[AjšŒaa·£l° b…0Ú“ZOÕpù¹W *’ÖÎÑŸŠlåRî9ùñžC®€ujeÞÆ ÁYó’èË Àœ«m²üë´uÜ3 »Ü¨ýþ$â©Fà€î,üõ0ktW¼-À°X9¹v¿˜S›ÿ* ™Vº‡»;~K'XzGƒh5y²rsq·pÓhÇ<þ³õß@m³œS¢¢”l­øöɉgq­ÄBÞE¼‹Cîç¨òÐê¸Ó-9§ˆÇVœDIeCúýˆˆˆ8û•+eFr•B:ê‹SÁvqR(Šøø%HÄ»(“¹ÔÉN!@ Kee[-4— 9ŸðgçÃgOUt^×BµSR—Ñ/­e§ }b<ö‰Š¶r-çËÓØTbÔžTTðºîº‘ʵ†kc*SÚæ›!ùWy@€/²S“ä'uo/¶_\ ‚ÂNè<)ÜYJ»§%‡m ºoDçãµ!^BuZ¾×üÙS@ËX™áÙgr±Àá‹§O™—0ã5fŸÐ>JU1"Úð…‡w»¡„ɽ$ñ-¥aHLøÿòÅõ{.)ß½„ ·vßñìM ŽáñKSê¦Õ<9»p !¾ä_ÈíN«5O0÷Ç:•€CÖ‰†ž½)Í‘@*LA…h *ЋH{7š+”>*fhyFÁ‡ëkjSQ“G|ùA2µ1Àw ]І!¼7L'ðäôM7ž›x*ŸºVWy!rü0$/D)´VŠÇã3Ðß> endobj 440 0 obj << /D [438 0 R /XYZ 121.4 736.262 null] >> endobj 82 0 obj << /D [438 0 R /XYZ 122.4 546.836 null] >> endobj 437 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 444 0 obj << /Length 2442 /Filter /FlateDecode >> stream xÚisÛÆõ»~£tP6!܇ݺ#¹’cGµâRU'g8°X‡(¦ÓÿÞwì’  ÙþB¼}ûvß},O¯ŽÏm›qà“«åÄvÓ›„N`F±;¹Ê&¿×ÓÈ5D“ÉÔ6ºéÌ6$Ít溞ᚑL¿zw|îZÃ{|ËŒ#{bñŽ ç,Ë2Χ¶m'S'2>ŸÿëìÿÏÞ_] ‡_ñB×8™ÿ|öao~õöòýï?8»:øt€Z{+¦kÚV8I˃ß~·&l½›X¦G“5–7M b2?øppú¹¾^hºV0 ¢ÈôÜ¥-åtfùr@è?m' Œ¥l˜*¯P­N4UR0¦oë¼[ɾãYÞvM~ÓwyuËÛÝJÑm9´\OdŒ¼ÇkEÓæ²2§3ÏñS¸ lzÍlÛŒ}Ÿå® ‘ G4^*Yb$ØY7IЏ;¦è¤ú®ÔvŠJ•åÔ ¾Ê;$Ý|·åã›A ìsYÁ ÏŒ"/ÀØÈ[Fu«Da6xì&U%ÕF_e¢a´»h¸ÈSQµ‚iQ€0¬®u,KѤ9×Ê1³1kä…Tæmóe鋤2®n”©û´ÓîKeSR6ÉÎ9;çwÚÓw‚Ï’»ÏÙʾIû;b¼3±'hÀ‚&(ÜýÔ÷˜ÜÂ3úI‹WØdhü¶]ReŠ ‡¢md¼Â1tÉÚˆŠ—s’é9,b›ã#TñVQ·îBWäïc—¢PG˜ /ê"I!nGÜ¡¼îº‘ޏðñ½¸—Êš¯ÉoWÀŒ&]¸xóËÅñIÓAå)ߢÇ䘗 J†hÕñ©e‘o«† ÖðÃØCž±£[òŠ¥ îoŠŒŸò2“e”·’ïÚ c ØãÓoy$Äc³†t@yV`Is«X¡&í­:Èc6‘ŽŠEl·Púœ‰úªmË'ñ©$ ,%æä:o9ÏxP0gŽgÆP0gvlº ñŸÕÔu T܉ñ‰ßëiì£o§Î;D“e"Ïh ‰‡Ög{EyËbþCÅñŒJˆ¬e°”PxÃ0Ô¢JChEÒˆ¶/8¿q9¨úfn¦ýÔçä× ŒD±ûrÙá{<2¿I‡‡‹a{(6Œ£PõlßKF€ôîøÙÞ@"ÝW@ñ⣠—Zàá;"­¬;¨áRä@ ì(‰lãíR#øÛ%wX-8‡|mnÜ`»VhÚb5UÏÅÞ&¿Ãú£å[*™Ý"~Ô·Q‹@ oÙ=@óÑrüLÜô·câYJ^ ¦!PEAˆSB½éR—ô†¹çH Mx¹ì)àx³Í<©k¨­œ¼#Æ'7:‘RQíâÀ3bI „8HòÞœ>W]ƒÚ' íµ¶ßœ2ÀÎR=•Ø<ä<”j‡ØÖ "%¢ÐÈ"ûjá cVá'.B\š2Éß·\¡nE%JBD®‘0ÁŸ{ü0õ•ªÒaHw ô½#KUAP؇y÷õ³gßZáæBìr”yè¸ZS}æ ø¥Ô%¸ªDa–H;ß@)/_3R”OÌhÀ ¼è±*/ADGúð²…ã¨ã5Æ+ÒïEÕsT×á@"*@A<È'>Z3Pˆ{ª'/_ó'ÕÂÒmЫ¸<îxÍÆòÙ‹$ò™–/+öJ/Ð'aW+…<ÏW…aJ-DqM×]Sµ-‘:Í^3­„`õã‘vؤC­±ç³Æ@²AÅP㑌áÁƒ„+PU «y©4…œ;$5F3?öðÙâ­¶«ŸW¯FB,4C/ÖY_Öd¼$ƒ2[T—Ñl˜=ðQ:BD±Ž6Fºëm»—’ÕœÙn QåìkûXœ>Fµ <Ó‹¿ªL¤ ÒB¶¨…Eš`³BxX‚Ÿh8uh˜¢¯xHJxaÉÏP±w—ZŸÄXY3Ž‹™£Æ; åé1t×úÍLëš• Óñì}]Ñ2…J[¹|4í|ø‚ÉÃ_IxìHRP¯ôxÀa\§0ðþ©sâHå9Žÿ~š-R”o¢>‹!ž)€*ûà¾A»ƒU‘WwØ=hpX>‘oðBÁbë[`GUöü òuÅöbÈdýÉD•æ8>à>&WÅà_Ð×?/Þ\\žž\,.Oß͹ˆÒ=’¿;)qõÏ„›,›üÇѱ5Q³m_ÐËÔ»ZéÌnÙ/¹š3Y‰G•Ue±ª¬Ê¡Û©ÄÛÕèǽö°~b°?è™Ó¥Ìñ“ÛQç¿—X‰œ`Àô`@€ãQôæ Cš @ õ=¼%Š>Cc;¾qx)`qO•uu8¦iš£Áªã«°{`™Û"à]ÏpSªI ¼+pqÛ÷ÛmÞò£#QÝsiÄå‰#©|“4×:‹_ =,=”^~ñè5…˜:bºeÍÀßøS‰5»@ürüÍS׳W(„ª‘¨= Ba³¬•úqü¤P@4{%kŒ¤Ä³‡Oßü±Èòæ¸[ðô!ªdAL¨“?˜àÈÃ'/}Âvëõ\ͧM0&‘à x¦ódµsÍ_ùƒsOS¸úáþ~w½«¦à†·²;Ï«¼]é;F]~>Fî~¦ìÿý¸©ÑP8ÿíà1Ô6z䃳1^ÿ{Òø4†á5Zôá-ÁÈ-ÿzw3Œ1 c3ŠÔ_I­ÿìÿ?j?ug endstream endobj 443 0 obj << /Type /Page /Contents 444 0 R /Resources 442 0 R /MediaBox [0 0 612 792] /Parent 441 0 R >> endobj 445 0 obj << /D [443 0 R /XYZ 121.4 736.262 null] >> endobj 442 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 177 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 448 0 obj << /Length 2248 /Filter /FlateDecode >> stream xÚ­ksÛÆñ»~ÇíLAÅ„ð&Lݱe)‰ãÚãJU'“d8p$/Â+8@”šÉï¾’2ì¤~öööööö}÷êúäìÒ g‰D^4»^Ï\ϳƒÙÒ‹ì8ñg×ùìëfû–ju‘Î]«›/\« /|?°|;£ùO×oÎ.}çOèØIìÎæá¹°ÎqërõrîÅÖ‡³Ë\|øçŻ뷸Ã÷Èз^^}wñšA˜»ºþöý»+ärq}òË 2tfî(¦o»Îr–•'?üäÌr˜z3sl?‰g;",g~´´=€ŠÙÕɇ“Wx^/ùè¼QÛ¿dY¿©ç¾gí@*¯ùÿ-þk£*Õ¦bä SüÜãG­ë¶4<õ£:]›fÊä2NWóE:¸z4*ÏÿÆj;R¿؉Ính'‹CºÊs`.­n«øÑñBâÏC³Ó]†„[¡«ù¿·]W·ÏùVZ 3”ÿ¸°îÛaiÃ@¡îqB<<—²U™+3ØÆ[Z¹ÖºZà¡@ß ×µ“0ä#dEŸƒ ž¿E½BÿA™T¾"D–¯Lfoíù"p=ëz«*¦ÎÒ¢`èà *ÿòK:úË×¾¯XÛ½B]?a[Y«Ðbr¥ u@¼ƒ‘7m”åWÎEV} 6‹¬ŸUÖ1qjxâå®{ìxPä<”™ž¸FZð´ØŸ'#hS?(P7x„8„XQêöHòH$GD õCZ6´-°ô,£›‚=H@‡0]ð€üþŸ¨zhBž:ÅhÀyáï;E«ò>“‹šITÿ[ –3n»™ºÎA°®!¯‚ÿð¥mtŸý}NLö]éR·¦#íE3¡õJstÐVGê>÷Qá"'Êòó©ªé.=;^º¿W6ǺZÍ ï“vG&›ñ œ]W•ȳ[R9D®ŠtoÝ…;vä=±ñp¤4¨;þ÷\ uÁCÚ™ìv ‚˜*wÐØ vlj18VUZ^ËŒ4î9 ‡SÁíe¾ˆ  |«9ŠwÚLFÓ¸™ï$VÊ ÀÒþ:±t3Mݦ¦8`‹ÿÍX°œ’šb[͡ޔ²“#W‚Ðq…M»M#ÇàI³­ÛNìÄ6ì|d¿a–{¾ô/뎮0¾ &ÀçªÃ2Ú&z{Œ–,íøã£s·ukµÊ=¥zÀX ðšˆ=~àÖÙéÁ5óOàBd·ÔXdä®›%‘Ó3^@Æwý}ŽB¤ðQ!w3¢;xðÀ¹’ºu+ï©¿2ŒÜ;! *Y0y½û¾%yh”°> endobj 449 0 obj << /D [447 0 R /XYZ 121.4 736.262 null] >> endobj 446 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 177 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 452 0 obj << /Length 2261 /Filter /FlateDecode >> stream xÚ­X[oÛÆ~÷¯ ˆ,šwR ŠÀIìÔm‘4±šâ )œµ´’ØP¤º»¬âæF],ÍÃy‘fgw‡³sùfv_NÏ.oÂt0ñ'Y” ¦‹AE~2È£Ì/&ñ`:üá}±§MY©Qè¹Ñ8ô ÌhljûEšþœþty‡rÒÀŸá `Qû‚ ðnFazW£¨ðÞ_Þ|¸~ÿÛõÛé/ø…ÿ¢ÀØ»ºûùú5“0w7½}÷öåŸ]OÏþ>CÁ Ü©ûafë³?þ s˜úiøñ¤liázg¹U îÎÞŸ½<=o’ûq ²¢ð“8zb×à9“гíf3G¹×g™õãÂkÜJ†UCŒží ó>iP•µ†ÿ9³§ÿÁmÔR3WÕs&Z«åƒe ¤ÓÂ_´õÌ•M­ª#1c´ œn†þ$MY{’ëÆI‘{/E½Ü3úï¶4ô½Âs+ÍÜ»GKÕàÑõ¯#8Ÿ6Om”œ$M=Q4÷\ÃÈ" TuªªX×Ü{hóç 3êF=JÃÁÙéÍ‚‹Uª¨Q·BtÃE­ÛÐW`áº!]æpäNnêO{Së.`A:ñL[‘õ;÷"k[¢¢ï"ñ)ˆÒÙƒ¤: '› zÆÞí‚™¸¨i‡Fµ¶¬—GSò5rÞV´Y«/$üS'•¾82NƧ˜5ëMY¡ÔI§à$ܼⱜápÉ›W¯˜ÂSµdzüúî×ûWèõwøá×(ß\wKÓ \ðþîÀ>ʉ¡½èsbéØ=Û²GQ7KËœebŸrãÔsÐ[q˜.N@FªEå9 cˆ>þŸ—pÈX\P£Ï\Ç7z:—Ú¢¿òØ»æÈ^Hä  =p*ÌŒVN3­ø¯j–ör—ǹäÛ¦ê³;µ/2¯S=} 0k¶3 š.ÊJd„Œœ¶Îb@©¸–Rtž" ®o]Y[@ÍGf {¦Y‹¸•¬ÛeYNX`D‰Æ}a a`K¶"’ú«žµ]`î,Ë9rNµÃ•`Ü9mÊYä›·Ø›—fÙ x‹ßK$QÆø‰RØ]¢‡ªû\¢jÀ#ÅÈ ahÁ´3š#ø\†Uiù#Ø®8k…q²¸Ø1þ;puª¬l/B¡u8'"Ô˜þõWµÞ 0—CÉ]¨à`ØA14†L–"G@4:©hÀšÃéL ` @&²Zï÷õ˜¿po7—'€g¾·§PžFxjÀl—~¨& ˆcô†g À*i™„bbœàN¶CµÌþgÈ!Z¨{µÜ®”ëHB‘<1@,õ[W¥f¯ÉÊZsh@eAô§’ ƒ“ˆä¦'š4€çþš‰q¼H²ä÷•&ð}ÂÀB²Ž£j *éûÁ‹™€ökè£qr ñc3«mAj‘x·"sY7|Õ €‚lÚ™{Ña듦g§æ> §hŸNôÒÄkêKÑ G8ôZY(übÅk©k°áå#s¯xPs&ʹV˜¥d©ì.ÝP(­¬lCŸ"g¥öfæ™ui{Ûœµr ãä®4¬‚b‘œ&ÒP¥Tx¡gky€a©ê¡ãG;0@)€†åZÊ*!ôV»å–©üì#ÓµVön ¨´€ÚRáìK!r}Vìár"…Þè|hˆúç¹´CYÎýöJO>јçèðô$¸3”‹HÉáŸûÏžC¹¿ýåj4}÷á¼OÅnëQ½Nº:tÑÁ&ÿËùa~kÔ†y»Öí D2*Å‚r •Œž¯žk&‘kôé™Ü)£;…m:d„m —“ÏåvÃÖ4J=9H„³ÑÑhK~|¾»f­¡©—÷¸òcg·û×¥­Ê/Ú>§ã£­’ËŸu=‡Þ¨'ó“ÀO!—X·¨Ë|LÛGNJNÛ˜Ó6Äq<>oký ¨?ãªÜÏófxÎ$Ù¿w!¢ÁçÈ&Y©iŒ}ño ²v¯JËÔ ’ F/„g´kM-®®ˆœHn) Õ7JæB@æjj™·<àÆãm¥Í’§¸x=v¢°=˳.‚°R¶'4¡·ÕûæˆïY+UsKµØ‡^N¡‡CÊeø§«”`4³ÒØ Áª[×™ÖÈléxnK0b¾Xfw×]½åð@bõšaâ]UãþJjjåJƹŠj#&V}F ^lÑâTêX»I¾á2ó#šª3)2¢ H/¿arÜ)5oYÖ÷O­ß§&ƒ¾du³ÏZÈ‚·Åqr¬®%Â'ào:?°n¨>4 ^”Úçaœ%c”|þÍÄ.k§—è ÜQýœ©². EK¼<Ë?à_âáÛ„×—õé>ëI¥†š6Õ“ ÷æv±»êHÂË ~Ý“«îvÕTBrŸ{hù]Ã2¶kTÔQ“Ã3!9J|’O.Ž!ûàrsïpôÝ„£üÿë·ï±š<†@¿0‚î•É.z±Vpϼ®`yíÈÃBÑÚšÿåù#ëZ-`·HÏ&5]o§»å¥‹m˜XAìɘCTŠ£Î·@@‘RmåxÀE5Šé‘ª:*úÝwª¬°ïàøøª€c~MB.çß#Ûx©èM»é#luûЩñ÷ã¿w¸»ö´§ÎVÿମñWjÞú .*‹ï\Pñ¥7æ»)RxCG¤¶·egŒ¶Ú½ø¾Æö_¨'y_và5ðÙ3Vá]MWcp¬Üju)â8ܱ3+HCL&ÌvÚÁ󺃿JÀfjYå•©Rö?tïm=ÁÀ¥šo‚\¡Á®”£[ÇÓ]].-ØšãK NSÿ¦Õ´3Äˉˆ¦ƒcÁŸLø ‚*ÿspÜ,·LÃÏ}È“ÂÔûø¥,A ¦»KÁÕS= føFÀhûyíSå6‹»wßÿW[è™ endstream endobj 451 0 obj << /Type /Page /Contents 452 0 R /Resources 450 0 R /MediaBox [0 0 612 792] /Parent 441 0 R >> endobj 453 0 obj << /D [451 0 R /XYZ 121.4 736.262 null] >> endobj 450 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 456 0 obj << /Length 2574 /Filter /FlateDecode >> stream xÚµYYoÜÈ~ׯ Ì=ïîK`K²W^¯d[³»‹I‹lIŒx̲IËFÿžúºŠsØt"΃=ÕÕÕÕÕuõbypüÒ'©›&A2YÞLü p£É~z»|bÏMþÄcOç<Ïs^N}ßwžOƒ…óîøåû³w¿œ],ßà†_Á0tž_ýtvÊ í]-Ï//®Àÿàlyðçz#fèúÞ|’U¿ýáMrÚz=ñÜ0]L,a5 “¹TN®Þ¼À{ƒô«÷&‹……s–õowÓ0p>“ $UÞðï9~"çVw¼>ìë\ÿî…Q­sÆ´úF·ºÎ4/;9øw“­º¢Ò+Ó©jý»{ôÏrøWVÚžòƒÈM½d2óc7X˜óšØDsòô)àP7‚½úl:]€##2º•T›k^~†ž›žµ¶¢de£ßႽ+È®†7°s_gƒÉ±5Üjšá€êHx˜¢šáa¤ñ™ï»ió3úRuu™À¹¿ºh†Q|žLžõ-é[ìêÜé,Š"çJ ‘PÎáÉåÅÅÙÉòüâ#–—LAÚ:dH“ÜŸp!œ·Z—Ú¸¬ø=/˜m4O8 þ~ðáÍêýó‹ÓÕû³«³åêüÉtS<@)q”Òö4Me¬¾<;:$êü‡\×÷oÏq~ELÁôQì‹éAü–E}ÏøHË«¬©ÖE9PoC¿P;†¥ºUEm:a~'Øà9œs³õšÑÐS©Çüã¦!=Q@žVã×f‘•d¼>‡5oæE«3ò¨Ï¼ln˜ts†Dh¨û¢#Gš{‰³¼+ Ÿã_x¶ðíTkMû¥ #"!?ü´zõæòÅó7«Ë¯¯$SϩԽU¯>NãØQm¡®KýŒ˜z‘ópWd ¸c s×ôeÎðµU°]«¶co Ó]{û³\4u¬ï'†CM¨íKýè087âÈwâÑoßH˜†¥iHF2MþÈœvY—ˆªxN™¤Ò”EÈ0±Ÿ8?7­–5+!+ð†L•t‚n$å…É ‘‘·V6+LbÍ s'tÂ0x”fMµ+˜;»<ŽlÐÒg£Æ5]³%år…cçè¡-:у²ÂÇŒs#] ~ß ¹`~ÎÞpÉ?û‚¼!qT)iÎàíi´WÐgª–;J›lédoôÖ#ë Æ |:§oÏ elº¹å­­ºÁ ›¢Ðj·O±ô´„ç­™„cDÖŸÕºÓ-#{²Íô¬ˆ;&ýòN·’Ý qWy:õeQCB>Ïýáí¹Pf™6rÊjœ~×ýuIfaSÜÖÄm{1\Ñï¾ANUs«~, ¬ÊPì{ÖQ©>Ö·LPYG„|YêOäqŒ›lÞÇÆNê´9žPº*:#ü:UçªÍyî1¢”Ö­ËÆ;Õ<^ˆ‹Ä)Jîšã‰êi;Ôjë¤qº›-hÅEW²SÒ©¶é»¢Ö†ÑRÕ ÊP3…x£cÀHÕ8X‰€£É§¸!¡b²«pìˆï÷¸ {EG™¯ãMT)V1í°ú……M9 )¬Dd*r²euMÛ»ŠŠ h7¬#åÜ9óüúðŸró*{úMEŽæ+ÿu¸ñßÿ˜8…ß ú‡‡Ñþõ6‡LÂ?C `ƒè—¨rJ×Cì+é;2J8hª ÅŒ%ÓP*¡àK"çT&ÿkZö¿hBz­t‹x·•‚"6ýÚÈöQ­È¤¸fŸZˆ(•wmŸqŽa¼ÊM„µ7WYÖRbÒæÙ†YͧA:}”ÙÐÞNe‘ HIA¦ð/au-E.Ev¿¤BsT¯ñ$Ê͉#;ñIÔ­Z}ÛR,wÇÝJêt¯²RÙà ®¹fL8*ò6þ8}ÙøE‡úI!…ðÂyúÝ£rZÞ ýoa¾‹nºØelÖ|ÝåP¾¨ð™ÇzÏ bfeF¢‡¹"/v^œ0º¶ÆPºdìÝP@:P"ìŽI¸µÓ®Û†TÎà ýWp1AÒ¹)›íÅ­p¤'†½a’â†7Ô^CUàa‘¿Ù hlÃÔ¶ë{{¡1 ¬ŸØÊé£nËc%¾î‡D]æè’4u–ˆûІ‰¸ ÙddÓÉkK#j°D'ò­`X$COEÌC!©±¤Ñ%¯*ÅÕ[ÊÑq’§­áT‹œ÷˜¡êЦ6BTv yUq<Æ dX#Zi Œ “’ÒÿºïfÔ£všLœf ÎýØ9+3f"†¾ÆbNƒCûÅv–É[´p þ¯Ë2ÞÜp+2SñjÍGîmŸ~«Íh²eŒ<âQ­™ûbÍõ mÕ › IwŽùNp€†ò÷E¦N”…2áo0 ®_³'ÉI•µ1 çh‘C½›Ç]º…—-¢>3Jn"¢d.NŸˆ¡yæÄ~¦9ùñŒ1z¨½‹¶©«Í˜Žc»Ž0j¾æl„7)iWJ4Zµ–¶¿}|~Ò‡¦¹RõÎîšíBêÛN“Nå6P(mÍAi•lÉõo[®¹¯yäÌcU™s{ú¾åA}`­š$쵘Z+¨/s0Ðæs&ÒT—²Ë·`ÃtÛù‘›GåøŠ&_ö¥ !Ö+;4›”˜Š†,Ä\œB`¿“Á6¤ÀW† ¹Îc—^Ò—áÚüäL³PØÛÎUQÍDrgzî8Õc#7h ÇÑR;¨sKëŠ1kîËìô0¢Ë’Õ<§ì“ÎzÜ'xª ùô/ s.Æ™í ,°Ü“~2#‹zÌÙy‚°Ÿ¼ö“i8xž\lWT¡Êô~@­úVŸ6`ÓÛ£èkVöq§Ì½ ™FOéì¿ ÐƒD” `o6M.¶Ní§†ß¢Ð«ª²O✓ 7ûðà Øf0È<PñÏWàI£Ê`ä…-ëáœfz3cì`¡¢¦òtÌUÊ0 [üE±ãs•ê6_sp˜{Üùb;VZôÞXiïkxGÚU{Û—÷Ÿ|k`eBC˜jï’Öš ÁŠXÍmH«äšÖ–Ãc‡-¤p'COÀ©³‰ÏfÀñ– Šz{bÌÕùɽ*¿»·Êdÿ¿yérøè, ÓtÒn‘¶ý!Ó‰…w>í¡‹gä7ü‡›OÐkNš­Üs:|¿€×2Ž¿‘‡»´©ÑºÎª°,ݘ?sÚ@s í sõ#v‚C²ÉÚBžœ3½Õ\:˜<Lž.ö¿éÁ¤ó-éÖº¼æKx@f?ݹM¨:äKžDÃßtþ õüàf endstream endobj 455 0 obj << /Type /Page /Contents 456 0 R /Resources 454 0 R /MediaBox [0 0 612 792] /Parent 441 0 R >> endobj 457 0 obj << /D [455 0 R /XYZ 121.4 736.262 null] >> endobj 454 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 460 0 obj << /Length 2352 /Filter /FlateDecode >> stream xÚkÛÆñûý !ý`ʱx|?ì …íÞI[®kð Åk™ ¨/ÎìG#ÐܘÑǘ¹I®ºÚöÕ©B$1™&jû²Ãþ&MÈlïTžqnÕO˜†Æ‰¨¶k à <ƒcÊ•¬{r6˜³æ ²íÅBkÎDºXª,[¹åÀ TiŽ{ñžôu­rÌ è½(%Q›Üc¦»©¦ ¬qÓ¯°}½Aèæ_¾gΣc%W”Dâ½â…bÇãÐ/ádŸIoFfô¹Òô¤6 G^KWíNºUšj7^¬<Ø‘ö¼¨=xSè…Ð<0M 7ìÀ‡l„HÓļ™s‡ëk&ú ;Å©€ö•Y® á‘C0úÎÖ[Ô?úFewúQ±ügÝöjî·Ø7ººÐ|›­²¢¶óÃXCK£VQç‹í°«þ³ ûKQçe¿é¿û¤Eñûïæó õWŸÙ‘kc~]Ðæb|+ӇիsdnÌÈ‹º²kÕÛòÍŸU)¹q¥„ž&‰³RcçAüñ!¸b(2ŒÓ·dܘÀ`½Ru’„»[Õ /Ãsh‘ ›—+4c¸5 à*rlçt*m+F óñØq¬u¥áh|àÂÔpeÈô¸¢¾ÂVýX÷÷{&;QîàÄ$%žÈé=U¿èFV1³Š&e`ËÄwT_Õ=“‚I¢­8¼nׯ-/¨jAn¸'­bDtß—Í­Ìõ­—ž¹D®Áa€óä°µyB°e<à[Ò÷¬mOI,¡—"Ìi"Ÿ–Ðc6Ñ÷Œ`kCj<µªÞÿuÆ)0³º"€®¼l)m'”>(Ý'¡x`Èbr/Œ€8é¤H[ÜÆÝ’j ÿƒOåŽÌþQÒ#ÒOip¿ÏÆÜ<9/´¨Âîu‘ô³½V€á‚[OÞ¿096¦MZïd¬yixú£úAoJ õÙ<»‘Wç B–Þ‹³e«x¸î¸ò[O´ÐÜºíæ¤6½ó#¤¦†+êÈïM€ž”tŒ%dy"ì£Æ+”ÔÀVa¸aÇ¡»Ö¨rxç–’=d{Ç»‡]û^3 ‡ ÇçŒäú¼nJlðRÊlh P1ˆÊÑòR‘ÛiW` 1‰qŠÆy6Å4 ƒQ%úm-áF~Ä@.~=Ó;¼•§®DuoZþÅ@¬ëRžÆg'N„62?ˆáØ1Js3üÍ|h*;ˆƒóÈÄA„üñÀw‹PßpäMâ^¸¬+\ÄÆ‰ˆ äÃAlb;ˆm(Hì {ÎîØm¾m\ü6#]eu­%JÜŸ7FrûU)½b9êËÔ JÚ8¼Æ’=7_Ït†h]pòsë:±±.,‰uäÆ¿÷Œ3Fv’§FvLUuâ‰}ŒxL“èî.ø¶ˆå7ÔHÛ þI°ÿÑÁdúc0¹t÷ #Zb³—Ò ¾åêÐZŠ§ì€ƒ*™þ!äe¦ LÁáèeØdtÉFȳn»L^éY7ÿ˜¬ÆŽ"€<åÄ˜î ¢R®Z¸ÄDmžÑ»%¦îÄ pº–EÊ7ÉmÁ…#ñÚ$–ZÆpuÁçâ™ðÅů!yÁÈÏ=[mŸdùÛÃóÂNÿì? Ï¥ü<ƒç!ˆ—K~ßAÕz9óOx—Áæf|¹¡oÇn°X%‘Ë…æ/üÿ‡yD endstream endobj 459 0 obj << /Type /Page /Contents 460 0 R /Resources 458 0 R /MediaBox [0 0 612 792] /Parent 441 0 R >> endobj 461 0 obj << /D [459 0 R /XYZ 121.4 736.262 null] >> endobj 458 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 464 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ü —L†– endstream endobj 463 0 obj << /Type /Page /Contents 464 0 R /Resources 462 0 R /MediaBox [0 0 612 792] /Parent 466 0 R >> endobj 465 0 obj << /D [463 0 R /XYZ 121.4 736.262 null] >> endobj 86 0 obj << /D [463 0 R /XYZ 122.4 698.4 null] >> endobj 90 0 obj << /D [463 0 R /XYZ 122.4 167.004 null] >> endobj 462 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F31 162 0 R /F32 163 0 R >> /ProcSet [ /PDF /Text ] >> endobj 469 0 obj << /Length 2513 /Filter /FlateDecode >> stream xÚX[WÛH~çWøQ>Ýeï’À&Èæaf©±;´ÔNK !¿~ë&a3âœ}îªêRu]¾ªöÙÝÑïï¢l¶Z¬ò8ŸÝ=Ì¢8^¤³"ÎËU2»«fÿ/“@{cÕ< ºùI8XøùI’¤A²Xfùüﻫßß%ážž8Oi”ÏBÖ§p. Ã`ýÇÍÝç˳/w|¾ÅcGwGß" gÑøõd…Ŭ¬þü;œUÀºš…‹dµœ=‘`=KòbÃÊÎnþstöÆ5òår‘&›ðdºíü$]¦âkþw¯Z]á2 ÖŸ¾0­vó“¸*myïX Ûj&œÚÝVÔì< /ƒRƒWZtOë¼|¨©xÑšz"½U’iöŒÉ¿ÀÝN¢h±Ê2¶^7¨à‡ñ®©yÝqJe-|Õâv½¾¾\ À«ˆÏ_âçVa­V~jµÖŽìfÛ)ÏÂæž\ M³á}ße[Ç«¾é*øØÛÎÔº2JD‘½Ñû„œdâ§Ñe-újÿº9›[éxB[·Û»n–ÛZSi^Ÿ›é”]ÌO²( Î{Õã½²÷†—É=òÖ‘çx1ÏUv†¿Åû7¾œS ø-ýv<+º|\ª*-ËVÔze™°#»´ÖªäjaÞâfør wK㜢ÊÇÈ‘ª¥±¢îžÕA&PÀÄ#;DžÒ—nµµo¦I¼Â4YÃ2KàwýfËt**Øè¿Â$q¾kyKE‚äŸ £´ÝùÅÚèVtÕÊ4öY¯4 9^""Ae™W'S.ë[R”Áí6^SjÂÃfËÀk«¡”„¸•Eëz_ʺäĨ4¸xåÁ_aÞâízp%„ù›.»C£šñ(o'‚¾:ì½n­&SäikJŒä«6 L+Åìêê DñM¡Âf£Ê’¸xó…Ÿú{ êh}mJÝ´z׉â»àbÄacáÁWü”4RÜRê=WÚó~¯‚ð @`<šŽäÌ…”ï k؉¾ç¶ÓõšO׃ëŽaLËAÓM¹ìÍ61–Išw[vdòR&è»Ñc¯©o;ÞìEàqŽ °aüêž/%‰Þ¬“e„nŒ7¢%û®ŒÈ•ÅèÊ((Ñ`=ô€è‚¦Ý“÷yíõ“7RJ,žî#6¼«yÕ–^uCN!Ì„׿ýöÊYéSxe€"ù>îÜ@Ýü‚Œt –0Òž¶™„;Å9ïzéFŠÉñIöSüù˜Cêp`ñVz’‚0\&óà›ó¼ç|BÏþpùz#×8ÿtÉ «šMÑå]ÛïØ­1O É“„ý0íuï½ 2€|ùµÐH0w<‚âj¶÷9óu À;é Ùÿ‰ürÈk>4¶’\Ð<§´žˆpC`˜ä+´¬ÕØB²,yÝî‘Oñ/B0nÑ´QÜ÷9¢°O~²ðƒ·{¦u`ª¨h˜"uK ÐHý›'ÇL›¸‚ió’€±Ö¾4Ø(’/•óí‚Ðx9‹ÒE’æ1Ž€ 3MaŠ]îM ÑÄújr„cI²(Š”}<( ÛYÉ(cÌ™PÄóŒaªa$3 ‰uç“ÆTuF¹¤j[èœ/U2`~zXùSzG—G‡ÕûÒù!åw˜FCêŽÃÜÀFqŠyÀÉ_¡5_"*äà¿Üa޶fÓD×R#}œwÞÜ÷„!ã‡&‚Žó#Ø©Š¶ÇY<ôMÕ2É4¥í+ý ¼ŠékfÒÀYŒ'ÂV é¶ÆÎú]ްO ò ˜…"›ãäj.¾÷f79{ìM…i>èZîéJÒepAé)AéÚš¥¯»j!L©ê“ÒZá\R×èð푤Ùô`â¦Q¯Ú‹¥ž~9ÜQ8¹34°Ò "%á*¸MIEiðєޑpOstˆ–ŒÜ)Ýzkv|ò\cÄEÍp©°¹o˜FÊÚ—k†9p25ì—½ðËc¡bGu1ÔÊ­gtZZ Z÷V)¤y~X¬HxÚ:^V-R2•Ús^p-e\K(ô@ãaSó¶k”5T bãâìÙӊμªh–šG8t¥½®ß„À3Ý4ºë¨ÑÄÁ5"FSùÌY+l¥c(Ôa”Fò'‚zËǾ"†Äp¾›r ,¸~™þè鑾8:hÞNÙ<Öe’gp=|ðú¼ï:NÜ" >+ûÀä+¿ÑD…ŽÍ!1³>è§VN$`_ÍÔ84Á¯m+ O-eðo!½kÕ5摪Ÿ€arü¾ÕðÐiƒOÉf­ú1 ±©_žW~³Õ¯ ü½n±¿R­‰°ŸœpnÝs Gü*Ë^u$<ÑkËñf«^Þ®"ÐjP¬” &GQpá~˜u‰õ0ì«’4p ÿÁSŠ }`ʉ§È«*ÃÊâÁmÏ?iœzÕªÆì”UF®4‚3ëÆ„3õòj”kƒ™c5 ÷Å*fÚñvQ0î÷^o°SÁÎ\ÏP¨|EÀÁæ¤Îí¸³ €¼ë„ƒéF‰÷8ð)A,™‹RêÄÃRÇ<Jøþ™JqOFØÆ^ó³òþ°Ð³°@_ñ³g‹ zÊÅ$†¯±Z‹Ü5UÓ ­%?!I]ßqù°›AŒnÎÌ5䋯Î÷8ð Ç[ ñ„­çø†G±á- ŽùµÌmÇûgaou#œÏN~ZÂ!y§ ‘qïQ„N­Ew¥I ,¢°yðŽˆ¼ï³éu…C¿jï¥_úÕÏ2ÒfNÛ-ÍŒkñ‰TDp‚ `­}!d­*O‰… ó84 â5Æ çÊm¡ãÝ1Q»'a$G‘kEÁç^ bò©vnô/„1^MÊ!KpRi6¹ä7H# €éê›þaJa36«·ße8‚33œ‘±†ù¼bmQp±5ý+'¨UYôöåOÀëät[ËoÄ´'Õ¶v}5¶@xÔp&,9Pìõ(ïwZ+Ú.ú cñ ¹Åaé´(;m*x[ï 8 á&-?çYÈ‚^WF÷ÇüCÄ-xàqža#g‘÷Æ›§j¡YUdp*¢›kœÆ†‚%hDF§ÎjÊ;’ÆÏ­ðo°L²õƒª•ö¹Ša¼‡ó<ñ?>=~¯ ‘PíÐI}¥ô ÃñÕ'+gÔ1C#^;~øòWG¿¢Âi€g¬46*– xoÌ-V˘-΋á—ýÿl»j endstream endobj 468 0 obj << /Type /Page /Contents 469 0 R /Resources 467 0 R /MediaBox [0 0 612 792] /Parent 466 0 R >> endobj 470 0 obj << /D [468 0 R /XYZ 121.4 736.262 null] >> endobj 94 0 obj << /D [468 0 R /XYZ 122.4 420.432 null] >> endobj 467 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R >> /ProcSet [ /PDF /Text ] >> endobj 473 0 obj << /Length 2006 /Filter /FlateDecode >> stream xÚµXmsܶþ®_qßÊ›ñQ|I;J–-[‘¥D'ÇI2èˆ;Â"‰ HJV}w± ꤰi¾t4£±û¾KžÞ¿ÓEé—Y”-n·‹0Šüd‘G™_”ñâ¶Züìý´,bOÕˆeè ËUèiX˜å*Ž/ö‹4[þz{qü>øDe’E@<¢ÎAà­ß½Ãƒ±wr¹¾ÆsGïn~; ,Âéú؃|±i~þ5XT@ºX~\‹G lq–û¬šÅúèÇ£Óÿ¢GV~ç$ÃÛÚ¨~ÐûZ‚iæ]èæ U{Yä}R÷Ë¨ð˜ø½ØÉŽ)çãÓêÄ´¢«­•]õU2ÙÚmÓ£mF‡é*Q)†ü€œÅ`ÔFiG_¡ö Á* ý2MIÆ}#ì­eá݈f «"¬ÙÙËÊÜ;ÛþÍȵnž÷Ú‰Á…îÄPOxÕ¶Ê9p`nçÒtz`À2ÊÁ³+ø¿Aqë‰;ìžîæäý‘¡I{ëA>° “ aŽ´ìî•E >>¨ Ap­ág«Î —KÑíž){Ph"ŒFvxÇÀ¬¿XO4ƒ4A¬;ýfNx E*½Kygµ—Ù1°v$Å[oka°¢’ŽÐUL:é*#Ý6`Hl ÷ÇÆÑFÞg_ÞåhC§ÇSÓíïQ#«’g$ù'a XŒF(–9lVª.š…¹wÛ¦¯EÓð‰ ÑëŽ)›OcÔ/ªå}E dÓ»{$*Ô©žc=¾ì©:뎄í—à;Fž.á|ƒ×äX´bÔ“u»ép¦Z9ÓõJ4w`0@ Šée-bHðYK‘ƒt”oº›KÕ ðzzWZP ¾Áç’-H›`]›…PÅNÐúÌ aDOÀkÜÁðÐ[r(^j™Q†D6Tk ó;Ó­êÀ„hÆŽÈÃÀǯ”ݬſb EXbŒ¸³&ÆèŠòÜû ^w$e-+ªcn²Ì;iî¬fÒ š g²¡ÅÒ ºnäŽ÷œt§mb1‚üŒˆ5äêf5kíµhZ'ðº–ê¾f¶øæ˜òDR`¨’ÂÐEý=š‚'ñX»±NV€AxD?"'ád“¿ql䓃j30É©ÓMDÕm¡Ì¬è§† ”™uËéqvÒÈo¼«ÝŠ¡£6Br£ÔhÆ ¢ídßó>K0$‘d¯¸;ÞµÚ¡F°p«‡W% ùÄêAMYCj«‡ešz‚‚l&»†¡õíÉÀßrˆ¯ )°Ân­ƒ€Ã-€J2á\˜'· jöÏxW«- Ó[Û‡~]?gKê˜Xr¬›6§Ñi”{ReJƒÂû ›­èyž:Šö¡±I”å$;2åNÐHbn½ñH-ÆBkŠ”î+æ4:l·´NCܹÁؙ͊V :ypâ¡Ú¾m¹DϼwãÎúˆéñämÃì9õlj‡lž[2/%EPUSqÇl;M5Q…·ýl<ßR{±ÞÓ†f2:ÓZQá‘rÇ‘:˜ìE1mOµF8j/Ý!M#GœèztÆ¡u¦º­þ©„†K»ï¤„ᯠYHàußKòjÙò];ð4ƒjÝKZÚ2 ÿâ·ZÕ÷’`®Õ$† /pÚâIŸ¦Ú¨X„‰'Y„c%ˆ—$0Ø<Ö¦àÚ øÇõíÍÇÓÏ·¯¯èÜ‹iŽÅ±Ÿç‰S‹jÄ“Öt«é•õ-JÈŠÓc3fð»†ÏnnyðŽß4õË¢pƒw= ûïŽý˜á÷¬åÊNf¾U×ìŽgD†ùÛòÈñ!ï@™Œý {᣷zo;»Q;ÊH`Ü£ ˆWQ&ôxGÝÖÄäÎ:­jH^Û<}ª¤ñ±c—/F'C{ vk¤¤Þ½ŒlíPËÅÛ«ü+•tÛ÷ôH7‚oƒ©J¹yŒ;ѹQMÉfÇ6E`ݺ¸}¢Áú?ÙD$Æ-EÓ) Ù¢éi ê®4¯N e²ÞÒ¯T@};¿úL‹Kh@ë?ÔŠÆ»‡ \_ªì\j°qŸC“\›)Řdæ- çåßsLœòÏ#?øS ”q,ãÐû|ûáúfýùÃo¤_jÉ×p<÷½‚¼àª°o¤pšbÕ’‚SÞ ¿q^ãS¶#ƒðwãî¹ÆÌdTYø9ýÿ'£â Å N)Î)(Ľ³$§Ê^IûâM¬ÃÖYæçYè8ÿmæòÜÏ“Òû)Ýþa×9¥ž6»æeêÇÙtöï3ÌWaVúE^¾¨ Ÿx¶pAµÑÝFî¶´«e9¿Å®u÷“þÏ=c´¯~¸<‡wõ‡ñ•|w§ïY6}wxåäWúÙzó_¶À½ÝlÇn3g\X±³Ðf:ÈŠÜú'Êv¿LC›[¿ç”Qö¿øM€‡ ²Ò 3þŠœcøEšüi[q?Ç%Šü¸,_s9´#”ü œ½…Ö$þDi-›ýÌ%^2…jÍ/£‡=ñ Bõz4×Ý3ÔWñ±¾ج£;^äÜgŠfFªÚþð«„ês¾®‚bh›=Jæ0/|ÃU-8ŠˆmV¸¯\ÿDzþÍ endstream endobj 472 0 obj << /Type /Page /Contents 473 0 R /Resources 471 0 R /MediaBox [0 0 612 792] /Parent 466 0 R >> endobj 474 0 obj << /D [472 0 R /XYZ 121.4 736.262 null] >> endobj 98 0 obj << /D [472 0 R /XYZ 122.4 492.163 null] >> endobj 102 0 obj << /D [472 0 R /XYZ 122.4 367.608 null] >> endobj 106 0 obj << /D [472 0 R /XYZ 122.4 239.18 null] >> endobj 471 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F32 163 0 R /F11 177 0 R /F33 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 475 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 477 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 478 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 479 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 480 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 399 0 obj << /Type /Font /Subtype /Type3 /Name /F37 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 5 -18 49 52 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 97 /LastChar 119 /Widths 481 0 R /Encoding 482 0 R /CharProcs 483 0 R >> endobj 481 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 482 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 483 0 obj << /a97 475 0 R /a103 476 0 R /a105 477 0 R /a110 478 0 R /a114 479 0 R /a119 480 0 R >> endobj 484 0 obj [500] endobj 485 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 486 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 487 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 488 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×36Q0P0T0´P06T02WH1ä*ä2² (XB$’s¹œ<¹ôÃŒ,¹ô=€„§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ÂÿÿÿÂ\®ž\\Ï5^ endstream endobj 489 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 490 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 491 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 494 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 495 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 496 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 497 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 498 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 499 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 500 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 501 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 502 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 503 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 504 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 505 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 506 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 507 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 508 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 510 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 511 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 512 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 514 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 515 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 516 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 517 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 518 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 519 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 520 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 521 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 522 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 523 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 524 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 525 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 526 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 527 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 528 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 529 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 530 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 531 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 532 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 533 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 534 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 535 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 536 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 537 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 538 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 539 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 540 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 541 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 272 0 obj << /Type /Font /Subtype /Type3 /Name /F36 /FontMatrix [0.01004 0 0 0.01004 0 0] /FontBBox [ 1 -25 102 75 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 38 /LastChar 122 /Widths 542 0 R /Encoding 543 0 R /CharProcs 544 0 R >> endobj 542 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 543 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 544 0 obj << /a38 489 0 R /a40 485 0 R /a41 486 0 R /a45 488 0 R /a47 487 0 R /a48 534 0 R /a49 535 0 R /a50 536 0 R /a51 537 0 R /a52 538 0 R /a53 539 0 R /a54 540 0 R /a56 541 0 R /a65 490 0 R /a66 491 0 R /a67 492 0 R /a68 493 0 R /a69 494 0 R /a70 495 0 R /a71 496 0 R /a72 497 0 R /a73 498 0 R /a75 499 0 R /a76 500 0 R /a77 501 0 R /a78 502 0 R /a79 503 0 R /a80 504 0 R /a82 505 0 R /a83 506 0 R /a84 507 0 R /a85 508 0 R /a86 509 0 R /a97 510 0 R /a98 511 0 R /a99 512 0 R /a100 513 0 R /a101 514 0 R /a102 515 0 R /a103 516 0 R /a104 517 0 R /a105 518 0 R /a107 519 0 R /a108 520 0 R /a109 521 0 R /a110 522 0 R /a111 523 0 R /a112 524 0 R /a114 525 0 R /a115 526 0 R /a116 527 0 R /a117 528 0 R /a118 529 0 R /a119 530 0 R /a120 531 0 R /a121 532 0 R /a122 533 0 R >> endobj 545 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 234 0 obj << /Type /Font /Subtype /Type3 /Name /F35 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 5 0 77 42 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 25 /LastChar 25 /Widths 546 0 R /Encoding 547 0 R /CharProcs 548 0 R >> endobj 546 0 obj [83.04 ] endobj 547 0 obj << /Type /Encoding /Differences [25/a25] >> endobj 548 0 obj << /a25 545 0 R >> endobj 549 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 550 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 551 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 552 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 553 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 555 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 556 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 557 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 558 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 559 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 560 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 561 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 562 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 563 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 564 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 565 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 566 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 568 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 569 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 570 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 571 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 572 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 573 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 178 0 obj << /Type /Font /Subtype /Type3 /Name /F34 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -1 -17 81 59 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 28 /LastChar 122 /Widths 574 0 R /Encoding 575 0 R /CharProcs 576 0 R >> endobj 574 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 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 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 575 0 obj << /Type /Encoding /Differences [28/a28/a29 30/.notdef 45/a45 46/.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 576 0 obj << /a28 550 0 R /a29 551 0 R /a45 549 0 R /a97 552 0 R /a98 553 0 R /a99 554 0 R /a100 555 0 R /a101 556 0 R /a103 557 0 R /a104 558 0 R /a105 559 0 R /a108 560 0 R /a109 561 0 R /a110 562 0 R /a111 563 0 R /a112 564 0 R /a114 565 0 R /a115 566 0 R /a116 567 0 R /a117 568 0 R /a118 569 0 R /a119 570 0 R /a120 571 0 R /a121 572 0 R /a122 573 0 R >> endobj 577 0 obj [777.8 500 777.8] endobj 578 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 579 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 581 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ]ο ‚PðOîœÅGð¼@]ÿ éb`955DS5¡öfö&>‚ã$»)5üÎð}œÃñü‘Ë6+X8!Cо¡ %j¡•P¦f•¢¶J`Rôò¢Ûþjµ×Ÿæ—­ùZzê FB”!Ì‚ž¥_©ºC4KhEoçM> endstream endobj 582 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 583 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 584 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 585 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 586 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 587 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 588 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 589 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 590 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 591 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 592 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 593 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 595 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 596 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 597 0 obj << /Length 205 /Filter /FlateDecode >> stream xÚUÍ1jÃ@Ð/¶L!]ÀXsxµ^ƒ¶¬"W.B*'¥Á v+éh:ÊaKÆxl%4þ†oÝlÎ9üdxaØüa苬•2gëÆËþ@ËšôŽ­%½‘štý§ïó'éåë3Ò+~3œ¿S½b$PTˆ§h»$&wÊ;.CÕ¹ Yw¬þÐ ¡A ß †¿ ¸HD†‘)Ô€ TøC‰8À!ö#Çÿø_¢^P=”W¼ÉDC)´ƒö­kÚÒ V²Aš endstream endobj 598 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 599 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 600 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 176 0 obj << /Type /Font /Subtype /Type3 /Name /F33 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 0 -17 70 60 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 65 /LastChar 121 /Widths 601 0 R /Encoding 602 0 R /CharProcs 603 0 R >> endobj 601 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 38.2 42.44 38.2 0 38.2 42.44 25.46 0 38.2 21.22 67.91 46.68 42.44 42.44 0 35.01 33.95 27.59 44.56 38.2 55.17 38.52 40.32 ] endobj 602 0 obj << /Type /Encoding /Differences [65/a65 66/.notdef 97/a97/a98/a99/a100/a101 102/.notdef 103/a103/a104/a105 106/.notdef 107/a107/a108/a109/a110/a111/a112 113/.notdef 114/a114/a115/a116/a117/a118/a119/a120/a121] >> endobj 603 0 obj << /a65 578 0 R /a97 579 0 R /a98 580 0 R /a99 581 0 R /a100 582 0 R /a101 583 0 R /a103 584 0 R /a104 585 0 R /a105 586 0 R /a107 587 0 R /a108 588 0 R /a109 589 0 R /a110 590 0 R /a111 591 0 R /a112 592 0 R /a114 593 0 R /a115 594 0 R /a116 595 0 R /a117 596 0 R /a118 597 0 R /a119 598 0 R /a120 599 0 R /a121 600 0 R >> endobj 604 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ52T2u ÍR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ(ª+¨ endstream endobj 605 0 obj << /Length 85 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3s…C®B.ˆMÎåròäÒW0çÒ÷ž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ €ËÕ“+ hz¯ endstream endobj 606 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 607 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3cs…C®B.ˆOÎåròäÒW0çÒ÷ ré{ú*”•¦ré;8+ré»(D*Äryº(üƒì*ËåêÉÈžã: endstream endobj 608 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 609 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 610 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 611 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 612 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 614 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 615 0 obj << /Length 132 /Filter /FlateDecode >> stream xÚ3¶Ô32T0P0VÐ5R06R0µPH1ä*ä2² (˜Ae’s¹œ<¹ôÃŒ,¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. Ñ@ƒb¹<]ø? },Âìq ÃÿÿŸÿoøÿŒìÿÿaàÿÿƒ(ÌÀåêÉÈÖZ endstream endobj 616 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 617 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 618 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 619 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 620 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 621 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 622 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 623 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 624 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 625 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 626 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 628 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bCSs…C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þC¨'p¹zrr4ö+³ endstream endobj 629 0 obj << /Length 89 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bC3…C®B.s ×ĉ'çr9yré‡+˜sé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þQ¸\=¹¹6VLÖ endstream endobj 630 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 631 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 632 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 633 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 634 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 635 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 636 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0TÐ5T0²P01WH1ä*ä22 (˜X@d’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒˆÁÿÿÿÇÀÄê¥ÿch`üÇØÀðŸýÐR®ÿÏÀ`””ÀÀåêÉÈ|Q  endstream endobj 637 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 638 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 639 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 641 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 643 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 163 0 obj << /Type /Font /Subtype /Type3 /Name /F32 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 0 -21 60 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 119 /Widths 644 0 R /Encoding 645 0 R /CharProcs 646 0 R >> endobj 644 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 645 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 646 0 obj << /a21 609 0 R /a45 608 0 R /a46 605 0 R /a47 606 0 R /a48 640 0 R /a49 641 0 R /a50 642 0 R /a57 643 0 R /a58 607 0 R /a65 610 0 R /a66 611 0 R /a67 612 0 R /a70 613 0 R /a71 614 0 R /a74 615 0 R /a78 616 0 R /a80 617 0 R /a83 618 0 R /a85 619 0 R /a95 604 0 R /a97 620 0 R /a98 621 0 R /a99 622 0 R /a100 623 0 R /a101 624 0 R /a102 625 0 R /a103 626 0 R /a104 627 0 R /a105 628 0 R /a108 629 0 R /a109 630 0 R /a110 631 0 R /a111 632 0 R /a112 633 0 R /a114 634 0 R /a115 635 0 R /a116 636 0 R /a117 637 0 R /a118 638 0 R /a119 639 0 R >> endobj 647 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 648 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 650 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 651 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0´TÐ5W02S0µPH1ä*ä2 (˜™Be’s¹œ<¹ôÃ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. (\®ž\\&Q# endstream endobj 652 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 653 0 obj << /Length 114 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04WÐ5W01T0µPH1ä*ä22Š(˜™B¥’s¹œ<¹ôÃŒŒ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ†þüa`üè?’›îçrõä ä—5ez endstream endobj 654 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0VÐ5W02W0µPH1ä*ä22 (˜™Bd’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ‚êÿÿc`¨ü¨æ`°›ÿp¹zrrléI endstream endobj 655 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 656 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 657 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 658 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UеP0¶TÐ5RH1ä*ä26 (˜A$’s¹œ<¹ôÃŒ¹ô≠ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿÏÄÿа—«'W *› endstream endobj 659 0 obj << /Length 113 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F ¦F )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêü€ÖÀ åPº‰õìä¸\=¹¹AQ@ endstream endobj 660 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 661 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 662 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 663 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 664 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F †† )†\…\@Ú$l‘IÎåròäÒ pé{€IO_…’¢ÒT.}§g ßE!¨'–ËÓEAžÁ¾¡þÀÿ0XÀ¾AžËÕ“+ ‰;“ endstream endobj 665 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 666 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F Æf )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêüƒõìäðì:¸\=¹¹{-= endstream endobj 667 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04UÐ54R06P06SH1ä*ä24 (˜XÀä’s¹œ<¹ôà M¸ô=€\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü òìÔ€Aûòøð Žöêá´ÿ#ÿ‡ÿÆ ?0`ÿ ÿ þÀÿ†ÿ@¡.WO®@.…8 endstream endobj 668 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V04S01T06QH1ä*ä26 (Z@d’s¹œ<¹ôÌ͹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿÿÿÄÿ °‘§\®ž\\ºâAŠ endstream endobj 669 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 670 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹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 131 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W01T06W05TH1ä*ä2 (Be’s¹œ<¹ôÃŒ,¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ? ˜ÿ1üàÿÏøCþûûÿç?ÔÏÿÿà?ÿÿØÿ7üJq¹zrr)}(Ë endstream endobj 673 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 674 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 675 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 676 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 677 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 678 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 679 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 680 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 681 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 682 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 683 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 684 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 685 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 686 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 688 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 689 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 690 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 691 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 692 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 693 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 694 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 695 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 696 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 697 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 698 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 699 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 700 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 701 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 702 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 703 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 704 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 705 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 706 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 707 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 708 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 709 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 710 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 711 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 712 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 713 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 714 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 715 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 716 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 717 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 718 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 719 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 720 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 721 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 722 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 723 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 725 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 726 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 727 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 728 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 729 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 730 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 731 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 732 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 733 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 734 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 735 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 736 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 737 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 738 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 739 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 740 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 741 0 R /Encoding 742 0 R /CharProcs 743 0 R >> endobj 741 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 742 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 743 0 obj << /a3 672 0 R /a21 671 0 R /a33 659 0 R /a34 673 0 R /a35 674 0 R /a36 675 0 R /a37 676 0 R /a38 678 0 R /a39 660 0 R /a40 648 0 R /a41 649 0 R /a42 661 0 R /a43 662 0 R /a44 663 0 R /a45 670 0 R /a46 664 0 R /a47 665 0 R /a48 731 0 R /a49 732 0 R /a50 733 0 R /a51 734 0 R /a52 735 0 R /a53 736 0 R /a54 737 0 R /a55 738 0 R /a56 739 0 R /a57 740 0 R /a58 666 0 R /a59 667 0 R /a60 650 0 R /a61 668 0 R /a62 652 0 R /a63 679 0 R /a64 677 0 R /a65 680 0 R /a66 681 0 R /a67 682 0 R /a68 683 0 R /a69 684 0 R /a70 685 0 R /a71 686 0 R /a72 687 0 R /a73 688 0 R /a75 689 0 R /a76 690 0 R /a77 691 0 R /a78 692 0 R /a79 693 0 R /a80 694 0 R /a81 695 0 R /a82 696 0 R /a83 697 0 R /a84 698 0 R /a85 699 0 R /a86 700 0 R /a87 701 0 R /a88 702 0 R /a89 703 0 R /a90 704 0 R /a91 653 0 R /a92 655 0 R /a93 654 0 R /a95 658 0 R /a96 669 0 R /a97 705 0 R /a98 706 0 R /a99 707 0 R /a100 708 0 R /a101 709 0 R /a102 710 0 R /a103 711 0 R /a104 712 0 R /a105 713 0 R /a106 714 0 R /a107 715 0 R /a108 716 0 R /a109 717 0 R /a110 718 0 R /a111 719 0 R /a112 720 0 R /a113 721 0 R /a114 722 0 R /a115 723 0 R /a116 724 0 R /a117 725 0 R /a118 726 0 R /a119 727 0 R /a120 728 0 R /a121 729 0 R /a122 730 0 R /a123 656 0 R /a124 651 0 R /a125 657 0 R /a126 647 0 R >> endobj 744 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 745 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 746 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32Ó35V0P0WÐ52T02U03RH1ä*ä24Š(XC¥’s¹œ<¹ôà ͹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿ7@ц`þårõä ä.§á endstream endobj 747 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ó35V0P0RÐ52T02P03RH1ä*ä24Š(XC¥’s¹œ<¹ôà ͹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿ7@ãÈ@pÿr¹zrrßb”ß endstream endobj 748 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 749 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 751 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 752 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 753 0 obj << /Length 112 /Filter /FlateDecode >> stream xÚ37Ñ32W0P0UÐ54R0³T05VH1ä*ä23Š(˜™B¥’s¹œ<¹ôÃÌŒ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Ì `0¢èÿð©áÁåêÉÈÇ‚J# endstream endobj 754 0 obj << /Length 143 /Filter /FlateDecode >> stream xÚ32Ó35V0P0WÐ54S02R04VH1ä*ä24Š(YB¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü öê?Ôøÿÿ€`=ÚÿáŸÃ Ã`Ã`†  0>`>ÀÞÀÏ ”’`àrõä 䦇, endstream endobj 755 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚ32Ó35V0P0b#CCc…C®B.C˜ˆ ’HÎåròäÒò¹ô=À¤§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒýƒúõþÿ€AÏþ—«'W !‘$‡ endstream endobj 756 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 757 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 758 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 759 0 obj << /Length 109 /Filter /FlateDecode >> stream xÚ37Ñ32W0P0U°T0³T06RH1ä*ä23Š(ƒ%’s¹œ<¹ôÃÌŒ¹ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÁà„úÿF3 €î.˜{¹\=¹¹X@ endstream endobj 760 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 761 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 762 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 763 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 764 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 766 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 767 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 768 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 769 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 770 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 771 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 772 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 773 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 774 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 775 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 776 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 777 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 778 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 780 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 781 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 782 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 783 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 784 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 786 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 787 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 788 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 790 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 791 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 792 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 793 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 794 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 795 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 796 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 797 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 798 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 799 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 800 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 802 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 803 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 804 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 805 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 806 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 807 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 808 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 809 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 810 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 811 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 812 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 813 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 814 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 815 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 816 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 818 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 819 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 820 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 821 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 822 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 823 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 824 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 825 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 826 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 827 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 829 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 830 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 831 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 833 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 834 0 R /Encoding 835 0 R /CharProcs 836 0 R >> endobj 834 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 835 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 836 0 obj << /a21 762 0 R /a27 767 0 R /a28 766 0 R /a29 768 0 R /a31 769 0 R /a34 763 0 R /a36 764 0 R /a38 770 0 R /a39 751 0 R /a40 744 0 R /a41 745 0 R /a42 752 0 R /a43 753 0 R /a44 754 0 R /a45 761 0 R /a46 755 0 R /a47 756 0 R /a48 824 0 R /a49 825 0 R /a50 826 0 R /a51 827 0 R /a52 828 0 R /a53 829 0 R /a54 830 0 R /a55 831 0 R /a56 832 0 R /a57 833 0 R /a58 757 0 R /a59 758 0 R /a61 759 0 R /a63 771 0 R /a64 765 0 R /a65 772 0 R /a66 773 0 R /a67 774 0 R /a68 775 0 R /a69 776 0 R /a70 777 0 R /a71 778 0 R /a72 779 0 R /a73 780 0 R /a74 781 0 R /a75 782 0 R /a76 783 0 R /a77 784 0 R /a78 785 0 R /a79 786 0 R /a80 787 0 R /a81 788 0 R /a82 789 0 R /a83 790 0 R /a84 791 0 R /a85 792 0 R /a86 793 0 R /a87 794 0 R /a88 795 0 R /a89 796 0 R /a90 797 0 R /a91 746 0 R /a93 747 0 R /a95 750 0 R /a96 760 0 R /a97 798 0 R /a98 799 0 R /a99 800 0 R /a100 801 0 R /a101 802 0 R /a102 803 0 R /a103 804 0 R /a104 805 0 R /a105 806 0 R /a106 807 0 R /a107 808 0 R /a108 809 0 R /a109 810 0 R /a110 811 0 R /a111 812 0 R /a112 813 0 R /a113 814 0 R /a114 815 0 R /a115 816 0 R /a116 817 0 R /a117 818 0 R /a118 819 0 R /a119 820 0 R /a120 821 0 R /a121 822 0 R /a122 823 0 R /a123 748 0 R /a125 749 0 R >> endobj 837 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 838 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 839 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 840 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 841 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 842 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 843 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 844 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 845 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 846 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 847 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 848 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 849 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 850 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bS #…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿA ÉÀþÿÃ(9THü±ÉåêÉÈ’:Õ° endstream endobj 851 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 852 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 853 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 854 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 855 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 856 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 857 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 858 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 860 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 861 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 862 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 863 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 865 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 866 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 867 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 868 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 869 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 871 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 872 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 873 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 874 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 875 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 876 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 877 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 879 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 880 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 881 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 882 0 R /Encoding 883 0 R /CharProcs 884 0 R >> endobj 882 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 883 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 884 0 obj << /a38 841 0 R /a40 837 0 R /a41 838 0 R /a43 839 0 R /a47 840 0 R /a48 872 0 R /a49 873 0 R /a50 874 0 R /a51 875 0 R /a52 876 0 R /a53 877 0 R /a54 878 0 R /a55 879 0 R /a56 880 0 R /a57 881 0 R /a65 842 0 R /a66 843 0 R /a67 844 0 R /a68 845 0 R /a69 846 0 R /a70 847 0 R /a71 848 0 R /a72 849 0 R /a73 850 0 R /a75 851 0 R /a76 852 0 R /a77 853 0 R /a78 854 0 R /a79 855 0 R /a80 856 0 R /a81 857 0 R /a82 858 0 R /a83 859 0 R /a84 860 0 R /a85 861 0 R /a86 862 0 R /a87 863 0 R /a88 864 0 R /a89 865 0 R /a90 866 0 R /a101 867 0 R /a110 868 0 R /a111 869 0 R /a115 870 0 R /a116 871 0 R >> endobj 885 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 886 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 887 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 888 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 889 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 890 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 891 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 892 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 893 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 894 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 896 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 897 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 898 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 899 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 901 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 903 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 904 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 905 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 906 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 908 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 909 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 910 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 911 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 912 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 913 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 914 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 915 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 916 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 917 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 918 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 919 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 920 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 922 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 923 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 924 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 925 0 R /Encoding 926 0 R /CharProcs 927 0 R >> endobj 925 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 926 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 927 0 obj << /a38 889 0 R /a40 885 0 R /a41 886 0 R /a43 887 0 R /a47 888 0 R /a48 915 0 R /a49 916 0 R /a50 917 0 R /a51 918 0 R /a52 919 0 R /a53 920 0 R /a54 921 0 R /a55 922 0 R /a56 923 0 R /a57 924 0 R /a65 890 0 R /a66 891 0 R /a67 892 0 R /a68 893 0 R /a69 894 0 R /a70 895 0 R /a71 896 0 R /a72 897 0 R /a73 898 0 R /a75 899 0 R /a76 900 0 R /a77 901 0 R /a78 902 0 R /a79 903 0 R /a80 904 0 R /a81 905 0 R /a82 906 0 R /a83 907 0 R /a84 908 0 R /a85 909 0 R /a86 910 0 R /a87 911 0 R /a88 912 0 R /a89 913 0 R /a90 914 0 R >> endobj 928 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 929 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 930 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ52T02R03RH1ä*ä24Š(XC¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿüÿó‡a0C ¹\=¹¹¶ h endstream endobj 931 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 932 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 933 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 934 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 935 0 obj << /Length 109 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCs3…C®B.K ×ĉ'çr9yré‡+Xré{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]dêþ7 ÂzlÐ+”Á Ѫ-õ@>—«'W Êî/ä endstream endobj 936 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 937 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 938 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 939 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 940 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 941 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 942 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 943 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 944 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0U04T03P06TH1ä*ä25 (Ae’s¹œ<¹ôÃLM¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿAà˜üÿ‡Îj-Ô\®ž\\~,Ü endstream endobj 945 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 946 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 947 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 948 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 949 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 950 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 951 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 952 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 953 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 954 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 955 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 956 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 957 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 958 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 959 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 960 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 961 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 962 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 963 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 965 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 966 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 967 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 968 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 969 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 970 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 971 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 972 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 973 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 974 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 975 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 976 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 977 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 978 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 979 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 980 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 982 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 983 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 984 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 985 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 986 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 987 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 988 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 989 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 990 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 992 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 993 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 994 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 995 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 996 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 997 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 998 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 999 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 1002 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 1004 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 1005 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 1006 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 1007 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 1009 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 1010 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 1011 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 1012 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 1013 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 1014 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 1015 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 1016 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 1018 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 1019 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 1020 0 R /Encoding 1021 0 R /CharProcs 1022 0 R >> endobj 1020 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 1021 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 1022 0 obj << /a21 947 0 R /a27 954 0 R /a28 953 0 R /a29 955 0 R /a30 956 0 R /a31 957 0 R /a33 935 0 R /a34 948 0 R /a35 949 0 R /a36 950 0 R /a37 951 0 R /a38 958 0 R /a39 936 0 R /a40 928 0 R /a41 929 0 R /a42 937 0 R /a43 938 0 R /a44 939 0 R /a45 946 0 R /a46 940 0 R /a47 941 0 R /a48 1010 0 R /a49 1011 0 R /a50 1012 0 R /a51 1013 0 R /a52 1014 0 R /a53 1015 0 R /a54 1016 0 R /a55 1017 0 R /a56 1018 0 R /a57 1019 0 R /a58 942 0 R /a59 943 0 R /a61 944 0 R /a63 959 0 R /a64 952 0 R /a65 960 0 R /a66 961 0 R /a67 962 0 R /a68 963 0 R /a69 964 0 R /a70 965 0 R /a71 966 0 R /a72 967 0 R /a73 968 0 R /a74 969 0 R /a75 970 0 R /a76 971 0 R /a77 972 0 R /a78 973 0 R /a79 974 0 R /a80 975 0 R /a82 976 0 R /a83 977 0 R /a84 978 0 R /a85 979 0 R /a86 980 0 R /a87 981 0 R /a88 982 0 R /a89 983 0 R /a91 930 0 R /a93 931 0 R /a95 934 0 R /a96 945 0 R /a97 984 0 R /a98 985 0 R /a99 986 0 R /a100 987 0 R /a101 988 0 R /a102 989 0 R /a103 990 0 R /a104 991 0 R /a105 992 0 R /a106 993 0 R /a107 994 0 R /a108 995 0 R /a109 996 0 R /a110 997 0 R /a111 998 0 R /a112 999 0 R /a113 1000 0 R /a114 1001 0 R /a115 1002 0 R /a116 1003 0 R /a117 1004 0 R /a118 1005 0 R /a119 1006 0 R /a120 1007 0 R /a121 1008 0 R /a122 1009 0 R /a123 932 0 R /a125 933 0 R >> endobj 1023 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 1024 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 1025 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 1026 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 1027 0 obj << /Length 289 /Filter /FlateDecode >> stream xÚeÐ;NÃ@àßrai›=‚ç`;qѰR. ¢@T@I‚.J|®²7aàÒˆÈÃÎ$ÊCi>˳óØI}^M©¤ ¨¾ iI/•y7õ8KšŽ6'ÏofÖ˜âê±)nbØÍ-}~|½šbvwE•)æôXQùdš9!a¤€åŽûè€Á"é‘[dÙ72ô¶•ÜÃEW¸Œ:,wæX¨ë¨=0;rØ™nåW-¤·WƒèzUR‘³„,k–Ÿ”9¶M˜¥<êåÜI÷z°Ö:©HxÛDL¹ÕÎc¿ŸêÔ|c=1;2œØ‰^´¾ßÛê]ÚA·Äº7™¿Ä_l´Æo'kïH;tÎÛ€_Ñ"èÅ=\lh®soþWŽŠÐ endstream endobj 1028 0 obj << /Length 333 /Filter /FlateDecode >> stream xÚÒAKÃ0ð „±^{û¾€6L»SaN°AOD¨GaŠž—–R¿Aa—‚£ñ½Ô‰®.x ?’ðþ¼dJg9*ãѧ9žäøÉg9ЦÂÓ¯“û'9+ezƒÓ‰L/h[¦å%¾¾¼=Êtvu†™Lçx›¡º“å­µ0°¶È¶ûØ ±`ka5@´!FðÖ ¡%¡£­£¬è~°Ùñð· CnɱÇÔCÈ…sŠÛZí¸¦npIm‡²Ø1õu°2ÎÜcÌ!æ/WÎÜ£¢¡÷[P `¿ùQ ½ÖÂPá{¥…&{6¦Gq.LÀ!qÏÙvNªC”ÏQí&²ðyи‰¯7<…w砳é$kgÑòDÖÐ3ÿ¸èÃ,O¤õûû7y\páÆïC^êxÙÙMŸGž—òZ~GÈ endstream endobj 1029 0 obj << /Length 212 /Filter /FlateDecode >> stream xڽϱ‚0à’$7À ˜x/ ¥$N$ˆ‰ &:9'utÐèf,Æ£ðŒ F¼‚†ÆÕÄßp×öþ ü¡ ÑÃ$ÇÜK8¯‹†ïÎîq b~bNeé/çëD¼œ¢‘àF¢·…4AFGi¢ú[«‘µª?«2’×%éæ72byg6ù ã•Nh—:¡]hÝB¿íçQÖ©L›)õ϶ÿ˜?›Í$nþIØd¦ä¼Ô[Xm”ÑFŽÊiÇžzÒÕŠäuA63`– ^¶Ñj» endstream endobj 1030 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 1031 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ¿NÃ0Æ?+C$/~„Ü @pK§V*E"L02€`«÷ÉÈ£Dâ`ž”7Ѭ$7ëãî¨d¸¬*¦ ¯:}§¿$ X endstream endobj 1032 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 1033 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 1034 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 1035 0 obj << /Length 159 /Filter /FlateDecode >> stream xÚ35Ñ34W0P0bSC…C®B.˜ˆ ’HÎåròäÒW01çÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(0þaüÇÀðÿûÿ@RŽý´`üÁÀþ§€ñóŸ ÿ`ø$@äÿ†z É€ ÿa/É òmÃÿÿ?ìÿÿC&¹\=¹¹?qjS endstream endobj 1036 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 1037 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 1038 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 1039 0 obj << /Length 213 /Filter /FlateDecode >> stream xÚMͱNÃ@б\DÚæÚTdëä""R.HE¨€’’‹ˆøÓü)÷ ‡h®°¼Œ!Åkfg´¾:[œë\½ž–ê—ºXêS)¯âK†såí÷òø"›ZŠ;õ¥׌¥¨oôýíãYŠÍí¥2Ýê=7Roë0ͬ¯&aÖ8äéYZi4 % :šŽú£¬1X[ÀÌz83L̺ܘE†œ[yß!8}†?£øË+–÷ÔðO2dñ»ÍÃWtm8 è\„\Õ²“uYÛ endstream endobj 1040 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 1041 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 1043 0 obj << /Length 248 /Filter /FlateDecode >> stream xÚeпJÄ@ðo \`^›B¼yÝÍ] ç ¦´²á@-íÄÛG²´Ì£äR^w¢ùÃÙüŠ™]¾™9ŽŽâ„ Oùpj8>åxƽPS5œÌþZ÷O´LIßpœ¾puÒé%¿½¾?’^^qDzÅ·›;JW\×…ªË¡~ lr¯&V‰÷g¸î¾{„'À´N2¬;säÀ8GÖêÊvn=§·õЪÊQoåb]pл ~‹‹¯^¶ã8ëõí®Ø:úg00ìœ7~Êžî¿®JT¥Ä٠Ͼüœ4s”M^!ÒyJ×ô[ÍX' endstream endobj 1044 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 1045 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 1046 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 1047 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚmÁJÄ0†'ô˜ƒyÅÎ h[éÖÞ ë ö ¸'âiõ(¨èÕöÑò(y„sÆ™ì$ä;dfþò·ýùåšjjéì‚Ú5u=5ø†mMrºþPÙ¿àfÄêžÚ«~Æj¼¥÷Ïg¬6wWÔ`µ¥‡†êG·*€‰`ˆß‹Z@y˜æÂÂ`5@éNŽ0Þ8FéÁ„ Ê ðÒxÖ‘õPºŒÁ fÆÄ¾ŠÍ¡HmVJ[ù\8ô¥ )ƒqYT‹‘Nà K†Jˆ¿8L3#Úÿ±Ä™g¾DïU”kñèÙ-¬Ä2¥¡gþBá8&%ÁÃ1DñÂëwø>³vq endstream endobj 1048 0 obj << /Length 206 /Filter /FlateDecode >> stream xÚ¥ÐÍjÂ@Àñ„@CÐkBç º·‚Ð õäA ¶GAEÏæÍÌ£äMbö/hèµûƒÙf–Éf¯Ó±Zµ'›èdª?©$¶¹u©{øÞÉ<³Ñl(æ½½“èéxþ3ÿ\h*f©ÛTí—äKõ> /FirstChar 45 /LastChar 121 /Widths 1049 0 R /Encoding 1050 0 R /CharProcs 1051 0 R >> endobj 1049 0 obj [32.5 27.08 48.75 48.75 48.75 48.75 48.75 48.75 0 0 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 54.17 0 0 0 100.18 0 0 0 0 0 0 0 0 0 0 0 0 54.17 43.33 0 48.75 54.17 27.08 0 0 27.08 0 54.17 48.75 54.17 0 37.92 38.46 37.92 0 51.46 70.42 0 51.46 ] endobj 1050 0 obj << /Type /Encoding /Differences [45/a45/a46/a47/a48/a49/a50/a51/a52 53/.notdef 58/a58 59/.notdef 83/a83 84/.notdef 87/a87 88/.notdef 100/a100/a101 102/.notdef 103/a103/a104/a105 106/.notdef 108/a108 109/.notdef 110/a110/a111/a112 113/.notdef 114/a114/a115/a116 117/.notdef 118/a118/a119 120/.notdef 121/a121] >> endobj 1051 0 obj << /a45 1026 0 R /a46 1023 0 R /a47 1024 0 R /a48 1044 0 R /a49 1045 0 R /a50 1046 0 R /a51 1047 0 R /a52 1048 0 R /a58 1025 0 R /a83 1027 0 R /a87 1028 0 R /a100 1029 0 R /a101 1030 0 R /a103 1031 0 R /a104 1032 0 R /a105 1033 0 R /a108 1034 0 R /a110 1035 0 R /a111 1036 0 R /a112 1037 0 R /a114 1038 0 R /a115 1039 0 R /a116 1040 0 R /a118 1041 0 R /a119 1042 0 R /a121 1043 0 R >> endobj 1052 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×31R0P0F¦ :Å« Ì ƒYɹ\Nž\úá@—¾˜ôôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàg°?Pÿàÿ¬`€ŸËÕ“+ è±"g endstream endobj 1053 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 1054 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 1056 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 1058 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 1059 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 1060 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 1061 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 1062 0 obj << /Length 312 /Filter /FlateDecode >> stream xÚÍÒ»JÄ@à˜&o°™Ð\ØÍ"uSne!Vj)¨(X9y´ˆ…¥o ó)S„gΉ²¢…¥Ó|äÌ%s~¦˜ïLMjæf;7Ejv§æ"Ó7z–S‘> ™9¿Ò‹J''f–ëäÊ:©ŽÌÝíý¥NÇû&ÓÉÒœf&=ÓÕÒ¨À”#&Pñ5AOt°A£œÐ`ÖmUï~Ô³Ÿ‚jÊ–þJ.óuË—ê•oåÅÁ¯5Jjó ˆ©éˆZŽ'¤@Z‰Ç}AýÑ|*OêMìHó ·Iù+íˆk†O%3Œ´?q2'X74BÍ\ËG¤‡‘=éÏCÝNÀ½{‚5""ìÕœRØpf“é·”'zÉÃJV¥‹¨€ˆ_~=´@ò‹}MTz¥?Î×À¥ endstream endobj 1063 0 obj << /Length 348 /Filter /FlateDecode >> stream xÚÒ½JÄ@à A"Ûì#d_@“È]äªÀy‚)­,ÄJ--í„ÝG[¹ÂÎÚÂ"2EÈ83»ÂqœbùÂþÌÎîl}|83¥©ÍÁ‘©+³˜™»J=ª97–fQ‡žÛµlUqeæ3UœQ³*Úsóüôr¯Šåʼn©T±2ו)oT»2MÀOƒžAìé›"Ž„îl:hë@;AS$ÔŸzH€=Y/£tG£:È ¤9>à &A¢[ϱhX:J"‘lØDGz!ß­ÿ+”Ô¾ ¤˜ñö¬Ï™WÎÑúžÇ·ŽwƒkÙ®çƒï”+~PŒˆü’3‡ŸŒÇA•CÌ#ý݃ w2J)¶±ÿ'Diþ ëm!y:¤É"ac‘TðR*ë’@(ª¼\X*8w4r‚{)%ÝŽK¿|;Ò)A'—¥Jré@ËyAÂmê´U—ê|Aæ endstream endobj 1064 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 1065 0 R /Encoding 1066 0 R /CharProcs 1067 0 R >> endobj 1065 0 obj [37.42 0 0 0 0 67.4 0 67.4 67.4 0 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 1066 0 obj << /Type /Encoding /Differences [46/a46 47/.notdef 51/a51 52/.notdef 53/a53/a54 55/.notdef 56/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 1067 0 obj << /a46 1052 0 R /a51 1061 0 R /a53 1062 0 R /a54 1063 0 R /a56 1064 0 R /a86 1053 0 R /a97 1054 0 R /a101 1055 0 R /a105 1056 0 R /a108 1057 0 R /a111 1058 0 R /a114 1059 0 R /a116 1060 0 R >> endobj 1068 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 1070 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 1071 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 1070 0 R >> endobj 177 0 obj << /Type /Font /Subtype /Type1 /BaseFont /SYFPBV+CMMI10 /FontDescriptor 1069 0 R /FirstChar 60 /LastChar 62 /Widths 577 0 R >> endobj 297 0 obj << /Type /Font /Subtype /Type1 /BaseFont /HAJUBM+CMSY10 /FontDescriptor 1071 0 R /FirstChar 110 /LastChar 110 /Widths 484 0 R >> endobj 118 0 obj << /Type /Pages /Count 6 /Parent 1072 0 R /Kids [110 0 R 138 0 R 155 0 R 159 0 R 165 0 R 169 0 R] >> endobj 179 0 obj << /Type /Pages /Count 6 /Parent 1072 0 R /Kids [173 0 R 181 0 R 185 0 R 189 0 R 193 0 R 197 0 R] >> endobj 204 0 obj << /Type /Pages /Count 6 /Parent 1072 0 R /Kids [201 0 R 206 0 R 210 0 R 214 0 R 218 0 R 222 0 R] >> endobj 229 0 obj << /Type /Pages /Count 6 /Parent 1072 0 R /Kids [226 0 R 231 0 R 236 0 R 240 0 R 244 0 R 248 0 R] >> endobj 255 0 obj << /Type /Pages /Count 6 /Parent 1072 0 R /Kids [252 0 R 257 0 R 261 0 R 265 0 R 269 0 R 275 0 R] >> endobj 284 0 obj << /Type /Pages /Count 6 /Parent 1072 0 R /Kids [280 0 R 286 0 R 292 0 R 299 0 R 304 0 R 308 0 R] >> endobj 322 0 obj << /Type /Pages /Count 6 /Parent 1073 0 R /Kids [317 0 R 324 0 R 328 0 R 332 0 R 336 0 R 340 0 R] >> endobj 348 0 obj << /Type /Pages /Count 6 /Parent 1073 0 R /Kids [344 0 R 350 0 R 357 0 R 365 0 R 371 0 R 381 0 R] >> endobj 390 0 obj << /Type /Pages /Count 6 /Parent 1073 0 R /Kids [387 0 R 392 0 R 396 0 R 401 0 R 405 0 R 409 0 R] >> endobj 416 0 obj << /Type /Pages /Count 6 /Parent 1073 0 R /Kids [413 0 R 418 0 R 422 0 R 426 0 R 430 0 R 434 0 R] >> endobj 441 0 obj << /Type /Pages /Count 6 /Parent 1073 0 R /Kids [438 0 R 443 0 R 447 0 R 451 0 R 455 0 R 459 0 R] >> endobj 466 0 obj << /Type /Pages /Count 3 /Parent 1073 0 R /Kids [463 0 R 468 0 R 472 0 R] >> endobj 1072 0 obj << /Type /Pages /Count 36 /Parent 1074 0 R /Kids [118 0 R 179 0 R 204 0 R 229 0 R 255 0 R 284 0 R] >> endobj 1073 0 obj << /Type /Pages /Count 33 /Parent 1074 0 R /Kids [322 0 R 348 0 R 390 0 R 416 0 R 441 0 R 466 0 R] >> endobj 1074 0 obj << /Type /Pages /Count 69 /Kids [1072 0 R 1073 0 R] >> endobj 1075 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 1075 0 R /Prev 103 0 R >> endobj 103 0 obj << /Title 104 0 R /A 101 0 R /Parent 1075 0 R /Prev 99 0 R /Next 107 0 R >> endobj 99 0 obj << /Title 100 0 R /A 97 0 R /Parent 1075 0 R /Prev 95 0 R /Next 103 0 R >> endobj 95 0 obj << /Title 96 0 R /A 93 0 R /Parent 1075 0 R /Prev 91 0 R /Next 99 0 R >> endobj 91 0 obj << /Title 92 0 R /A 89 0 R /Parent 1075 0 R /Prev 87 0 R /Next 95 0 R >> endobj 87 0 obj << /Title 88 0 R /A 85 0 R /Parent 1075 0 R /Prev 83 0 R /Next 91 0 R >> endobj 83 0 obj << /Title 84 0 R /A 81 0 R /Parent 1075 0 R /Prev 79 0 R /Next 87 0 R >> endobj 79 0 obj << /Title 80 0 R /A 77 0 R /Parent 1075 0 R /Prev 75 0 R /Next 83 0 R >> endobj 75 0 obj << /Title 76 0 R /A 73 0 R /Parent 1075 0 R /Prev 71 0 R /Next 79 0 R >> endobj 71 0 obj << /Title 72 0 R /A 69 0 R /Parent 1075 0 R /Prev 67 0 R /Next 75 0 R >> endobj 67 0 obj << /Title 68 0 R /A 65 0 R /Parent 1075 0 R /Prev 63 0 R /Next 71 0 R >> endobj 63 0 obj << /Title 64 0 R /A 61 0 R /Parent 1075 0 R /Prev 59 0 R /Next 67 0 R >> endobj 59 0 obj << /Title 60 0 R /A 57 0 R /Parent 1075 0 R /Prev 55 0 R /Next 63 0 R >> endobj 55 0 obj << /Title 56 0 R /A 53 0 R /Parent 1075 0 R /Prev 51 0 R /Next 59 0 R >> endobj 51 0 obj << /Title 52 0 R /A 49 0 R /Parent 1075 0 R /Prev 47 0 R /Next 55 0 R >> endobj 47 0 obj << /Title 48 0 R /A 45 0 R /Parent 1075 0 R /Prev 43 0 R /Next 51 0 R >> endobj 43 0 obj << /Title 44 0 R /A 41 0 R /Parent 1075 0 R /Prev 39 0 R /Next 47 0 R >> endobj 39 0 obj << /Title 40 0 R /A 37 0 R /Parent 1075 0 R /Prev 35 0 R /Next 43 0 R >> endobj 35 0 obj << /Title 36 0 R /A 33 0 R /Parent 1075 0 R /Prev 31 0 R /Next 39 0 R >> endobj 31 0 obj << /Title 32 0 R /A 29 0 R /Parent 1075 0 R /Prev 27 0 R /Next 35 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 1075 0 R /Prev 23 0 R /Next 31 0 R >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 1075 0 R /Prev 19 0 R /Next 27 0 R >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 1075 0 R /Prev 15 0 R /Next 23 0 R >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 1075 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 1075 0 R /Prev 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 1075 0 R /Prev 3 0 R /Next 11 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R /Parent 1075 0 R /Next 7 0 R >> endobj 1076 0 obj << /Names [(Doc-Start) 114 0 R (page.1) 113 0 R (page.10) 191 0 R (page.11) 195 0 R (page.12) 199 0 R (page.13) 203 0 R] /Limits [(Doc-Start) (page.13)] >> endobj 1077 0 obj << /Names [(page.14) 208 0 R (page.15) 212 0 R (page.16) 216 0 R (page.17) 220 0 R (page.18) 224 0 R (page.19) 228 0 R] /Limits [(page.14) (page.19)] >> endobj 1078 0 obj << /Names [(page.2) 140 0 R (page.20) 233 0 R (page.21) 238 0 R (page.22) 242 0 R (page.23) 246 0 R (page.24) 250 0 R] /Limits [(page.2) (page.24)] >> endobj 1079 0 obj << /Names [(page.25) 254 0 R (page.26) 259 0 R (page.27) 263 0 R (page.28) 267 0 R (page.29) 271 0 R (page.3) 157 0 R] /Limits [(page.25) (page.3)] >> endobj 1080 0 obj << /Names [(page.30) 277 0 R (page.31) 282 0 R (page.32) 288 0 R (page.33) 294 0 R (page.34) 301 0 R (page.35) 306 0 R] /Limits [(page.30) (page.35)] >> endobj 1081 0 obj << /Names [(page.36) 310 0 R (page.37) 319 0 R (page.38) 326 0 R (page.39) 330 0 R (page.4) 161 0 R (page.40) 334 0 R] /Limits [(page.36) (page.40)] >> endobj 1082 0 obj << /Names [(page.41) 338 0 R (page.42) 342 0 R (page.43) 346 0 R (page.44) 352 0 R (page.45) 359 0 R (page.46) 367 0 R] /Limits [(page.41) (page.46)] >> endobj 1083 0 obj << /Names [(page.47) 373 0 R (page.48) 383 0 R (page.49) 389 0 R (page.5) 167 0 R (page.50) 394 0 R (page.51) 398 0 R] /Limits [(page.47) (page.51)] >> endobj 1084 0 obj << /Names [(page.52) 403 0 R (page.53) 407 0 R (page.54) 411 0 R (page.55) 415 0 R (page.56) 420 0 R (page.57) 424 0 R] /Limits [(page.52) (page.57)] >> endobj 1085 0 obj << /Names [(page.58) 428 0 R (page.59) 432 0 R (page.6) 171 0 R (page.60) 436 0 R (page.61) 440 0 R (page.62) 445 0 R] /Limits [(page.58) (page.62)] >> endobj 1086 0 obj << /Names [(page.63) 449 0 R (page.64) 453 0 R (page.65) 457 0 R (page.66) 461 0 R (page.67) 465 0 R (page.68) 470 0 R] /Limits [(page.63) (page.68)] >> endobj 1087 0 obj << /Names [(page.69) 474 0 R (page.7) 175 0 R (page.8) 183 0 R (page.9) 187 0 R (section*.1) 143 0 R (section*.15) 273 0 R] /Limits [(page.69) (section*.15)] >> endobj 1088 0 obj << /Names [(section*.16) 278 0 R (section*.17) 283 0 R (section*.18) 289 0 R (section*.19) 290 0 R (section*.20) 295 0 R (section*.22) 296 0 R] /Limits [(section*.16) (section*.22)] >> endobj 1089 0 obj << /Names [(section*.24) 302 0 R (section*.27) 311 0 R (section*.28) 312 0 R (section*.29) 313 0 R (section*.30) 314 0 R (section*.31) 315 0 R] /Limits [(section*.24) (section*.31)] >> endobj 1090 0 obj << /Names [(section*.32) 320 0 R (section*.33) 321 0 R (section*.36) 347 0 R (section*.37) 353 0 R (section*.38) 354 0 R (section*.39) 355 0 R] /Limits [(section*.32) (section*.39)] >> endobj 1091 0 obj << /Names [(section*.40) 360 0 R (section*.41) 361 0 R (section*.42) 362 0 R (section*.43) 363 0 R (section*.44) 368 0 R (section*.45) 369 0 R] /Limits [(section*.40) (section*.45)] >> endobj 1092 0 obj << /Names [(section*.46) 374 0 R (section*.47) 375 0 R (section*.48) 376 0 R (section*.49) 377 0 R (section*.50) 378 0 R (section*.51) 379 0 R] /Limits [(section*.46) (section*.51)] >> endobj 1093 0 obj << /Names [(section*.52) 384 0 R (section*.53) 385 0 R (section.10) 34 0 R (section.11) 38 0 R (section.12) 42 0 R (section.13) 46 0 R] /Limits [(section*.52) (section.13)] >> endobj 1094 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 1095 0 obj << /Names [(section.3) 6 0 R (section.34) 70 0 R (section.35) 74 0 R (section.4) 10 0 R (section.5) 14 0 R (section.54) 78 0 R] /Limits [(section.3) (section.54)] >> endobj 1096 0 obj << /Names [(section.55) 82 0 R (section.56) 86 0 R (section.57) 90 0 R (section.58) 94 0 R (section.59) 98 0 R (section.6) 18 0 R] /Limits [(section.55) (section.6)] >> endobj 1097 0 obj << /Names [(section.60) 102 0 R (section.61) 106 0 R (section.7) 22 0 R (section.8) 26 0 R (section.9) 30 0 R] /Limits [(section.60) (section.9)] >> endobj 1098 0 obj << /Kids [1076 0 R 1077 0 R 1078 0 R 1079 0 R 1080 0 R 1081 0 R] /Limits [(Doc-Start) (page.40)] >> endobj 1099 0 obj << /Kids [1082 0 R 1083 0 R 1084 0 R 1085 0 R 1086 0 R 1087 0 R] /Limits [(page.41) (section*.15)] >> endobj 1100 0 obj << /Kids [1088 0 R 1089 0 R 1090 0 R 1091 0 R 1092 0 R 1093 0 R] /Limits [(section*.16) (section.13)] >> endobj 1101 0 obj << /Kids [1094 0 R 1095 0 R 1096 0 R 1097 0 R] /Limits [(section.14) (section.9)] >> endobj 1102 0 obj << /Kids [1098 0 R 1099 0 R 1100 0 R 1101 0 R] /Limits [(Doc-Start) (section.9)] >> endobj 1103 0 obj << /Dests 1102 0 R >> endobj 1104 0 obj << /Type /Catalog /Pages 1074 0 R /Outlines 1075 0 R /Names 1103 0 R /PageMode/UseOutlines/PageLabels<>1<>]>> /OpenAction 109 0 R >> endobj 1105 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.10)/Keywords() /CreationDate (D:20140311195155-04'00') /ModDate (D:20140311195155-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 1106 0000000000 65535 f 0000000015 00000 n 0000011030 00000 n 0000361781 00000 n 0000000060 00000 n 0000000084 00000 n 0000011086 00000 n 0000361696 00000 n 0000000129 00000 n 0000000157 00000 n 0000011144 00000 n 0000361609 00000 n 0000000202 00000 n 0000000234 00000 n 0000011203 00000 n 0000361520 00000 n 0000000280 00000 n 0000000317 00000 n 0000017703 00000 n 0000361431 00000 n 0000000363 00000 n 0000000393 00000 n 0000052800 00000 n 0000361342 00000 n 0000000439 00000 n 0000000481 00000 n 0000054460 00000 n 0000361253 00000 n 0000000527 00000 n 0000000573 00000 n 0000058485 00000 n 0000361164 00000 n 0000000619 00000 n 0000000670 00000 n 0000061010 00000 n 0000361075 00000 n 0000000717 00000 n 0000000743 00000 n 0000063083 00000 n 0000360986 00000 n 0000000790 00000 n 0000000823 00000 n 0000067381 00000 n 0000360897 00000 n 0000000870 00000 n 0000000909 00000 n 0000069504 00000 n 0000360808 00000 n 0000000956 00000 n 0000000999 00000 n 0000069563 00000 n 0000360719 00000 n 0000001046 00000 n 0000001104 00000 n 0000077768 00000 n 0000360630 00000 n 0000001151 00000 n 0000001214 00000 n 0000080116 00000 n 0000360541 00000 n 0000001261 00000 n 0000001300 00000 n 0000082451 00000 n 0000360452 00000 n 0000001347 00000 n 0000001388 00000 n 0000084540 00000 n 0000360363 00000 n 0000001435 00000 n 0000001482 00000 n 0000090103 00000 n 0000360274 00000 n 0000001529 00000 n 0000001570 00000 n 0000101452 00000 n 0000360185 00000 n 0000001617 00000 n 0000001659 00000 n 0000117691 00000 n 0000360096 00000 n 0000001706 00000 n 0000001747 00000 n 0000144891 00000 n 0000360007 00000 n 0000001794 00000 n 0000001846 00000 n 0000160716 00000 n 0000359918 00000 n 0000001893 00000 n 0000001919 00000 n 0000160773 00000 n 0000359829 00000 n 0000001966 00000 n 0000001995 00000 n 0000163722 00000 n 0000359740 00000 n 0000002042 00000 n 0000002076 00000 n 0000166138 00000 n 0000359649 00000 n 0000002123 00000 n 0000002158 00000 n 0000166197 00000 n 0000359556 00000 n 0000002206 00000 n 0000002236 00000 n 0000166257 00000 n 0000359476 00000 n 0000002284 00000 n 0000002315 00000 n 0000002653 00000 n 0000002883 00000 n 0000002367 00000 n 0000002765 00000 n 0000002825 00000 n 0000341828 00000 n 0000336215 00000 n 0000326353 00000 n 0000357694 00000 n 0000003942 00000 n 0000004093 00000 n 0000004243 00000 n 0000004395 00000 n 0000004547 00000 n 0000004699 00000 n 0000004850 00000 n 0000005002 00000 n 0000005153 00000 n 0000005306 00000 n 0000005459 00000 n 0000005612 00000 n 0000005765 00000 n 0000005918 00000 n 0000006070 00000 n 0000006222 00000 n 0000006373 00000 n 0000007463 00000 n 0000006646 00000 n 0000003682 00000 n 0000002981 00000 n 0000006526 00000 n 0000300458 00000 n 0000286149 00000 n 0000006586 00000 n 0000267726 00000 n 0000007616 00000 n 0000007768 00000 n 0000007919 00000 n 0000008072 00000 n 0000008225 00000 n 0000008378 00000 n 0000008531 00000 n 0000008684 00000 n 0000008837 00000 n 0000009050 00000 n 0000007259 00000 n 0000006757 00000 n 0000008990 00000 n 0000011262 00000 n 0000010858 00000 n 0000009148 00000 n 0000010970 00000 n 0000240509 00000 n 0000215020 00000 n 0000013292 00000 n 0000013120 00000 n 0000011386 00000 n 0000013232 00000 n 0000015301 00000 n 0000015129 00000 n 0000013390 00000 n 0000015241 00000 n 0000017762 00000 n 0000017531 00000 n 0000015399 00000 n 0000017643 00000 n 0000204127 00000 n 0000357404 00000 n 0000196123 00000 n 0000357812 00000 n 0000020591 00000 n 0000020419 00000 n 0000017925 00000 n 0000020531 00000 n 0000023403 00000 n 0000023231 00000 n 0000020728 00000 n 0000023343 00000 n 0000026059 00000 n 0000025887 00000 n 0000023514 00000 n 0000025999 00000 n 0000028765 00000 n 0000028593 00000 n 0000026196 00000 n 0000028705 00000 n 0000031330 00000 n 0000031158 00000 n 0000028915 00000 n 0000031270 00000 n 0000033619 00000 n 0000033447 00000 n 0000031454 00000 n 0000033559 00000 n 0000357930 00000 n 0000036411 00000 n 0000036239 00000 n 0000033756 00000 n 0000036351 00000 n 0000039130 00000 n 0000038958 00000 n 0000036548 00000 n 0000039070 00000 n 0000041406 00000 n 0000041234 00000 n 0000039267 00000 n 0000041346 00000 n 0000044000 00000 n 0000043828 00000 n 0000041543 00000 n 0000043940 00000 n 0000046149 00000 n 0000045977 00000 n 0000044137 00000 n 0000046089 00000 n 0000048396 00000 n 0000048224 00000 n 0000046286 00000 n 0000048336 00000 n 0000358048 00000 n 0000051299 00000 n 0000051127 00000 n 0000048507 00000 n 0000051239 00000 n 0000188155 00000 n 0000052857 00000 n 0000052628 00000 n 0000051436 00000 n 0000052740 00000 n 0000054519 00000 n 0000054288 00000 n 0000052968 00000 n 0000054400 00000 n 0000056166 00000 n 0000055994 00000 n 0000054630 00000 n 0000056106 00000 n 0000058544 00000 n 0000058313 00000 n 0000056264 00000 n 0000058425 00000 n 0000061069 00000 n 0000060838 00000 n 0000058655 00000 n 0000060950 00000 n 0000358166 00000 n 0000063142 00000 n 0000062911 00000 n 0000061180 00000 n 0000063023 00000 n 0000065507 00000 n 0000065335 00000 n 0000063266 00000 n 0000065447 00000 n 0000067440 00000 n 0000067209 00000 n 0000065605 00000 n 0000067321 00000 n 0000069682 00000 n 0000069332 00000 n 0000067564 00000 n 0000069444 00000 n 0000185999 00000 n 0000069622 00000 n 0000071230 00000 n 0000070998 00000 n 0000069806 00000 n 0000071110 00000 n 0000071170 00000 n 0000073274 00000 n 0000073042 00000 n 0000071341 00000 n 0000073154 00000 n 0000073214 00000 n 0000358284 00000 n 0000075224 00000 n 0000074932 00000 n 0000073385 00000 n 0000075044 00000 n 0000075104 00000 n 0000075164 00000 n 0000077887 00000 n 0000077536 00000 n 0000075335 00000 n 0000077648 00000 n 0000077708 00000 n 0000077827 00000 n 0000357548 00000 n 0000080233 00000 n 0000079944 00000 n 0000078037 00000 n 0000080056 00000 n 0000080175 00000 n 0000082510 00000 n 0000082279 00000 n 0000080357 00000 n 0000082391 00000 n 0000084896 00000 n 0000084368 00000 n 0000082647 00000 n 0000084480 00000 n 0000084597 00000 n 0000084656 00000 n 0000084716 00000 n 0000084776 00000 n 0000084836 00000 n 0000087371 00000 n 0000087079 00000 n 0000085007 00000 n 0000087191 00000 n 0000087251 00000 n 0000087311 00000 n 0000358402 00000 n 0000090160 00000 n 0000089931 00000 n 0000087482 00000 n 0000090043 00000 n 0000092074 00000 n 0000091902 00000 n 0000090284 00000 n 0000092014 00000 n 0000094600 00000 n 0000094428 00000 n 0000092172 00000 n 0000094540 00000 n 0000096309 00000 n 0000096137 00000 n 0000094724 00000 n 0000096249 00000 n 0000098888 00000 n 0000098716 00000 n 0000096433 00000 n 0000098828 00000 n 0000101571 00000 n 0000101280 00000 n 0000098999 00000 n 0000101392 00000 n 0000101511 00000 n 0000358520 00000 n 0000103988 00000 n 0000103637 00000 n 0000101721 00000 n 0000103749 00000 n 0000103809 00000 n 0000103869 00000 n 0000103928 00000 n 0000106571 00000 n 0000106159 00000 n 0000104099 00000 n 0000106271 00000 n 0000106331 00000 n 0000106391 00000 n 0000106451 00000 n 0000106511 00000 n 0000108835 00000 n 0000108545 00000 n 0000106682 00000 n 0000108657 00000 n 0000108717 00000 n 0000108775 00000 n 0000111246 00000 n 0000110714 00000 n 0000108959 00000 n 0000110826 00000 n 0000110886 00000 n 0000110946 00000 n 0000111006 00000 n 0000111066 00000 n 0000111126 00000 n 0000111186 00000 n 0000113597 00000 n 0000113305 00000 n 0000111344 00000 n 0000113417 00000 n 0000113477 00000 n 0000113537 00000 n 0000115621 00000 n 0000115449 00000 n 0000113708 00000 n 0000115561 00000 n 0000358638 00000 n 0000117750 00000 n 0000117519 00000 n 0000115719 00000 n 0000117631 00000 n 0000119715 00000 n 0000119543 00000 n 0000117874 00000 n 0000119655 00000 n 0000168166 00000 n 0000122287 00000 n 0000122115 00000 n 0000119839 00000 n 0000122227 00000 n 0000125135 00000 n 0000124963 00000 n 0000122411 00000 n 0000125075 00000 n 0000127764 00000 n 0000127592 00000 n 0000125272 00000 n 0000127704 00000 n 0000130280 00000 n 0000130108 00000 n 0000127875 00000 n 0000130220 00000 n 0000358756 00000 n 0000132105 00000 n 0000131933 00000 n 0000130378 00000 n 0000132045 00000 n 0000134555 00000 n 0000134383 00000 n 0000132216 00000 n 0000134495 00000 n 0000137314 00000 n 0000137142 00000 n 0000134666 00000 n 0000137254 00000 n 0000140013 00000 n 0000139841 00000 n 0000137438 00000 n 0000139953 00000 n 0000142007 00000 n 0000141835 00000 n 0000140137 00000 n 0000141947 00000 n 0000144950 00000 n 0000144719 00000 n 0000142118 00000 n 0000144831 00000 n 0000358874 00000 n 0000147769 00000 n 0000147597 00000 n 0000145074 00000 n 0000147709 00000 n 0000150394 00000 n 0000150222 00000 n 0000147893 00000 n 0000150334 00000 n 0000153032 00000 n 0000152860 00000 n 0000150518 00000 n 0000152972 00000 n 0000155970 00000 n 0000155798 00000 n 0000153143 00000 n 0000155910 00000 n 0000158673 00000 n 0000158501 00000 n 0000156068 00000 n 0000158613 00000 n 0000160832 00000 n 0000160544 00000 n 0000158784 00000 n 0000160656 00000 n 0000358992 00000 n 0000163781 00000 n 0000163550 00000 n 0000160956 00000 n 0000163662 00000 n 0000166316 00000 n 0000165966 00000 n 0000163879 00000 n 0000166078 00000 n 0000166453 00000 n 0000166742 00000 n 0000167058 00000 n 0000167330 00000 n 0000167617 00000 n 0000167883 00000 n 0000168416 00000 n 0000168506 00000 n 0000168671 00000 n 0000168777 00000 n 0000168800 00000 n 0000169114 00000 n 0000169419 00000 n 0000169673 00000 n 0000169850 00000 n 0000170314 00000 n 0000170686 00000 n 0000171002 00000 n 0000171389 00000 n 0000171699 00000 n 0000171988 00000 n 0000172242 00000 n 0000172623 00000 n 0000172825 00000 n 0000173010 00000 n 0000173381 00000 n 0000173611 00000 n 0000173970 00000 n 0000174328 00000 n 0000174695 00000 n 0000174961 00000 n 0000175293 00000 n 0000175678 00000 n 0000175921 00000 n 0000176210 00000 n 0000176593 00000 n 0000176906 00000 n 0000177216 00000 n 0000177511 00000 n 0000177813 00000 n 0000178120 00000 n 0000178368 00000 n 0000178730 00000 n 0000178978 00000 n 0000179190 00000 n 0000179491 00000 n 0000179679 00000 n 0000179969 00000 n 0000180212 00000 n 0000180506 00000 n 0000180814 00000 n 0000181056 00000 n 0000181360 00000 n 0000181614 00000 n 0000181861 00000 n 0000182158 00000 n 0000182515 00000 n 0000182830 00000 n 0000183178 00000 n 0000183467 00000 n 0000183759 00000 n 0000183966 00000 n 0000184313 00000 n 0000184652 00000 n 0000184949 00000 n 0000185283 00000 n 0000185628 00000 n 0000186250 00000 n 0000186669 00000 n 0000187119 00000 n 0000187904 00000 n 0000188402 00000 n 0000188428 00000 n 0000188489 00000 n 0000188525 00000 n 0000188706 00000 n 0000189081 00000 n 0000189464 00000 n 0000189753 00000 n 0000190056 00000 n 0000190340 00000 n 0000190661 00000 n 0000190950 00000 n 0000191273 00000 n 0000191589 00000 n 0000191877 00000 n 0000192129 00000 n 0000192490 00000 n 0000192806 00000 n 0000193090 00000 n 0000193414 00000 n 0000193683 00000 n 0000193957 00000 n 0000194229 00000 n 0000194539 00000 n 0000194831 00000 n 0000195172 00000 n 0000195492 00000 n 0000195832 00000 n 0000196374 00000 n 0000196681 00000 n 0000196933 00000 n 0000197300 00000 n 0000197335 00000 n 0000197635 00000 n 0000197928 00000 n 0000198222 00000 n 0000198489 00000 n 0000198807 00000 n 0000199081 00000 n 0000199398 00000 n 0000199708 00000 n 0000199976 00000 n 0000200305 00000 n 0000200558 00000 n 0000200905 00000 n 0000201211 00000 n 0000201482 00000 n 0000201801 00000 n 0000202064 00000 n 0000202345 00000 n 0000202604 00000 n 0000202901 00000 n 0000203187 00000 n 0000203506 00000 n 0000203803 00000 n 0000204377 00000 n 0000204597 00000 n 0000204827 00000 n 0000205168 00000 n 0000205352 00000 n 0000205518 00000 n 0000205747 00000 n 0000205921 00000 n 0000206096 00000 n 0000206268 00000 n 0000206593 00000 n 0000206884 00000 n 0000207191 00000 n 0000207379 00000 n 0000207692 00000 n 0000207905 00000 n 0000208174 00000 n 0000208423 00000 n 0000208751 00000 n 0000209000 00000 n 0000209264 00000 n 0000209525 00000 n 0000209785 00000 n 0000210053 00000 n 0000210327 00000 n 0000210541 00000 n 0000210856 00000 n 0000211078 00000 n 0000211254 00000 n 0000211424 00000 n 0000211670 00000 n 0000211888 00000 n 0000212159 00000 n 0000212429 00000 n 0000212643 00000 n 0000212912 00000 n 0000213126 00000 n 0000213334 00000 n 0000213597 00000 n 0000213914 00000 n 0000214192 00000 n 0000214391 00000 n 0000214691 00000 n 0000215270 00000 n 0000215641 00000 n 0000216061 00000 n 0000216621 00000 n 0000216834 00000 n 0000217107 00000 n 0000217375 00000 n 0000217623 00000 n 0000217800 00000 n 0000218043 00000 n 0000218238 00000 n 0000218435 00000 n 0000218668 00000 n 0000218924 00000 n 0000219176 00000 n 0000219361 00000 n 0000219555 00000 n 0000219784 00000 n 0000220036 00000 n 0000220233 00000 n 0000220450 00000 n 0000220630 00000 n 0000220868 00000 n 0000221056 00000 n 0000221292 00000 n 0000221483 00000 n 0000221709 00000 n 0000221893 00000 n 0000222077 00000 n 0000222289 00000 n 0000222487 00000 n 0000222736 00000 n 0000223068 00000 n 0000223396 00000 n 0000223716 00000 n 0000224060 00000 n 0000224332 00000 n 0000224597 00000 n 0000224868 00000 n 0000225167 00000 n 0000225431 00000 n 0000225659 00000 n 0000225885 00000 n 0000226193 00000 n 0000226394 00000 n 0000226583 00000 n 0000226882 00000 n 0000227086 00000 n 0000227344 00000 n 0000227619 00000 n 0000227870 00000 n 0000228125 00000 n 0000228415 00000 n 0000228693 00000 n 0000229010 00000 n 0000229215 00000 n 0000229463 00000 n 0000229733 00000 n 0000230011 00000 n 0000230318 00000 n 0000230591 00000 n 0000230854 00000 n 0000231126 00000 n 0000231394 00000 n 0000231657 00000 n 0000231931 00000 n 0000232213 00000 n 0000232448 00000 n 0000232782 00000 n 0000233024 00000 n 0000233237 00000 n 0000233487 00000 n 0000233766 00000 n 0000233962 00000 n 0000234214 00000 n 0000234450 00000 n 0000234714 00000 n 0000234995 00000 n 0000235287 00000 n 0000235526 00000 n 0000235792 00000 n 0000236028 00000 n 0000236257 00000 n 0000236524 00000 n 0000236779 00000 n 0000237062 00000 n 0000237380 00000 n 0000237637 00000 n 0000237921 00000 n 0000238143 00000 n 0000238446 00000 n 0000238753 00000 n 0000239015 00000 n 0000239303 00000 n 0000239625 00000 n 0000239889 00000 n 0000240183 00000 n 0000240759 00000 n 0000241403 00000 n 0000241916 00000 n 0000243187 00000 n 0000243468 00000 n 0000243745 00000 n 0000243931 00000 n 0000244116 00000 n 0000244386 00000 n 0000244655 00000 n 0000244839 00000 n 0000245061 00000 n 0000245335 00000 n 0000245528 00000 n 0000245752 00000 n 0000245935 00000 n 0000246184 00000 n 0000246376 00000 n 0000246610 00000 n 0000246800 00000 n 0000247022 00000 n 0000247199 00000 n 0000247373 00000 n 0000247592 00000 n 0000247942 00000 n 0000248326 00000 n 0000248577 00000 n 0000248844 00000 n 0000249080 00000 n 0000249348 00000 n 0000249757 00000 n 0000250032 00000 n 0000250369 00000 n 0000250658 00000 n 0000251002 00000 n 0000251279 00000 n 0000251544 00000 n 0000251784 00000 n 0000252127 00000 n 0000252330 00000 n 0000252512 00000 n 0000252760 00000 n 0000253104 00000 n 0000253323 00000 n 0000253657 00000 n 0000253999 00000 n 0000254329 00000 n 0000254575 00000 n 0000254973 00000 n 0000255287 00000 n 0000255631 00000 n 0000255864 00000 n 0000256141 00000 n 0000256493 00000 n 0000256919 00000 n 0000257297 00000 n 0000257598 00000 n 0000257925 00000 n 0000258205 00000 n 0000258477 00000 n 0000258742 00000 n 0000259019 00000 n 0000259291 00000 n 0000259527 00000 n 0000259872 00000 n 0000260110 00000 n 0000260313 00000 n 0000260567 00000 n 0000260846 00000 n 0000261032 00000 n 0000261301 00000 n 0000261533 00000 n 0000261790 00000 n 0000262063 00000 n 0000262344 00000 n 0000262569 00000 n 0000262837 00000 n 0000263068 00000 n 0000263298 00000 n 0000263578 00000 n 0000263895 00000 n 0000264190 00000 n 0000264516 00000 n 0000264797 00000 n 0000265066 00000 n 0000265269 00000 n 0000265581 00000 n 0000265899 00000 n 0000266168 00000 n 0000266478 00000 n 0000266794 00000 n 0000267075 00000 n 0000267408 00000 n 0000267977 00000 n 0000268557 00000 n 0000269141 00000 n 0000270359 00000 n 0000270693 00000 n 0000271021 00000 n 0000271225 00000 n 0000271482 00000 n 0000272029 00000 n 0000272437 00000 n 0000272785 00000 n 0000273204 00000 n 0000273543 00000 n 0000273852 00000 n 0000274125 00000 n 0000274555 00000 n 0000274759 00000 n 0000274945 00000 n 0000275370 00000 n 0000275608 00000 n 0000276000 00000 n 0000276397 00000 n 0000276803 00000 n 0000277093 00000 n 0000277596 00000 n 0000277967 00000 n 0000278394 00000 n 0000278651 00000 n 0000278965 00000 n 0000279393 00000 n 0000279933 00000 n 0000280375 00000 n 0000280741 00000 n 0000281144 00000 n 0000281469 00000 n 0000281734 00000 n 0000282046 00000 n 0000282386 00000 n 0000282653 00000 n 0000282963 00000 n 0000283181 00000 n 0000283563 00000 n 0000283949 00000 n 0000284255 00000 n 0000284621 00000 n 0000285016 00000 n 0000285336 00000 n 0000285756 00000 n 0000286400 00000 n 0000286767 00000 n 0000287126 00000 n 0000287739 00000 n 0000288015 00000 n 0000288285 00000 n 0000288520 00000 n 0000288754 00000 n 0000289159 00000 n 0000289473 00000 n 0000289799 00000 n 0000290146 00000 n 0000290468 00000 n 0000290779 00000 n 0000291066 00000 n 0000291417 00000 n 0000291715 00000 n 0000291957 00000 n 0000292312 00000 n 0000292589 00000 n 0000292975 00000 n 0000293341 00000 n 0000293684 00000 n 0000293972 00000 n 0000294371 00000 n 0000294701 00000 n 0000295048 00000 n 0000295327 00000 n 0000295648 00000 n 0000295972 00000 n 0000296371 00000 n 0000296728 00000 n 0000297051 00000 n 0000297379 00000 n 0000297670 00000 n 0000297912 00000 n 0000298229 00000 n 0000298550 00000 n 0000298845 00000 n 0000299168 00000 n 0000299500 00000 n 0000299788 00000 n 0000300129 00000 n 0000300707 00000 n 0000300991 00000 n 0000301278 00000 n 0000301821 00000 n 0000302091 00000 n 0000302360 00000 n 0000302545 00000 n 0000302728 00000 n 0000302986 00000 n 0000303241 00000 n 0000303425 00000 n 0000303615 00000 n 0000303826 00000 n 0000304071 00000 n 0000304257 00000 n 0000304469 00000 n 0000304644 00000 n 0000304878 00000 n 0000305060 00000 n 0000305281 00000 n 0000305469 00000 n 0000305681 00000 n 0000305856 00000 n 0000306027 00000 n 0000306230 00000 n 0000306511 00000 n 0000306855 00000 n 0000307287 00000 n 0000307663 00000 n 0000307916 00000 n 0000308172 00000 n 0000308406 00000 n 0000308695 00000 n 0000308965 00000 n 0000309376 00000 n 0000309642 00000 n 0000309958 00000 n 0000310248 00000 n 0000310589 00000 n 0000310864 00000 n 0000311126 00000 n 0000311373 00000 n 0000311708 00000 n 0000311914 00000 n 0000312101 00000 n 0000312347 00000 n 0000312671 00000 n 0000312892 00000 n 0000313217 00000 n 0000313541 00000 n 0000313861 00000 n 0000314109 00000 n 0000314411 00000 n 0000314748 00000 n 0000314979 00000 n 0000315251 00000 n 0000315572 00000 n 0000315960 00000 n 0000316320 00000 n 0000316632 00000 n 0000316917 00000 n 0000317196 00000 n 0000317459 00000 n 0000317738 00000 n 0000318008 00000 n 0000318230 00000 n 0000318548 00000 n 0000318784 00000 n 0000318987 00000 n 0000319218 00000 n 0000319495 00000 n 0000319684 00000 n 0000319942 00000 n 0000320170 00000 n 0000320439 00000 n 0000320716 00000 n 0000321000 00000 n 0000321222 00000 n 0000321499 00000 n 0000321732 00000 n 0000321967 00000 n 0000322232 00000 n 0000322547 00000 n 0000322839 00000 n 0000323140 00000 n 0000323405 00000 n 0000323675 00000 n 0000323878 00000 n 0000324188 00000 n 0000324505 00000 n 0000324775 00000 n 0000325083 00000 n 0000325408 00000 n 0000325687 00000 n 0000326034 00000 n 0000326607 00000 n 0000327199 00000 n 0000327778 00000 n 0000329043 00000 n 0000329220 00000 n 0000329468 00000 n 0000329655 00000 n 0000329831 00000 n 0000330202 00000 n 0000330617 00000 n 0000330911 00000 n 0000331203 00000 n 0000331560 00000 n 0000331809 00000 n 0000332016 00000 n 0000332208 00000 n 0000332449 00000 n 0000332740 00000 n 0000333040 00000 n 0000333266 00000 n 0000333561 00000 n 0000333803 00000 n 0000334087 00000 n 0000334415 00000 n 0000334745 00000 n 0000335034 00000 n 0000335247 00000 n 0000335588 00000 n 0000335927 00000 n 0000336468 00000 n 0000336747 00000 n 0000337077 00000 n 0000337480 00000 n 0000337658 00000 n 0000338114 00000 n 0000338483 00000 n 0000338832 00000 n 0000339056 00000 n 0000339261 00000 n 0000339592 00000 n 0000339859 00000 n 0000340132 00000 n 0000340542 00000 n 0000340936 00000 n 0000341366 00000 n 0000342081 00000 n 0000342290 00000 n 0000342571 00000 n 0000342783 00000 n 0000349926 00000 n 0000350161 00000 n 0000357172 00000 n 0000359086 00000 n 0000359206 00000 n 0000359326 00000 n 0000359399 00000 n 0000361853 00000 n 0000362027 00000 n 0000362198 00000 n 0000362367 00000 n 0000362536 00000 n 0000362707 00000 n 0000362877 00000 n 0000363048 00000 n 0000363218 00000 n 0000363389 00000 n 0000363559 00000 n 0000363730 00000 n 0000363909 00000 n 0000364112 00000 n 0000364315 00000 n 0000364518 00000 n 0000364721 00000 n 0000364924 00000 n 0000365118 00000 n 0000365305 00000 n 0000365489 00000 n 0000365676 00000 n 0000365843 00000 n 0000365961 00000 n 0000366081 00000 n 0000366204 00000 n 0000366307 00000 n 0000366409 00000 n 0000366449 00000 n 0000366621 00000 n trailer << /Size 1106 /Root 1104 0 R /Info 1105 0 R /ID [<755D92C5220989035C6670D5F87D94A6> <755D92C5220989035C6670D5F87D94A6>] >> startxref 366948 %%EOF verilator-3.856/verilator.txt0000664000177100017500000045367712307713746016333 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 and Sugar/PSL assertions, into C++, SystemC or SystemPerl code. It is not a complete simulator, just 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. For SystemPerl format, it outputs .sp files for the SystemPerl preprocessor, which greatly simplifies writing SystemC code and is available at . 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 --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 PSL/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 -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-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 --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 --psl Enable PSL parsing --public Debugging; see docs --report-unoptflat Extra diagnostics for UNOPTFLAT --savable Enable model save-restore --sc Create SystemC output --sp Create SystemPerl output --stats Create statistics file -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-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, includes enabling the --psl flag. (If psl is not desired, but other assertions are, use --assert --nopsl.) 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 and --sp. --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. --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 PSL which must be separately enabled with --psl. For example, the following PSL statement will add a coverage point, with the comment "DefaultClock": // psl default clock = posedge clk; // psl cover {cyc==9} report "DefaultClock,expect=1"; -D*var*=*value* Defines the given preprocessor symbol. Same as +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, debugging messages, and intermediate form dump files. --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 source file to the specified level. Higher levels produce more detailed messages (plain "--debug" is equivalent to "--debugi 4"). --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* Defines the given preprocessor symbol. Same as -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 Rarely needed. Enable writing .tree debug files with a specific dumping level, 0 disbles dumps and is equivelent 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-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. This 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. --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. --psl Enable PSL parsing. Without this switch, PSL meta-comments are ignored. See the --assert flag to enable all assertions, and --coverage-user to enable functional coverage. --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 analysing 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 and -sp. --sp Specifies SystemPerl output mode; see also --cc and -sc. --stats Creates a dump file with statistics on the design in {prefix}__stats.txt. -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. --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. -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-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-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 behaviour. 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 SystemPerl. 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 --sp our.v Then we convert the SystemPerl output to SystemC. cd obj_dir export SYSTEMPERL=/path/to/where/systemperl/kit/came/from $SYSTEMPERL/sp_preproc --preproc *.sp (You can also skip the above sp_preproc by getting pure SystemC from Verilator by replacing the verilator --sp flag in the previous step with -sc.) 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 # 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_sp 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. 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 For -sp mode, instead of .cpp and .h it creates: {prefix}.sp // Top level SystemC file {prefix}{each_verilog_module}.sp // Lower level internal SC 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 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. SYSTEMPERL Specifies the directory containing the SystemPerl distribution kit. This is used to find the SystemPerl library and include files. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). See also SYSTEMPERL_INCLUDE. SYSTEMPERL_INCLUDE Specifies the directory containing the Verilog-Perl include .cpp files, from the src/ directory of the SystemPerl kit. If not specified, it will be computed from the SYSTEMPERL environment variable if it is set, and if SYSTEMPERL is not set SYSTEMPERL_INCLUDE will come from a default optionally specified at configure time (before Verilator was compiled). 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). 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 equivelents 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. Sugar/PSL Support Most future work is being directed towards improving SystemVerilog assertions instead of PSL. If you are using these PSL features, please contact the author as they may be depreciated in future versions. With the --assert switch, Verilator enables support of the Property Specification Language (PSL), specifically the simple PSL subset without time-branching primitives. Verilator currently only converts PSL assertions to simple "if (...) error" statements, and coverage statements to increment the line counters described in the coverage section. Verilator implements these keywords: assert, assume (same as assert), default (for clocking), countones, cover, isunknown, onehot, onehot0, report, and true. Verilator implements these operators: -> (logical if). Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. PSL vmode/vprop/vunits are not supported. PSL statements must be in the module they reference, at the module level where you would put an initial... statement. Verilator only supports (posedge CLK) or (negedge CLK), where CLK is the name of a one bit signal. You may not use arbitrary expressions as assertion clocks. 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 statements. However, "unique if" and "priority if" are 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. _(*expr*) A underline followed by an expression in parenthesis returns a Verilog expression. This is different from normal parenthesis in special contexts, such as PSL expressions, and can be used to embed bit concatenation ({}) inside of PSL statements. $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 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. SystemPerl when tracing such signals 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*/ (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. Often this is placed just after a primitive's module statement, so that the entire module is not traced. /*verilator tracing_on*/ Re-enable waveform tracing for all future signals 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. Unititialized 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 passed to DPI imports. 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. 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 +include used on the command line to specify the top include source directory. 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. 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 Error 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 error message as you would disable warnings, 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 copyright? 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. Note also older versions of Verilator used the SystemPerl package and SpTraceVcdC class. This still works, but is depreciated as it requires strong coupling between the Verilator and SystemPerl versions. #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_sp/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. Both require the SystemPerl package to be installed but do not require use of the SystemPerl output mode. First, run verilator with the --coverage option. If you're using your own makefile, compile the model with the GCC flag -DSP_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, the vcoverage utility (from the SystemPerl package) is executed. Vcoverage 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_sp/logs/coverage_source 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. 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 Cavium Networks, Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems, Nauticus Networks, and SiCortex Inc. The people who have contributed major functionality are Byron Bradley, Jeremy Bennett, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers include Jeff Dutton, Ralf Karge, David Hewson, Wim Michiels, Alex Solomatnikov, Sebastien Van Cauwenberghe and Gene Weber. Some of the people who have provided ideas and feedback for Verilator include: David Addison, Vasu Arasanipalai, Jens Arm, J Baxter, Jeremy Bennett, David Black, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee, Lawrence Butcher, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike Denio, John Deroo, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic, Alex Duller, Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete, Andrea Foletto, Bob Fredieu, Shankar Giri, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Thomas Hawkins, David Hewson, Jae Hossell, Ben Jackson, Iztok Jeras, Christophe Joly, Mike Kagen, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki, David Kravitz, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber, John Li, Charlie Lind, Andrew Ling, Paul Liu, Dan Lussier, Fred Ma, Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, Dominic Plunkett, Niranjan Prabhu, Usha Priyadharshini, Alberto Del Rio, Oleg Rodionov, John Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Brian Small, Alex Solomatnikov, Art Stamness, John Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Stefan Thiede, Gary Thomas, Steve Tong, Hans Van Antwerpen, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston, Joshua Wise, Johan Wouters, and Ding Xiaoliang. Thanks to them, and all those we've missed including above. DISTRIBUTION The latest version is available from . Copyright 2003-2014 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. AUTHORS When possible, please instead report bugs to . Wilson Snyder Major concepts by Paul Wasson and Duane Galbi. SEE ALSO verilator_profcfunc, systemperl, vcoverage, make, "verilator --help" which is the source for this document, and internals.txt in the distribution. verilator-3.856/doxygen.config0000664000177100017500000022213412151516242016372 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_sp \ test_v \ test_vcs \ 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.856/doxygen-mainpage0000664000177100017500000000023312151516242016677 0ustar wsnyderwsnyder/*! \mainpage Verilator Doxygen Documentation * * \section intro_sec Introduction * * This is a full doxygen analysis of the Verilator source tree. */verilator-3.856/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.856/internals.pdf0000664000177100017500000057607112307720633016240 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.17) >> endobj 20 0 obj (5 TESTING) endobj 21 0 obj << /S /GoTo /D (section.20) >> endobj 24 0 obj (6 DEBUGGING) endobj 25 0 obj << /S /GoTo /D (section.25) >> endobj 28 0 obj (7 ADDING A NEW FEATURE) endobj 29 0 obj << /S /GoTo /D (section.31) >> endobj 32 0 obj (8 DISTRIBUTION) endobj 33 0 obj << /S /GoTo /D [34 0 R /Fit ] >> endobj 36 0 obj << /Length 225 /Filter /FlateDecode >> stream xÚ-޽jÄ0„{?Å–V¡µVÿºò RE$EHa8_r ìCçÄäí#Y×,»Ã|;sŒÝðHÈ¡$£!ž‚À`ÍLÚ~ò<¦[“^Æ]ûûŒÏ%ÃQùkdÍpÀµ@¯u‹x¿¤Û2º`¯výßiÊ•. ÚBrR´kþïjY×ëa¶mÃßz–†WÆË²´™pÉ_û eÐ\iôâž(i.'ºw40XikEYŒäKÅ@(ƒiÄnìb÷ä»K÷ 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’Oo!Åïû)8fX8úÏÚÚ¨ÙU½89D9X#ErÕqÕ¯_Ž“T{bïÇ›70‹ÕÕ­*8r"> $RFÔä”,⣸‡[évÇçýV"œäá5G9a6ÀÊ[—K†ö ÉÃiwÛ¾$§\»´h8½•F)|iT‹Fù3€rÈB7½iRHDWeè"⣢k»¸–LÐ/6óØöœeëÇ.̼_ä»ÓØ—?ú ß s!Øÿ°B™ Õv«Â¥aÞ¦a&¿LjO옡-hl†øÎR°Vƒ1qE¹hf›Õªh'Ôc÷ÖE=]|¶4-K×ÜåÂÀ2}¢f*S¦¸Y§¸è@3âíÏÞí×íló1Fc Жûþ‰=*Ät…eU;ü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.17) >> >> 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.20) >> >> 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.25) >> >> 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.31) >> >> 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 1688 /Filter /FlateDecode >> stream xÚXKsÛ6¾ûWhz 5cÑßÊÍIìgš¸ÕÇL’L¦©”ç×w» (‡n{H¸ûüvò›ÕÙŵÈfËp™Çùlõ0q¦³"ÎÃr™ÌVõìsðû¼Let#ç"èç t@˜ù"IÒ Ë,G2 nÚy\½2­l,m}°W{ÙÌ¿®Þ_\'ÑHU\&ažf³ˆÔ$ 9Š¢àíí»+º}ýó-Jüã/Ÿ]­Îþ>ÀÍÄ`fЍ˜UÛ³Ï_£Y GïgQ˜,ËÙÁ1ngI^„1PÍìîì׳7èo\ÎD&iÎË2L“‚,` ˜|¼üpEvŸ„(šuaQ¤ÿ#<§1q²NÕƒ°4…X³ê˜Uß|\}š'"¸}÷ÛÛÕÍíÇÿ6cµÑô4Šƒ/Q’6ŠèZÛjo-Z¥À*Ç‘zdñɶ¦£éÖFn·À¬Û5íÕª—ºaé!âèwß™p¾È3Üô¯˜­ß(ºŒÖÛ/ƒ'h»á2ËÈv£”Qm¥(ïNµzDø¨¬év󭌥Èb´[ô«ö¼÷ûõÚÙŒKðã¾Q[z}•¥ uwŠAN:¢œ¹(¼J¯èL; s´\ ‘qg”UGÙë®e‰=}7îJ¿{}qq8Âǹ3]“ N»&ìÌ:ü7P”ÇÊÇÊÈsWIÄ•eáÂéo'YXä¹ÇçòÄ£" ®›ÁuxUPAiâQ…iLÊ`+! Ž‚„fús u÷@ßg‘íJò{Ê. HoÓ°LníY`ç‰h£dMèvWR¾{ ºj·£ mÓJYû%Ê"ø'¦€ö°o+LÖë T\k€é9È7½Yʵdia‚•à‰³0ûø®UÝvK%‹F·¼-#ç ”LÁ§Á×ÌCÍ¡¥k4¬àN.Nœâ£Ó MOr´­yШoºr à}²®EÀê û Q×Àå9j"vÒX²Hd#Î7Úv-Öù2öÍ™]äË ÞWÊzAS¡—÷¶7²Âú(ÊÀ>qé|Ãõ2è«Éá•E—w+—A·ŽÿPjá¿Tº@ÔÊêu aH–QpØè olè ÍÅïa#ûÓGmõ}Ã"ô¤éÜ’ d3“ä ì ¹¢ž]†;w&^1æ§ÒË#$œP¤¶ò/ \JúX¸è·\L໓ÖÒ^¢<¤ÔQ"— åխΉ×u„Ó±ï>«QèqKý•#ZœÊÝb2fz«¿ÝX÷§n³ßoUã_ º}ÖˆÇH»‚ ¨%ŠA}Nlã<ÃùA7 QXbÜ“©Ø²ؾó×µF(Éæ‡t¡ÿÞs»†ÿ( SÉ»Æäq_±çtóqžA- Y8®Z¶¦7‘Çž×gÔØËÂl¶½?*=LGJ‰S2FöªžLíËNci v®m+ãF> œç+œleËW'ùJá1Kf$³èv:|·|w]‚»vÐIW7Zi4®?N —ZIˆ5ãf—D9€´Â’Ø»g¿§p¿AÄ÷‰Sˆ6B9š BâÅ " eÒ:sù@·|êæ¸¬àJO‘èI”èN®å EGrÆÉ¬¹p(¹`ל\´ô¨~ ?ŸFøŒ—™«Ñx™S(qƒÂD´ŸòÖÎîënïÙ÷ªE¤@@ãàJú’E®­ zÅŠ |²¡|\”Q°s qŠONBŸvx­•ë"øé®Bäñèþ‰6 Š}ð¯bòK¡ïÐ}[ù'­Ož¨—B„³Î äçGµ7wc`êièµoÇá˜J!w?I¸~]ƒL}óNÝ3ß òï`ß,àh q*"(Fô/_:ÿ@Ì(ê^®3+fðe(¡æ‰˜:ò-lÎ e……ð4å·g‘yK´ƒã øôhxë$ Â7ÑgL®ÓHs÷Œ—~D¯ІÛch…ôx¼¤“ÓˆˆÔGDÐ EdªìÜ`ך8+ØI¤ÐÉ¡/¸IŸ±c¸vÆ"q4WG½Uç˜nxxÜèŽ6Ü| ;%¾ðâÇS c!–Ôë¦^oþÉn)6®×Ž­HhB‰txVÊ 8‘•é¬õAåèŽëÀm ÃÆµ>|ªé=ã&¡Ÿ]æ‘^,o¢¼PÈ)J”Z¤q˜‹Òÿìæ¿0ü–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 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 2818 /Filter /FlateDecode >> stream xÚ•ÉrÛÈõ®¯`ùfÌV57Û±\ž83IYãfæ-e@°X¶¿>ok  ’çBôòºûí_ß^]ßøÑ&SYÄ›Ûû*Ü$A¬ÒÌln‹ÍïÞ§mj<Û•U¾õ½a»ó½ÝvgLè•F1÷¾Þ©7خΫž—þ•ÃZâyµýóöçë£gO©Qqm4?càf­µ÷æ×¼åÓ7~Åÿû_½½½úß•ÐzãOhåëd³?]ýþ§Þ°õóF+“¥›ÐfêU|QÓòîXwMU·¿l£ÈË»2¿£‡ÒÌ«Ê{ Ä˳9°é[_º§*f@óyl×°äšxÔYbLÕ²>ÇŸo=ƒôHK[1å0JŠBÀýª9”{¦Þ$ayÒ—§¶*ÁáÞIÁÿБnÇþ7ñBI úŸ´è.‘jÏ{€õ•£4-óýg "È`Øp 3†Äƒ½HÊ‚|à ó^Û~`ð=ÞÑ; ‡cÙ;‰öc5ôNj|&çiD8É¿° ¤8ø‚çKq?Gðþ‘Ïó~M0yU±Ý-䀨‰5÷°÷dÙÌe U¸A>”¬æ>Èvî»æÄ£‹ì4îXA†!B8<¤nø;©d¿ÁsH ˜E?TßpÿÀH‚TÜó"‹lƒu¦†^ßð%à ö¬Î…œ9åH­\Ï„ÈNÌ'Ë+øÙˆA„‚­åœh˶Zµí²žÐfNìÏNF{Í=~}çO@ò“ŒfNIyïÞ©ÜEUùݲÖá¬8lݨý ³!üîÊÚÊ‹eaÉRÐ$´T>ëÔ Î­Ð`¿¶`§pAè#ßð`×ÈU¿oðÞ+J`x¥p‡ïº¼vÌààEÁqÿXŠRº“èp£et÷Mw’»àÖr·@7Çäü=¨ßhr¾”Uüz›HI#ñ,º!¸•/èÊÁŠý°aðæ'<ôOæž]܃’ ±X`ôL¦Òqø§Å’È{Så}O/Àä·žŒÐ˜$”7aáÓ6¤‡¦ã¥Ð€²òkÁ,T^xÁWýðKÃé"¦¡Êt ÌT&¨ÝÒ“Yä½úxËôpøí,³§B˜Â"Eøî»,ö0€¯C¡V¼u'nj¿G¬Ð˜D%€”~Ž«XOp`I±Ñ@…Ã:¿ë‡.ߤ  b!% ígÀá&äpi¡¡dä ^Ø;Iáä¾éx q£SQ~) ÌŸ¼9µìë³Æ ŒkÎ÷¨ƒZ£<ÜÂtFù;[Ûæcêc­ÂÔw°^9“k0g ²%¹wÛÎøàøœ³A$?c$ÅõÐ#5ƒï¡kƶgXrf°&Ä%B\Â1Æ7Dœ}‚*¨( .äys›SØú¼FZ¤ÒÄ,HÃÇ'OÆO¢aÑÆ)Lÿ™\%3ÅÖÄ“øE6†v=v2’h{¸¯S¥³x†ø `°¦ˆ0 &E¼./ËxíÙ]·ù*íw‰ ¥LI)Ñ]‰RžóŸ] eÀðç&ý6¼"•PùÉØ m&-c#÷$^ºrB–‰Ìc;Ÿƒäš±ããSVEg9¥;ÝC Lœ«Ä ®`h•ú‹šÖo×.Ðpe>¬ñag€oY”-ãLÓ†O\šÄ“}žìp” ÐSÒ˜º¢ HãÅ.¯äl]˜b¤É䣈zØ¡ôAùÓ3Ÿíž³d^aýGµKYy:9T ˆèÒ": 95 !~:]¿Û5d+Š#õ ÆMö/Š¾æ§–SZ—âè QiFA4S³÷÷klÍ”>Ûûœª,$Ï‚.àñí!¸8=ù•rífß(“N¼LŽÑv^®iD•f’ÆÉÞ}¿ª‘ ³É> o«ÖCš CóœÆâU“ÂbîeÞAÌžgtBHõÄ se4HA‰îC€‚9È.¶^ ¾àñ2`ŠEøÍjM¬;ˆ¥!8©e&Y?Z£Ë„ä—žc‘¯RŸYÞ¿·—ÑA©”u oœ-g ²ÕÛÕ·Wj%ôD3I~cÚ¯e?Hö„UI.9Å;UîÝC¡Vðlì©·Á÷pJ¸’0$)T “ÝÜåûÏëy<äË%õp‚Y»(^mRBH·Óe~Aek‰2k ÌÞ¯÷á å½åJ•ÒÉ6.•že)ÁÎE®£Ÿ.t¨âlžÃØ¡a¬PE*:GB^Ê/Ÿæd²#9¦VAl."jgíK)îI×"Éo,k'KVEß"é —& =·$z¡*ÖEÞ<[4zNÞê­À“RÂEß04#/R¶«Dåüz¤rE½›ûE¹y[©j/ýÐkÄsŽÆ5Angr‚ú…ä\JÐ.ƒ¿žéïŒ\ srăyÓc5M”Öé9k(l»ž[dçË#9‡ q%c g/j¨õDÇO”…?”NϲûýØuâp\ßAŒdòܪwG)òZ€Ø¥€]ŠÁ8£\kÂà˜‚Ë›~¨öL൮ÖÅM'‹Ø§\#¥ª°{çzl0æ _ʾ¤>NöØ -碷çet£¨ºLŠY„÷*ÿÉL?Ñeø¨\xC 9W®ÔÙ¨žÜµ¬¯%-çÂXÇJGñ2Ýg[IüÇ”ê Ší@?²„öçöÏ–ãš–¸0µhF°/WÓÂ@eçêJ„†4ï0¡[qc‰Š‚YÃ#ŠR®ñ¸¶…·Ús i¨Šý‹†vó í;pøñRmoy•ˆ‰1°0ÉW±AÈäÀ4^TÖʱÚÇÊIÙ‚©îm¾néðd³æš¤@¡áEO ^5‹IËgfñɼëòöøc6ñ óœˆ=ÚxÁpêx2\{Ë‹z‡ÖòêÐtP(¨ó„ÒùÔ‘ËÍâ§#\dTM!îiô!ÇšU»e/˜uÜX/ ëZ%dÚ\4U¶’s›/Á ŒK ¢†D‘´9wqyïd›½d@U”År–š¼Ú5yõŒ 2çþcõ㪠”S^—íXQ÷*µŸª‡Žù9IýðÛŒC;SÝsâ³ ¦ÌëpÑVÇpN¥Þu[TÓöø©ü¾Æp Sa[4ÃTdr?íç°Go]äÄÇahÿ~}ýð𠈦/åwÅÞïp½VÚêtŽÂÔ ºŒL¾ÒçäO4H­éP¤¡Vž¼ËL.R©ò§éèL9çæ>îs‡R:V¤Ò’:ú[B€2€0à&ÿ$ËÿÅÿðf÷A 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 2490 /Filter /FlateDecode >> stream xÚ½Y[ܶ~ß_1Ø'mà‘EQ¥-b;ÞÖA£ðÂ}H‚B;âÌÑH]<6úçsnÔeVÛ4@чÅP‡‡‡‡çör_?ܼ¼Wñ&ó³$L6û C?Ú˜0ñÓLoŠÍÞÇ»T{¶-«üNyýÝVy Ú»­Ö‘§ý4Np¨½wõ]˜z½më¼ê˜ô}4ã yu÷óÃw/ïu0Û*LµŸDñ&àm4H‚À{óþÛ·¼úþïïQâ??àâ›·7¿Þ(à6jTSû*0›ÝéæÇŸƒMSßm_géæBŒ§NŒ¨Ú|¸ùÇÍk<¯Ÿœ7IS?ÒFΫÿÚæçãGÛÒaígÖ}a¦0ò³ ÙlUìÇZñº‡c Çuæñ/Øâh™ð˜w2Ú‘;,Lû¦å©OxXØ´ÜY'§f–œ?¨–·”F§DKæcŽëYSòZ~»®‘ñveÞÛB\1·‚R_ÅÚ¹bŸ×ÍЯ[+_›Ñc/V$ã2?S0ò³8aÎ]SÁ)WÌCcœ¼¼^ÓMe~j2ÇÓæõ/k‚?SɤØVgƻˆß>ÁZ'2Ðüˆ½G0 g†¬Bd´8Ròêдe£øSÈþ5逬+J’ ¯×ÔºQpùƒýÜ{ð>Èóo©V (I—GOs° uxî—m FCQló+, вµ»žÜ_ä[YÆÉH™z¡ ±5Ïœó’‚*ÖdϤ9˜úl|q„±æd®˜1§S@Óç4 ý ËíÅ–‡ã*~Æ~`ÔïHþ„L¸—UME<…]CÇ ô³pDîÝÐS¡^Ù:ñ“`äC“ĈO$±ˆ[:®ßk¨c³fþ/¨¥£=[:ãN®<…¼Á+䢂%j­·‰ • Gí±?‹©Éïö4И:ž¾Y“<ÁTÒ[Ûm=Ö\.Ê·¨Ã­œ—‚ ·}s댃H‡9àbž ¹COtt_2ÔJèb´X%À ð j«E©gŠ ¶z‚ÚJÀTÍP{ÿEf޲¨ÊÅ­µŠ¥adɵÈAŒ6£'± ‡®®ùª® ¾FëXÍ0:Kž€Ì FãðêDqà0ÚxŽ0b4ò?‡Ñ1u]aô35Q~ ÆlP™üޝ”Y¦‡ƒjP=âtú§¡¶î7v^þZ'?Vuèᠶ͵~Uþ D€Ìî—œŽ† à`tÙá!4ã ±ôãà²Tè%D*æ¹+1ùšR0êÔí>6MµvT>Zâ1Ð×o;—Õ…+öMU5—g< Q ã§Ž…^1]Ü:°wÜ!á` Kܘ"¡€,*,/GP "‰ˆ›L)Ei5a§ëÐYŸ…þÝQ¸ Élß–Gå^(”ÐQ⼇4ÖGÇ\²€‘.@vh-`këäô‚ ¦–Å\p°–ׄGܰ 5Tµ¦~±ŽÒi:ú»îµâ¾žî`Ø*uÃù\•VŠly]ŠwMÝ=vÐÞrCÅ™ÈÖZP%A‚ ù{—ZñW˜AòGWY†8IA ?ÖµÝyͧFûá¨®ä© kr̓Ø·P<ÍÜXñ+ebïRI+ä§ÛX|i—Lh èR,÷*Õcx2­âäü§O%¾³a£‚Ô\)Í!ŒåÙU!|å*,.lWد@%t¤ý\Ò9gjWÖ‡Jô‚„!›!(ˆb´|Åoà-^ŠØ}x¨d~(pØP.OM'øÓ•=óLWC¸_d¿ïqièîïaâaŒ¶´QV,² ºÍ§ŽÛL/”À!>ÂP’Ê%"Ü;ž)ë²/©—ú£8 ñ/Èæ¸d•D¹ÛÎö}eÝóÝ-/G%VLu’͇ʢÈ0 F?†Iº°>&!ÍU.¼ê'†Šµ4™WT4ù¢Ð1­ëá°sìãʃ‹‡ýÜòVNHÅÓ)ôHKTLW¢ÒÝa韅ƒ Rit˜]¹ží–9Ÿ¤³WcqHºtþöpÑëøãrÌ{–×_ºØqT?ÆË7{Îc€|û"í½Û?ssäž—b¬lRqP"û=ÂÞˬDKì‚—ž¡ [¼òLg¤Zq8mæE\3y'¯½ˆßðçVÓYi®!ÎæÝÈÓpf£2zv7øìÞÉÓVK=pú ÔqÍ4u1 ãÔLaüDீ†Í RšÕUã1×Ìuèîâß|5ž ö^í ø£PK[ZrŽ!#u/0:@£×ã£^mkM1„<£ŸqfÂŠÍ íÑ8h*Oh<¾By¬É"•®¯UÎþÙAw¨qô¤+៻§…ªãxO£ž ~¹Ão®Øއì>¸ÚÚ†ØE¢Ç‚cåò²^Íå{ÌLj³Mâ}øÒAX½á1AA×nSܪÄËõé] ©û½UOÈÃƒÉ ²àEÁ”²æß|eçoþõýÛ‡¿½ÿöÅjìÛð£ÿ·‘r"þrIK — ªPCPÏw…•'Wœíù—"±ª‚?›Ú1Œo-øñö»rª(Q‹¼ëL™ãs)¸‚€ ‰£F”¹ÿnýÆž%­ 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 2107 /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¨0ORlªà¡YÊú¨{Ðx×/8bhälÜò{ÔLvGBŠÊè .Á´Ê£=4p¯;´½¡ÅÔg®D~TÓ£zâˆZãÈ Ín áÔé?Û#C¾ ‰"d¾q¨âTbhÂq T”9BL9"M¯9H¨Áë5HPI˜¥,á¡)M³Trì-•%Aï–J/Y/à‚p?ÐIÌd8FE9ÜË øRÑ€n·þ ôÆp ¢Cq°iLlê¼Á`èþ»ïhMßžº‚Ð/T@Üó1Ïá=µž ^#®+¿9fjñsÞúŒ…¿9½e¶F0¡¿röc[ê†b\ÕÒפî…Ö¶pköûùÚÔŸjE‹íp}àd–=f•#6ÂÎzëÖÆ•aAý¡=U% /p¿O7N{ÂÁ ´ZïmA̓Ñå ²kY±¦?u&ØNwåõ¥´WÒÂ!mó†‘&§é,eS@ ¤ÄŒÑrw·\%2 Vß®¨Q·¥yCMðú÷Ô*V; Øé«Þ yÁ7E±Âõßœe¼†çjîØ§-™Ë 7Ž[¯@‰ƒ®å/Ú þHÏ\%”f§O•ë0c†” a\uìL©=)cOÓçþž„å,LL)x‰"AiÆ” ~àÅwu×S¹pßRûù`Gއn{Æz×ÙÒðâj•·Á^<[Çû~zü7Ÿíoâ&M¥ü i›Ò*äο\ûªêv†‰ÍYgÉ·ˆ;æ3ÜYû‚7l=V§J¬æmùü^tm?ÇÚXÉWI/öµ ÇœAßõ€¡³§ppËZbûÔ¬`DÓÈ/éõàCq·sð]<8—¾KÂ4N†eH’(8nuQ×ñ=ˆ ÀZDÛúÒÒÞFPËœãö÷¾Žèh‹é£§œ‰zušB *}T÷mÓ»°€êéµú© …£údh”Ì_(,кPïù«áÌÔô4äFê¹Ô#Rƒì/¶·S™Ï.™ªø0êí¢~ßšÙ” ‘ƒ1öÀÖ”"ƒ¶ÑC´Jž¡¦Bn%@L2}lþõî݇_†¬ÀœÃåÆÓ˜DØ=â$Ù[Rq!Fí)ÓI6" Ã{£éñ™FHõaÖk©7Š*Îé”WÑöYó*n>?‰Ûí?µ³”Ga.F„ò;éJÔ½"‰ºJ² ³ÜîçP‰GÉ1[–ðØ- b-½óbŸýùþòÝØ¦Æ8 zÛÚþÏ“t9'÷ä;IüŽÅ:ÎòÏô,(ÃÁ)>ÄXÃùgLj€q´=! 08&‡#P‘Œá-óÄÅß(aÃØgÂÿ£ð*üðÙŒ|çõ#4f«Fñq)øÓ§½/›¯x®Â4MϹe&õcVE$/뉯þºðêy¿\ÇÁŠ_ùÈÿó7„—úÉgvlOde4“QãA ª0‰Gs  Ü£Çw|Ýz2hÊ:V¤3øTh®¦} Æ'± ¥J ¾H]rÕªã‹ß8âºZ ÿ‡¥rî÷æ¨Gf‚¾G·Þ„Ð8RUá·î!¢Ü¡¦î®këéZoÁ®Ohà c¡“Z»ÖñôÀŒ³¥Vå¨~”ÿ±ðÜæ×¶Å]JÿG–ÌT+ãòÌgü¿Gy*øÙ ùÙ ‡gƒÄìÖæèX–RW©W®Gv98w|swgšð™•ʼRa‹ôßíïpÌpGPñƒŸ<ss9[䘙’‹ ÎOr@p摜î%ɲ 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 2945 /Filter /FlateDecode >> stream xÚµYÛÆù}…>˜ VcÎ Ï<pœu±A¼n³Š" ®4Z±¦H…¤¼õ¿ïwÌðgèÓŒæúî“ú~}ñúŒ¹È•,Ö»…TJD‹T%"Ëõb½]ü|\f:0mYKôË• ˜´Ë•ÖQ E'8ÕÁu½TYЛ¶.ªŽ—Þ°–§¢Zþ¾þñõ;N@)-E¦³EÈ`"x9 Ãà퇮oþÆ÷ß~¸ùxu³¾þps‹\\­/þ¸p#\ÈU-d˜.6‡‹_[Øúq g‹:xXè$ fÕâöâß?Bs’e"Ò)#ó HuP7½Ùò´¸[®€– úŒ”šKØÈTPTŸø\veß´öjÑžlw|Á¾´©Š®3öX³³¬QSÖ¨Pä2u¬yÓõ7öq>È´<+s0¬ËU”ƒíçù$*ÕîZ±Ù˜cïy]'B%ÃëÓïJlA±ƒ‡}¹Aùì-¬â‘ÞñÏ‚FX{š#UðКiM½1Ì™„"ÕrÎ F!ˆ·æ±¬»¾À+ô #€ðÐú•&É”…Q¦dP>¹&RÄ:rçg‚DP$H‡‹]+ŽÇª4v9MÈ|FŠÍ·&œ³xïÆ;_c¾’1XÔœþ~ÜC‘ ¨#ËК !œ”õ`Dͧ²¾çUR*Fj8çx‹¿~ ã°Fø´3 A1F€û²ó 57*xN k±¡Aƒ/É¥äý5ÀU±Žl÷r±+ï*`£ÝÙ–¿…:ÙœªIù‹šÆ~_ô8Ce … 9 Új|4$<”ÏÛ¸ÜÑÅô‘¸gÚ]Ó,èšw̶ìyÆ&’¡‰ ¦ëÛ†Þðv꟧"ÍÏÄ^O$e¾Šck6ƪgÇ+…±¥AÎ)Êò`íU2 BÈÓ9ù·§;²Ö˜ŸMjë+ Ã'Z©2˜§ÏÀXx}Z”‰$Ο÷i }¡ˆódΉ’TÁ‘Ù÷¹Ü’‹…ÒwÑ¿xàæR„:~^БH_G&޶Ä ˆ Š;PB¶¤HŽBÂEaÉØ[åîìvÓ–÷%í³ËV T,2ÀëkÚõL{PÀÄg©;ký;N ¢úï‚Ymùˆ»òPRƒÙ¿O]ȇsƒ?™ õHÀhááÜ´×|1 îØ`öK°iy¹Ùñhä.²óê¾áGiÇ‚ª4c°…{wÖ8éQ‚áHm«¦ØZ×—?âvU–ˆtô„„Ï­å"–ƒ:íNõ¦/›šîØ;ƒ KòL…™¾D±#Óû8(~ $aô‚ð~8̽1 áXÖ ŽÖ×;^-xè¬ûÚ 2ц1h I¸¢Ç"w;Y©`²kN5&:ÉGG~LEùœôîK×t’Yfõ gèÛY{šO¼RÖ<²Öá YJ'Pô¸(M$’®L“žeÑñƉ"öèÓ ÿ(ë=pɆ9<:Ô­õѤ>~j<¥áî°V‚‡ÿOpù†T.oùáK|O’òv{3ÂLOUâzçWÎhLzF‹®F6ÛŒ€S„Á¸ÍßùS‘D„yŽNYd©-Q>7%0?V±5š¢b´€ÛßâZD¾üŒ9^òÔä_:Ó~koŸŽè4|Ì~ Ä}õzgß©›ÿˆÛþÐÿo@’—ùS΃¥ Egsù€Ãm­jnÒï!ª³¬PÏ —„Pp(ú»rDÏaã‹uÛ”uÑ]c¬ÖLµ\aÇÖ#•éb]o0Ç®¯lnKðjˆ­=·Œ ¤,î*ƒI pd½/í 7Þ£Ÿ¯Á˜«ê ¯°ë€ CÎ|s,Zëݾ±/Ô˜Á+‡vª²3ÇÍ>†(G^èÁþ¢ÌF.‚Êj {óåP 5æÿ:4Û£ß äÑpŒ$gä®Fs88,¬óAfÊ<¸î_åt::ÓÏq»ùå§ŸxV:¬‡ŒS§B&jNëØ·§ È»Ž!…µÚÛ$gÓÄT³F{?’¯õ¾Ùž*_(Ã’'ÏgÁ·iIé ÐÕñ¬ì/2¬†±KâÀf$^Aýgb³ÂÒY^Õƒºô†"X–¸Ó6KáǦ2ðʹÊàíø|'´àzkl‡N>ç­Bàƒz)²1ô[ž"ŒÃÍ-ôo¨1*ãJ+ˆ$*~¤ˆÀJ5†PXuÆ 2 œu()XFPÎ (\'ýižQ{ýøÀ†Šs˜X«å5$œT<ÓCæ`£¦a&6Šz¼³—dë ßyËa )BŠbZæ™÷Ñ !õü›RÀ Ój–ŸdݹLoÕÆl­‘5ÂÒÀ!’`1樫å„ýýªuÓÎ6,\¾Ž P}Rïd°êä9²0óˆÏÌîÒæù(ㇲ3.å)mÍ3-ªf .4¶[9Í?:sÖ•8ƒ“··^Ù¢T!ÙvA”ŠHa] X+«ÊŒ‘ð v™ú¾-ïN=¥»‘–Á•­¼þÒ¤ôí5¹þ´…aœÊ§‡(¾Ù37MïZ&çê“%ƒ{£Š±~s»ÆÉ¤Š9#ûCÉY6êù´ž{EÜÙcÙ;˜Âsnl½]ªDž5NÌ,l–̺D°ñ¬Mû‡%6é@/)’ªQmé2d±œàarƒÇÒ¶¥ï¬“ ½µ»T’‰dlL#–YýHÆ2Ñ£+…´¦9Ýû„ €«RcŒ?Ð [ôØJAQ6„q³ãŸlÄp¨©í„Z„0r:Ίã7¼uêìY×Ùp?Zp*±/ŽÏ\ÛwßQ¢ùË[Äi µÀ’‘:¤$Ø>ri{ >Y¦¿êiPZÉähê»Ú…CÑ~â÷…÷ÉÓ¥àéÈÛÇše@†Î?”X³Ó Nòå[ª ‰éÀ?Š 2øÙô-jgyR ê{ 12¬„ª²•e’ŽÀ¸)ºž÷Šã±mŽ„ô¦¢N¾AYÐðþúpzEÜlÀpjžN’?3Ír‘déy^ùkâ?ÅšÁQøÞ›;¼ÇÞôÙqûáýÕúŸHÒ߯ž`{ª… ³É×¼(’`Úü©J;³Õ žæÈ+Ô­„Ѹü‚¶ÇJX¹¢Mü–q–m?rå™ÏÌ|ñxø4³·9ÕiyK±Ç’ò9åš%y]Âö£í¸OX”›5daû¿³ŸÊtâQäm†yHy&2¬KD*†ÿú575n>üpųÛõ›õ•¯{⎾匘º/‘ÁÔ31”W¥ßÂñ¾ŒÓx¬¸ÀbØÃKclZ©Dè€Ý5M%xºnO²DzÇëÖö%yUîu¸›ã¯êVöc3bhÓPïÜ{çì›^Ãû9KabëV¼zCE4s÷¦'nP¨ Z_äñ#(¿ÇOˆ/ôTùFaúTB@]–å/)o!™“Ao_uÞÄ É=yÛ3Ya®føSa{XÑðQ´¬·å¼£ýe¿špùòÊõÊî›±Îî±Üù‹ípa“”Ñ•6-HÜ'þ ÌI® 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 2348 /Filter /FlateDecode >> stream xÚ•YMsã6½ûW¨²‡P[#„H‚ÜÛÌì8åTÖ³[ãš=$9À"da‡"’²Çÿ~»ÑII°­l€øhׯ»¡wW?]'Ù¢deÎóÅÝf‘pÎÒ…ä9+J±¸«¿E_—…ˆtgjµL¢a¹J¢*Ýr%D Vd9VEtÓ,y ºkTÝSÓ¿´Éè êåw¿üt-âÙR\$¬Å"¦eRÇqôñó?on¦ù?ß~ýt{wóùö ¸útwõçU3âE2nU°$–‹õîê·?âE]¿,b&Êbñdî"—ŒC­^|¹úÏÕ‡ó3§’‰8_äEÁR!i;w[Ýëå*å"Z·»¦ÃõÔ¢:ÛÅ#³Û/WÐÑvƒ¢4`h©Ü©oØêõ‡ÎÕ”ÓŸë#IYœú8ôºûÛïqÃ_BÃvƬHr?ºm¼`[<À ™GÔ=lü|©ìhîû~¸m+Xc%âŒååb•$¬Ì2>à‰žéÜšîÉô„†F?ÚãvÔ|OcLó@ßp¤Šj›ÖáÇ {Â-õTæ÷XÝi¯Nµ?t¸žŒÚñ§át=ÃýÂVIÆ wi·í€;J²hتjkUר ØÄ¹"dÎ䱯?ÖZuw¸J§C*"Mý{pXd£úáV‹È¸u«–Nß7?º{LUó;ô[……Üܾ¥&3üè·~tk ‡¸óôøFìI¯Êtõ3ÕÛÍ xH³èzY¤‘×¹þ®vû•øŽÜr‚ Þ6^Êõ7†ÃRªžiöŽZ¬HæöÉ™ä”%(8¥m ØLþo«‡Ní4,Ìó–j¨rïq…{Õ[ÈÌ:&Àhí¦XMbåÑôfh½Hãº×uÛ»h–G3~hÚn§êèkshÖƒi­Å,Æœ(Ú‚»àV–¶MSnØÚ’&ž·L€J,L ß—t÷Péõºmª0ÀY<áìñ°`”›–㘽W)‰n7n­#s=_©àHás.@;PÁ¸˜µ/{Ó‚m‰DÚƒJ0†P°…|XÉ2ÚLÈ×±¡’Ôw‘ôáo¥GuÂô¯â¿¦¶$ËZà±§ÏT .Êèþà¤Wî;ò] b©jdÙÎw-r´Èóh§û!žKÏ¢/íNW‘Ð[ ÑÀ~Í[½swóa“BO§wsµ½Ã>iwŒC …Xík;îÉ­@fíû®}pí?§ýW4£qîÀy­:Òë¬)jhsJꞟ¶à7Øä/ VUÜ:3j n~%€“dIË߀½(Ëç–£ÿ¶o¹Itżí°#e™JÛp!%§ ×}#Þ±4ãâö“‚ !µ6µÔ éÛû ëGQÐì2:7uëÆ¢3«—‰Œ>)º`š3¸H¤'«u[>wì“/æÀÑù­YaÎBß…¨ dbðè©+ °Œñ±ßɵ Þ¦+¸¼"sºúj·b=v`©*ýx²N´çL²$ña¬8Rîû¦ºµÉÈ÷áÆF9Ÿ*3\¦é÷“Vå 'Î8+¥¼D«Rˆ´*VÁ7zWÈ€b8¡¸Lµù8Î4$XQQŒ´Áaè‚Ò,‡t¢iôzÐn;÷`„\FÁÄ$½îƒéh’³$=q[*@— qTà½Z IäAçcðëryã2z4ž 0¤½—ÇéÍ9.þ"<ÙÑÈô4€¿ ¢Á: ßqú+€È Øay ²<™+*lÆÝ[gé|Î͆œˆиécç£+K¾Úíø©ü™&:Í ÎA‡§ÎcJ)S>u˜1KÅ L˜ÙQd",†@ „›O(ŸzP¦q‚„3S»×ÓÔL7öEÄ?$øÞÁ¹{ƒªyÐAˆ&YÆbž1ú«»›`Oª«ú7š—§P•éKPMÀµ&—h%‰ÃîeÛØÊ×qÊùe8ÓÕ[œJ’cÄeÝ?ä.ƒêbcÇ“ÁìÌ“ƪ~p»kÂ*ç@c¼Lƒ*ÿ¸Å{†X¡ó/r—ðÂók^c;1¢õ"ú‘9˦ÀçÜ ûGž1u@`RÝÔ!š-A`6ÞB»OöáÃq‘OO]{x]©,Ÿž"Ú}ú¶0ãv<º° ‡°)]øüN.5…ãËy™²Óœ‰‰Fÿ‚Ý%±d™(_fñ†øpº#l}õŽ2ûBþÆ 8›¸èŽø”ܽtGGÂ(ˆÇ«¬,O^Šæ÷rº^¸l½ã<öq¥©Ü#5ìæ$Òì]î¶Æ×ìt|íÏ¿4ð}º=-ñ´œÞßíïÖWhå»iИ{‘åÄNâ$7½ÆgJ b*óÝæ·øB‡/ĶYQ1¥"ð±3÷>Ÿä“ z ·å™â |øÀ´p™ Ç6ý…]$§•EÈ&zZÓ©€/Ê!ºKg*† ä-Ùáhr%2¤‘íÄŸušâo[â$’ 'IL°PË.ÉDfàÖjwg̼ñI ƒX !m¯gyá?èÑÐÂ!oN`Eá¬FúßÎþlÊ# 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.806 null] >> endobj 99 0 obj << /D [95 0 R /XYZ 122.4 522.886 null] >> endobj 100 0 obj << /D [95 0 R /XYZ 122.4 139.097 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 >> /ProcSet [ /PDF /Text ] >> endobj 103 0 obj << /Length 2132 /Filter /FlateDecode >> stream xÚ•Xmsܶþ®_q©Æ‘øÖI=c§²«Lâ:Õ93™$£¡Hœ _.$(YÓéÏ.à‘•º_ޏÅÛâÙÝgx»;»xÅ›œå O6»ý&âœÉMÊ–åb³«6??žg"P½®‹ó(0çÛ(è ÑŸo…`Yœ`SWí9Ï£ú¶¨}_€, Æ¢>ÿu÷íÅ;ζaÂ’4Û„´M +‡aì.¯wWÞㄳËÝÙïgŒ7Ѥš`Q˜nÊæìç_ÃM]ßnB&òló`6‘¤ŒC«Þ\ŸýpöÏ(øüŒ‚ƒÖÙ&É2&EJÛßwº:߯<îõ  5 ãðÍ`>txêJ]íÿBò¶«Ôñµ±ÿÓ z×u?aVDç]@ Çc¶dX–:pÿÑ!hø£î+ÀrÎs( µe Œ¨œ@ß,Ôô×N& ÄtôŽvš*õþ‘$EUi£;°ý/ÝŠþê½ûº…ôà†u­Üîû®wÆœc*À,¡Þ˜Ê{Õ^íW`Ë÷ŽH ˜Ä€QÄò8þŽ'#T¤¹ð/Â¥ê¸E8©}ì-¼÷ºÒ퉊å£X²$št*‹Á\ÿóûËÝO¸çÇKô‚lš¦LD“ /,…Z!VvWU”¨ÈÄd–nôm­h@‹óR4„Ń ÀA,á0ö`Τà|"΃q°±¾ùê«•£‚9D‹S°zl‹F—7e'ÌʉÎÀ“u¶q; ®ˆe ´9 ‡b»WfìÛv/HæN¦=ýÁ\t·°pü[=KC2D}nAˆdÈ’8}‚‚ ‘Ê%$BK¡c[»aVuøvN^ÖÅ0¬9A$Yù““ý?^¾äÀ“§¿r«÷ô-èSÛÞÛ ®æ»zEžïžçLdòÿÞݺåBUŒŸ¾ûÎ…ÏS'ÈÄíÑGwãj$éü8ø?ö¤á¨†8ÿÚp:õC\uNY7óùo®wŒtáÙ‚FÈ„2eI$.Ìóô”Ö£eZrˆÐ"—¦’&¼CÖGoæyŽim+`6Ñ8åÇ{´ñà:öô=¸ëY<`‚C†T—Îr¯˜ËÖ\l%•ãÜ›^ÝõÊÍÃ…¹ÀE`cM!·Ýã Kƒ)Á‰œ!¥!©¶D.aj5ϰOcS‹msQî¡FÓÙsÙ…°Ò°TšÛr«¢Ö ¼œ.t(ƃ8Vl-Y_²7®ÉÜM«W¿ºWþ^e?eá‡Sÿ,„E_@Pú§§‹Õ0ÞöÝVUÓÚ´››Oƒo€Á ’L"ÖTË ›±Ýݸ+V”$PI?½]`vy…)8rWJŽQd¿9dÚºžÝ×+êõùG$"°eKüÔêÅ3cᩚÿSJãiò8¦ä"xÛ™íƒâöÃ{6÷ckË™ÁëÖ:àR Â| @w¤çŸ“o§ë•xæ5kÚv('0>6¥#^Óß:Õ5bñBqŠY|¤ 7 {A±* «5¹ô¬…­9ká¸vÁžè±2ES¥öm@âU{_Œµ›E¥µÜ’\ŒJEc§’¯»£N¨dí:1“´)Œ+”†Ób+´ˆL gËø’caX k%¼wç]Ñ2Â;ƒÖá³·¼g+Ø_)TB¨ÈÅNæÂÜ4.L Ök/K³)á?hËʰ¾úìMætqÊMþ€Ý R¨;ø“g «à¹‡ñ¹Â2a2‹žë‹ê²ûž-d>{·Røw ب´U)4NþŒRk¬¢½³îÌOÏ)Ð|!`¥`Q2Ábºãͨµï)ÍZäË„|…È^¹‡¯(cò)D®S-ŽC£,ê„Ë•`î|v`æ_Iÿ½þ’> 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 18 0 obj << /D [102 0 R /XYZ 122.4 498.141 null] >> endobj 105 0 obj << /D [102 0 R /XYZ 122.4 304.133 null] >> endobj 101 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F28 56 0 R /F11 92 0 R /F31 63 0 R >> /ProcSet [ /PDF /Text ] >> endobj 108 0 obj << /Length 1791 /Filter /FlateDecode >> stream xÚ•XmoÛ6þž_aý ±"‘zݰi’né’¶«îC[ŒDÛZõâŠT^0ì¿ïŽGÙR¦Ý'“Gòxw|_®ŽN^ùá,uÓˆE³Õzæ3泘En’òÙ*Ÿ}t>Ìîȶ(ÅÜwô|á; Úù‚óÀánF8äÎe=g‰£e[‹R‘èZ€,v:QÎ?¯^Ÿ¼âÞà*îEn'3® A³çyÎêb¹º|ó+8ºX}=òa‡7ó÷¦q×÷âYV}üìÍrXz=ó\ž&³{³±šñ(vŒÊÙò裗è#gC9«“Y”$nÀcº^7»›uQÊZ ‡•üä…Þ3}¢oªÇFoe«¥Ò..Ý=ƒ%ÿgrh;°ß @ïôûžOz_>B("îär-ºRÓD”% P«¢á}Ñ Û®îEzK£ ¬ Cç¯ÃŽ** vW Ý´VZ|™‰¶³sx·À¼[³9Iì;oÎŽû%8|¶´³ëf¾€y¾@Ÿ n ßwÓ0$ûe¹,*ôU€åŠ~ïQƒ4¤¨€Y¨=a=bh§,ÄÄ=IZ© *ö¸¶Ûn='ÌÉšj'Z™CðCðü·o¦ëïP‘léP±¦ßG\j:kf¡¶ýÕÎaø ©M]>¢|hL:%sÙ7áÎòáå )oEMcP@;K4X7&àKQo~²ù1‚éMŒ ~¾”åzñâﻣªÿ˜°£kÇÏqL»Ô—bg`üÁZ9ØÖÔ8AŸCš8ü?X¿Åh‡­-ê‘4©„¡ $€YbgÌ,`ÔÔŠÄz+4mÏLp@t5H•Ô½ê¶é6[Ú"ÚMWIbe×›‰ ±r;Ù“ ‚’ºp+]Ȥ~£¨ó©'HÝðÀPòAf–º80™·×ul †y ôꑞ¨ŠÝÐãcMôÙ‰=¤Ì'tƱEßoá |„#-r0ªTSVâ§ãÁˆJde¦6&I¨”ÇžËG­SR`D04"„½û Uâ‹DÜ{ôý1*(ŽÑÞA9«-¶,Hþ7/â.§Ù­…½Yé?6q"ìv‹˜“§1*k@Yiã_ºQÝÛµ ÜW©}Iúöû#üJ†ï­¾¿¬É¾}7\bâûÉö‘tÁT·d?€þ4,ÅR8‰Ig 'ÎL¶0¨¦˜„V„F‚ôà­ÊHÚ'›(iÿ»‹÷W´RY2êJCp´lzr\­¥´| êî·E†ÞoiSÿÕ7‘GD¼&&Â};¿oú³¨É_?ñ]ß·Sócާýß ÿr ”] 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 110 0 obj << /D [107 0 R /XYZ 122.4 313.463 null] >> endobj 106 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 113 0 obj << /Length 1937 /Filter /FlateDecode >> stream xÚ•XM“Û6¾ï¯ð­òÌšõ­í©i’m:Mfßd“NÛt:²EÛj$Q•¨uœÃûÛ  ?m›ž R$<‡~rµ|.ãY.ò$Hf÷›™ ÍÒ YÎîËÙoÞ»yzª¯êb.=3_HOƒÐÏay¡ÈâÅÐ{Ñ΃Ì3ªo‹z ©—Ì¥ÞXÔóßï\>ý³£‚,YÎ|:´Hß÷½§Ïž¼½½}ñê·\=»¿úëJÂ&Æ…BúélÝ\ýö»?+áÓ3_„y6ÛÛ…Í,LR€TÏÞ\ýïê zç^F¡e2KÀ„(LÉ€uÖ.â öªv0E]Óàm[}D§onîz½Vàû¼¹nø"•‹0AÂ*ïwªWEá„A7а3}Ñ1PFó*„ð1ÓUISûjIêǶ­Ú-Ô¶c*ݲ25¶+L.\y³Y™õ>þ„ (I0}¾¢ËƒpLYq_Õ 5 ŠaÞcv…!é€é‘»“{vaþÚ4Õ»COoèÛÃ`TsG; éø,„ ›Â¬QåN ;`úBJ‘Ç1»€Ÿ]µ†XµjChí­Yý‡#œš1>%»Ñ=MmzÝ´­Ì5í‡ çˆÇõhjûkZv±ULDgA˜/d.‚,üúèüLI‘¦ù¯ì»³£‡ÂËï^½xþìÍýõgóE’ ˆ5I«¢ß¤Yùت@Yô×F•|¨¶“%+«Ú“ö‰8L`jz¥Ä|E‘÷†lŠœö–Œî¾¸«A_ÑŽŽc`ëÍÁ­' 蓵/%û`¨G3T¥Ó·Sç6üKL¢¯É+mõ½‚õ½Ÿ*kâø‘†ƒÍǃ—5%ẦٕóäRmб†ZÄq—³rjø·Uª¤èøÞÆ¢ Çü‹ÎŒÁ±,Ùïý Þ©º›ªinéE8ug¸ê$œCC|MsE[²À—%aË@¸¬^±MGH^L‰8pîÁºuÁ­l@ ;ÅúÇó~"ñ°¢ß0çåß–êJv(ò4ùÇê§Ë›,ÿw6<ëG+¿SÇ•ÿå1;ƒ  DHm"àð˜8 tPÒïý0T=Oã䵋¾¤É® {>Õ­¢%Tüj6DÐO½×ŠwüP˜ås{ÿJÝËï5i=Láå ø2g°ñ†¹K™nKL×ÅF©\8(O”J‘ùÇkríÚZUóE|ªVUÑ.ß®F‹’—?Á-?Af™]%ÃÕúQCe&E}iéãÖ…¡ºã6L¼å?—é×®cyvÙHaÜ.C` >îŠK2­ôØ× !mH™9àÌYaÁ!ç"ëÇ$½©Öc]ôÐõ&¢ ØEµU”CGnËšÎÉ=äw-æzIj¡µõô¥ë¹0ýÊæ˜å{ë^›µf`¥¶;Ã/¸ÁÍcmª[âê}’Éu§eŸÜ–$D×~žL7s[¶“Ük”Ùqû¡*‡\?”šÛŸooMºúHñBÅfµ%_Û3o5¢÷†VÙÒ¿§ÛóeQǸè£ëòÂx..½úk¬\CSee޼ãT¢Ï T´:K]-•Y/µ¶Öõ•9,ëª©Ì ÖºÝL¤  #áGÙ©ÀS¼-¿d¾ÉñÔŽ”Å0JªhQ ²z` œrü\~ÎÏÁn å6Lv'øÆ"uü{K©VãvÂJ\ ¬= /¢Œ8ÎËøVfGÒI©krYl¼N0¨‚"B]_5EϽè@7§ŒÁq»rG݆s§«‹µë­\†ôEƒý¢ŽB·‚ ýçeÕs¹È68-3{Qj®gdÅ ƒ4qÂL„7¥±sã_‘}j7ÈÔù*½Æ娨‡ˆLè2ÉÔùis4³…×ÊŽWYÂs·8g9}õ‰m/º>:ŽLcgLw³\î÷{a•Á&¡qw¿]N¥± „<•òÒ¹ýnaQGn'"]‚odI‰L)ÛLÃT² Ÿ¢p…* %Æ, .I -vdY:Rs[ÇÞäÎ ¼ºj­ÔlÄ`J=ò"z ¡„ g"…V̺Ý£¼$Û³g¸ô¬>|:zKéÁéÇÄ+²<Þ>g‹¦ÃÇ›z”%—oF‹2¢Å=投4ýþY7§Wõ¨¿ê—ïŒîþØhmSö+_Ì¿`µµ—ÿÄþìÂyà9Øð¶¤1ÂïLO½]¯6Êýe‰L@ËF!Y,Bò‘Ó "ñ˜‰«¡ý†Ú*úûåž”Ž}·M¿*îO!ÝŒ5S!*mèÙ[^@×íØ ‘[JI*mGr¤¯<´E¦ÛÝDâC¥öD=`@¼å×Û×s)¥÷–ÐÃcêîú™ðeòÙÝýô`AädÃWW‰V™å§m'B{zÊ‹iê©K ü,Œó ºåJÚ%r/6„Ä©BZMµrœŸóü:0Fqš?]ã†W+ã€wÏIHRVö-MMàB¸$ˆ`U¸4ˆÜ­ ‹›L3lŸÀl ó="Òˆÿký Íy  endstream endobj 112 0 obj << /Type /Page /Contents 113 0 R /Resources 111 0 R /MediaBox [0 0 612 792] /Parent 93 0 R >> endobj 114 0 obj << /D [112 0 R /XYZ 121.4 736.262 null] >> endobj 22 0 obj << /D [112 0 R /XYZ 122.4 405.512 null] >> endobj 116 0 obj << /D [112 0 R /XYZ 122.4 333.315 null] >> endobj 117 0 obj << /D [112 0 R /XYZ 122.4 251.453 null] >> endobj 111 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F36 115 0 R /F34 72 0 R /F28 56 0 R /F31 63 0 R /F33 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 120 0 obj << /Length 1943 /Filter /FlateDecode >> stream xÚ•ksÛ6ò»…ÆýBÝX,ñàËÓtÎIœœ[7É%JnnÜL‹w©#éW;ùï·‹]PSéÝŒF\,ûÂîbçó£ï_‰x’‡y"“ÉüËDHêI*“0ËÕd^L®‚OÓL¶-+3A?‰  Î”Ò ³8APõTfAoÛÚT¡~1€Kƒ[SM?Ïúþ•жDÉ, 3¥&‰."Š¢àåùó¯__¼yKŽÎçGÿ9@MÄ œ E”N«£«ÏѤ€©Ÿ&Q¨òlrïW•¤¡¨š|8úûÑs´RÁræq,7f& V)ÉûÖZP;ƒæ¶_ßö¤òŽw¢ÉL$Íž™£ghU¿FJW¶£i[ܮ֌k¾Ð·_òÜÙ‡9ÀHo™ºØc²n›é œ[Ü.,Ï];„íÑç÷øgmM3ö}nÛG®ÌtÇÁ¿š–™V7Í mCkÈ%dM[öËU¹ ëzscÃéLkœÕ´×öÁ¬Ö•…Í?åí”ÛÛ™„BÇà ‰”ôæ|~yFÆ2¢‡<ú‚ásE„ùÁŠ úÃD_N³8”2ßULœÑ/o_~¼<˜ y-‘c¦²LÊgöc*Ž‚¾Y3t)‰ú ‰ß}>(ó/âT²ØOgï72Mš=‘™êï‘R~%ð¯Eÿ,z0Ò&:ú$ß+§,€UÑ9FÙoˆº/ Kk®Þ~&àïÏjÛš%ÞòÔ{äùÙ‡‹/çÈåŸïÏPïb)tîÕ³Ro©×/qaÙ¡zèçu7•uoolK´ÿ¾/ží ZSßàRûìJ‰ÓèóH¦Ìdæ"ápœ/øQ𥩪ÆEn‰œÕÝ®V¦-§Š|’DÁHO¡æÀß tÂûht̲st'Ú…ÈUÓúiÛ›²"¸©y½Y 7¦ÅäµU±“ì𲦔 07ì¢/N Òβ9¡g5*´þwìÈòxåÂôh$K–%d•mM»@3—Èë‘f°hxÒ§I'â4T‘ö5Cõé^ˆ,LtâiÊî[ !‹õ†¶YËõC‰{{¢µ«DMéË?±¿­ ŽKJA«Xz&œÛOe)ª¬âx¿,yó\þ*•„ÊÿNÛvÛòV¡;ÇUJ fc±1^Œ¯C©’ÃÆ£L6þ°¤4S8x¢Ý29’F"Ña.5”¨OS!Dpöþ˜Ä•ÝN„BÅîú7 ÌÂÎ1¢×¦£ñÉu-:ÄÍEk;ƺCÌÍzºšÏ¦qæl”Ø2 ,ʼé?Œ†©Î=Mõ ¡C• þûñ“A [¶²¦ŒsŒ©v% [”=4{^¨m_•Ϻ×ì;ª2~~Å>)±®, î̦bl8ðàLé0Kö÷Ü-XF²d§Œd)s‰Mxtk+ .˜º!dUÖ– )™¼¦ñàtÍm»`˜ZœÚ¬˜ÿ±9v™@FÚ–‰9Ö^ì…•rÌZäFÜ n­)N<þýxÏÏ2é—aÇÁÊöKÖ™/*ÐCoŸ©Z„±Èv¯*óižø+˜ þVR3¦$Dü=Ž7y®ˆÃ\o7¸©b?«Tº*Û’¯l7.¸`ìòxHc ¥Ëò u=ìRË«©Ò¥XAª¦f¤Û/XéKc½”eU0ÿ­R³Ërtϸ Í| î€ÏàºsF ”N"`åÎÇtÄ£u5o³ÚybÈC¹ié~Æ`Búp|vè+çÁÇγGo!Æ…ˆON¾Gô.è[B¿âk€“ âc«‰iÈÂ$Ù‹¼±vLEq˜ì]—Ô¤¶ R±ƒ:ÒÛ£LO_®p°ri„…–üVÑ ëåÙ‡ù ¡àô¨áöA9•nåÔÁ~>ƒÖ8º©Ú>ôßJ$`<´MrOYÎ\¤Nw½°níÝŸqÖâPÛܹ§†ˆŽ¨ k®T¦eDGßM=b|O_vW<8V“cñvÆì_a07ÌosÄ£þKO=¾lQF ï]!¡Æ|ÿ€r ¡DÞ?d¾@)b‘>€8è>úBäµYì¼J8K”Ðz¸÷ ½áN7üùÛw¿õþQDðû?ˆDûb½àç——oà‡ÎIZô€TâZ f©$K¾û†ô;Ϙdì­M(¦yŠájˆ`REøWÁÿ½&"L endstream endobj 119 0 obj << /Type /Page /Contents 120 0 R /Resources 118 0 R /MediaBox [0 0 612 792] /Parent 93 0 R >> endobj 121 0 obj << /D [119 0 R /XYZ 121.4 736.262 null] >> endobj 122 0 obj << /D [119 0 R /XYZ 122.4 679.68 null] >> endobj 118 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F31 63 0 R /F32 70 0 R /F11 92 0 R /F29 58 0 R /F33 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 125 0 obj << /Length 2336 /Filter /FlateDecode >> stream xÚ­YmoÜ6þî_±h>T d’zrÅ9±¸ç:m¼ pHC»âz‰ÓJ[IÛ)òßo†Cq%[ŽÝ¢A`‘Ôh83|æûz~ðâD„“”¥‘Œ&óÕDHÉ‚I,#–¤þdžO>y§‰ï©ZÙTxít&¼ õtæûç³$Œpè{§åT&^«ê2+Zú%ƒµØÛeÅôóüç'>ïm%“„%¾?á´ pœsïèøõ‡·oOÏßâ'Çóƒ?Ðð‰pÂùLðx²Ü|úÌ'9¼úy™Ÿ&“kC¸™øQÌ$ŒŠÉÅÁo¯QK_öµŒ&¥?‰@„ÀIñR¼œÎBzoŽÏÎNÏá?*{ŒkÇop’ÊÅRä ‘½R>0xöÍþT2øFÃkŽº„Üûryyôn~y©/ñãV5íå•*‰hf¿s« .ˆ<‚¥aH"1ÆÆ–;9ywôáì˜ÆüdK ܈“ȯp¬Bî; ƒø®„{™ÌôÌÿŽ/NdÚ3â,YFœÉ‰$ Òæ=¯àð¥—+xrÚ)Ln·fM›âdÀRÁ†È˜Ì׿[ ÒÝ´3)³]®VöõZ7öì àË-ÁáÅÜR üpsxØw¿ƒžYq/2ì­e¡Kz.³­nÁ@'X+c ¼»»jÔÀ\‰¿¬êZ5[#QUæðL}/×µZ¶Å-ί­hÕùVuE Ê8L«[­ZAyWUMß©›l³-¬–àiÜ9“EÆ}kû“iÚ‘e Ý}V"N²£™^ügìØ8KEÔ¡±ž“ˆ‹]K‚Wízf̳˜‰0‚JÕ6Hdµ¢X¢!¬ú&†Ð[´>;KeE[Õ´ä,ƒ“‡-#Î’Äé|~¼8}s4ÿï¯c¦%˜Zô-4êE¾ˆ™£qR%Ö8‡è4y0jÈ‹t>‚Ž¥ó²G\Jtg~˜xk°S®–`i½1&†µÌm³QÛ`¡ïZ°nÜ–7jSÕ·Ó$ðÐIDâ}hÔjW Pá©èR—W´~­Û5½@ö#‘&W‹ÝÕ•ªG-åÔBCY_;Ëš– ¢rmG%o·Á¿ ;õÓâλ"—“î8=6öSÑ?YŸ…Â쫘Ä,âT ÿFØ@’AØQý4"£à,ò“Uõ°^¥M–g#||( ÆAßx{â]¯U=ætgw»ö 08¨¸ÛS7w¬o‚.œ#ü] ªš^ Fe’z&q'…A¾6H À¾$þc&ö&ÂÛX`ëÕ--P:Á‘Á| hl00 ÉÔ™.Î#‘Òaì'6ÏFôM—Ž@—¹^f­jºÍÕpo§÷Ö™%²fÀtSTTå4nt¹T{VF}@£h¨>Ù)ààâµR4Êw›-ŽS¯×z‰F_[2“û¶ lé —6*+b<0TÝYàd¿G­~ç~Pª¢êV1<˜ç¶Õý5ku5Zÿl³¦ËÃAxo^S¦Xf%Eýkd𵏸Îe<Îç4lT‡Q¿b!¸>wrdbÅ*dM± F¸íÈa¦,.Œ¬˜3á‡ÃˆuQíê¥ âh›ÂŽ1ßÀ ð “ÕÓC–Ï¥ ×0؇¬: IäTýóæ]òÛÈèåh?Þy¹áÿ¾ý†Cav°7©cë4˜ ˆj[t[zòÊŽ ³n—ÆÓ­„Ú2ŠãGâÄxŒ^ɰ 3â6žø0âèÒNFƒ ’ã¹›$g>ÍZ"'Õ‡QhëSx«u3 ¡°÷x‰ï~6V3@[’ötæ¦22ˆ„­!c;„“Ãä׿¼AL< ?†Y~8ôÑlL'”™ä‡ùhe*=ˆãQb ¡AAÕEM~BD¥M–G =±ºXWxØ× ‰@JƒL_¦aäeÅÎNMýÓïêŸm½ºQÄz"„[bôª#/gçÎί`¬fGY›ýNÉjÕoMz²Úªqm:œ/Ó}÷c'VK7ÛB/»Š)ïÉ@Ü„g›&ÓÞÿÎÛñÐú"쥯A]šÝ©ZG¢º3­Ý­M9†q_ÝÛnÒ¨t4ïÓØÀaÃü“rçÔìÛç}È<]ì3zX!yOX¢"½-èä2˜ùØ@ºG1OôÒ846­s´²ã§‰[3pA Ñ''´}fÿ$ûÍè}ÀÜ™c*¬·i õÌ:ß;ej„=ÌÍave³ªÉ¢Y-Û}sÖ¹n'ÐuÇo-Õª* ë]/Gb¶-B;Wºï‚C½}UªœE*îèù?´§U<¯v‹¢TÍì$Û›µ‚²¦´¦%g …í­íX š`×ëQåúUÌåFÒ»ÜÀý÷øíâù¯+wön¤ïFHwô_ jz÷}W6úëSOúÅCÍä®(ú›[[£=Ôí }ƾ’|H‚€É}7×™ÛI€òÆ\—nzvÏ#ñ™Œƒûù·×764ßÇEšÓ•! yçI Íl³$?5¶Ctëɇ7›Ü³×Šj©‘Á’u‰U¿é¢0]'d$ËÝ6„#Q¹—DÀ’ïOÆ®ÅB&®¨ìÉHÌWEA#—Òp  u÷.ƒmÓ”Á!tì>}ü<— éß½øúœÏxâ\îÓû'ðÁÎEíj’4£ÅB­ZÑÙ›Š§¦Y…g­¯Ö=]ÝøÜÂ#M øN‡FíO-'.:È|'Ý«Ci?B$­Ø:Ã…ðZ­T]w›´•íšÇül,KÛݼÅKùrÿ»ˆÖ†'ö7ߤr)ÃÔý&òô;¿ˆ,‹ÿÑŠ90údæ¸ïÊȤJyÇ26?½8®"p R¨\€Àq>µŒOÏý0vÏ+˜Å<À{i–„HSÙýÞô(#· endstream endobj 124 0 obj << /Type /Page /Contents 125 0 R /Resources 123 0 R /MediaBox [0 0 612 792] /Parent 127 0 R >> endobj 126 0 obj << /D [124 0 R /XYZ 121.4 736.262 null] >> endobj 123 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 130 0 obj << /Length 1803 /Filter /FlateDecode >> stream xÚXëoÛ6ÿž¿BÀ¾È@ň¢žÙ:`]Ó CÛa¨W h ƒ–h[‹,¹•Äÿýîx”b%JÛ¢­Ž¯ã=~÷ _-ÏÎßðÈÉX±³Ü8<Xè$AÌÒL8ËÂùì~\¤ÂUmYÉwõÂãnD»ð„]ÁÒ(FR¸×õ"H]­ÚZVM½“0—¸½¬_—¿þÉUAš²Tǧk€ ÷}ß}}ùêß««ë÷WxäìryöíŒÃßá£p‚q?qòýÙ篾SÀÒ_ŽÏD–:wfãÞq *çÃÙ?g¯žÑ2B‘Ðõ ½f¾»UµjeõbáEAæª{¹/kKiFºï”U%8åÇ&ÂlP¥è÷‡/~äÃ?N»'·‹˜QZoÆ'1Kÿyùöíõ{ø;wlõÓhØ:šÞ^תj[UÐ]Æ–0» t©»9Øù ãáȶ9ðïÂn¢+yºLÛàE&ܼ©=òºoal½[ÉU®œà1+ßS±ÂˆE<•U÷ú»b„ÃnYsŠf Bz½U·?Ïñ±¢ÈãaÈ’ ™`éC¹‡4×VÇsЊ²SõÞ_.ß^XþP Â0•„ê …à N}¥ìîhŒafLŸ¸VÈg í‡? ÅYôœÅ˜å Ø$€x™/" ÀqJG_«u¿Ý–õdK"÷®Ô;¢®^¿š¹×G69ÅC(Üc¸´Ó«Vm[ÕuçE[Þ¢¾ È¡¢õ.o˃&Zæ¹:èŽ_ü *P&f¸-Ö–ickÙjZ‡ÒRiÓMK«}]¨–Vñ¤Í7§™!ê‰8r×­’7DÞífÂò]M3à5ÃȲ£ï®Ô´gX0¹‰CÛl[¹ŸnÇr»&WôÚh,óûRCæDæ~Bšžæóáv¨Àvkß)ºm1§Ž5W…ƒ¹Öš†x~ÿë;;³–9bâF·2W4e¬av …ÒÌ@̧î›ËïäFc$N<¡ŠÊ{-וz1'7)f*Š‘º+÷Óò`cúzC™í¸0–¤Á]Ùíˆ2&…ï€ BL ¨‘lŒ§a]Ö ¨bF¿­j1Ø ­†~jóD òòïÔœŽ§pÆÔQÛÔƒbƦgàn÷Èy³ßƒé.~RhÆÎoÉ ¦×mWë²^ëí :”ŸMyO£¤n,°jÐŽ{Ov]¹­iÜ×%4KOï>u¸—çv㻢l‰lÖÿ­Ì€»£9v^¾S9®ßàtèzZëÀä¡×ìÖ²}pÈ‘ÝΙû&OÍÿÁ††0àaK‘m†¹;×®&Ø…bëémAÆÂxljm±°u×V¿½,k cÈ5í¶ßÃʼ*tÇfnö²ˆ%PP&.55õÖ·3ÁÇ›ÉÈ~¦’ž6sŒà@Îò}pà e]‡´ ˜"ŠP3>mÌ,HÀ½ÈàYÜà#+òOòxzŠÇúÿ>A¥Á2'Îo+½‚p;”•b˜¤¸K¦õ&2ßÀKµ?4­l­øXe ¶БX;óôEt…^xä/¹°k0º}é߯7Ƶ‘¡]Q5-àd‘-‘3@Rëõˆ›§¸að予ydH3'qÑ piÙtݱÎkå«Ne3ôc¿NŒ?EÙ²¤ù'“§{›ód=ÆR=¤AjèPŠÒÄ->ÍÕױ؎﹇X4Mδ#´ùUŽ-ê·¾lŸyœÙ²/¢tl—€4 ¿ôéì³3/ñu˜Ó¤*†<e®¹bþ§–ÈÔZØu·+MK²£!ѲޚŽùᆓÇ.Ѻ©]¿‡öâHsºÖDXw©ç¼³—…ºyòŸvÓi<¾ ›{šCŠ_æêø3Ç^ÝÁ¸ë÷6 ’ÿð¢«ì›Û”ûÓ< ¥°Uv šèUsÕÐK"ól «;©óEýÑátÑ­ÀCúÏZ_­«—/Ot˜H,!Õ§©}$p1ü´ó?F¡Â* endstream endobj 129 0 obj << /Type /Page /Contents 130 0 R /Resources 128 0 R /MediaBox [0 0 612 792] /Parent 127 0 R >> endobj 131 0 obj << /D [129 0 R /XYZ 121.4 736.262 null] >> endobj 132 0 obj << /D [129 0 R /XYZ 122.4 568.381 null] >> endobj 128 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F31 63 0 R /F11 92 0 R >> /ProcSet [ /PDF /Text ] >> endobj 135 0 obj << /Length 1786 /Filter /FlateDecode >> stream xÚ­XKoÛF¾ûWéÁTaÑäò©Z8m$¨´VI¬È•Äš¯T¡èïÌÎ,E)t›C†fwggçùÍÐ/'çWn0™ÛóP„“Åjâ aû“H„v<÷&‹tòκŸÆž¥š,—S×ê¦3ת€h¦3Ïó-ÏŽƒIÏzUNEluª)eÞÒÖ„½ÈÚÊ|úañúüÊsO áØN¹;ùåäÅ.ãØö½ˆ”[à³)Q7JKI~(á,MÕs¶T %vG“™çØ~ä’ȺœÎÀÅTÕx4š¹®=bøŽÎ«æ9‰ÌóÁ•Ùé¶À`Ô×éò½8ðçÒ9ß”y&[•Ò¢«è÷Y]>#*cÚ&9·×é2+³î@Ð(Úý_š.¥´uú/u»'õE™¤óQgc»Q%Æjn]¿|AÄFæ]{´ï  ½—µô»mÕj›ÝU¼§ŸL¥¿kµ,SfÙÈÎPŠˆ¥L0OºF&¼õ˜å,2©Š¢*ó­ÚM…¬cÞ%y±ªFvdãj[&]V•-.!ýbKu$Im-œ(RcC×2]Ÿq§ÒW RÀ æ®V#ù‹•‘)ÕÏY;êvd_ÐKdý½CØÌyhý1Å7·Ä©½ƒ˜‰Á‘#ðö®Î0½vT|­RT~’Ö«FÊ}Úª21«ªPÝ&+״̳í£±Z…” bNA/Û¶=í‡>™G(bê§M†Ù’§*¿ýsʵnÕ—.“DÕãá7êÇv_‰xâú¶ç‡‚ʇ}àÞ+öøìñ9 5>‡ã3¬ŸçnÏGé{žEÜV®U æö¡|äò0}#ȉ<¥åNçê–iEñîŒeš`سJõH +%»m£~Ôf»Âv££˜º˜`ÏU–«ËíšD ç²mB7Ì–µå©Áþ¼Q2Ý–á•–ÕªŸ{àCɵ­9öf²]§F.™Ý<ôIZ•û¬‹í ôIqÁŠßHÎáaêTÛ%£¬jÙkÏlÔºQm{Þw/¿¸yóó%û¬j ÙíK‹ªÃ?(ñÈŽ½¹©ñÅåݳáë`ûhlØÈ€YñœÍáôØœWài!„µ†.dC B.Y®U‹h&C¯"†R) Ǻb@sáûVNÀV= úµô ïhÔq‚>Bª’©X•{'|ªõ ŽÆýü”UÁ>tÿEȦUפ¶½Ã;g&ë"(¬Ã¢ÅË‘ʘGõ†;0NÛm]“ MÇç¤=œASʉºÛµ*p2é'´jMG9¸l+×|E7)²1ÏKf«::ÐÆèÙ(à”é RUö2¢âÁ€ÝI»6Ù ˆ®/맪ÖèMgd ÈuÝT0PêÑI³ÕH ~Ѩ÷â/º›†v‚£ÇU¤ì-(Òlµ;(Æ7žÔ¶Ô>97û` RÓ¤æÆ\´\ÊÜ™¨”0Ì éw)ƒV™¹Èxqï¬[ÖYµöf¯Õ¸x޹5pâƒWv„•´H`ÚÖD³eâÙWÿ—ÖÏ Tüm×9í¼wD*À¿g´ÖÞôCœN!"˜w¸.å2 ÀJf8à˜~¶çr> ž „¤Ÿ+˜c‚Àúócš5¬m¯çù÷vטËïÏÏ™~Üdýˆ³è“‘Ö¨¾È"+ÕaúiërÅ€j ³†*ï¡YOX€ÕRÌqÀ;e°87} ÏºV%ý˜¥k^óÑЦãùy€åUI—4²-uE¬ZÃó}G€Ïœ9'Ä͹cÔUC¤ž*þhÎŽû©4`$„HI:î«lÀA’ó,áÁ§˜ÎašþÜ&?.¦€uJŽŒ‘Ïâa]Kxz|t€8ŸG‡+ý9†ÆÀ÷@QiuD°¹Ä‰\œe2§Íƒ‚ƒô­B2,áÍ ™Ú#°C‹„á€8<ªêÈ k±1dE+ Ewôá v¤fôLbƒÒ º¸Ã'IžÄ76·Bc|·ï¸I]Mè¾Ãå=2ÿÎí0ØËÙŒHQÑ {1T‰¬ñª© ²±wÔ—¬í(Þ°b§žcFÂ…PïÃUc6y Fà €ñÑ?ô}lò´ƒ‘ç ‘Ãܘê5)Íriؕ쭃šÀrNÑGÞ€O/îùMiõ*}ý\½Þú¯QóÔÿZiž]Ûñ<8š¨\Ï·cøL‚/¯8Žy°õÍÿFþ™X endstream endobj 134 0 obj << /Type /Page /Contents 135 0 R /Resources 133 0 R /MediaBox [0 0 612 792] /Parent 127 0 R >> endobj 136 0 obj << /D [134 0 R /XYZ 121.4 736.262 null] >> endobj 26 0 obj << /D [134 0 R /XYZ 122.4 451.092 null] >> endobj 137 0 obj << /D [134 0 R /XYZ 122.4 370.283 null] >> endobj 138 0 obj << /D [134 0 R /XYZ 122.4 351.165 null] >> endobj 139 0 obj << /D [134 0 R /XYZ 122.4 332.6 null] >> endobj 140 0 obj << /D [134 0 R /XYZ 122.4 278.723 null] >> endobj 141 0 obj << /D [134 0 R /XYZ 122.4 139.097 null] >> endobj 133 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 144 0 obj << /Length 710 /Filter /FlateDecode >> stream xÚuTMsÓ0½çWè†|°¢/Á‰í¤Ó–B]8”ãÄJ*pì"ÛÍäߣõÚ4r±W«Ý§}»O:ÉgóS‘Œe±ŒI¾&BJ¦I"c–fŠä%¹£_‚TQãlU‚vA(hã „JiªXÅ`*º¨™Òθº¨Zt]ޗо¨‚ûü|~ªøÁQ2ñ‡Ä áxLê‘9çôýâ&ÿ¼8¹Í¯ kö!Ÿýš ƉøSŸb‚'dµÝÝsRú­s™ÊR²·DÅ “ÞªÈÍìÓìä?Dã4eZ%XAD› Œ´¤ƒdÁÞ‡¦w¸z,Ú­nˆtÙÛª< }Uùì ]µ1åa¼¤E9:l7"-m]¸=Ú߸ҕ©‹­Aô)«{0hT¶ ³õØVy@Œ“P–E’jÝj~Yü4k[ÁèÌ÷fùƒM‰Çá’ʼnšæQÔ%Ñ™USCU›Þ†‰2%B3¥c ™á”jíu“<T¼0пŽõõ*Å’DCšplUtˆ‚ým5®µM; ¬É=QD ¯Ïe5æ®]³[£FËÒtbøÐu¯çóÝnÇž¼¾ƒÐƒùnÃ+Ö´ÛÌ_ìTÂx"'œ¡'$”±b<öÅ2;ïšG@Ù;»y.‡÷è’ó4”\h\.‡°cú†dA=-p…í›á^íKãXjž\È®q˜ý€Øµ3=ítQ×`t±ƒOáÌZõt{L\ãiΔpüÞ9»ì;3Лd#3 T2*™Ex{Û ,ízŽ)¨)yíá³!3b†-ÿ\l[4›5þõ»#ä§éÙ•O¾Eû´ípfjãüó2,®ûeeWh_Ø•©ÛãÚ££íYM ÇÔô:d\…î·®ó7ða5á‹%㨠‘¤Ì_’P§1“IŠˆhzØ~\ðbB endstream endobj 143 0 obj << /Type /Page /Contents 144 0 R /Resources 142 0 R /MediaBox [0 0 612 792] /Parent 127 0 R >> endobj 145 0 obj << /D [143 0 R /XYZ 121.4 736.262 null] >> endobj 30 0 obj << /D [143 0 R /XYZ 122.4 659.259 null] >> endobj 142 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F28 56 0 R /F33 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 146 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 115 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 147 0 R /Encoding 148 0 R /CharProcs 149 0 R >> endobj 147 0 obj [41.52 ] endobj 148 0 obj << /Type /Encoding /Differences [136/a136] >> endobj 149 0 obj << /a136 146 0 R >> endobj 150 0 obj [777.8 500 777.8] endobj 151 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 152 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 153 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 154 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 155 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 156 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 157 0 R /Encoding 158 0 R /CharProcs 159 0 R >> endobj 157 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 158 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 159 0 obj << /a97 151 0 R /a101 152 0 R /a103 153 0 R /a110 154 0 R /a115 155 0 R /a116 156 0 R >> endobj 160 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ3²Ô37T0P0W04S0²T02TH1ä*ä2 (˜B$’s¹œ<¹ôÃÒ\ú ¦\úž¾ %E¥©\úNÎ @A…h ŽX.O…úÿ?€è?}àrõä ä¿Iz endstream endobj 161 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ%‰»@@ûóç ÜÝ»¶öHl!¡Rˆ ¥‚ð÷„)¦˜ñšxOÃŒjéSªãl±Á…7ê?¦y„ôtRS!±á±Ÿ $o ZHÉÁÒŒˆ%ï—몈 û¢ endstream endobj 162 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 164 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 165 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 166 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 167 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 168 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 169 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 170 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 172 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 173 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 174 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 175 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 176 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 177 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 178 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 179 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 180 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 181 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 183 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 184 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 185 0 R /Encoding 186 0 R /CharProcs 187 0 R >> endobj 185 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 0 42.44 42.44 0 35.01 33.95 27.59 0 0 0 0 0 33.95 ] endobj 186 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 110/.notdef 111/a111/a112 113/.notdef 114/a114/a115/a116 117/.notdef 122/a122] >> endobj 187 0 obj << /a21 161 0 R /a45 160 0 R /a69 162 0 R /a71 163 0 R /a73 164 0 R /a78 165 0 R /a80 166 0 R /a83 167 0 R /a84 168 0 R /a86 169 0 R /a97 170 0 R /a99 171 0 R /a100 172 0 R /a101 173 0 R /a104 174 0 R /a105 175 0 R /a107 176 0 R /a108 177 0 R /a109 178 0 R /a111 179 0 R /a112 180 0 R /a114 181 0 R /a115 182 0 R /a116 183 0 R /a122 184 0 R >> endobj 188 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ52T2u ÍR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ(ª+¨ endstream endobj 189 0 obj << /Length 85 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3s…C®B.ˆMÎåròäÒW0çÒ÷ž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ €ËÕ“+ hz¯ endstream endobj 190 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 191 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3cs…C®B.ˆOÎåròäÒW0çÒ÷ ré{ú*”•¦ré;8+ré»(D*Äryº(üƒì*ËåêÉÈžã: endstream endobj 192 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 193 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 195 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 196 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 197 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 198 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 199 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 200 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 201 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 202 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 203 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 204 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 205 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 206 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 208 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bCSs…C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þC¨'p¹zrr4ö+³ endstream endobj 209 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 210 0 obj << /Length 89 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bC3…C®B.s ×ĉ'çr9yré‡+˜sé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þQ¸\=¹¹6VLÖ endstream endobj 211 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 212 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 213 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 214 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 215 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 216 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 217 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0TÐ5T0²P01WH1ä*ä22 (˜X@d’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒˆÁÿÿÿÇÀÄê¥ÿch`üÇØÀðŸýÐR®ÿÏÀ`””ÀÀåêÉÈ|Q  endstream endobj 218 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 219 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 220 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 222 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 223 0 R /Encoding 224 0 R /CharProcs 225 0 R >> endobj 223 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 224 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 225 0 obj << /a46 189 0 R /a47 190 0 R /a58 191 0 R /a66 192 0 R /a67 193 0 R /a68 194 0 R /a70 195 0 R /a71 196 0 R /a75 197 0 R /a85 198 0 R /a86 199 0 R /a95 188 0 R /a97 200 0 R /a98 201 0 R /a99 202 0 R /a100 203 0 R /a101 204 0 R /a102 205 0 R /a103 206 0 R /a104 207 0 R /a105 208 0 R /a107 209 0 R /a108 210 0 R /a109 211 0 R /a110 212 0 R /a111 213 0 R /a112 214 0 R /a114 215 0 R /a115 216 0 R /a116 217 0 R /a117 218 0 R /a118 219 0 R /a119 220 0 R /a121 221 0 R /a122 222 0 R >> endobj 226 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 227 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 229 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 230 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 231 0 obj << /Length 114 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04WÐ5W01T0µPH1ä*ä22Š(˜™B¥’s¹œ<¹ôÃŒŒ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ†þüa`üè?’›îçrõä ä—5ez endstream endobj 232 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0VÐ5W02W0µPH1ä*ä22 (˜™Bd’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ‚êÿÿc`¨ü¨æ`°›ÿp¹zrrléI endstream endobj 233 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 234 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 235 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UеP0¶TÐ5RH1ä*ä26 (˜A$’s¹œ<¹ôÃŒ¹ô≠ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿÏÄÿа—«'W *› endstream endobj 236 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 237 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 238 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 239 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F †† )†\…\@Ú$l‘IÎåròäÒ pé{€IO_…’¢ÒT.}§g ßE!¨'–ËÓEAžÁ¾¡þÀÿ0XÀ¾AžËÕ“+ ‰;“ endstream endobj 240 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 241 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F Æf )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêüƒõìäðì:¸\=¹¹{-= endstream endobj 242 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04UÐ54R06P06SH1ä*ä24 (˜XÀä’s¹œ<¹ôà M¸ô=€\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü òìÔ€Aûòøð Žöêá´ÿ#ÿ‡ÿÆ ?0`ÿ ÿ þÀÿ†ÿ@¡.WO®@.…8 endstream endobj 243 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V04S01T06QH1ä*ä26 (Z@d’s¹œ<¹ôÌ͹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿÿÿÄÿ °‘§\®ž\\ºâAŠ endstream endobj 244 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 245 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 246 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 247 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 248 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 249 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 250 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 251 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 252 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 253 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 254 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 255 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 257 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 258 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 259 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 260 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 261 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 262 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 263 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 264 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 265 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 266 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 267 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 268 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 269 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 270 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 271 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 272 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 273 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 274 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 275 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 276 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 277 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 278 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 279 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 280 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 281 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 282 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 283 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 284 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 285 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 286 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 287 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 288 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 290 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 291 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 292 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 293 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 294 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 295 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 296 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 297 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 298 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 299 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 300 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 301 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 302 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 303 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 304 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 305 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 306 0 R /Encoding 307 0 R /CharProcs 308 0 R >> endobj 306 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 307 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 308 0 obj << /a34 245 0 R /a35 246 0 R /a36 247 0 R /a40 227 0 R /a41 228 0 R /a42 236 0 R /a43 237 0 R /a44 238 0 R /a45 244 0 R /a46 239 0 R /a47 240 0 R /a48 296 0 R /a49 297 0 R /a50 298 0 R /a51 299 0 R /a52 300 0 R /a53 301 0 R /a54 302 0 R /a55 303 0 R /a56 304 0 R /a57 305 0 R /a58 241 0 R /a59 242 0 R /a60 229 0 R /a61 243 0 R /a62 230 0 R /a64 248 0 R /a65 249 0 R /a66 250 0 R /a67 251 0 R /a68 252 0 R /a69 253 0 R /a70 254 0 R /a71 255 0 R /a73 256 0 R /a75 257 0 R /a76 258 0 R /a77 259 0 R /a78 260 0 R /a79 261 0 R /a80 262 0 R /a82 263 0 R /a83 264 0 R /a84 265 0 R /a85 266 0 R /a86 267 0 R /a87 268 0 R /a89 269 0 R /a91 231 0 R /a93 232 0 R /a95 235 0 R /a97 270 0 R /a98 271 0 R /a99 272 0 R /a100 273 0 R /a101 274 0 R /a102 275 0 R /a103 276 0 R /a104 277 0 R /a105 278 0 R /a106 279 0 R /a107 280 0 R /a108 281 0 R /a109 282 0 R /a110 283 0 R /a111 284 0 R /a112 285 0 R /a113 286 0 R /a114 287 0 R /a115 288 0 R /a116 289 0 R /a117 290 0 R /a118 291 0 R /a119 292 0 R /a120 293 0 R /a121 294 0 R /a122 295 0 R /a123 233 0 R /a125 234 0 R /a126 226 0 R >> endobj 309 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 310 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 311 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 312 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 315 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 316 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 317 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 318 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 319 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 320 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 321 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 323 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 324 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 325 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 327 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 328 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 329 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 330 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 331 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 332 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 333 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 334 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 335 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 336 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 337 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 338 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 339 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 340 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 341 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 342 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 343 0 R /Encoding 344 0 R /CharProcs 345 0 R >> endobj 343 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 0 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 344 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 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 345 0 obj << /a21 310 0 R /a46 309 0 R /a65 311 0 R /a66 312 0 R /a67 313 0 R /a68 314 0 R /a70 315 0 R /a71 316 0 R /a73 317 0 R /a75 318 0 R /a82 319 0 R /a84 320 0 R /a85 321 0 R /a86 322 0 R /a97 323 0 R /a98 324 0 R /a99 325 0 R /a100 326 0 R /a101 327 0 R /a102 328 0 R /a103 329 0 R /a104 330 0 R /a105 331 0 R /a108 332 0 R /a110 333 0 R /a111 334 0 R /a112 335 0 R /a114 336 0 R /a115 337 0 R /a116 338 0 R /a117 339 0 R /a118 340 0 R /a119 341 0 R /a121 342 0 R >> endobj 346 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚ32Ó35V0P0b#CCc…C®B.C˜ˆ ’HÎåròäÒò¹ô=À¤§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒýƒúõþÿ€AÏþ—«'W !‘$‡ endstream endobj 347 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 348 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 349 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 350 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 351 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 352 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 353 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 354 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 355 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 356 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 358 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 359 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 360 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 362 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 363 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 364 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 365 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 366 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 367 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 368 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 369 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 370 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 371 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 373 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 374 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 375 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 376 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 377 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 378 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 379 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 380 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 381 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 382 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 383 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 384 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 386 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 387 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 388 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 389 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 390 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 391 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 392 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 393 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 395 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 396 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 397 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 [ 0 -17 97 59 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 121 /Widths 399 0 R /Encoding 400 0 R /CharProcs 401 0 R >> endobj 399 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 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 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 400 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 28/a28 29/.notdef 45/a45/a46 47/.notdef 48/a48/a49/a50/a51/a52/a53/a54/a55/a56 57/.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 401 0 obj << /a21 348 0 R /a28 349 0 R /a45 347 0 R /a46 346 0 R /a48 390 0 R /a49 391 0 R /a50 392 0 R /a51 393 0 R /a52 394 0 R /a53 395 0 R /a54 396 0 R /a55 397 0 R /a56 398 0 R /a65 350 0 R /a66 351 0 R /a67 352 0 R /a68 353 0 R /a69 354 0 R /a70 355 0 R /a71 356 0 R /a72 357 0 R /a73 358 0 R /a76 359 0 R /a77 360 0 R /a78 361 0 R /a79 362 0 R /a82 363 0 R /a83 364 0 R /a84 365 0 R /a85 366 0 R /a86 367 0 R /a87 368 0 R /a97 369 0 R /a98 370 0 R /a99 371 0 R /a100 372 0 R /a101 373 0 R /a102 374 0 R /a103 375 0 R /a104 376 0 R /a105 377 0 R /a108 378 0 R /a109 379 0 R /a110 380 0 R /a111 381 0 R /a112 382 0 R /a114 383 0 R /a115 384 0 R /a116 385 0 R /a117 386 0 R /a119 387 0 R /a120 388 0 R /a121 389 0 R >> endobj 402 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 403 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 404 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 405 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 406 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 407 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 408 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 409 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bS #…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿA ÉÀþÿÃ(9THü±ÉåêÉÈ’:Õ° endstream endobj 410 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 411 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 412 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 413 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 414 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 416 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 417 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 418 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 419 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 421 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 422 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 424 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 425 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 426 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 427 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 428 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 429 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 431 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 432 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 433 0 R /Encoding 434 0 R /CharProcs 435 0 R >> endobj 433 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 434 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 435 0 obj << /a49 425 0 R /a50 426 0 R /a51 427 0 R /a52 428 0 R /a53 429 0 R /a54 430 0 R /a55 431 0 R /a56 432 0 R /a65 402 0 R /a66 403 0 R /a67 404 0 R /a68 405 0 R /a69 406 0 R /a70 407 0 R /a71 408 0 R /a73 409 0 R /a76 410 0 R /a77 411 0 R /a78 412 0 R /a79 413 0 R /a82 414 0 R /a83 415 0 R /a84 416 0 R /a85 417 0 R /a86 418 0 R /a87 419 0 R /a101 420 0 R /a110 421 0 R /a111 422 0 R /a115 423 0 R /a116 424 0 R >> endobj 436 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 437 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 438 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 439 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 440 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 442 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 443 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 444 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 445 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 446 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 447 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 449 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 450 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 451 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 452 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 453 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 454 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 455 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 457 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 458 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 459 0 R /Encoding 460 0 R /CharProcs 461 0 R >> endobj 459 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 460 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 461 0 obj << /a51 453 0 R /a52 454 0 R /a53 455 0 R /a54 456 0 R /a55 457 0 R /a56 458 0 R /a65 436 0 R /a66 437 0 R /a67 438 0 R /a68 439 0 R /a69 440 0 R /a70 441 0 R /a71 442 0 R /a73 443 0 R /a76 444 0 R /a78 445 0 R /a79 446 0 R /a82 447 0 R /a83 448 0 R /a84 449 0 R /a85 450 0 R /a86 451 0 R /a87 452 0 R >> endobj 462 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 463 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 464 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ52T02R03RH1ä*ä24Š(XC¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿüÿó‡a0C ¹\=¹¹¶ h endstream endobj 465 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 466 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 467 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 468 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 469 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 470 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 471 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 472 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 473 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 474 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 475 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 476 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 477 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0U04T03P06TH1ä*ä25 (Ae’s¹œ<¹ôÃLM¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿAà˜üÿ‡Îj-Ô\®ž\\~,Ü endstream endobj 478 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 479 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 480 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 481 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 482 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 483 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 484 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 485 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 486 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 487 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 488 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 489 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 490 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 491 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 493 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 494 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 495 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 496 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 497 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 498 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 499 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 500 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 501 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 502 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 503 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 504 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 505 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 506 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 508 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 509 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 510 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 511 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 512 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 513 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 514 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 515 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 516 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 517 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 519 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 520 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 521 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 522 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 523 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 524 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 525 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 526 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 529 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 531 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 532 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 533 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 534 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 536 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 537 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 538 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 539 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 540 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 541 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 542 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 543 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 545 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 546 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 547 0 R /Encoding 548 0 R /CharProcs 549 0 R >> endobj 547 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 548 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 549 0 obj << /a21 479 0 R /a27 484 0 R /a28 483 0 R /a29 485 0 R /a30 486 0 R /a34 480 0 R /a35 481 0 R /a39 469 0 R /a40 462 0 R /a41 463 0 R /a42 470 0 R /a43 471 0 R /a44 472 0 R /a45 478 0 R /a46 473 0 R /a47 474 0 R /a48 537 0 R /a49 538 0 R /a50 539 0 R /a51 540 0 R /a52 541 0 R /a53 542 0 R /a54 543 0 R /a55 544 0 R /a56 545 0 R /a57 546 0 R /a58 475 0 R /a59 476 0 R /a61 477 0 R /a63 487 0 R /a64 482 0 R /a65 488 0 R /a66 489 0 R /a67 490 0 R /a68 491 0 R /a69 492 0 R /a70 493 0 R /a71 494 0 R /a72 495 0 R /a73 496 0 R /a76 497 0 R /a77 498 0 R /a78 499 0 R /a79 500 0 R /a80 501 0 R /a82 502 0 R /a83 503 0 R /a84 504 0 R /a85 505 0 R /a86 506 0 R /a87 507 0 R /a88 508 0 R /a89 509 0 R /a90 510 0 R /a91 464 0 R /a93 465 0 R /a95 468 0 R /a97 511 0 R /a98 512 0 R /a99 513 0 R /a100 514 0 R /a101 515 0 R /a102 516 0 R /a103 517 0 R /a104 518 0 R /a105 519 0 R /a106 520 0 R /a107 521 0 R /a108 522 0 R /a109 523 0 R /a110 524 0 R /a111 525 0 R /a112 526 0 R /a113 527 0 R /a114 528 0 R /a115 529 0 R /a116 530 0 R /a117 531 0 R /a118 532 0 R /a119 533 0 R /a120 534 0 R /a121 535 0 R /a122 536 0 R /a123 466 0 R /a125 467 0 R >> endobj 550 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 551 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 552 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 553 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 554 0 obj << /Length 289 /Filter /FlateDecode >> stream xÚeÐ;NÃ@àßrai›=‚ç`;qѰR. ¢@T@I‚.J|®²7aàÒˆÈÃÎ$ÊCi>˳óØI}^M©¤ ¨¾ iI/•y7õ8KšŽ6'ÏofÖ˜âê±)nbØÍ-}~|½šbvwE•)æôXQùdš9!a¤€åŽûè€Á"é‘[dÙ72ô¶•ÜÃEW¸Œ:,wæX¨ë¨=0;rØ™nåW-¤·WƒèzUR‘³„,k–Ÿ”9¶M˜¥<êåÜI÷z°Ö:©HxÛDL¹ÕÎc¿ŸêÔ|c=1;2œØ‰^´¾ßÛê]ÚA·Äº7™¿Ä_l´Æo'kïH;tÎÛ€_Ñ"èÅ=\lh®soþWŽŠÐ endstream endobj 555 0 obj << /Length 333 /Filter /FlateDecode >> stream xÚÒAKÃ0ð „±^{û¾€6L»SaN°AOD¨GaŠž—–R¿Aa—‚£ñ½Ô‰®.x ?’ðþ¼dJg9*ãѧ9žäøÉg9ЦÂÓ¯“û'9+ezƒÓ‰L/h[¦å%¾¾¼=Êtvu†™Lçx›¡º“å­µ0°¶È¶ûØ ±`ka5@´!FðÖ ¡%¡£­£¬è~°Ùñð· CnɱÇÔCÈ…sŠÛZí¸¦npIm‡²Ø1õu°2ÎÜcÌ!æ/WÎÜ£¢¡÷[P `¿ùQ ½ÖÂPá{¥…&{6¦Gq.LÀ!qÏÙvNªC”ÏQí&²ðyи‰¯7<…w砳é$kgÑòDÖÐ3ÿ¸èÃ,O¤õûû7y\páÆïC^êxÙÙMŸGž—òZ~GÈ endstream endobj 556 0 obj << /Length 212 /Filter /FlateDecode >> stream xڽϱ‚0à’$7À ˜x/ ¥$N$ˆ‰ &:9'utÐèf,Æ£ðŒ F¼‚†ÆÕÄßp×öþ ü¡ ÑÃ$ÇÜK8¯‹†ïÎîq b~bNeé/çëD¼œ¢‘àF¢·…4AFGi¢ú[«‘µª?«2’×%éæ72byg6ù ã•Nh—:¡]hÝB¿íçQÖ©L›)õ϶ÿ˜?›Í$nþIØd¦ä¼Ô[Xm”ÑFŽÊiÇžzÒÕŠäuA63`– ^¶Ñj» endstream endobj 557 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 558 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ¿NÃ0Æ?+C$/~„Ü @pK§V*E"L02€`«÷ÉÈ£Dâ`ž”7Ѭ$7ëãî¨d¸¬*¦ ¯:}§¿$ X endstream endobj 559 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 560 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 561 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 562 0 obj << /Length 159 /Filter /FlateDecode >> stream xÚ35Ñ34W0P0bSC…C®B.˜ˆ ’HÎåròäÒW01çÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(0þaüÇÀðÿûÿ@RŽý´`üÁÀþ§€ñóŸ ÿ`ø$@äÿ†z É€ ÿa/É òmÃÿÿ?ìÿÿC&¹\=¹¹?qjS endstream endobj 563 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 564 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 565 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 566 0 obj << /Length 213 /Filter /FlateDecode >> stream xÚMͱNÃ@б\DÚæÚTdëä""R.HE¨€’’‹ˆøÓü)÷ ‡h®°¼Œ!Åkfg´¾:[œë\½ž–ê—ºXêS)¯âK†såí÷òø"›ZŠ;õ¥׌¥¨oôýíãYŠÍí¥2Ýê=7Roë0ͬ¯&aÖ8äéYZi4 % :šŽú£¬1X[ÀÌz83L̺ܘE†œ[yß!8}†?£øË+–÷ÔðO2dñ»ÍÃWtm8 è\„\Õ²“uYÛ endstream endobj 567 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 568 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 570 0 obj << /Length 248 /Filter /FlateDecode >> stream xÚeпJÄ@ðo \`^›B¼yÝÍ] ç ¦´²á@-íÄÛG²´Ì£äR^w¢ùÃÙüŠ™]¾™9ŽŽâ„ Oùpj8>åxƽPS5œÌþZ÷O´LIßpœ¾puÒé%¿½¾?’^^qDzÅ·›;JW\×…ªË¡~ lr¯&V‰÷g¸î¾{„'À´N2¬;säÀ8GÖêÊvn=§·õЪÊQoåb]pл ~‹‹¯^¶ã8ëõí®Ø:úg00ìœ7~Êžî¿®JT¥Ä٠Ͼüœ4s”M^!ÒyJ×ô[ÍX' endstream endobj 571 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 572 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 573 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 574 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚmÁJÄ0†'ô˜ƒyÅÎ h[éÖÞ ë ö ¸'âiõ(¨èÕöÑò(y„sÆ™ì$ä;dfþò·ýùåšjjéì‚Ú5u=5ø†mMrºþPÙ¿àfÄêžÚ«~Æj¼¥÷Ïg¬6wWÔ`µ¥‡†êG·*€‰`ˆß‹Z@y˜æÂÂ`5@éNŽ0Þ8FéÁ„ Ê ðÒxÖ‘õPºŒÁ fÆÄ¾ŠÍ¡HmVJ[ù\8ô¥ )ƒqYT‹‘Nà K†Jˆ¿8L3#Úÿ±Ä™g¾DïU”kñèÙ-¬Ä2¥¡gþBá8&%ÁÃ1DñÂëwø>³vq endstream endobj 575 0 obj << /Length 206 /Filter /FlateDecode >> stream xÚ¥ÐÍjÂ@Àñ„@CÐkBç º·‚Ð õäA ¶GAEÏæÍÌ£äMbö/hèµûƒÙf–Éf¯Ó±Zµ'›èdª?©$¶¹u©{øÞÉ<³Ñl(æ½½“èéxþ3ÿ\h*f©ÛTí—äKõ> /FirstChar 45 /LastChar 121 /Widths 576 0 R /Encoding 577 0 R /CharProcs 578 0 R >> endobj 576 0 obj [32.5 27.08 48.75 48.75 48.75 48.75 48.75 48.75 0 0 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 54.17 0 0 0 100.18 0 0 0 0 0 0 0 0 0 0 0 0 54.17 43.33 0 48.75 54.17 27.08 0 0 27.08 0 54.17 48.75 54.17 0 37.92 38.46 37.92 0 51.46 70.42 0 51.46 ] endobj 577 0 obj << /Type /Encoding /Differences [45/a45/a46/a47/a48/a49/a50/a51/a52 53/.notdef 58/a58 59/.notdef 83/a83 84/.notdef 87/a87 88/.notdef 100/a100/a101 102/.notdef 103/a103/a104/a105 106/.notdef 108/a108 109/.notdef 110/a110/a111/a112 113/.notdef 114/a114/a115/a116 117/.notdef 118/a118/a119 120/.notdef 121/a121] >> endobj 578 0 obj << /a45 553 0 R /a46 550 0 R /a47 551 0 R /a48 571 0 R /a49 572 0 R /a50 573 0 R /a51 574 0 R /a52 575 0 R /a58 552 0 R /a83 554 0 R /a87 555 0 R /a100 556 0 R /a101 557 0 R /a103 558 0 R /a104 559 0 R /a105 560 0 R /a108 561 0 R /a110 562 0 R /a111 563 0 R /a112 564 0 R /a114 565 0 R /a115 566 0 R /a116 567 0 R /a118 568 0 R /a119 569 0 R /a121 570 0 R >> endobj 579 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×31R0P0F¦ :Å« Ì ƒYɹ\Nž\úá@—¾˜ôôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàg°?Pÿàÿ¬`€ŸËÕ“+ è±"g endstream endobj 580 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 581 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 583 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 585 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 587 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 588 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 589 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 590 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 591 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 592 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 593 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 594 0 obj << /Length 312 /Filter /FlateDecode >> stream xÚÍÒ»JÄ@à˜&o°™Ð\ØÍ"uSne!Vj)¨(X9y´ˆ…¥o ó)S„gΉ²¢…¥Ó|äÌ%s~¦˜ïLMjæf;7Ejv§æ"Ó7z–S‘> ™9¿Ò‹J''f–ëäÊ:©ŽÌÝíý¥NÇû&ÓÉÒœf&=ÓÕÒ¨À”#&Pñ5AOt°A£œÐ`ÖmUï~Ô³Ÿ‚jÊ–þJ.óuË—ê•oåÅÁ¯5Jjó ˆ©éˆZŽ'¤@Z‰Ç}AýÑ|*OêMìHó ·Iù+íˆk†O%3Œ´?q2'X74BÍ\ËG¤‡‘=éÏCÝNÀ½{‚5""ìÕœRØpf“é·”'zÉÃJV¥‹¨€ˆ_~=´@ò‹}MTz¥?Î×À¥ endstream endobj 595 0 obj << /Length 348 /Filter /FlateDecode >> stream xÚÒ½JÄ@à A"Ûì#d_@“È]äªÀy‚)­,ÄJ--í„ÝG[¹ÂÎÚÂ"2EÈ83»ÂqœbùÂþÌÎîl}|83¥©ÍÁ‘©+³˜™»J=ª97–fQ‡žÛµlUqeæ3UœQ³*Úsóüôr¯Šåʼn©T±2ו)oT»2MÀOƒžAìé›"Ž„îl:hë@;AS$ÔŸzH€=Y/£tG£:È ¤9>à &A¢[ϱhX:J"‘lØDGz!ß­ÿ+”Ô¾ ¤˜ñö¬Ï™WÎÑúžÇ·ŽwƒkÙ®çƒï”+~PŒˆü’3‡ŸŒÇA•CÌ#ý݃ w2J)¶±ÿ'Diþ ëm!y:¤É"ac‘TðR*ë’@(ª¼\X*8w4r‚{)%ÝŽK¿|;Ò)A'—¥Jré@ËyAÂmê´U—ê|Aæ endstream endobj 596 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 597 0 R /Encoding 598 0 R /CharProcs 599 0 R >> endobj 597 0 obj [37.42 0 0 0 0 67.4 0 67.4 67.4 0 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 598 0 obj << /Type /Encoding /Differences [46/a46 47/.notdef 51/a51 52/.notdef 53/a53/a54 55/.notdef 56/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 599 0 obj << /a46 579 0 R /a51 593 0 R /a53 594 0 R /a54 595 0 R /a56 596 0 R /a73 580 0 R /a77 581 0 R /a86 582 0 R /a97 583 0 R /a101 584 0 R /a105 585 0 R /a108 586 0 R /a110 587 0 R /a111 588 0 R /a114 589 0 R /a115 590 0 R /a116 591 0 R /a117 592 0 R >> endobj 600 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 601 0 R /FirstChar 60 /LastChar 62 /Widths 150 0 R >> endobj 42 0 obj << /Type /Pages /Count 6 /Parent 602 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 602 0 R /Kids [87 0 R 95 0 R 102 0 R 107 0 R 112 0 R 119 0 R] >> endobj 127 0 obj << /Type /Pages /Count 4 /Parent 602 0 R /Kids [124 0 R 129 0 R 134 0 R 143 0 R] >> endobj 602 0 obj << /Type /Pages /Count 16 /Kids [42 0 R 93 0 R 127 0 R] >> endobj 603 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 603 0 R /Prev 27 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 603 0 R /Prev 23 0 R /Next 31 0 R >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 603 0 R /Prev 19 0 R /Next 27 0 R >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 603 0 R /Prev 15 0 R /Next 23 0 R >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 603 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 603 0 R /Prev 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 603 0 R /Prev 3 0 R /Next 11 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R /Parent 603 0 R /Next 7 0 R >> endobj 604 0 obj << /Names [(Doc-Start) 38 0 R (Item.12) 90 0 R (Item.13) 91 0 R (Item.14) 98 0 R (Item.26) 137 0 R (Item.27) 138 0 R] /Limits [(Doc-Start) (Item.27)] >> endobj 605 0 obj << /Names [(Item.28) 139 0 R (Item.29) 140 0 R (page.1) 37 0 R (page.10) 109 0 R (page.11) 114 0 R (page.12) 121 0 R] /Limits [(Item.28) (page.12)] >> endobj 606 0 obj << /Names [(page.13) 126 0 R (page.14) 131 0 R (page.15) 136 0 R (page.16) 145 0 R (page.2) 54 0 R (page.3) 62 0 R] /Limits [(page.13) (page.3)] >> endobj 607 0 obj << /Names [(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 (page.9) 104 0 R] /Limits [(page.4) (page.9)] >> endobj 608 0 obj << /Names [(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 (section*.18) 105 0 R] /Limits [(section*.1) (section*.18)] >> endobj 609 0 obj << /Names [(section*.19) 110 0 R (section*.21) 116 0 R (section*.22) 117 0 R (section*.23) 122 0 R (section*.24) 132 0 R (section*.30) 141 0 R] /Limits [(section*.19) (section*.30)] >> endobj 610 0 obj << /Names [(section*.5) 64 0 R (section*.6) 69 0 R (section*.7) 77 0 R (section*.9) 82 0 R (section.17) 18 0 R (section.2) 2 0 R] /Limits [(section*.5) (section.2)] >> endobj 611 0 obj << /Names [(section.20) 22 0 R (section.25) 26 0 R (section.3) 6 0 R (section.31) 30 0 R (section.4) 10 0 R (section.8) 14 0 R] /Limits [(section.20) (section.8)] >> endobj 612 0 obj << /Kids [604 0 R 605 0 R 606 0 R 607 0 R 608 0 R 609 0 R] /Limits [(Doc-Start) (section*.30)] >> endobj 613 0 obj << /Kids [610 0 R 611 0 R] /Limits [(section*.5) (section.8)] >> endobj 614 0 obj << /Kids [612 0 R 613 0 R] /Limits [(Doc-Start) (section.8)] >> endobj 615 0 obj << /Dests 614 0 R >> endobj 616 0 obj << /Type /Catalog /Pages 602 0 R /Outlines 603 0 R /Names 615 0 R /PageMode/UseOutlines/PageLabels<>1<>]>> /OpenAction 33 0 R >> endobj 617 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.10)/Keywords() /CreationDate (D:20140311195155-04'00') /ModDate (D:20140311195155-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 618 0000000000 65535 f 0000000015 00000 n 0000005335 00000 n 0000180813 00000 n 0000000060 00000 n 0000000084 00000 n 0000005390 00000 n 0000180729 00000 n 0000000129 00000 n 0000000161 00000 n 0000005447 00000 n 0000180643 00000 n 0000000206 00000 n 0000000237 00000 n 0000014174 00000 n 0000180555 00000 n 0000000283 00000 n 0000000322 00000 n 0000023254 00000 n 0000180467 00000 n 0000000369 00000 n 0000000397 00000 n 0000027927 00000 n 0000180379 00000 n 0000000444 00000 n 0000000474 00000 n 0000037653 00000 n 0000180291 00000 n 0000000521 00000 n 0000000562 00000 n 0000039104 00000 n 0000180216 00000 n 0000000609 00000 n 0000000642 00000 n 0000000997 00000 n 0000001219 00000 n 0000000692 00000 n 0000001105 00000 n 0000001163 00000 n 0000171162 00000 n 0000164065 00000 n 0000154373 00000 n 0000179741 00000 n 0000001970 00000 n 0000002120 00000 n 0000002269 00000 n 0000002420 00000 n 0000002571 00000 n 0000002723 00000 n 0000002875 00000 n 0000003027 00000 n 0000003295 00000 n 0000001794 00000 n 0000001313 00000 n 0000003179 00000 n 0000131005 00000 n 0000122365 00000 n 0000003237 00000 n 0000109739 00000 n 0000005563 00000 n 0000005169 00000 n 0000003401 00000 n 0000005277 00000 n 0000093720 00000 n 0000005505 00000 n 0000008791 00000 n 0000008567 00000 n 0000005669 00000 n 0000008675 00000 n 0000008733 00000 n 0000081434 00000 n 0000059591 00000 n 0000049516 00000 n 0000011715 00000 n 0000011491 00000 n 0000008921 00000 n 0000011599 00000 n 0000011657 00000 n 0000014404 00000 n 0000014008 00000 n 0000011821 00000 n 0000014116 00000 n 0000014231 00000 n 0000041715 00000 n 0000014289 00000 n 0000014347 00000 n 0000017865 00000 n 0000017583 00000 n 0000014558 00000 n 0000017691 00000 n 0000017749 00000 n 0000017807 00000 n 0000179599 00000 n 0000179851 00000 n 0000020752 00000 n 0000020411 00000 n 0000017983 00000 n 0000020519 00000 n 0000020577 00000 n 0000020635 00000 n 0000020693 00000 n 0000023373 00000 n 0000023083 00000 n 0000020870 00000 n 0000023194 00000 n 0000023313 00000 n 0000025607 00000 n 0000025376 00000 n 0000023504 00000 n 0000025487 00000 n 0000025547 00000 n 0000028106 00000 n 0000027756 00000 n 0000025738 00000 n 0000027867 00000 n 0000039512 00000 n 0000027986 00000 n 0000028046 00000 n 0000030516 00000 n 0000030286 00000 n 0000028262 00000 n 0000030397 00000 n 0000030457 00000 n 0000033248 00000 n 0000033076 00000 n 0000030659 00000 n 0000033188 00000 n 0000179965 00000 n 0000035495 00000 n 0000035263 00000 n 0000033379 00000 n 0000035375 00000 n 0000035435 00000 n 0000038010 00000 n 0000037481 00000 n 0000035614 00000 n 0000037593 00000 n 0000037712 00000 n 0000037772 00000 n 0000037832 00000 n 0000037890 00000 n 0000037950 00000 n 0000039163 00000 n 0000038932 00000 n 0000038141 00000 n 0000039044 00000 n 0000039282 00000 n 0000039761 00000 n 0000039787 00000 n 0000039850 00000 n 0000039887 00000 n 0000039922 00000 n 0000040228 00000 n 0000040534 00000 n 0000040898 00000 n 0000041149 00000 n 0000041457 00000 n 0000041964 00000 n 0000042048 00000 n 0000042197 00000 n 0000042303 00000 n 0000042480 00000 n 0000042655 00000 n 0000042981 00000 n 0000043332 00000 n 0000043568 00000 n 0000043940 00000 n 0000044229 00000 n 0000044565 00000 n 0000044860 00000 n 0000045172 00000 n 0000045465 00000 n 0000045732 00000 n 0000046050 00000 n 0000046324 00000 n 0000046634 00000 n 0000046902 00000 n 0000047231 00000 n 0000047484 00000 n 0000047831 00000 n 0000048102 00000 n 0000048421 00000 n 0000048684 00000 n 0000048965 00000 n 0000049224 00000 n 0000049765 00000 n 0000050086 00000 n 0000050476 00000 n 0000050837 00000 n 0000051021 00000 n 0000051187 00000 n 0000051416 00000 n 0000051590 00000 n 0000051881 00000 n 0000052188 00000 n 0000052465 00000 n 0000052653 00000 n 0000052966 00000 n 0000053296 00000 n 0000053545 00000 n 0000053870 00000 n 0000054134 00000 n 0000054395 00000 n 0000054655 00000 n 0000054923 00000 n 0000055197 00000 n 0000055411 00000 n 0000055726 00000 n 0000055948 00000 n 0000056124 00000 n 0000056401 00000 n 0000056571 00000 n 0000056817 00000 n 0000057035 00000 n 0000057306 00000 n 0000057576 00000 n 0000057790 00000 n 0000058059 00000 n 0000058273 00000 n 0000058481 00000 n 0000058744 00000 n 0000059061 00000 n 0000059362 00000 n 0000059840 00000 n 0000060145 00000 n 0000060508 00000 n 0000061006 00000 n 0000061219 00000 n 0000061492 00000 n 0000061760 00000 n 0000062008 00000 n 0000062251 00000 n 0000062446 00000 n 0000062643 00000 n 0000062899 00000 n 0000063151 00000 n 0000063336 00000 n 0000063588 00000 n 0000063785 00000 n 0000064002 00000 n 0000064182 00000 n 0000064420 00000 n 0000064608 00000 n 0000064844 00000 n 0000065035 00000 n 0000065219 00000 n 0000065417 00000 n 0000065666 00000 n 0000065998 00000 n 0000066318 00000 n 0000066583 00000 n 0000066854 00000 n 0000067153 00000 n 0000067417 00000 n 0000067645 00000 n 0000067871 00000 n 0000068179 00000 n 0000068368 00000 n 0000068667 00000 n 0000068871 00000 n 0000069129 00000 n 0000069404 00000 n 0000069655 00000 n 0000069910 00000 n 0000070188 00000 n 0000070505 00000 n 0000070710 00000 n 0000070958 00000 n 0000071228 00000 n 0000071506 00000 n 0000071779 00000 n 0000072051 00000 n 0000072319 00000 n 0000072582 00000 n 0000072856 00000 n 0000073138 00000 n 0000073373 00000 n 0000073707 00000 n 0000073949 00000 n 0000074162 00000 n 0000074412 00000 n 0000074691 00000 n 0000074887 00000 n 0000075139 00000 n 0000075375 00000 n 0000075639 00000 n 0000075920 00000 n 0000076212 00000 n 0000076451 00000 n 0000076717 00000 n 0000076953 00000 n 0000077182 00000 n 0000077449 00000 n 0000077704 00000 n 0000077987 00000 n 0000078305 00000 n 0000078562 00000 n 0000078846 00000 n 0000079068 00000 n 0000079371 00000 n 0000079678 00000 n 0000079940 00000 n 0000080228 00000 n 0000080550 00000 n 0000080814 00000 n 0000081108 00000 n 0000081684 00000 n 0000082210 00000 n 0000082769 00000 n 0000083858 00000 n 0000084044 00000 n 0000084218 00000 n 0000084590 00000 n 0000084906 00000 n 0000085293 00000 n 0000085603 00000 n 0000085857 00000 n 0000086238 00000 n 0000086423 00000 n 0000086794 00000 n 0000087126 00000 n 0000087369 00000 n 0000087658 00000 n 0000088041 00000 n 0000088354 00000 n 0000088664 00000 n 0000088959 00000 n 0000089261 00000 n 0000089568 00000 n 0000089816 00000 n 0000090178 00000 n 0000090426 00000 n 0000090638 00000 n 0000090826 00000 n 0000091069 00000 n 0000091363 00000 n 0000091671 00000 n 0000091913 00000 n 0000092217 00000 n 0000092471 00000 n 0000092718 00000 n 0000093015 00000 n 0000093372 00000 n 0000093969 00000 n 0000094327 00000 n 0000094713 00000 n 0000095195 00000 n 0000095378 00000 n 0000095555 00000 n 0000095729 00000 n 0000095980 00000 n 0000096317 00000 n 0000096606 00000 n 0000096950 00000 n 0000097227 00000 n 0000097492 00000 n 0000097732 00000 n 0000098075 00000 n 0000098278 00000 n 0000098460 00000 n 0000098679 00000 n 0000099013 00000 n 0000099355 00000 n 0000099685 00000 n 0000099999 00000 n 0000100343 00000 n 0000100576 00000 n 0000100853 00000 n 0000101205 00000 n 0000101631 00000 n 0000101911 00000 n 0000102183 00000 n 0000102448 00000 n 0000102725 00000 n 0000102997 00000 n 0000103233 00000 n 0000103578 00000 n 0000103816 00000 n 0000104019 00000 n 0000104205 00000 n 0000104474 00000 n 0000104706 00000 n 0000104963 00000 n 0000105236 00000 n 0000105461 00000 n 0000105729 00000 n 0000105960 00000 n 0000106190 00000 n 0000106507 00000 n 0000106802 00000 n 0000107128 00000 n 0000107397 00000 n 0000107600 00000 n 0000107912 00000 n 0000108230 00000 n 0000108499 00000 n 0000108809 00000 n 0000109125 00000 n 0000109406 00000 n 0000109988 00000 n 0000110418 00000 n 0000110851 00000 n 0000111581 00000 n 0000111989 00000 n 0000112337 00000 n 0000112756 00000 n 0000113095 00000 n 0000113404 00000 n 0000113677 00000 n 0000114107 00000 n 0000114293 00000 n 0000114531 00000 n 0000114923 00000 n 0000115320 00000 n 0000115726 00000 n 0000116097 00000 n 0000116524 00000 n 0000116781 00000 n 0000117095 00000 n 0000117523 00000 n 0000118063 00000 n 0000118388 00000 n 0000118653 00000 n 0000118965 00000 n 0000119305 00000 n 0000119572 00000 n 0000119790 00000 n 0000120172 00000 n 0000120558 00000 n 0000120864 00000 n 0000121230 00000 n 0000121625 00000 n 0000121945 00000 n 0000122614 00000 n 0000122899 00000 n 0000123188 00000 n 0000123619 00000 n 0000123933 00000 n 0000124259 00000 n 0000124606 00000 n 0000124928 00000 n 0000125239 00000 n 0000125526 00000 n 0000125877 00000 n 0000126119 00000 n 0000126396 00000 n 0000126762 00000 n 0000127105 00000 n 0000127435 00000 n 0000127782 00000 n 0000128061 00000 n 0000128382 00000 n 0000128706 00000 n 0000129105 00000 n 0000129426 00000 n 0000129721 00000 n 0000130044 00000 n 0000130376 00000 n 0000130664 00000 n 0000131252 00000 n 0000131436 00000 n 0000131655 00000 n 0000131977 00000 n 0000132247 00000 n 0000132516 00000 n 0000132701 00000 n 0000132884 00000 n 0000133142 00000 n 0000133397 00000 n 0000133581 00000 n 0000133792 00000 n 0000134037 00000 n 0000134223 00000 n 0000134435 00000 n 0000134610 00000 n 0000134844 00000 n 0000135026 00000 n 0000135247 00000 n 0000135435 00000 n 0000135610 00000 n 0000135781 00000 n 0000135984 00000 n 0000136265 00000 n 0000136641 00000 n 0000136894 00000 n 0000137150 00000 n 0000137384 00000 n 0000137673 00000 n 0000137939 00000 n 0000138255 00000 n 0000138545 00000 n 0000138886 00000 n 0000139161 00000 n 0000139423 00000 n 0000139670 00000 n 0000140005 00000 n 0000140211 00000 n 0000140398 00000 n 0000140619 00000 n 0000140944 00000 n 0000141268 00000 n 0000141588 00000 n 0000141836 00000 n 0000142138 00000 n 0000142475 00000 n 0000142706 00000 n 0000142978 00000 n 0000143299 00000 n 0000143687 00000 n 0000144047 00000 n 0000144359 00000 n 0000144672 00000 n 0000144957 00000 n 0000145236 00000 n 0000145499 00000 n 0000145778 00000 n 0000146048 00000 n 0000146270 00000 n 0000146588 00000 n 0000146824 00000 n 0000147027 00000 n 0000147258 00000 n 0000147535 00000 n 0000147724 00000 n 0000147982 00000 n 0000148210 00000 n 0000148479 00000 n 0000148756 00000 n 0000149039 00000 n 0000149260 00000 n 0000149536 00000 n 0000149768 00000 n 0000150002 00000 n 0000150266 00000 n 0000150580 00000 n 0000150871 00000 n 0000151171 00000 n 0000151435 00000 n 0000151704 00000 n 0000151906 00000 n 0000152215 00000 n 0000152531 00000 n 0000152800 00000 n 0000153107 00000 n 0000153431 00000 n 0000153709 00000 n 0000154055 00000 n 0000154623 00000 n 0000155188 00000 n 0000155766 00000 n 0000156919 00000 n 0000157095 00000 n 0000157342 00000 n 0000157528 00000 n 0000157703 00000 n 0000158073 00000 n 0000158487 00000 n 0000158780 00000 n 0000159071 00000 n 0000159427 00000 n 0000159675 00000 n 0000159881 00000 n 0000160072 00000 n 0000160312 00000 n 0000160602 00000 n 0000160901 00000 n 0000161126 00000 n 0000161420 00000 n 0000161661 00000 n 0000161944 00000 n 0000162271 00000 n 0000162600 00000 n 0000162888 00000 n 0000163100 00000 n 0000163440 00000 n 0000163778 00000 n 0000164314 00000 n 0000164592 00000 n 0000164921 00000 n 0000165297 00000 n 0000165474 00000 n 0000165673 00000 n 0000166070 00000 n 0000166525 00000 n 0000166893 00000 n 0000167241 00000 n 0000167464 00000 n 0000167668 00000 n 0000167956 00000 n 0000168286 00000 n 0000168552 00000 n 0000168914 00000 n 0000169186 00000 n 0000169470 00000 n 0000169879 00000 n 0000170272 00000 n 0000170701 00000 n 0000171412 00000 n 0000171643 00000 n 0000171958 00000 n 0000172224 00000 n 0000179366 00000 n 0000180066 00000 n 0000180142 00000 n 0000180884 00000 n 0000181054 00000 n 0000181222 00000 n 0000181387 00000 n 0000181544 00000 n 0000181740 00000 n 0000181942 00000 n 0000182127 00000 n 0000182310 00000 n 0000182425 00000 n 0000182507 00000 n 0000182588 00000 n 0000182626 00000 n 0000182793 00000 n trailer << /Size 618 /Root 616 0 R /Info 617 0 R /ID [<3D0EAA8E5D064DEF95B32D1627C6AAFA> <3D0EAA8E5D064DEF95B32D1627C6AAFA>] >> startxref 183119 %%EOF verilator-3.856/src/0000775000177100017500000000000012307720634014316 5ustar wsnyderwsnyderverilator-3.856/src/V3LinkLevel.cpp0000664000177100017500000001354612306677750017142 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-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. // //************************************************************************* // 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 } //###################################################################### // 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); 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.856/src/V3Broken.h0000664000177100017500000000237212306677750016135 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-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. // //************************************************************************* #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.856/src/V3Combine.cpp0000664000177100017500000004050012306677750016617 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-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. // //************************************************************************* // 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__<<": "< #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(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__<<": "< #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,"__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()+"'"; } string AstNode::quoteName(const string& namein) { // Encode control chars into C style escapes // Reverse is V3Parse::deQuote const char* start = namein.c_str(); string out; for (const char* pos = start; *pos; pos++) { if (pos[0]=='\\' || pos[0]=='"') { out += string("\\")+pos[0]; } else if (pos[0]=='\n') { out += "\\n"; } else if (pos[0]=='\r') { out += "\\r"; } else if (pos[0]=='\t') { out += "\\t"; } else if (isprint(pos[0])) { out += pos[0]; } else { // This will also cover \a etc char octal[10]; sprintf(octal,"\\%03o",pos[0]); out += octal; } } return out; } //###################################################################### // 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 4 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::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); // 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 it nodep = niterp; } else { // Same node, just 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::iterateAndNextIgnoreEdit(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; 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::sameTree(AstNode* node2p) { return sameTreeIter(node2p, true); } bool AstNode::sameTreeIter(AstNode* node2p, bool ignNext) { // 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)) { return false; } return (this->op1p()->sameTreeIter(node2p->op1p(),false) && this->op2p()->sameTreeIter(node2p->op2p(),false) && this->op3p()->sameTreeIter(node2p->op3p(),false) && this->op4p()->sameTreeIter(node2p->op4p(),false) && (ignNext || this->nextp()->sameTreeIter(node2p->nextp(),false)) ); } //====================================================================== // 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 (v3Global.opt.dumpTree() && 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.856/src/V3Trace.cpp0000664000177100017500000006513712306677750016316 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* // 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__<<": "< #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.856/src/V3Life.cpp0000664000177100017500000004273412306677750016135 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-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. // //************************************************************************* // 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__<<": "<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.856/src/V3Ast.h0000664000177100017500000024502012306677750015443 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ast node structure // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #ifndef _V3AST_H_ #define _V3AST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.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 // 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 }; 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", "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" }; 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); } }; 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; } 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 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)); } }; //###################################################################### struct VBasicTypeKey { int m_width; // From AstNodeDType: Bit width of operation int m_widthMin; // From AstNodeDType: If unsized, bitwidth of minimum implementation AstNumeric m_numeric; // From AstNodeDType: Node is signed AstBasicDTypeKwd m_keyword; // From AstBasicDType: What keyword created basic type VNumRange m_nrange; // From AstBasicDType: Numeric msb/lsb (if non-opaque keyword) inline bool operator== (const VBasicTypeKey& rhs) const { return m_width == rhs.m_width && m_widthMin == rhs.m_widthMin && m_numeric == rhs.m_numeric && m_keyword == rhs.m_keyword && m_nrange == rhs.m_nrange; } inline bool operator< (const VBasicTypeKey& rhs) const { if ( (m_width < rhs.m_width)) return true; if (!(m_width == rhs.m_width)) return false; // lhs > 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); 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 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 quoteName(const string& namein); // Name with control chars quoted 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 name" for error messages 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 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; 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 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* 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? 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 iterateAndNextIgnoreEdit(AstNVisitor& v, AstNUser* vup=NULL); void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next void iterateChildrenBackwards(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(); } struct AstNodeMath : public AstNode { // Math -- anything that's part of an expression tree 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; } }; struct AstNodeTermop : public AstNodeMath { // Terminal operator -- a operator with no "inputs" 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) { } }; struct AstNodeUniop : public AstNodeMath { // Unary math 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 signedFlavor() const { return false; } // Signed flavor of nodes with both flavors? virtual bool doubleFlavor() const { return false; } // D 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; } }; struct AstNodeBiop : public AstNodeMath { // Binary math 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 signedFlavor() const { return false; } // Signed flavor of nodes with both flavors? virtual bool doubleFlavor() const { return false; } // D 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; } }; struct AstNodeTriop : public AstNodeMath { // Trinary math 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; } }; struct AstNodeBiCom : public AstNodeBiop { // Binary math with commutative properties AstNodeBiCom(FileLine* fl, AstNode* lhs, AstNode* rhs) : AstNodeBiop(fl, lhs, rhs) {} ASTNODE_BASE_FUNCS(NodeBiCom) }; struct AstNodeBiComAsv : public AstNodeBiCom { // Binary math with commutative & associative properties AstNodeBiComAsv(FileLine* fl, AstNode* lhs, AstNode* rhs) : AstNodeBiCom(fl, lhs, rhs) {} ASTNODE_BASE_FUNCS(NodeBiComAsv) }; struct AstNodeCond : public AstNodeTriop { 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(); } }; struct AstNodePreSel : public AstNode { // Something that becomes an AstSel 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; } }; struct AstNodeStmt : public AstNode { // Statement -- anything that's directly under a function 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 }; struct AstNodeAssign : public AstNodeStmt { 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 "="; } }; struct AstNodeFor : public AstNodeStmt { 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; } }; struct 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; } }; struct AstNodeCase : public AstNodeStmt { 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); } }; struct AstNodeSenItem : public AstNode { // An AstSenItem or AstSenGate 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) { } }; struct 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; } }; struct AstNodeDType : public AstNode { private: // 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 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 to next non-typeref type virtual AstNodeDType* skipRefToConstp() const = 0; // recurses over typedefs to next non-typeref-or-const 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; } }; struct 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 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); } }; struct 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 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; }; struct AstNodeSel : public AstNodeBiop { // Single bit range extraction, perhaps with non-constant selection or array selection 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; } }; //###################################################################### // Tasks/functions common handling struct 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; } }; struct 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); } }; struct 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 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) { } 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; } 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::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 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.856/src/V3Premit.cpp0000664000177100017500000002575012307211732016476 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-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. // //************************************************************************* // 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" //###################################################################### // 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 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() && !nodep->lhsp()->castVarRef()->varp()->isSc() && 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()) { // Else might be cell interconnect or something 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, VFlagLogicPacked(), nodep->widthMin()); 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 { AstNRelinker linker; m_stmtp->unlinkFrBack(&linker); newp->addNext(m_stmtp); linker.relink(newp); } } void createDeepTemp(AstNode* nodep) { if (debug()>8) nodep->dumpTree(cout,"deepin:"); AstNRelinker linker; nodep->unlinkFrBack(&linker); AstVar* varp = getBlockTemp(nodep); // 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); 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()); } 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()->sameTree(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))); } } } //-------------------- // 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__<<": "< #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() // Until NEW_ORDERING, 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 = rhsVarRefs().begin(); it != 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 // 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); void optimizeElimVar(AstVarScope* varscp, AstNode* logicp, AstNode* consumerp); void warnSignals(); void consumedMark(); void consumedMarkRecurse(GateEitherVertex* vertexp); void consumedMove(); void replaceAssigns(); void dedupe(); // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { nodep->iterateChildren(*this); //if (debug()>6) m_graph.dump(); if (debug()>6) m_graph.dumpDotFilePrefixed("gate_pre"); 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(); // Warn warnSignals(); 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); } }; //---------------------------------------------------------------------- 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; while (V3GraphEdge* edgep = vvertexp->outBeginp()) { GateLogicVertex* consumeVertexp = dynamic_cast(edgep->top()); AstNode* consumerp = consumeVertexp->nodep(); optimizeElimVar(vvertexp->varScp(), substp, consumerp); // If the new replacement referred to a signal, // Correct the graph to point to this new generating variable for (GateVarRefList::const_iterator it = okVisitor.rhsVarRefs().begin(); it != okVisitor.rhsVarRefs().end(); ++it) { AstVarScope* newvarscp = (*it)->varScopep(); UINFO(9," Point-to-new vertex "<propagateAttrClocksFrom(vvertexp); } // Remove the edge edgep->unlinkDelete(); edgep=NULL; ++m_statRefs; } // 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); } } } } } } void GateVisitor::replaceAssigns() { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->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() {} // 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(); } //###################################################################### // 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__<<": "< $@ $(TGT): V3Ast__gen_classes.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} ${CPPFLAGSNOWALL} -c $< V3ParseGrammar.o: V3ParseGrammar.cpp V3ParseBison.c $(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $< V3ParseImp.o: V3ParseImp.cpp V3ParseBison.c $(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $< V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp $(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $< #### Generated files # Target rule called before parallel build to make generated files serial:: V3Ast__gen_classes.h V3ParseBison.c 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.856/src/V3Cdc.cpp0000664000177100017500000006663412306677750015754 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-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. // //************************************************************************* // 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*) { } //-------------------- // 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__<<": "<cast ##name(); } //###################################################################### //=== Ast* : Specific types // Netlist interconnect struct 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 { 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 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(widthMin()); } }; struct AstConstString : public AstNodeMath { // A constant string private: string m_name; public: AstConstString(FileLine* fl, const string& name) : AstNodeMath(fl), m_name(name) { rewidth(); } void rewidth() { if (m_name.length()==0) { dtypeSetLogicSized(1,1,AstNumeric::UNSIGNED); // 0 width isn't allowed due to historic special cases } else { dtypeSetLogicSized(((int)m_name.length())*8, ((int)m_name.length())*8, AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(ConstString, CONSTSTRING) 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(name()); } virtual bool same(AstNode* samep) const { return name()==samep->castConstString()->name(); } virtual int instrCount() const { return 2; } // C just loads a pointer virtual string name() const { return m_name; } void name(const string& flag) { m_name = flag; rewidth(); } }; struct 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; } }; //###################################################################### //==== Data Types struct AstTypedef : public AstNode { private: string m_name; public: AstTypedef(FileLine* fl, const string& name, VFlagChildDType, AstNodeDType* dtp) : AstNode(fl), m_name(name) { childDTypep(dtp); // Only for parser dtypep(NULL); // V3Width will resolve } ASTNODE_NODE_FUNCS(Typedef, TYPEDEF) 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(); } // 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; } }; struct 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; } }; struct 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, AstNode* 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 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; } }; struct 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) }; struct 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) }; struct 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 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 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); } } }; struct 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 int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } }; struct 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 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(); } }; struct 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 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; } }; struct AstStructDType : public AstNodeClassDType { AstStructDType(FileLine* fl, AstNumeric numericUnpack) : AstNodeClassDType(fl,numericUnpack) {} ASTNODE_NODE_FUNCS(StructDType, STRUCTDTYPE) virtual string verilogKwd() const { return "struct"; }; }; struct AstUnionDType : public AstNodeClassDType { //UNSUP: bool isTagged; AstUnionDType(FileLine* fl, AstNumeric numericUnpack) : AstNodeClassDType(fl,numericUnpack) {} ASTNODE_NODE_FUNCS(UnionDType, UNIONDTYPE) virtual string verilogKwd() const { return "union"; }; }; struct 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 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; } }; struct 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); } }; struct 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; } }; struct 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 int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } }; //###################################################################### struct 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); }; struct AstWordSel : public AstNodeSel { // Select a single word from a multi-word wide value 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; } }; struct AstSelExtract : public AstNodePreSel { // Range extraction, gets replaced with AstSel 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(); } }; struct AstSelBit : public AstNodePreSel { // Single bit range extraction, perhaps with non-constant selection or array selection // Gets replaced during link with AstArraySel or AstSel 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(); } }; struct AstSelPlus : public AstNodePreSel { // +: range extraction, perhaps with non-constant selection // Gets replaced during link with AstSel 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(); } }; struct AstSelMinus : public AstNodePreSel { // -: range extraction, perhaps with non-constant selection // Gets replaced during link with AstSel 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(); } }; struct 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; } }; struct 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); } }; struct 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_trace:1; // Trace this variable 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_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) 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 bool hasSimpleInit() const { return (op3p() && !op3p()->castInitArray()); } void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } void attrClockEn(bool flag) { m_attrClockEn = 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 trace(bool flag) { m_trace=flag; } // METHODS virtual void name(const string& name) { m_name = name; } 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; } 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; } }; struct 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; } }; struct AstImplicit : public AstNode { // Create implicit wires and do nothing else, for gates that are ignored // Parents: MODULE AstImplicit(FileLine* fl, AstNode* exprsp) : AstNode(fl) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(Implicit, IMPLICIT) AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Assign from }; struct 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 }; struct 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 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 }; struct 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 public: AstVarScope(FileLine* fl, AstScope* scopep, AstVar* varp) :AstNode(fl) , m_scopep(scopep), m_varp(varp) { m_circular = false; 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; } }; struct AstVarRef : public AstNodeVarRef { // A reference to a variable (lvalue or rvalue) 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; } }; struct 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()); } }; struct 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; } 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; } }; struct 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(); } }; struct AstModule : public AstNodeModule { // A module declaration AstModule(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(Module, MODULE) virtual string verilogKwd() const { return "module"; } }; struct AstNotFoundModule : public AstNodeModule { // A missing module declaration AstNotFoundModule(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(NotFoundModule, NOTFOUNDMODULE) virtual string verilogKwd() const { return "/*not-found-*/ module"; } }; struct AstPackage : public AstNodeModule { // A package declaration 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(); } }; struct AstPrimitive : public AstNodeModule { // A primitive declaration AstPrimitive(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(Primitive, PRIMITIVE) virtual string verilogKwd() const { return "primitive"; } }; struct 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; } }; struct AstIface : public AstNodeModule { // A module declaration AstIface(FileLine* fl, const string& name) : AstNodeModule (fl,name) { } ASTNODE_NODE_FUNCS(Iface, IFACE) }; struct 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; } }; struct 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; } }; struct 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 }; struct 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; // True if a Var has been created for 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) { 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; } }; struct 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; } }; struct 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 }; struct 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 }; //###################################################################### struct AstGenerate : public AstNode { // A Generate/end block // Parents: MODULE // Children: modItems 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); } }; struct 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 }; struct 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; } }; struct 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(); } }; //###################################################################### struct AstTask : public AstNodeFTask { // A task inside a module AstTask(FileLine* fl, const string& name, AstNode* stmtp) :AstNodeFTask(fl, name, stmtp) {} ASTNODE_NODE_FUNCS(Task, TASK) }; struct AstFunc : public AstNodeFTask { // A function inside a module 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; } }; struct AstTaskRef : public AstNodeFTaskRef { // A reference to a task 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) }; struct AstFuncRef : public AstNodeFTaskRef { // A reference to a function 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; } }; struct 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; } }; //###################################################################### struct 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()); } }; struct 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 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; } }; struct 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 }; struct 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(); } }; struct AstAlwaysPublic : public AstNodeStmt { // "Fake" sensitivity created by /*verilator public_flat_rw @(edgelist)*/ // Body statements are just AstVarRefs to the public signals 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(); } }; struct AstAlwaysPost : public AstNode { // Like always but post assignments for memory assignment IFs 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); } }; struct AstAssign : public AstNodeAssign { 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); } }; struct AstAssignAlias : public AstNodeAssign { // Like AstAssignW, but a true bidirect interconnection alias // If both sides are wires, there's no LHS vs RHS, 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; } }; struct AstAssignDly : public AstNodeAssign { 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 "<="; } }; struct AstAssignW : public AstNodeAssign { // Like assign, but wire/assign's in verilog, the only setting of the specified variable 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; } }; struct AstAssignVarScope : public AstNodeAssign { // Assign two VarScopes to each other 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); } }; struct 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; } }; struct AstAssignPre : public AstNodeAssign { // Like Assign, but predelayed assignment requiring special order handling 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); } }; struct AstAssignPost : public AstNodeAssign { // Like Assign, but predelayed assignment requiring special order handling 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); } }; struct 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 }; struct AstCond : public AstNodeCond { // Conditional ?: statement // Parents: MATH // Children: MATH AstCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) : AstNodeCond(fl, condp, expr1p, expr2p) {} ASTNODE_NODE_FUNCS(Cond, COND) }; struct AstCondBound : public AstNodeCond { // Conditional ?: statement, specially made for saftey checking of array bounds // Parents: MATH // Children: MATH AstCondBound(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) : AstNodeCond(fl, condp, expr1p, expr2p) {} ASTNODE_NODE_FUNCS(CondBound, CONDBOUND) }; struct 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; } }; struct 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 }; struct AstCoverToggle : public AstNodeStmt { // Toggle analysis of given signal // Parents: MODULE // Children: AstCoverInc, orig var, change det var 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(); } }; struct AstGenCase : public AstNodeCase { // Generate Case statement // Parents: {statement list} // exprp Children: MATHs // casesp Children: CASEITEMs AstGenCase(FileLine* fileline, AstNode* exprp, AstNode* casesp) : AstNodeCase(fileline, exprp, casesp) { } ASTNODE_NODE_FUNCS(GenCase, GENCASE) }; struct 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; } }; struct 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; } }; struct 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; } }; struct 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); } }; struct AstSFormat : public AstNode { // Parents: statement container // Children: string to load // Children: SFORMATF to generate print string AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp) : AstNode (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); } }; struct AstSysIgnore : public AstNodeStmt { // Parents: stmtlist // Children: varrefs or exprs 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 }; struct AstFClose : public AstNodeStmt { // Parents: stmtlist // Children: file which must be a varref 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); } }; struct AstFOpen : public AstNodeStmt { 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(); } }; struct AstFFlush : public AstNodeStmt { // Parents: stmtlist // Children: file which must be a varref 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); } }; struct 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); } }; struct 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); } }; struct 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(); } }; struct AstSystemT : public AstNodeStmt { // $system used as task 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(); } }; struct AstSystemF : public AstNodeMath { // $system used as function 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(); } }; struct 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; } }; struct 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; } }; struct AstGenFor : public AstNodeFor { AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp, AstNode* incsp, AstNode* bodysp) : AstNodeFor(fileline, initsp, condp, incsp, bodysp) { } ASTNODE_NODE_FUNCS(GenFor, GENFOR) }; struct AstRepeat : public AstNodeStmt { 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; } }; struct AstWhile : public AstNodeStmt { 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 }; struct AstBreak : public AstNodeStmt { 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 }; struct AstContinue : public AstNodeStmt { 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 }; struct 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 }; struct AstReturn : public AstNodeStmt { 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 }; struct AstGenIf : public AstNodeIf { AstGenIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp) : AstNodeIf(fileline, condp, ifsp, elsesp) { } ASTNODE_NODE_FUNCS(GenIf, GENIF) }; struct 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; } }; struct 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; } }; struct 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; } }; struct AstUntilStable : public AstNodeStmt { // Quasi-while loop until given signals are stable // Parents: CFUNC (generally) // Children: VARREF, statements 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; } }; struct 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 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(); } }; struct 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; } }; struct 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; } }; struct AstInitial : public AstNode { 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(); } }; struct AstFinal : public AstNode { AstFinal(FileLine* fl, AstNode* bodysp) : AstNode(fl) { addNOp1p(bodysp); } ASTNODE_NODE_FUNCS(Final, FINAL) AstNode* bodysp() const { return op1p()->castNode(); } // op1 = Expressions to evaluate }; struct AstInside : public AstNodeMath { 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 }; struct AstInsideRange : public AstNodeMath { 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 }; struct 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. // Parents: ASTVAR::init() // Children: CONSTs... AstInitArray(FileLine* fl, AstNode* initsp) : AstNode(fl) { addNOp1p(initsp); } ASTNODE_NODE_FUNCS(InitArray, INITARRAY) AstNode* initsp() const { return op1p()->castNode(); } // op1 = Initial value expressions void addInitsp(AstNode* newp) { addOp1p(newp); } }; struct 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(); } }; struct AstStop : public AstNodeStmt { 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(); } }; struct AstFinish : public AstNodeStmt { 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(); } }; struct 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; } }; struct 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(); } }; struct 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(); } }; struct 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); }; struct 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); } string scopeSymName() const; // Name for __Vscope variable including children string scopePrettyName() const; // Name for __Vscope printing bool dpiExport() const { return m_dpiExport; } void dpiExport(bool flag) { m_dpiExport=flag; } }; struct AstUdpTable : public AstNode { AstUdpTable(FileLine* fl, AstNode* bodysp) : AstNode(fl) { addNOp1p(bodysp); } ASTNODE_NODE_FUNCS(UdpTable, UDPTABLE) AstUdpTableLine* bodysp() const { return op1p()->castUdpTableLine(); } // op1 = List of UdpTableLines }; struct 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 struct 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; } }; struct AstTime : public AstNodeTermop { 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; } }; struct AstTimeD : public AstNodeTermop { 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; } }; struct AstUCFunc : public AstNodeMath { // User's $c function // Perhaps this should be an AstNodeListop; but there's only one list math right now 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 struct AstNegate : public AstNodeUniop { 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;} }; struct AstNegateD : public AstNodeUniop { 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; } }; struct AstRedAnd : public AstNodeUniop { 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;} }; struct AstRedOr : public AstNodeUniop { 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;} }; struct AstRedXor : public AstNodeUniop { 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()); } }; struct AstRedXnor : public AstNodeUniop { // AstRedXnors are replaced with AstRedXors in V3Const. 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()); } }; struct AstLogNot : public AstNodeUniop { 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;} }; struct AstNot : public AstNodeUniop { 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;} }; struct AstExtend : public AstNodeUniop { // Expand a value into a wider entity by 0 extension. Width is implied from nodep->width() 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; } }; struct AstExtendS : public AstNodeUniop { // Expand a value into a wider entity by sign extension. Width is implied from nodep->width() AstExtendS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} AstExtendS(FileLine* fl, AstNode* lhsp, int width) : AstNodeUniop(fl, lhsp) { dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); } ASTNODE_NODE_FUNCS(ExtendS, EXTENDS) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opExtendS(lhs); } 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; } }; struct AstSigned : public AstNodeUniop { // $signed(lhs) 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; } }; struct AstUnsigned : public AstNodeUniop { // $unsigned(lhs) 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; } }; struct AstRToIS : public AstNodeUniop { // $rtoi(lhs) 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(); } }; struct AstRToIRoundS : public AstNodeUniop { 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(); } }; struct AstIToRD : public AstNodeUniop { 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(); } }; struct AstRealToBits : public AstNodeUniop { 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(); } }; struct AstBitsToRealD : public AstNodeUniop { 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(); } }; struct AstCLog2 : public AstNodeUniop { 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; } }; struct AstCountOnes : public AstNodeUniop { // Number of bits set in vector 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; } }; struct AstIsUnknown : public AstNodeUniop { // True if any unknown bits 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;} }; struct AstOneHot : public AstNodeUniop { // True if only single bit set in vector 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; } }; struct AstOneHot0 : public AstNodeUniop { // True if only single bit, or no bits set in vector 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; } }; struct AstCast : public AstNode { // Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc 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(); } }; struct AstCastSize : public AstNode { // Cast to specific size; signed/twostate inherited from lower element per IEEE 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(); } }; struct 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; } }; struct AstCvtPackString : public AstNodeUniop { // Convert to Verilator Packed Pack (aka Pack) AstCvtPackString(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetUInt64(); } // 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; } }; struct AstFEof : public AstNodeUniop { 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(); } }; struct AstFGetC : public AstNodeUniop { 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(); } }; struct AstCeilD : public AstNodeUniop { 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; } }; struct AstExpD : public AstNodeUniop { 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; } }; struct AstFloorD : public AstNodeUniop { 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; } }; struct AstLogD : public AstNodeUniop { 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; } }; struct AstLog10D : public AstNodeUniop { 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; } }; struct AstSqrtD : public AstNodeUniop { 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 struct AstLogOr : public AstNodeBiop { 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(); } }; struct AstLogAnd : public AstNodeBiop { 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(); } }; struct AstLogIf : public AstNodeBiop { 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(); } }; struct AstLogIff : public AstNodeBiCom { 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(); } }; struct AstOr : public AstNodeBiComAsv { 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;} }; struct AstAnd : public AstNodeBiComAsv { 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;} }; struct AstXor : public AstNodeBiComAsv { 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;} }; struct AstXnor : public AstNodeBiComAsv { 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;} }; struct AstEq : public AstNodeBiCom { 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;} }; struct AstEqD : public AstNodeBiCom { 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; } }; struct AstNeq : public AstNodeBiCom { 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;} }; struct AstNeqD : public AstNodeBiCom { 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; } }; struct AstLt : public AstNodeBiop { 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;} }; struct AstLtD : public AstNodeBiop { 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; } }; struct AstLtS : public AstNodeBiop { 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; } }; struct AstGt : public AstNodeBiop { 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;} }; struct AstGtD : public AstNodeBiop { 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; } }; struct AstGtS : public AstNodeBiop { 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; } }; struct AstGte : public AstNodeBiop { 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;} }; struct AstGteD : public AstNodeBiop { 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; } }; struct AstGteS : public AstNodeBiop { 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; } }; struct AstLte : public AstNodeBiop { 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;} }; struct AstLteD : public AstNodeBiop { 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; } }; struct AstLteS : public AstNodeBiop { 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; } }; struct AstShiftL : public AstNodeBiop { 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;} }; struct AstShiftR : public AstNodeBiop { 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 }; struct AstShiftRS : public AstNodeBiop { // Shift right with sign extension, >>> operator // Output data type's width determines which bit is used for sign extension AstShiftRS(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0) : AstNodeBiop(fl, lhsp, rhsp) { 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); } 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; } }; struct AstAdd : public AstNodeBiComAsv { 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;} }; struct AstAddD : public AstNodeBiComAsv { 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; } }; struct AstSub : public AstNodeBiop { 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;} }; struct AstSubD : public AstNodeBiop { 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; } }; struct AstMul : public AstNodeBiComAsv { 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(); } }; struct AstMulD : public AstNodeBiComAsv { 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; } }; struct AstMulS : public AstNodeBiComAsv { 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; } }; struct AstDiv : public AstNodeBiop { 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(); } }; struct AstDivD : public AstNodeBiop { 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; } }; struct AstDivS : public AstNodeBiop { 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; } }; struct AstModDiv : public AstNodeBiop { 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(); } }; struct AstModDivS : public AstNodeBiop { 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; } }; struct AstPow : public AstNodeBiop { 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(); } }; struct AstPowD : public AstNodeBiop { 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(); } virtual bool doubleFlavor() const { return true; } }; struct AstPowS : public AstNodeBiop { AstPowS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(PowS, POWS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "VL_POWS_%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(); } virtual bool signedFlavor() const { return true; } }; struct AstEqCase : public AstNodeBiCom { 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;} }; struct AstNeqCase : public AstNodeBiCom { 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;} }; struct AstEqWild : public AstNodeBiop { // Note wildcard operator rhs differs from lhs 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;} }; struct AstNeqWild : public AstNodeBiop { 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;} }; struct AstConcat : public AstNodeBiop { // If you're looking for {#{}}, see AstReplicate 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; } }; struct AstReplicate : public AstNodeBiop { // Verilog {rhs{lhs}} - Note rhsp() is the replicate value, not the lhsp() AstReplicate(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { if (AstConst* constp=rhsp->castConst()) { dtypeSetLogicSized(lhsp->width()*constp->toUInt(), lhsp->width()*constp->toUInt(), AstNumeric::UNSIGNED); } } AstReplicate(FileLine* fl, AstNode* lhsp, uint32_t repCount) : AstNodeBiop(fl, lhsp, new AstConst(fl, repCount)) {} 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; } }; struct 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 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;} }; struct AstFGetS : public AstNodeBiop { 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(); } }; struct AstPattern : public AstNodeMath { // Verilog '{a,b,c,d...} // Parents: AstNodeAssign, AstPattern, ... // Children: expression, AstPattern, AstPatReplicate 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 }; struct 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) { setOp1p(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 lhsp()?"%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* lhsp() const { return op1p(); } // op1 = expression to assign or another AstPattern 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 struct AstVAssert : public AstNodeStmt { // Verilog Assertion // Parents: {statement list} // Children: expression, if pass statements, if fail statements 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 struct AstClocking : public AstNode { // Set default clock region // Parents: MODULE // Children: Assertions 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 struct AstPslDefClock : public AstNode { // Set default PSL clock // Parents: MODULE // Children: SENITEM AstPslDefClock(FileLine* fl, AstNodeSenItem* sensesp) : AstNode(fl) { addNOp1p(sensesp); } ASTNODE_NODE_FUNCS(PslDefClock, PSLDEFCLOCK) AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list }; struct AstPslClocked : public AstNode { // A clocked property // Parents: ASSERT|COVER (property) // Children: SENITEM, Properties 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 }; struct AstPslAssert : public AstNodeStmt { // Psl Assertion // Parents: {statement list} // Children: expression, report string private: string m_name; // Name to report public: AstPslAssert(FileLine* fl, AstNode* propp, const string& name="") : AstNodeStmt(fl) , m_name(name) { addOp1p(propp); } ASTNODE_NODE_FUNCS(PslAssert, PSLASSERT) 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(); } 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 }; struct 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 }; //====================================================================== // PSL Expressions struct AstPslBool : public AstNode { // Separates PSL Sere/sequences from the normal expression boolean layer below. // Note this excludes next() and similar functions; they are time domain, so not under AstPslBool. // Parents: Sequences, etc. // Children: math AstPslBool(FileLine* fileline, AstNode* exprp) : AstNode(fileline) { addOp1p(exprp); } ASTNODE_NODE_FUNCS(PslBool, PSLBOOL) AstNode* exprp() const { return op1p()->castNode(); } // op1= expression virtual bool hasDType() const { return true; } virtual bool isGateOptimizable() const { return false; } // Not relevant virtual bool isPredictOptimizable() const { return false; } // Not relevant virtual int instrCount() const { return 0; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; //====================================================================== // Text based nodes struct 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; } }; struct AstScCtor : public AstNodeText { 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; } }; struct AstScDtor : public AstNodeText { 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; } }; struct AstScHdr : public AstNodeText { 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; } }; struct AstScImp : public AstNodeText { 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; } }; struct AstScImpHdr : public AstNodeText { 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; } }; struct AstScInt : public AstNodeText { 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; } }; struct AstUCStmt : public AstNodeStmt { // User $c statement 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 struct 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; } }; struct 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_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_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 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 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; } }; struct 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); } }; struct AstCReturn : public AstNodeStmt { // C++ return from a function // Parents: CFUNC/statement // Children: Math 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(); } }; struct 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 }; struct AstCStmt : public AstNodeStmt { // Emit C statement 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 struct 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 struct 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.856/src/.gitignore0000664000177100017500000000011412111011551016262 0ustar wsnyderwsnyder*~ *.old config_build.h Makefile Makefile_obj .objcache* obj_* config_rev.h verilator-3.856/src/V3EmitXml.cpp0000664000177100017500000001464312306677750016633 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-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 "config_build.h" #include "verilatedos.h" #include #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(AstNode::quoteName(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.856/src/V3Descope.cpp0000664000177100017500000002270012306677750016627 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-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. // //************************************************************************* // 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__<<": "< #include #include #include #include #include "V3Global.h" #include "V3Broken.h" #include "V3Ast.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 static const int FLAG_ALLOCATED = 0x01; // new() and not delete()ed static const int FLAG_IN_TREE = 0x02; // Is in netlist tree static const int FLAG_LINKABLE = 0x04; // Is in netlist tree, can be linked to static const int FLAG_LEAKED = 0x08; // Known to have been leaked static const int 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()) { s_nodes.insert(make_pair(nodep,FLAG_ALLOCATED)); } } 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->iterateChildren(*this); } public: // CONSTUCTORS BrokenMarkVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~BrokenMarkVisitor() {} }; //###################################################################### // Broken state, as a visitor of each AstNode class BrokenCheckVisitor : public AstNVisitor { private: 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()) { if (dnodep->width() != dnodep->widthMin() && v3Global.assertWidthsMatch()) { dnodep->v3fatalSrc("Width != WidthMin"); } } } if (v3Global.assertWidthsMatch()) { if (nodep->width() != nodep->widthMin()) { nodep->v3fatalSrc("Width != WidthMin"); } } nodep->iterateChildren(*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__<<": "< 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__<<": "< #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); } } } 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.856/src/V3Simulate.h0000664000177100017500000005727712306677750016516 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-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. // //************************************************************************* // // 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); } // 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 (!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()); // Copy by value, not reference, as we don't want a=a+1 to get right results if (nodep->castAssignDly()) { // Don't do setNumber, as value isn't yet visible to following statements newOutNumber(vscp)->opAssign(*fetchNumber(nodep->rhsp())); } else { newNumber(vscp)->opAssign(*fetchNumber(nodep->rhsp())); newOutNumber(vscp)->opAssign(*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"); 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.856/src/V3Undriven.cpp0000664000177100017500000003264312306677750017046 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-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. // //************************************************************************* // 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*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().c_str(), regexpp); } 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) 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 (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"; } } 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; } 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()!="") 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 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":"") <<"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.856/src/V3Cdc.h0000664000177100017500000000225512306677750015406 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-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. // //************************************************************************* #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.856/src/V3TraceDecl.h0000664000177100017500000000224712306677750016544 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves Tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #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.856/src/V3Unroll.h0000664000177100017500000000234612306677750016171 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-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. // //************************************************************************* #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.856/src/V3Split.cpp0000664000177100017500000005276112306677750016352 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-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. // //************************************************************************* // 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) {} 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 uint32_t m_stepNum; // Step number we need to ignore a edge in 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__<<": "< #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); 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); 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__<<": "< #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__<<": "< #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 AstNodeModule* m_modp; // Current module 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* varIgnoreTrace(AstVar* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3Coverage::varIgnoreToggle string prettyName = nodep->prettyName(); if (!nodep->isTrace()) { return "Verilator trace_off"; } else if (!v3Global.opt.traceUnderscore()) { if (prettyName.c_str()[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) { VNumRange bitRange; AstBasicDType* bdtypep = m_traValuep->dtypep()->basicp(); if (bdtypep) bitRange = bdtypep->nrange(); AstTraceDecl* declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname, m_traValuep, bitRange, arrayRange); if (m_initSubStmts && v3Global.opt.outputSplitCTrace() && m_initSubStmts > 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 (varIgnoreTrace(varp)) { addIgnore(varIgnoreTrace(varp)); } 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()); } 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()); } 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()); } 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(); m_traValuep->dumpTree(cout, "-tv: "); 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) { addTraceDecl(VNumRange()); } } 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__<<": "< 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__<<": "< #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 // AstVar::user3p -> AstVarScope for packages AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; // 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 // METHODS 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*) { 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); } 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); // 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 if (m_modp->castPackage() ? !nodep->user3p() : !nodep->user1p()) { AstVarScope* varscp = new AstVarScope(nodep->fileline(), m_scopep, nodep); UINFO(6," New scope "<user1p(varscp); if (m_modp->castPackage()) nodep->user3p(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 { nodep->varp()->accept(*this); AstVarScope* varscp = nodep->packagep() ? (AstVarScope*)nodep->varp()->user3p() : (AstVarScope*)nodep->varp()->user1p(); if (!varscp) nodep->v3fatalSrc("Can't locate varref scope"); nodep->varScopep(varscp); } } 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); 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__<<": "< #include #include "V3Error.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 int m_pslParenLevel;// PSL Parenthesis (){} counting, so we can find final ; bool m_pslMoreNeeded;// Next // comment is really psl bool m_defCmtSlash; // /*...*/ comment in define had \ ending 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_defCmtSlash = false; m_tokFilelinep = filelinep; m_enterExit = 0; m_pslParenLevel = 0; m_pslMoreNeeded = false; 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.856/src/bisonpre0000775000177100017500000004017312306677750016103 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.318'; 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/) { ($line =~ /BISONPRE_VERSION\((\S+)\s*,\s*([^\),]+)\)\s*$/) or die "%Error: $filename:$l: Bad form of BISONPRE_VERSION: $line\n"; my $ver=$1; my $cmd=$2; if ($Self->{bison_version} >= $1) { $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-2014 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.856/src/V3Order.cpp0000664000177100017500000021661312306677750016330 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Block code ordering // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* // 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. // // #ifdef NEW_ORDERING // Determine nodes that form loops within combo logic // (Strongly connected ignoring assign post/pre's) // Make a subgraph for each loop of combo logic // Break circular logic in each subgraph // // Determine nodes that form loops within a single eval call // Make a subgraph for each loop of sequential logic // Break circular logic in each subgraph #endif // // 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(); } }; //###################################################################### // 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_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()); return up->newVarUserVertex(&m_graph, m_scopep, varscp, type, createdp); } 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: "< 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(); 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 if (nodep->hasInitial()) return; // Ignore initials 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 (gen) varscp->user4(varscp->user4() | VU_GEN); if (con) varscp->user4(varscp->user4() | VU_CON); // Add edges if (!m_inClocked || m_inPost ) { // Combo logic if ( #ifdef NEW_ORDERING m_activep && m_activep->hasSettle() #else 0 #endif ) { // Inside settlement; we use special variable names to prevent // having extra logic to break arcs within #ifdef NEW_ORDERING if (gen) { // Add edge logic_vertex->logic_generated_var bool created = false; OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_SETL, &created); new OrderComboCutEdge(&m_graph, m_logicVxp, varVxp); if (created) new OrderEdge(&m_graph, m_settleVxp, varVxp, WEIGHT_INPUT); } if (con) { // Add edge logic_consumed_var->logic_vertex bool created = false; OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_SETL, &created); new OrderEdge(&m_graph, varVxp, m_logicVxp, WEIGHT_MEDIUM); if (created) new OrderEdge(&m_graph, m_settleVxp, varVxp, WEIGHT_INPUT); } #endif // NEW_ORDERING } else { // 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 { 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*) { iterateNewStmt(nodep); } virtual void visit(AstAssignPre* nodep, AstNUser*) { m_inPre = true; iterateNewStmt(nodep); m_inPre = false; } virtual void visit(AstAssignPost* nodep, AstNUser*) { m_inPost = true; iterateNewStmt(nodep); m_inPost = false; } virtual void visit(AstCoverToggle* nodep, AstNUser*) { 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_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); } }; //###################################################################### // Pre-Loop elimination #ifdef NEW_ORDERING void OrderVisitor::processInsLoop() { // Input is graph with color() reflecting the sub-graphs we need // to loop remove. Take all the I/O from each subgraph and route // through a new begin/end vertex // Note we DON'T only do certain edges; we want all edges to be preserved, // we'll select which are important later on. uint32_t maxcolor = 0; for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (maxcolor <= vertexp->color()) maxcolor = vertexp->color() + 1; if (OrderVarVertex* vvertexp = dynamic_cast(vertexp)) { vvertexp->pilNewVertexp(NULL); // Clear user-ish information before loop } } m_pmlLoopEndps.clear(); m_pmlLoopEndps.reserve(maxcolor); m_pmlLoopEndps.assign(maxcolor,NULL); m_graph.userClearVertices(); // Vertex::user() // true if added as begin/end for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (uint32_t loopColor = vertexp->color()) { OrderEitherVertex* evertexp = dynamic_cast(vertexp); if (!evertexp) v3fatalSrc("Non either vertex found"); if (!vertexp->user()) { UINFO(8," pil:nowInLoop lp="<fileline(), NULL, NULL); m_topScopep->addStmtsp(untilp); OrderLoopBeginVertex* beginp = new OrderLoopBeginVertex(&m_graph, m_scopetopp, evertexp->domainp(), untilp, m_loopIdMax, loopColor); m_loopIdMax = (OrderLoopId)(m_loopIdMax+1); UASSERT(LOOPID_MAX>m_loopIdMax, "loopid overflow "<color(loopColor); endp->color(loopColor); beginp->user(1); // Added; don't iterate on it endp->user(1); // Added; don't iterate on it } if (evertexp->inLoop()) { // Adding node to loop, but already in loop... // Ok if the nodes were a combo loop and now become a sequent loop, // The combo loop will be "under" the sequent loop, so keep the combo #. //UINFO(9, "Adding node to loop, but already in loop: "<name()<beginVertexp(); new OrderEdge(&m_graph, beginp, vertexp, WEIGHT_LOOPBE); new OrderEdge(&m_graph, vertexp, endp, WEIGHT_LOOPBE); evertexp->inLoop(beginp->loopId()); } } } } m_graph.userClearEdges(); // Edge::user() // true if we added it for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (vertexp->color()) { for (V3GraphEdge* nextp,* edgep = vertexp->outBeginp(); edgep; edgep = nextp) { nextp = edgep->outNextp(); // Func may edit the list if (edgep->weight()) { processInsLoopEdge(edgep); } else { // No purpose to this edge any longer edgep->unlinkDelete(); edgep=NULL; // remove old edge } } for (V3GraphEdge* nextp,* edgep = vertexp->inBeginp(); edgep; edgep = nextp) { nextp = edgep->inNextp(); // Func may edit the list if (edgep->weight()) { processInsLoopEdge(edgep); } else { // No purpose to this edge any longer edgep->unlinkDelete(); edgep=NULL; // remove old edge } } } } // Done with space m_pmlLoopEndps.clear(); } void OrderVisitor::processInsLoopNewEdge(V3GraphEdge* oldEdgep, V3GraphVertex* newFromp, V3GraphVertex* newTop) { // Create new edge based on the old edge's parameters const OrderEdge* oedgep = dynamic_cast(oldEdgep); V3GraphEdge* newEdgep = oedgep->clone(&m_graph, newFromp, newTop); newEdgep->user(1); // New edge doesn't need to be changed } OrderVarVertex* OrderVisitor::processInsLoopNewVar(OrderVarVertex* oldVertexp, bool& createdr) { // Create new VarVertex from given template if (oldVertexp->pilNewVertexp()) { createdr = false; } else { OrderVarVertex* newVertexp = oldVertexp->clone(&m_graph); oldVertexp->pilNewVertexp(newVertexp); createdr = true; } return oldVertexp->pilNewVertexp(); } void OrderVisitor::processInsLoopEdge(V3GraphEdge* oldEdgep) { if (!oldEdgep->user()) { // if not processed oldEdgep->user(1); // mark as processed if (oldEdgep->fromp()->color() == oldEdgep->top()->color()) { return; // Doesn't cross subgraphs } else { V3GraphVertex* newFromp = oldEdgep->fromp(); V3GraphVertex* newTop = oldEdgep->top(); //UINFO(6, " pile: "< "<fromp()->color()) { // Change to come from end block OrderLoopEndVertex* endp = m_pmlLoopEndps[fromId]; newFromp = endp; // If it goes from(to) a cutable VarVertex inside the Begin/End block, // we can't lose the variable, as we might need to cut that variable out // in the next pass of processLoops, and processBrokeLoops needs the var pointer. // We'll make another VarVertex (dup of the one "inside" the loop) // and point to it. if (oldEdgep->cutable()) { if (OrderVarVertex* vvFromp = dynamic_cast(oldEdgep->fromp())) { // end => newvarvtx -> {whatever} bool created; newFromp = processInsLoopNewVar(vvFromp, created/*ref*/); if (created) processInsLoopNewEdge(oldEdgep, endp, newFromp); } } } if (uint32_t toId = oldEdgep->top()->color()) { // Change to go to begin block OrderLoopEndVertex* endp = m_pmlLoopEndps[toId]; OrderLoopBeginVertex* beginp = endp->beginVertexp(); newTop = beginp; // Ditto above if (oldEdgep->cutable()) { if (OrderVarVertex* vvTop = dynamic_cast(oldEdgep->top())) { // oldfrom -> newvarvtx => begin bool created; newTop = processInsLoopNewVar(vvTop, created/*ref*/); if (created) processInsLoopNewEdge(oldEdgep, newTop, beginp); } } } // New edge with appropriate to/from processInsLoopNewEdge(oldEdgep, newFromp, newTop); oldEdgep->unlinkDelete(); oldEdgep=NULL; // remove old edge } } } #endif // NEW_ORDERING //###################################################################### // Pre-Loop elimination #ifdef NEW_ORDERING void OrderVisitor::processBrokeLoop() { // Find those loops that were broken for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { // Above processInsLoopEdge makes sure there's always a OrderVarVertex on // boundaries to/from LoopBegin/EndVertex'es if (OrderVarVertex* vvertexp = dynamic_cast(vertexp)) { // Any cut edges? bool anyCut = false; for (V3GraphEdge* nextp,* edgep = vertexp->inBeginp(); edgep; edgep = nextp) { nextp = edgep->inNextp(); // We may edit the list if (edgep->weight()==0) { // was cut anyCut = true; edgep->unlinkDelete(); edgep=NULL; // remove old edge } } for (V3GraphEdge* nextp,* edgep = vertexp->outBeginp(); edgep; edgep = nextp) { nextp = edgep->outNextp(); // We may edit the list if (edgep->weight()==0) { // was cut anyCut = true; edgep->unlinkDelete(); edgep=NULL; // remove old edge } } if (anyCut) { UINFO(6," pbl: Cut "<name()<varScp(), endp/*ref*/); // Add edge to graphically indicate change detect required endedgep->unlinkDelete(); endedgep=NULL; // remove old edge new OrderChangeDetEdge(&m_graph, vvertexp, endp); // Add variable dependency to until loop AstUntilStable* untilp = endp->beginVertexp()->untilp(); untilp->addStablesp(new AstVarRef(vvertexp->varScp()->fileline(), vvertexp->varScp(), false)); } } } } #endif // NEW_ORDERING //###################################################################### // 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 #ifndef NEW_ORDERING // *NOT* new ordering 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"); #ifndef NEW_ORDERING // New ordering set the input node as combo, so this happens automatically if (vvertexp && vvertexp->varScp()->varp()->isInput()) { domainp = m_comboDomainp; } #endif 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() #ifndef NEW_ORDERING && fromVertexp->domainMatters() #endif ) { UINFO(9," from d="<<(void*)fromVertexp->domainp()<<" "<hasSettle()) { // or, we can ignore being in the settle domain 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()) { // 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"); #ifdef NEW_ORDERING OrderMoveDomScope* domScopep = NULL; // Currently active domain/scope while (!m_pomReadyDomScope.empty()) { // Always need to reamin in same loop construct OrderLoopId curLoop = processMoveLoopCurrent(); // Scan list to find search candidates OrderMoveDomScope* loopHuntp = NULL; // Found domscope under same loop OrderMoveDomScope* domHuntp = NULL; // Found domscope under same domain OrderMoveDomScope* scopeHuntp = NULL; // Found domscope under same scope if (domScopep) { UINFO(6," MoveSearch: loop="<readyDomScopeNextp()) { if (huntp->inLoop() == curLoop) { if (!loopHuntp) loopHuntp = huntp; if (domScopep && huntp->domainp() == domScopep->domainp()) { if (!domHuntp) domHuntp = huntp; if (domScopep && huntp->scopep() == domScopep->scopep()) { if (!scopeHuntp) scopeHuntp = huntp; break; // Exact match; all we can hope for } } } } // Recompute the next domScopep to process if (scopeHuntp) { domScopep = scopeHuntp; UINFO(6," MoveIt: SameScope "<<*domScopep<domainp()->v3fatalSrc("Can't find more nodes like "<<*domScopep); // Should be at least a "end loop" break; } // Work on all vertices in this loop/domain/scope OrderMoveVertex* topVertexp = domScopep->readyVertices().begin(); UASSERT(topVertexp, "domScope on ready list without any nodes ready under it"); m_pomNewFuncp = NULL; while (OrderMoveVertex* vertexp = domScopep->readyVertices().begin()) { processMoveOne(vertexp, domScopep, 1); if (curLoop != processMoveLoopCurrent()) break; // Hit a LoopBegin/end, change loop } } if (!m_pomWaiting.empty()) { OrderMoveVertex* vertexp = m_pomWaiting.begin(); vertexp->logicp()->nodep()->v3fatalSrc("Didn't converge; nodes waiting, none ready, perhaps some input activations lost: "<readyVertices().begin(); 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()) { 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."); #endif // 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()) { #ifdef NEW_ORDERING // Beginning of loop. if (OrderLoopBeginVertex* beginp = dynamic_cast(lvertexp)) { m_pomNewFuncp = NULL; // Close out any old function // Create new active record string name = cfuncName(modp, domainp, scopep, nodep); AstActive* callunderp = new AstActive(nodep->fileline(), name, domainp); if (domainp == m_deleteDomainp) { UINFO(6," Delete loop "<unlinkFrBack(); callunderp->addStmtsp(nodep); // Remember we're in a loop processMoveLoopPush(beginp); } else if (OrderLoopEndVertex* endp = dynamic_cast(lvertexp)) { // Nodep is identical to OrderLoopBeginVertex's, so we don't move it m_pomNewFuncp = NULL; // Close out any old function processMoveLoopPop(endp->beginVertexp()); } else { nodep->v3fatalSrc("AstUntilStable node isn't under an OrderLoop{End}Vertex.\n"); } #else nodep->v3fatalSrc("Not implemented"); #endif } 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 #ifdef NEW_ORDERING void OrderVisitor::processLoops(string stepName, V3EdgeFuncP edgeFuncp) { UINFO(2," "<=4) m_graph.dumpDotFilePrefixed((string)"orderg_"+stepName+"_loops", true); // Remove loops from the graph UINFO(2," "<=4) m_graph.dumpDotFilePrefixed((string)"orderg_"+stepName+"_broke", true); m_graph.makeEdgesNonCutable(edgeFuncp); m_graph.dumpDotFilePrefixed((string)"orderg_"+stepName+"_done", true); } #endif void OrderVisitor::process() { // Dump data m_graph.dumpDotFilePrefixed("orderg_pre"); #ifdef NEW_ORDERING // Ignoring POST assignments and clocked statements, detect strongly connected components // Split components into subgraphs // Detect, loop begin/end, and acyc combo loops UINFO(2," Combo loop elimination...\n"); processLoops("combo", &OrderEdge::followComboConnected); // Detect, loop begin/end, and acyc post assigns UINFO(2," Sequential loop elimination...\n"); processLoops("sequent", &OrderEdge::followSequentConnected); // Detect and acyc any PRE assigns // As breaking these does not cause any problems, we don't need to loop begin/end, etc. UINFO(2," Pre Loop Detect & Acyc...\n"); m_graph.stronglyConnected(&V3GraphEdge::followAlwaysTrue); if (debug()>=4) m_graph.dumpDotFilePrefixed("orderg_preasn_strong", true); m_graph.acyclic(&V3GraphEdge::followAlwaysTrue); m_graph.dumpDotFilePrefixed("orderg_preasn_done", true); #else // 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"); #endif // 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 #ifndef NEW_ORDERING UINFO(2," Process Circulars...\n"); processCircular(); // must be before processDomains #endif // 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 "< #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(AstPslDefClock* nodep, AstNUser*) { nodep->iterateChildren(*this); // Store the new default clock, reset on new module m_seniDefaultp = nodep->sensesp(); // Trash it nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } 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(AstPslAssert* 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__<<": "< //============================================================================ 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.856/src/V3Graph.cpp0000664000177100017500000002753112306677750016315 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph optimizations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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 "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 #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 V3StringList m_vFiles; // argument: Verilog files to read DebugSrcMap m_debugSrcs; // argument: --debugi-= bool m_preprocOnly; // main switch: -E bool m_makeDepend; // main switch: -MMD bool m_makePhony; // main switch: -MP 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_warnFatal; // main switch: --warnFatal 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_psl; // main switch: --psl 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_trace; // main switch: --trace bool m_traceDups; // main switch: --trace-dups 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_errorLimit; // main switch: --error-limit 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_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); 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 getenvStr(const string& envvar, const string& defaultValue); static void setenvStr(const string& envvar, const string& value, const string& why); 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()); // METHODS void addCppFile(const string& filename); void addCFlags(const string& filename); void addLdLibs(const string& filename); void addLibraryFile(const string& filename); 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 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() || coverage()); } bool savable() const { return m_savable; } bool skipIdentical() const { return m_skipIdentical; } bool stats() const { return m_stats; } 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 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 warnFatal() const { return m_warnFatal; } 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 psl() const { return m_psl; } 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 errorLimit() const { return m_errorLimit; } 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; // 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 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 (generic file 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 static void unlinkRegexp(const string& dir, const string& regexp); // 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.856/src/V3LinkJump.h0000664000177100017500000000226512306677750016447 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-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. // //************************************************************************* #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.856/src/V3LinkLValue.cpp0000664000177100017500000002020712306677750017253 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-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. // //************************************************************************* // 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__<<": "< #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 class functions AstAssignW* V3Inst::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); if (pinVarp->width() > rhsp->width()) { if (rhsp->isSigned()) { rhsp = new AstExtendS(pinp->fileline(), rhsp); } else { rhsp = new AstExtend (pinp->fileline(), rhsp); } } else if (pinVarp->width() < rhsp->width()) { rhsp = new AstSel (pinp->fileline(), rhsp, 0, pinVarp->width()); } rhsp->dtypeFrom(pinVarp); // Need proper widthMin, which may differ from AstSel created above assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsp); pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, true)); } 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 visitor void V3Inst::instAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "< #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())); AstNode* timesp = nodep->fmtp()->exprsp(); if (timesp) timesp->unlinkFrBack(); // cppcheck-suppress nullPointer timesp = timesp->addNext(new AstTime(nodep->fileline())); nodep->fmtp()->exprsp(timesp); 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. return 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); } AstNode* newIfCoverageOn(AstNode* nodep) { // Add a internal if to check coverage is on // Don't make this a AND term, as it's unlikely to need to test this. return 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.coverage() ? (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicTrue())) : (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))), nodep, NULL); } 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 if (nodep->castPslAssert()) { bodysp = newFireAssert(nodep,message); // We assert the property is always true... so report when it fails // (Note this is opposite the behavior of coverage statements.) // Need: 'never' operator: not hold in current or any future cycle propp = new AstLogNot (nodep->fileline(), propp); } 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->castPslAssert()) 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; } // 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(AstPslAssert* nodep, AstNUser*) { nodep->iterateChildren(*this); newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), NULL, nodep->name()); nodep=NULL; ++m_statAsPsl; } 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; } // VISITORS //========== Temporal Layer // VISITORS //========== Boolean Layer virtual void visit(AstPslBool* nodep, AstNUser*) { nodep->replaceWith(nodep->exprp()->unlinkFrBack()); pushDeletep(nodep); nodep=NULL; } 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__<<": "<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.856/src/V3PreProc.h0000664000177100017500000000774112306677750016274 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilog::Preproc: Preprocess verilog code // // Code available from: http://www.veripool.org/verilator // // Authors: Wilson Snyder // //************************************************************************* // // Copyright 2000-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. // // 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 #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() { return true; } // Insert `line directives static bool pedantic() { return false; } // Obey standard; Don't substitute `error static bool optPsl(); // 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.856/src/V3Subst.cpp0000664000177100017500000003131312306677750016345 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-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. // //************************************************************************* // 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; } } // 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 (varrefp->varp()->isStatementTemp()) { 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() && varrefp->varp()->isStatementTemp()) { 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 && varrefp->varp()->isStatementTemp() && !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()->isStatementTemp()) { 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__<<": "< #include #include #include #include #include #include #include "V3Global.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"+V3Options::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.systemPerl()) { putMakeClassEntry(of, "Sp.cpp"); // Note Sp.cpp includes SpTraceVcdC } else { if (v3Global.opt.coverage()) { putMakeClassEntry(of, "SpCoverage.cpp"); } 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"); for (V3StringSet::const_iterator it = v3Global.opt.cFlags().begin(); it != v3Global.opt.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"); for (V3StringSet::const_iterator it = v3Global.opt.ldLibs().begin(); it != v3Global.opt.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"); for (V3StringSet::const_iterator it = v3Global.opt.cppFiles().begin(); it != v3Global.opt.cppFiles().end(); ++it) { string cppfile = *it; of.puts("\t"+V3Options::filenameNonExt(cppfile)+" \\\n"); string dir = V3Options::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 = v3Global.opt.cppFiles().begin(); it != v3Global.opt.cppFiles().end(); ++it) { string cppfile = *it; string basename = V3Options::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 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 (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* assignp) { assignp->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; } // Find out how many explicit dimensions are in a given ArraySel. unsigned explicitDimensions(AstArraySel* nodep) { 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; } 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 "<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->castNode(); } return topp->castArraySel(); } 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; } // 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 accross 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->op3p()) { refp = findVarRefRecurse(nodep->op3p()); 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()) { // 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 or 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__<<": "< #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(AstNode::quoteName(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()->iterateChildren(*this); putbs(","); if (nodep->filenamep()) nodep->filenamep()->iterateChildren(*this); putbs(","); if (nodep->modep()) nodep->modep()->iterateChildren(*this); puts(");\n"); } virtual void visit(AstFClose* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filep()) nodep->filep()->iterateChildren(*this); puts(");\n"); } virtual void visit(AstFFlush* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filep()) nodep->filep()->iterateChildren(*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()->iterateChildren(*this); puts("end\n"); } virtual void visit(AstReadMem* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filenamep()) nodep->filenamep()->iterateChildren(*this); putbs(","); if (nodep->memp()) nodep->memp()->iterateChildren(*this); if (nodep->lsbp()) { putbs(","); nodep->lsbp()->iterateChildren(*this); } if (nodep->msbp()) { putbs(","); nodep->msbp()->iterateChildren(*this); } puts(");\n"); } virtual void visit(AstSysIgnore* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); nodep->exprsp()->iterateChildren(*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(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)); } virtual void visit(AstConstString* nodep, AstNUser*) { putfs(nodep,""); putsQuoted(nodep->name()); } // 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()->iterateAndNext(*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) bool m_user3mark; // nodep->user3() if set means mark with %% // 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), m_user3mark(user3mark) { 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.856/src/V3EmitMk.h0000664000177100017500000000223012306677750016074 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit Makefile // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #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.856/src/V3Expand.h0000664000177100017500000000227612306677750016137 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-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. // //************************************************************************* #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.856/src/V3Case.cpp0000664000177100017500000004502412306677750016124 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-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. // //************************************************************************* // 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; 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; 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__<<": "< #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) {} 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.856/src/V3LinkCells.h0000664000177100017500000000240012306677750016565 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-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. // //************************************************************************* #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.856/src/V3Param.cpp0000664000177100017500000005375112306677750016317 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-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. // //************************************************************************* // 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 // 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->hasSimpleInit()) { nodep->v3fatalSrc("Parameter without initial value"); } V3Const::constifyParamsEdit(nodep); // The variable, not just the var->init() } } } // 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 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__<<": "< //============================================================================ 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.856/src/V3DepthBlock.cpp0000664000177100017500000001031112306677750017257 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-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. // //************************************************************************* // 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__<<": "< #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.856/src/config_rev.pl0000775000177100017500000000226612306677750017016 0ustar wsnyderwsnyder#!/usr/bin/perl -w ###################################################################### # # Copyright 2005-2014 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.856/src/V3Clean.cpp0000664000177100017500000002174412306677750016276 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-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. // //************************************************************************* // 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()); } // 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__<<": "< #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.856/src/V3Global.h0000664000177100017500000000653012306677750016115 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Common headers // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #ifndef _V3GLOBAL_H_ #define _V3GLOBAL_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.h" #include "V3Options.h" class AstNetlist; //====================================================================== // Statics //###################################################################### // V3 - The top level class for the entire program class V3Global { // Globals AstNetlist* m_rootp; // Root of entire netlist int m_debugFileNumber; // Number to append to debug files created bool m_assertDTypesResolved; // Tree should have dtypep()'s bool m_assertWidthsMatch; // Tree should have width()==widthMin() 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_assertDTypesResolved = false; m_assertWidthsMatch = 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; } bool assertDTypesResolved() const { return m_assertDTypesResolved; } bool assertWidthsMatch() const { return m_assertWidthsMatch; } // 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 assertWidthsMatch(bool flag) { m_assertWidthsMatch = 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.856/src/V3Width.h0000664000177100017500000000315312306677750015772 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-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. // //************************************************************************* #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.856/src/V3LinkResolve.h0000664000177100017500000000227412306677750017153 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-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. // //************************************************************************* #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.856/src/V3Assert.h0000664000177100017500000000224112306677750016151 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Assertion expansion // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-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. // //************************************************************************* #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.856/src/astgen0000775000177100017500000004331112306677750015540 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" => \&report, "debug" => \&debug, "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 debug { $Debug = 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; } 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 $self->print(" // Generated by astgen\n", " virtual void visit(Ast${type}* nodep, AstNUser*) {\n", " 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-2014 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.856/src/V3Number_test.cpp0000664000177100017500000001065212306677750017537 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-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. // //************************************************************************* // CHEAT! #define V3NUMBER_ASCII_BINARY #define _V3ERROR_NO_GLOBAL_ 1 #include "V3Error.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: "< //###################################################################### // 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.856/src/V3ParseGrammar.cpp0000664000177100017500000000211612306677750017625 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Parse syntax tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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 "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.856/src/V3Delayed.h0000664000177100017500000000225212306677750016261 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-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. // //************************************************************************* #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.856/src/V3LinkParse.cpp0000664000177100017500000003130712306677750017140 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-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. // //************************************************************************* // 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 // 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(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::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; } } 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(), 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_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__<<": "< #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__<<": "< #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 (const char* inp = format.c_str(); *inp; inp++) { char ch = tolower(*inp); // Breaks with iterators... 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__<<": "<$@ 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.856/src/V3GraphAcyc.cpp0000664000177100017500000005364012306677750017115 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph acyclic algorithm // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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 "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_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; } ~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.856/src/V3Tristate.cpp0000664000177100017500000014315312306677750017052 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-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. // //************************************************************************* // 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* andp = 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(nodep->fileline(), newlhsp,false); AstNode* ref2p = new AstVarRef(nodep->fileline(), newenp, false); andp = new AstAnd(nodep->fileline(), ref1p, ref2p); // or this to the others orp = (!orp) ? andp : new AstOr(nodep->fileline(), orp, andp); if (envarp) { AstNode* ref3p = new AstVarRef(nodep->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(nodep->fileline(), tmp, undrivenp)); } if (!undrivenp) { // No drivers on the bus V3Number ones(nodep->fileline(), lhsp->width()); ones.setAllBits1(); undrivenp = new AstConst(nodep->fileline(), ones); } if (!outvarp) { // This is the final resolution of the tristate, so we apply // the pull direction to any undriven pins. V3Number pull(nodep->fileline(), lhsp->width()); AstPull* pullp = (AstPull*)lhsp->user3p(); if (pullp && pullp->direction() == 1) { pull.setAllBits1(); UINFO(9,"Has pullup "<fileline(), undrivenp, new AstConst(nodep->fileline(), pull)); orp = new AstOr(nodep->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__<<": "< #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__<<": "< #include #include #include #include "V3Error.h" #ifndef _V3ERROR_NO_GLOBAL_ # include "V3Ast.h" # include "V3Global.h" # include "V3Stats.h" # include "V3Config.h" #endif //====================================================================== // Statics int V3Error::s_errCount = 0; int V3Error::s_warnCount = 0; int V3Error::s_debugDefault = 0; 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; codei 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; } void FileLine::updateLanguage () { language(v3Global.opt.fileLanguage(filename())); } 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 } //###################################################################### // V3Error class functions void V3Error::init() { for (int i=0; i20) numsp = 20; out<<(spaces + numsp); return out.str(); } void V3Error::incWarnings() { s_warnCount++; // We don't exit on a lot of warnings. } void V3Error::incErrors() { s_errCount++; if (errorCount() == v3Global.opt.errorLimit()) { // Not >= as would otherwise recurse v3fatal ("Exiting due to too many errors encountered; --error-limit="<=V3ErrorCode::EC_MIN) { V3Stats::addStatSum(string("Warnings, Suppressed ")+s_errorCode.ascii(), 1); 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.856/src/V3GenClk.h0000664000177100017500000000224512306677750016057 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Generated Clock Repairs // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #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.856/src/Verilator.cpp0000664000177100017500000005651712307212521016776 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: main() // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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 "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 "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 for (V3StringList::const_iterator it = v3Global.opt.vFiles().begin(); it != v3Global.opt.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 for (V3StringSet::const_iterator it = v3Global.opt.libraryFiles().begin(); it != v3Global.opt.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 () { bool dumpMore = (v3Global.opt.dumpTree() >= 9); // Sort modules by level so later algorithms don't need to care V3LinkLevel::modSortByLevel(); V3Global::dumpCheckGlobalTree("cells.tree"); V3Error::abortIfErrors(); // Convert parseref's to varrefs, and other directly post parsing fixups V3LinkParse::linkParse(v3Global.rootp()); V3Global::dumpCheckGlobalTree("linkparse.tree", 0, dumpMore); // Cross-link signal names // Cross-link dotted hierarchical references V3LinkDot::linkDotPrimary(v3Global.rootp()); V3Global::dumpCheckGlobalTree("linkdot.tree", 0, dumpMore); 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()); V3Global::dumpCheckGlobalTree("linkresolve.tree", 0, dumpMore); // Set Lvalue's in variable refs V3LinkLValue::linkLValue(v3Global.rootp()); V3Global::dumpCheckGlobalTree("linklvalue.tree", 0, dumpMore); // Convert return/continue/disable to jumps V3LinkJump::linkJump(v3Global.rootp()); V3Global::dumpCheckGlobalTree("link.tree"); 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()); V3Global::dumpCheckGlobalTree("param.tree", 0, dumpMore); V3LinkDot::linkDotParamed(v3Global.rootp()); // Cleanup as made new modules V3Global::dumpCheckGlobalTree("paramlink.tree"); V3Error::abortIfErrors(); // Remove any modules that were parameterized and are no longer referenced. V3Dead::deadifyModules(v3Global.rootp()); V3Global::dumpCheckGlobalTree("dead.tree", 0, dumpMore); v3Global.checkTree(); // Calculate and check widths, edit tree to TRUNC/EXTRACT any width mismatches V3Width::width(v3Global.rootp()); V3Global::dumpCheckGlobalTree("width.tree"); V3Error::abortIfErrors(); // Commit to the widths we've chosen; Make widthMin==width V3Width::widthCommit(v3Global.rootp()); v3Global.assertDTypesResolved(true); v3Global.assertWidthsMatch(true); V3Global::dumpCheckGlobalTree("widthcommit.tree", 0, dumpMore); // Coverage insertion // Before we do dead code elimination and inlining, or we'll lose it. if (v3Global.opt.coverage()) { V3Coverage::coverage(v3Global.rootp()); V3Global::dumpCheckGlobalTree("coverage.tree"); } // Push constants, but only true constants preserving liveness // so V3Undriven sees variables to be eliminated, ie "if (0 && foo) ..." V3Const::constifyAllLive(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const.tree"); // 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()); V3Global::dumpCheckGlobalTree("assertpre.tree"); // V3Assert::assertAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("assert.tree"); 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()); V3Global::dumpCheckGlobalTree("const.tree"); if (!v3Global.opt.xmlOnly()) { // Remove cell arrays (must be between V3Width and scoping) V3Inst::dearrayAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("dearray.tree", 0, dumpMore); } if (!v3Global.opt.xmlOnly()) { // Expand inouts, stage 2 // Also simplify pin connections to always be AssignWs in prep for V3Unknown V3Tristate::tristateAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("tristate.tree"); // 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 V3Global::dumpCheckGlobalTree("begin.tree"); // 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::dumpCheckGlobalTree("unknown.tree"); // 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()); V3Global::dumpCheckGlobalTree("inline.tree"); V3LinkDot::linkDotArrayed(v3Global.rootp()); // Cleanup as made new modules V3Global::dumpCheckGlobalTree("linkdot.tree", 0, dumpMore); } } //--PRE-FLAT OPTIMIZATIONS------------------ // Initial const/dead to reduce work for ordering code V3Const::constifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); v3Global.checkTree(); V3Dead::deadifyDTypes(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const.tree"); 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()); V3Global::dumpCheckGlobalTree("inst.tree"); // Inst may have made lots of concats; fix them V3Const::constifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const.tree"); // Flatten hierarchy, creating a SCOPE for each module's usage as a cell V3Scope::scopeAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("scope.tree"); V3LinkDot::linkDotScope(v3Global.rootp()); V3Global::dumpCheckGlobalTree("linkdot.tree"); } //--SCOPE BASED OPTIMIZATIONS-------------- if (!v3Global.opt.xmlOnly()) { // Cleanup V3Const::constifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyDTypes(v3Global.rootp()); v3Global.checkTree(); V3Global::dumpCheckGlobalTree("const.tree"); // 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()); V3Global::dumpCheckGlobalTree("case.tree"); // Inline all tasks V3Task::taskAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("task.tree"); // Add __PVT's // After V3Task so task internal variables will get renamed V3Name::nameAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("name.tree", 0, dumpMore); // Loop unrolling & convert FORs to WHILEs V3Unroll::unrollAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("unroll.tree"); // Expand slices of arrays V3Slice::sliceAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("slices.tree"); // Push constants across variables and remove redundant assignments V3Const::constifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const.tree"); if (v3Global.opt.oLife()) { V3Life::lifeAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("life.tree"); } // 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()); V3Global::dumpCheckGlobalTree("table.tree"); } // Cleanup V3Const::constifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyDTypes(v3Global.rootp()); v3Global.checkTree(); V3Global::dumpCheckGlobalTree("const.tree"); // 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()); V3Global::dumpCheckGlobalTree("clkgater.tree"); } // 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()); V3Global::dumpCheckGlobalTree("active.tree"); // Split single ALWAYS blocks into multiple blocks for better ordering chances if (v3Global.opt.oSplit()) { V3Split::splitAlwaysAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("split.tree", 0, dumpMore); } V3SplitAs::splitAsAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("splitas.tree"); // Create tracing sample points, before we start eliminating signals if (v3Global.opt.trace()) { V3TraceDecl::traceDeclAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("tracedecl.tree"); } // 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()); V3Global::dumpCheckGlobalTree("gate.tree"); // 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()); V3Global::dumpCheckGlobalTree("coveragejoin.tree"); } // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const.tree"); // 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()); V3Global::dumpCheckGlobalTree("reorder.tree"); } // Create delayed assignments // This creates lots of duplicate ACTIVES so ActiveTop needs to be after this step V3Delayed::delayedAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("delayed.tree"); // 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()); V3Global::dumpCheckGlobalTree("activetop.tree"); if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "PreOrder"); // Order the code; form SBLOCKs and BLOCKCALLs V3Order::orderAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("order.tree"); #ifndef NEW_ORDERING // Change generated clocks to look at delayed signals V3GenClk::genClkAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("genclk.tree"); #endif // Convert sense lists into IF statements. V3Clock::clockAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("clock.tree"); // 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()); } if (v3Global.opt.oLife() || v3Global.opt.oLifePost()) { V3Global::dumpCheckGlobalTree("life.tree"); } // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const.tree"); #ifndef NEW_ORDERING // Detect change loop V3Changed::changedAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("changed.tree"); #endif // 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()); V3Global::dumpCheckGlobalTree("trace.tree"); } if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Scoped"); // Remove scopes; make varrefs/funccalls relative to current module V3Descope::descopeAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("descope.tree"); } //--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()); V3Global::dumpCheckGlobalTree("deepblock.tree"); } // Move BLOCKTEMPS from class to local variables if (v3Global.opt.oLocalize()) { V3Localize::localizeAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("localize.tree", 0, dumpMore); } // Icache packing; combine common code in each module's functions into subroutines if (v3Global.opt.oCombine()) { V3Combine::combineAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("combine.tree"); } } V3Error::abortIfErrors(); //--GENERATION------------------ if (!v3Global.opt.xmlOnly()) { // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const.tree"); // 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.assertWidthsMatch(false); // Make all math operations either 8, 16, 32 or 64 bits V3Clean::cleanAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("clean.tree"); // Move wide constants to BLOCK temps. V3Premit::premitAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("premit.tree"); } // Expand macros and wide operators into C++ primitives if (!v3Global.opt.xmlOnly() && v3Global.opt.oExpand()) { V3Expand::expandAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("expand.tree"); } // Propagate constants across WORDSEL arrayed temporaries if (!v3Global.opt.xmlOnly() && v3Global.opt.oSubst()) { // Constant folding of expanded stuff V3Const::constifyCpp(v3Global.rootp()); V3Global::dumpCheckGlobalTree("const.tree"); V3Subst::substituteAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("subst.tree"); } if (!v3Global.opt.xmlOnly() && v3Global.opt.oSubstConst()) { // Constant folding of substitutions V3Const::constifyCpp(v3Global.rootp()); V3Global::dumpCheckGlobalTree("constc.tree", 0, dumpMore); V3Dead::deadifyAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("dead.tree"); } if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly()) { // Fix very deep expressions // Mark evaluation functions as member functions, if needed. V3Depth::depthAll(v3Global.rootp()); V3Global::dumpCheckGlobalTree("depth.tree", 0, dumpMore); // 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()); V3Global::dumpCheckGlobalTree("cast.tree"); } 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, --sp, --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 V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.tree"); V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.dot"); V3Options::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); 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.856/src/verilog.y0000664000177100017500000046126712306677750016210 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Bison grammer file // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* // 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 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 AstNodeModule* m_modp; // Module int m_modTypeImpNum; // Implicit type number, incremented each module // CONSTRUCTORS V3ParseGrammar() { m_impliedDecl = false; m_varDecl = AstVarType::UNKNOWN; m_varIO = AstVarType::UNKNOWN; m_varDTypep = NULL; m_memDTypep = NULL; m_pinNum = -1; m_instModule = ""; m_instParamp = NULL; m_modp = NULL; m_modTypeImpNum = 0; m_varAttrp = NULL; m_caseAttrp = NULL; } static V3ParseGrammar* singletonp() { static V3ParseGrammar singleton; return &singleton; } // METHODS void argWrapList(AstNodeFTaskRef* nodep); 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; } 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) { 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(); GRAMMARP->m_modp = pkgp; GRAMMARP->m_modTypeImpNum = 0; 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 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 yPSL "psl" %token yPSL_ASSERT "PSL assert" %token yPSL_CLOCK "PSL clock" %token yPSL_COVER "PSL cover" %token yPSL_REPORT "PSL report" %token yVL_CLOCK "/*verilator sc_clock*/" %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 yPSL_BRA "{" %token yPSL_KET "}" %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 %left prPSLCLK // 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 %% //********************************************************************** // Feedback to the Lexer // Note we read a parenthesis ahead, so this may not change the lexer at the right point. stateExitPsl: // For PSL lexing, return from PSL state /* empty */ { PARSEP->stateExitPsl(); } ; statePushVlg: // For PSL lexing, escape current state into Verilog state /* empty */ { PARSEP->statePushVlg(); } ; statePop: // Return to previous lexing state /* empty */ { PARSEP->statePop(); } ; //********************************************************************** // 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(v3Global.opt.trace() && $1->fileline()->tracingOn()); // 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(v3Global.opt.trace()); GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0; 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_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 parameter_port_listE portsStarE ';' module_itemListE yENDMODULE endLabelE { $1->modTrace(v3Global.opt.trace() && $1->fileline()->tracingOn()); // 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); 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(v3Global.opt.trace()); GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0; PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; udpFront: yPRIMITIVE lifetimeE idAny { $$ = new AstPrimitive($1,*$3); $$->inLibrary(true); $$->modTrace(false); $$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE)); PARSEP->fileline()->tracingOn(false); GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0; 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 param_assignment { $$ = $1; } | parameter_port_declarationFront 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 //UNSUP 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_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(v3Global.opt.trace() && $1->fileline()->tracingOn()); // 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(v3Global.opt.trace()); GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0; 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_declarationFront: // IEEE: parameter_port_declaration w/o assignment // // IEEE: parameter_declaration (minus assignment) parameter_declarationFront { } // //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; } ; 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->m_modTypeImpNum++), GRAMMARP->m_modp,VFlagChildDType(),$1),$2,true); } | enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->m_modTypeImpNum++), GRAMMARP->m_modp,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 AstSub($1,$2, new AstConst($1,1)), new AstConst($1,0)); } // // 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 ';' { $$ = new AstTypedef($1, *$3, 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($$); } ; //************************************************ // 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; } // // Verilator only | pslStmt { $$ = $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; } ; sigId: id { $$ = VARDONEA($1,*$1, NULL, NULL); } ; sigAttrListE: /* empty */ { $$ = NULL; } | sigAttrList { $$ = $1; } ; sigAttrList: sigAttr { $$ = $1; } | sigAttrList sigAttr { $$ = $1->addNextNull($2); } ; sigAttr: yVL_CLOCK { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK); } | 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 sigId sigAttrListE '=' expr { $$ = $1; $1->addAttrsp($2); $$->valuep($4); } //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;} //UNSUP: strengthSpecE for udp_instantiations ; instnameList: instnameParen { $$ = $1; } | instnameList ',' instnameParen { $$ = $1->addNext($3); } ; instnameParen: id instRangeE '(' cellpinList ')' { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp,$2); } | id instRangeE { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp,$2); } //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 } //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 AstNot($1,new AstRedAnd($1,$2)); } | yP_NOR ~r~expr %prec prREDUCTION { $$ = new AstNot($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 | '_' '(' statePushVlg expr statePop ')' { $$ = $4; } // 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. //UNSUP ~l~expr yP_TICK '(' expr ')' { UNSUP } | yaINTNUM yP_TICK '(' expr ')' { $$ = new AstCastSize($2,$4,new AstConst($1->fileline(),*$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 | '{' cateList '}' { $$ = $2; } // // 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; } // //UNSUP streaming_concatenation { UNSUP } ; 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} ; // Psl excludes {}'s by lexer converting to different token exprPsl: expr { $$ = $1; } ; // 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); } ; 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); } ; gateBuf: gateIdE instRangeE '(' variable_lvalue ',' expr ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateBufif0: gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8),$6)); DEL($2); } ; gateBufif1: gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8,$6)); DEL($2); } ; gateNot: gateIdE instRangeE '(' variable_lvalue ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateNotif0: gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8), new AstNot($3, $6))); DEL($2); } ; gateNotif1: gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8, new AstNot($3,$6))); DEL($2); } ; gateAnd: gateIdE instRangeE '(' variable_lvalue ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateNand: gateIdE instRangeE '(' variable_lvalue ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateOr: gateIdE instRangeE '(' variable_lvalue ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateNor: gateIdE instRangeE '(' variable_lvalue ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateXor: gateIdE instRangeE '(' variable_lvalue ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateXnor: gateIdE instRangeE '(' variable_lvalue ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gatePullup: gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, true); DEL($2); } ; gatePulldown: gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, false); DEL($2); } ; gateUnsup: gateIdE instRangeE '(' gateUnsupPinList ')' { $$ = new AstImplicit ($3,$4); DEL($2); } ; gateIdE: /*empty*/ {} | id {} ; gateAndPinList: expr { $$ = $1; } | gateAndPinList ',' expr { $$ = new AstAnd($2,$1,$3); } ; gateOrPinList: expr { $$ = $1; } | gateOrPinList ',' expr { $$ = new AstOr($2,$1,$3); } ; gateXorPinList: expr { $$ = $1; } | gateXorPinList ',' expr { $$ = new AstXor($2,$1,$3); } ; gateUnsupPinList: expr { $$ = $1; } | gateUnsupPinList ',' expr { $$ = $1->addNext($3); } ; 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 } ; 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::VerilogString(),$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 } ; //************************************************ // PSL Statements pslStmt: yPSL pslDir stateExitPsl { $$ = $2; } | yPSL pslDecl stateExitPsl { $$ = $2; } ; pslDir: id ':' pslDirOne { $$ = $3; } | pslDirOne { $$ = $1; } ; pslDirOne: yPSL_ASSERT pslProp ';' { $$ = new AstPslAssert($1,$2); } | yPSL_ASSERT pslProp yPSL_REPORT yaSTRING ';' { $$ = new AstPslAssert($1,$2,*$4); } | yPSL_COVER pslProp ';' { $$ = new AstPslCover($1,$2,NULL); } | yPSL_COVER pslProp yPSL_REPORT yaSTRING ';' { $$ = new AstPslCover($1,$2,NULL,*$4); } ; pslDecl: yDEFAULT yPSL_CLOCK '=' senitemEdge ';' { $$ = new AstPslDefClock($3, $4); } | yDEFAULT yPSL_CLOCK '=' '(' senitemEdge ')' ';' { $$ = new AstPslDefClock($3, $5); } ; //************************************************ // PSL Properties, Sequences and SEREs // Don't use '{' or '}'; in PSL they're yPSL_BRA and yPSL_KET to avoid expr concatenates pslProp: pslSequence { $$ = $1; } | pslSequence '@' %prec prPSLCLK '(' senitemEdge ')' { $$ = new AstPslClocked($2,$4,NULL,$1); } // or pslSequence @ ...? ; pslSequence: yPSL_BRA pslSere yPSL_KET { $$ = $2; } ; pslSere: pslExpr { $$ = $1; } | pslSequence { $$ = $1; } // Sequence containing sequence ; // Undocumented PSL rule is that {} is always a SERE; concatenation is not allowed. // This can be bypassed with the _(...) embedding of any arbitrary expression. pslExpr: exprPsl { $$ = new AstPslBool($1->fileline(), $1); } | yTRUE { $$ = new AstPslBool($1, new AstConst($1, AstConst::LogicTrue())); } ; //********************************************************************** // 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(); 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 nodep->trace(v3Global.opt.trace() && nodep->fileline()->tracingOn()); // 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 AstNode::quoteName(...) 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.856/src/V3Task.cpp0000664000177100017500000014236212306677750016156 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-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. // //************************************************************************* // 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) { // 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) { string dpiproto = dpiprotoName(nodep,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 #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 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(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(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 (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_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__<<": "< #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.856/src/V3LangCode.h0000664000177100017500000000437212306677750016373 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Language code class // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #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.856/src/V3Order.h0000664000177100017500000000223512306677750015766 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Block code ordering // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #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.856/src/V3Undriven.h0000664000177100017500000000226712306677750016512 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-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. // //************************************************************************* #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.856/src/V3OrderGraph.h0000664000177100017500000005571712306677750016765 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Block code ordering // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* // 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) {} 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.856/src/V3File.h0000664000177100017500000002100412306677750015565 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-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. // //************************************************************************* #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", (classname + "*").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.856/src/V3Graph.h0000664000177100017500000002660012306677750015756 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph optimizations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #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.856/src/V3Number.cpp0000664000177100017500000014526612306677750016512 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-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 "config_build.h" #include "verilatedos.h" #include #include #include #include #include #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(VerilogString, 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); 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 '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: "<width() != 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(); for (int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIs(bit + rhsval)); } return *this; } V3Number& V3Number::opShiftRS (const V3Number& lhs, const V3Number& rhs) { // 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(); for (int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIsExtend(bit + rhsval)); } 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 ** math not implemented yet: "<<*this); if (rhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large >64bit ** math not implemented yet: "<<*this); 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 (ens.bitIs1(bit)) { setBit(bit, if1s.bitIs(bit)); } else setBit(bit,'z'); } return *this; } V3Number& V3Number::opAssign (const V3Number& lhs) { // Note may be a width change during the assign setZero(); for(int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIs(bit)); } return *this; } V3Number& V3Number::opExtendS (const V3Number& lhs) { // Note may be a width change during the sign extension setZero(); for(int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIsExtend(bit)); } return *this; } V3Number& V3Number::opClean (const V3Number& lhs, uint32_t bits) { return opSel(lhs, bits-1, 0); } void V3Number::opCleanThis() { // Clean in place number if (uint32_t okbits = (width() & 31)) { m_value[words()-1] &= ((1UL<width(); bit++) { if (ibit>=0 && ibitwidth(); 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()); } verilator-3.856/src/V3SymTable.h0000664000177100017500000002505712306677750016442 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Symbol table // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #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* srcp = it->second; VSymEnt* symp = new VSymEnt(graphp, srcp); reinsert(name, symp); // And recurse to create children srcp->importFromIface(graphp, symp); } } 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.856/src/config_build.h.in0000664000177100017500000000466112306677750017540 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Configure source; system configuration // // This file is part of Verilator. // // Author: Wilson Snyder // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* //********************************************************************** //**** 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.856/src/V3ParseLex.cpp0000664000177100017500000000564612307713445016773 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-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 "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 stateExitPsl() { if (YY_START != PSL) yyerrorf("Internal error: Exiting PSL state when not in PSL state"); yy_pop_state(); } void statePushVlg() { yy_push_state(STATE_VERILOG_RECENT); } 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::stateExitPsl() { parsep()->m_lexerp->stateExitPsl(); } void V3ParseImp::statePushVlg() { parsep()->m_lexerp->stateExitPsl(); } 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.856/src/V3ClkGater.cpp0000664000177100017500000010225212306677750016742 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-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. // //************************************************************************* // 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__<<": "< #include #include #include "V3Global.h" #include "V3Width.h" #include "V3Number.h" #include "V3Const.h" #include "V3Task.h" // More code; this file was getting too large; see actions there #define _V3WIDTH_CPP_ #include "V3WidthCommit.h" //###################################################################### // Width state, as a visitor of each AstNode enum Stage { PRELIM=1,FINAL=2,BOTH=3 }; class WidthVP : public AstNUser { // Parameters to pass down hierarchy with visit functions. int m_width; // Expression width, for (2+2), it's 32 bits int m_widthMin; // Minimum width, for (2+2), it's 2 bits, for 32'2+32'2 it's 32 bits AstNodeDType* m_dtypep; // Parent's data type to resolve to Stage m_stage; // If true, report errors public: WidthVP(int width, int widthMin, Stage stage) : m_width(width), m_widthMin(widthMin), m_dtypep(NULL), m_stage(stage) {} WidthVP(AstNodeDType* dtypep, Stage stage) : m_width(dtypep->width()), m_widthMin(dtypep->widthMin()), m_dtypep(dtypep), m_stage(stage) {} WidthVP(AstNodeDType* dtypep, int width, int widthMin, Stage stage) : m_width(width), m_widthMin(widthMin), m_dtypep(dtypep), m_stage(stage) {} int width() const { return m_width; } int widthMin() const { return m_widthMin?m_widthMin:m_width; } AstNodeDType* dtypep() const { return m_dtypep; } bool prelim() const { return m_stage&1; } bool final() const { return m_stage&2; } char stageAscii() const { return "-PFB"[m_stage]; } }; ostream& operator<<(ostream& str, const WidthVP* vup) { str<<" VUP(s="<stageAscii()<<",w="<width()<<",wm="<widthMin()<<",dt="<<(void*)vup->dtypep()<<")"; return str; } //###################################################################### class WidthVisitor : public AstNVisitor { private: // 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 // CLASSES #define ANYSIZE 0 // 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 // Where _Wlhs = Width comes from LHS // Where _Wleqrhs = Width matches LHS and RHS // Where _Slandrhs = Signed if LHS and RHS // Widths: 1 bit out, lhs 1 bit; Real: converts via compare with 0 virtual void visit(AstLogNot* nodep, AstNUser* vup) { visit_log_O1_L1rus(nodep,vup); } virtual void visit(AstPslBool* nodep, AstNUser* vup) { visit_log_O1_L1rus(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_O1_LR1rus(nodep,vup); } virtual void visit(AstLogOr* nodep, AstNUser* vup) { visit_log_O1_LR1rus(nodep,vup); } virtual void visit(AstLogIf* nodep, AstNUser* vup) { visit_log_O1_LR1rus(nodep,vup); } // Conversion from real not in IEEE, but a fallout virtual void visit(AstLogIff* nodep, AstNUser* vup) { visit_log_O1_LR1rus(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_O1_Lrus(nodep,vup,false); } virtual void visit(AstRedOr* nodep, AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); } virtual void visit(AstRedXnor* nodep, AstNUser* vup){ visit_red_O1_Lrus(nodep,vup,false); } virtual void visit(AstRedXor* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); } virtual void visit(AstIsUnknown* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,true); } // Allow real virtual void visit(AstOneHot* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); } virtual void visit(AstOneHot0* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); } // 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_O1_DSreplace(nodep,vup); } virtual void visit(AstNeq* nodep, AstNUser* vup) { visit_cmp_O1_DSreplace(nodep,vup); } virtual void visit(AstGt* nodep, AstNUser* vup) { visit_cmp_O1_DSreplace(nodep,vup); } virtual void visit(AstGte* nodep, AstNUser* vup) { visit_cmp_O1_DSreplace(nodep,vup); } virtual void visit(AstLt* nodep, AstNUser* vup) { visit_cmp_O1_DSreplace(nodep,vup); } virtual void visit(AstLte* nodep, AstNUser* vup) { visit_cmp_O1_DSreplace(nodep,vup); } virtual void visit(AstGtS* nodep, AstNUser* vup) { visit_cmp_O1_DSreplace(nodep,vup); } virtual void visit(AstGteS* nodep, AstNUser* vup) { visit_cmp_O1_DSreplace(nodep,vup); } virtual void visit(AstLtS* nodep, AstNUser* vup) { visit_cmp_O1_DSreplace(nodep,vup); } virtual void visit(AstLteS* nodep, AstNUser* vup) { visit_cmp_O1_DSreplace(nodep,vup); } // ... These comparisons don't care about inbound types // ... (Though they should match. We don't check.) virtual void visit(AstEqCase* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,false); } virtual void visit(AstEqWild* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,false); } virtual void visit(AstNeqCase* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,false); } virtual void visit(AstNeqWild* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,false); } // ... Real compares virtual void visit(AstEqD* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,true); } virtual void visit(AstNeqD* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,true); } virtual void visit(AstLtD* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,true); } virtual void visit(AstLteD* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,true); } virtual void visit(AstGtD* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,true); } virtual void visit(AstGteD* nodep, AstNUser* vup) { visit_cmp_O1_LRrus(nodep,vup,true); } // 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_Ous_LRus(nodep,vup); } virtual void visit(AstOr* nodep, AstNUser* vup) { visit_boolmath_Ous_LRus(nodep,vup); } virtual void visit(AstXnor* nodep, AstNUser* vup) { visit_boolmath_Ous_LRus(nodep,vup); } virtual void visit(AstXor* nodep, AstNUser* vup) { visit_boolmath_Ous_LRus(nodep,vup); } virtual void visit(AstBufIf1* nodep, AstNUser* vup) { visit_boolmath_Ous_LRus(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_math_Orus_DSreplace(nodep,vup,true); } virtual void visit(AstSub* nodep, AstNUser* vup) { visit_math_Orus_DSreplace(nodep,vup,true); } virtual void visit(AstDiv* nodep, AstNUser* vup) { visit_math_Orus_DSreplace(nodep,vup,true); } virtual void visit(AstMul* nodep, AstNUser* vup) { visit_math_Orus_DSreplace(nodep,vup,true); } // These can't promote to real virtual void visit(AstModDiv* nodep, AstNUser* vup) { visit_math_Orus_DSreplace(nodep,vup,false); } virtual void visit(AstModDivS* nodep, AstNUser* vup) { visit_math_Orus_DSreplace(nodep,vup,false); } virtual void visit(AstMulS* nodep, AstNUser* vup) { visit_math_Orus_DSreplace(nodep,vup,false); } virtual void visit(AstDivS* nodep, AstNUser* vup) { visit_math_Orus_DSreplace(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_math_Orus_Dreplace(nodep,vup,true); } // Unary never real virtual void visit(AstNot* nodep, AstNUser* vup) { visit_math_Orus_Dreplace(nodep,vup,false); } // Real: inputs and output real virtual void visit(AstAddD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); } virtual void visit(AstSubD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); } virtual void visit(AstDivD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); } virtual void visit(AstMulD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); } virtual void visit(AstPowD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); } // Signed/Real: Output real or signed iff LHS signed/real virtual void visit(AstNegateD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } // Real: Output real virtual void visit(AstCeilD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } virtual void visit(AstExpD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } virtual void visit(AstFloorD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } virtual void visit(AstLogD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } virtual void visit(AstLog10D* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } virtual void visit(AstSqrtD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } // Widths: out signed/unsigned width = lhs width, input un|signed virtual void visit(AstSigned* nodep, AstNUser* vup) { visit_Ous_Lus_Wforce(nodep,vup,AstNumeric::SIGNED); } virtual void visit(AstUnsigned* nodep, AstNUser* vup) { visit_Ous_Lus_Wforce(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_Ous_Lus_Rus32(nodep,vup); } virtual void visit(AstShiftR* nodep, AstNUser* vup) { visit_shift_Ous_Lus_Rus32(nodep,vup); } // ShiftRS converts to ShiftR, but not vice-versa virtual void visit(AstShiftRS* nodep, AstNUser* vup) { visit_shift_Ous_Lus_Rus32(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 is a Good large example of the propagation mess // Signed: Output signed iff RHS & THS signed // Real: Output real if either expression is real, signed if both signed if (vup->c()->prelim()) { // First stage evaluation // Just once, do the conditional, expect one bit out. nodep->condp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); spliceCvtCmpD0(nodep->condp()); // auto-compares with zero // Determine sub expression widths only relying on what's in the subops nodep->expr1p()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); nodep->expr2p()->iterateAndNext(*this,WidthVP(ANYSIZE,0,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()) { spliceCvtD(nodep->expr1p()); spliceCvtD(nodep->expr2p()); nodep->dtypeSetDouble(); } else { int width = max(vup->c()->width(), max(nodep->expr1p()->width(), nodep->expr2p()->width())); int mwidth = max(vup->c()->widthMin(), max(nodep->expr1p()->widthMin(), nodep->expr2p()->widthMin())); nodep->dtypeSetLogicSized(width,mwidth, ((nodep->expr1p()->isSigned() && nodep->expr2p()->isSigned()) ? AstNumeric::SIGNED : AstNumeric::UNSIGNED)); } if (vup->c()->final()) { // Final width known, so make sure children recompute & check their sizes int width = nodep->width(); int mwidth = nodep->widthMin(); nodep->expr1p()->iterateAndNext(*this,WidthVP(width,mwidth,FINAL).p()); nodep->expr2p()->iterateAndNext(*this,WidthVP(width,mwidth,FINAL).p()); // Error report and change sizes for suboperands of this node. widthCheckReduce(nodep,"Conditional Test",nodep->condp()); widthCheck(nodep,"Conditional True",nodep->expr1p(),width,mwidth); widthCheck(nodep,"Conditional False",nodep->expr2p(),width,mwidth); } } virtual void visit(AstConcat* nodep, AstNUser* vup) { // Real: Not allowed // Signed: unsigned output, input either if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); 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 (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) { if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); 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->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(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()) { nodep->msbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->msbp()); checkCvtUS(nodep->lsbp()); 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 if (nodep->didWidth()) return; if (vup->c()->prelim()) { if (debug()>=9) nodep->dumpTree(cout,"-selWidth: "); nodep->fromp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); nodep->widthp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->fromp()); checkCvtUS(nodep->lsbp()); checkCvtUS(nodep->widthp()); 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. widthCheck(nodep,"errorless...",nodep->fromp(),width,width,true/*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 nodep->fromp()->iterateAndNext(*this,WidthVP(selwidth,selwidth,FINAL).p()); nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,FINAL).p()); if (widthBad(nodep->lsbp(),selwidth,selwidth) && 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 widthCheck 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(),selwidth, selwidth,true); } } } 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 if (vup->c()->prelim()) { nodep->bitp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->bitp()); // nodep->fromp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).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 nodep->fromp()->iterateAndNext(*this,WidthVP(selwidth,selwidth,FINAL).p()); if (widthBad(nodep->bitp(),selwidth,selwidth) && 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(),selwidth,selwidth,true); } } 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(0,0,PRELIM).p()); //FINAL in AstSel nodep->rhsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->thsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(0,0,FINAL).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(0,0,PRELIM).p()); //FINAL in AstSel nodep->rhsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->thsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(0,0,FINAL).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(0,0,PRELIM).p()); //FINAL in AstSel nodep->rhsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->thsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(0,0,FINAL).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(0,0,PRELIM).p()); //FINAL in AstSel nodep->rhsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->thsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(0,0,FINAL).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().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(AstConstString* nodep, AstNUser* vup) { nodep->rewidth(); } 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 } if (vup->c()->final()) { nodep->dtypeSetLogicSized(vup->c()->width(),vup->c()->widthMin(),AstNumeric::UNSIGNED); // We don't care if (nodep->width()>64) nodep->v3error("Unsupported: $c can't generate wider than 64 bits"); } // Just let all arguments seek their natural sizes nodep->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p()); } virtual void visit(AstCLog2* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->lhsp()); nodep->dtypeSetSigned32(); } } virtual void visit(AstPow* nodep, AstNUser* vup) { // Pow is special, output sign only depends on LHS sign // Real if either side is real (as with AstAdd) shift_prelim(nodep, vup); if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); spliceCvtD(nodep->rhsp()); replaceWithDVersion(nodep); nodep=NULL; } else { AstNodeBiop* newp = shift_final(nodep, vup); nodep=NULL; newp->dtypeChgSigned(newp->lhsp()->isSigned()); if (newp->isSigned()) { replaceWithUOrSVersion(newp, false); newp=NULL; } } } virtual void visit(AstPowS* nodep, AstNUser* vup) { // Pow is special, output sign only depends on LHS sign shift_prelim(nodep, vup); AstNodeBiop* newp = shift_final(nodep, vup); nodep=NULL; newp->dtypeChgSigned(newp->lhsp()->isSigned()); if (!newp->isSigned()) { replaceWithUOrSVersion(newp, true); newp=NULL; } } virtual void visit(AstCountOnes* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->lhsp()); // 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(ANYSIZE,0,BOTH).p()); } virtual void visit(AstAttrOf* nodep, AstNUser*) { AstAttrOf* oldAttr = m_attrp; m_attrp = nodep; nodep->fromp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); // Don't iterate children, don't want to lose VarRef. if (nodep->attrType()==AstAttrType::VAR_BASE) { // Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf } else if (nodep->attrType()==AstAttrType::MEMBER_BASE) { // Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf } else if (nodep->attrType()==AstAttrType::DIM_DIMENSIONS || nodep->attrType()==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; } else if (nodep->attrType()==AstAttrType::DIM_BITS || nodep->attrType()==AstAttrType::DIM_HIGH || nodep->attrType()==AstAttrType::DIM_INCREMENT || nodep->attrType()==AstAttrType::DIM_LEFT || nodep->attrType()==AstAttrType::DIM_LOW || nodep->attrType()==AstAttrType::DIM_RIGHT || nodep->attrType()==AstAttrType::DIM_SIZE) { if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); pair dim = nodep->fromp()->dtypep()->skipRefp()->dimensions(true); uint32_t maxdim = dim.first+dim.second; if (!nodep->dimp() || nodep->dimp()->castConst() || maxdim<1) { int dim = !nodep->dimp() ? 1 : nodep->dimp()->castConst()->toSInt(); int val = dimensionValue(nodep->fromp()->dtypep(), nodep->attrType(), dim); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32(), val)); 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()); 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; } } else { // 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"); } 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(ANYSIZE,0,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(ANYSIZE,0,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(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(ANYSIZE,0,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 widthCheck might modify nodep->lhsp() widthCheck(nodep,"Cast",nodep->lhsp(),nodep->width(),nodep->width(),true); } 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) { if (!nodep->rhsp()->castConst()) nodep->v3fatalSrc("Unsupported: Non-const cast of size"); //if (debug()) nodep->dumpTree(cout," CastPre: "); 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(ANYSIZE,0,BOTH).p()); AstBasicDType* underDtp = nodep->lhsp()->dtypep()->castBasicDType(); if (!underDtp) { nodep->v3error("Unsupported: Size-changing cast on non-basic data type"); underDtp = nodep->findLogicBoolDType()->castBasicDType(); } AstNodeDType* newDtp = (underDtp->keyword().isFourstate() ? nodep->findLogicDType(width, width, underDtp->numeric()) : nodep->findBitDType(width, width, underDtp->numeric())); nodep->dtypep(newDtp); AstNode* underp = nodep->lhsp()->unlinkFrBack(); nodep->replaceWith(underp); if (underp->width()!=width) { fixWidthExtend(underp, newDtp); } pushDeletep(nodep); nodep=NULL; } 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()) { int width=0; nodep->valuep()->iterateAndNext(*this,WidthVP(width,0,PRELIM).p()); UINFO(9,"implicitParamPRELIMIV "<valuep()<valuep()->isDouble()) { nodep->dtypeSetDouble(); bdtypep=NULL; nodep->valuep()->iterateAndNext(*this,WidthVP(width,0,FINAL).p()); } else { 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(), issigned?AstNumeric::SIGNED : AstNumeric::UNSIGNED); nodep->dtypep(nodep->findLogicRangeDType (VNumRange(0,0,false), nodep->valuep()->widthMin(), issigned?AstNumeric::SIGNED : AstNumeric::UNSIGNED)); } else { nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(), issigned?AstNumeric::SIGNED : AstNumeric::UNSIGNED); } didchk = true; nodep->valuep()->iterateAndNext(*this,WidthVP(width,nodep->widthMin(),FINAL).p()); } 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()) { //if (debug()) nodep->dumpTree(cout," final: "); if (!didchk) nodep->valuep()->iterateAndNext(*this,WidthVP(nodep->dtypep()->width(),0,BOTH).p()); if (!nodep->valuep()->castInitArray()) { // No dtype at present, perhaps TODO widthCheck(nodep,"Initial value",nodep->valuep(),nodep->width(),nodep->widthMin()); } if (nodep->isDouble() && !nodep->valuep()->isDouble()) { spliceCvtD(nodep->valuep()); } } 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 int width = vdtypep->width(); // Always from parent type nodep->valuep()->iterateAndNext(*this,WidthVP(width,0,BOTH).p()); int mwidth = nodep->valuep()->widthMin(); // Value determines minwidth nodep->dtypeChgWidth(width, mwidth); widthCheck(nodep,"Enum value",nodep->valuep(),width,mwidth); } } 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); } nodep->dtypeFrom(nodep->itemp()); } virtual void visit(AstInitArray* nodep, AstNUser* vup) { // Should be correct by construction, so we'll just loop through all types nodep->iterateChildren(*this, vup); } virtual void visit(AstInside* nodep, AstNUser* vup) { nodep->exprp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,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(ANYSIZE,0,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 nodep->exprp()->iterateAndNext(*this,WidthVP(width,mwidth,FINAL).p()); for (AstNode* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()) { widthCheck(nodep,"Inside Item",itemp,width,mwidth); } widthCheck(nodep,"Inside expression",nodep->exprp(),width,mwidth); 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("-ms-in-"); nodep->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p()); // Find the fromp dtype - should be a class AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp(); UINFO(9," from dt "<castNodeClassDType(); AstMemberDType* memberp = NULL; // NULL=error below if (!fromClassp) { nodep->v3error("Member selection of non-struct/union object '" <fromp()->prettyTypeName()<<"' which is a '"<fromp()->dtypep()->prettyTypeName()<<"'"); } else { // No need to width-resolve the fromClassp, as it was done when we did the child memberp = fromClassp->findMember(nodep->name()); if (!memberp) { nodep->v3error("Member '"<prettyName()<<"' not found in structure"); } } if (memberp) { if (m_attrp) { // Looking for the base of the attribute nodep->dtypep(memberp); UINFO(9," MEMBERSEL(attr) -> "<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 -> "<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(AstPattern* nodep, AstNUser* vup) { if (nodep->didWidthAndSet()) return; UINFO(9,"PATTERN "<childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); // data_type '{ pattern } if (!nodep->dtypep() && vup->c()->dtypep()) { // 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); for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) { // Determine replication count, and replicate initial value as widths need to be individually determined int times = visitPatMemberRep(patp); for (int i=1; icloneTree(false); patp->addNextHere(newp); // This loop will see the new elements as part of nextp() } } 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 { patp->v3error("Assignment pattern missed initializing elements: "<prettyTypeName()); } } else { patp = it->second; } // Determine initial values vdtypep = memp; patp->dtypep(memp); patp->accept(*this,WidthVP(memp,BOTH).p()); // Convert to concat for now if (!newp) newp = patp->lhsp()->unlinkFrBack(); else { AstConcat* concatp = new AstConcat(patp->fileline(), newp, patp->lhsp()->unlinkFrBack()); newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), concatp->lhsp()->width()+concatp->rhsp()->width(), nodep->dtypep()->numeric()); } if (newpatp) pushDeletep(newpatp); } if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); 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()->dtypep(); if (!vdtypep) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor"); nodep->dtypep(vdtypep); nodep->lhsp()->dtypeFrom(nodep); nodep->iterateChildren(*this,WidthVP(nodep->dtypep(),BOTH).p()); widthCheck(nodep,"LHS",nodep->lhsp(),nodep->width(),nodep->width()); } int visitPatMemberRep(AstPatMember* nodep) { uint32_t times = 1; if (nodep->repp()) { // else repp()==NULL shorthand for rep count 1 nodep->repp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->repp()); 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*) { nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); nodep->sensesp()->iterateAndNext(*this); if (nodep->disablep()) { nodep->disablep()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); widthCheckReduce(nodep,"Disable",nodep->disablep()); // it's like an if() condition. } widthCheckReduce(nodep,"Property",nodep->propp()); // it's like an if() condition. nodep->dtypeSetLogicBool(); } //-------------------- // Top levels virtual void visit(AstNodeCase* nodep, AstNUser*) { // TOP LEVEL NODE nodep->exprp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,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(ANYSIZE,0,PRELIM).p()); condp=NULL; } } // Take width as maximum across all items int width = nodep->exprp()->width(); int mwidth = nodep->exprp()->widthMin(); for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* condp = itemp->condsp(); condp; condp=condp->nextp()) { width = max(width,condp->width()); mwidth = max(mwidth,condp->widthMin()); } } // Apply width nodep->exprp()->iterateAndNext(*this,WidthVP(width,mwidth,FINAL).p()); for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* condp = itemp->condsp(); condp; condp=condp->nextp()) { condp->iterate(*this,WidthVP(width,mwidth,FINAL).p()); widthCheck(nodep,"Case Item",condp,width,mwidth); } } widthCheck(nodep,"Case expression",nodep->exprp(),width,mwidth); } virtual void visit(AstNodeFor* nodep, AstNUser*) { // TOP LEVEL NODE nodep->initsp()->iterateAndNext(*this); nodep->condp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); if (!nodep->castGenFor()) nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); widthCheckReduce(nodep,"For Test Condition",nodep->condp()); // it's like an if() condition. } virtual void visit(AstRepeat* nodep, AstNUser*) { nodep->countp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstWhile* nodep, AstNUser*) { // TOP LEVEL NODE nodep->precondsp()->iterateAndNext(*this); nodep->condp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); widthCheckReduce(nodep,"For Test Condition",nodep->condp()); // it's like an if() condition. } virtual void visit(AstNodeIf* nodep, AstNUser*) { // TOP LEVEL NODE //if (debug()) nodep->dumpTree(cout," IfPre: "); if (!nodep->castGenIf()) { // for m_paramsOnly nodep->ifsp()->iterateAndNext(*this); nodep->elsesp()->iterateAndNext(*this); } nodep->condp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); spliceCvtCmpD0(nodep->condp()); widthCheckReduce(nodep,"If",nodep->condp()); // it's like an if() condition. //if (debug()) nodep->dumpTree(cout," IfOut: "); } virtual void visit(AstNodeAssign* nodep, AstNUser*) { // TOP LEVEL NODE //if (debug()) nodep->dumpTree(cout," AssignPre: "); { //if (debug()) nodep->dumpTree(cout,"- assin: "); nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,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->rhsp()->iterateAndNext(*this,WidthVP(nodep->lhsp()->dtypep(),ANYSIZE,0,PRELIM).p()); //if (debug()) nodep->dumpTree(cout,"- assign: "); if (!nodep->lhsp()->isDouble() && nodep->rhsp()->isDouble()) { spliceCvtS(nodep->rhsp(), false); // Round RHS } else if (nodep->lhsp()->isDouble() && !nodep->rhsp()->isDouble()) { spliceCvtD(nodep->rhsp()); } int awidth = nodep->lhsp()->width(); if (awidth==0) { awidth = nodep->rhsp()->width(); // Parameters can propagate by unsized assignment } nodep->rhsp()->iterateAndNext(*this,WidthVP(nodep->lhsp()->dtypep(),awidth,awidth,FINAL).p()); nodep->dtypeFrom(nodep->lhsp()); nodep->dtypeChgWidth(awidth,awidth); // We know the assign will truncate, so rather // than using "width" and have the optimizer truncate the result, we do // it using the normal width reduction checks. //UINFO(0,"aw "<rhsp()->width()<<" m"<rhsp()->widthMin()<rhsp(),awidth,awidth); //if (debug()) nodep->dumpTree(cout," AssignOut: "); } } virtual void visit(AstSFormatF* nodep, AstNUser*) { // Excludes NodeDisplay, see below // TOP LEVEL NODE // Just let all arguments seek their natural sizes nodep->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p()); // UINFO(9," Display in "<text()<exprsp(); for (const char* inp = nodep->text().c_str(); *inp; inp++) { char ch = *inp; // Breaks with iterators... 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; } 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()) { nodep->filep()->iterateAndNext(*this,WidthVP(32,32,BOTH).p()); widthCheckFileDesc(nodep,nodep->filep()); } // Just let all arguments seek their natural sizes nodep->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p()); } virtual void visit(AstFOpen* nodep, AstNUser*) { nodep->filep()->iterateAndNext(*this,WidthVP(32,32,BOTH).p()); nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->modep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); widthCheckFileDesc(nodep,nodep->filep()); } virtual void visit(AstFClose* nodep, AstNUser*) { nodep->filep()->iterateAndNext(*this,WidthVP(32,32,BOTH).p()); widthCheckFileDesc(nodep,nodep->filep()); } virtual void visit(AstFEof* nodep, AstNUser*) { nodep->filep()->iterateAndNext(*this,WidthVP(32,32,BOTH).p()); nodep->dtypeSetLogicSized(32,1,AstNumeric::SIGNED); // Spec says integer return widthCheckFileDesc(nodep,nodep->filep()); } virtual void visit(AstFFlush* nodep, AstNUser*) { if (nodep->filep()) { nodep->filep()->iterateAndNext(*this,WidthVP(32,32,BOTH).p()); widthCheckFileDesc(nodep,nodep->filep()); } } virtual void visit(AstFGetC* nodep, AstNUser* vup) { nodep->filep()->iterateAndNext(*this,WidthVP(32,32,BOTH).p()); if (vup->c()->prelim()) { nodep->dtypeSetLogicSized(32,8,AstNumeric::SIGNED); // Spec says integer return } widthCheckFileDesc(nodep,nodep->filep()); } virtual void visit(AstFGetS* nodep, AstNUser* vup) { nodep->filep()->iterateAndNext(*this,WidthVP(32,32,BOTH).p()); nodep->strgp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); if (vup->c()->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return } widthCheckFileDesc(nodep,nodep->filep()); } virtual void visit(AstFScanF* nodep, AstNUser* vup) { nodep->filep()->iterateAndNext(*this,WidthVP(32,32,BOTH).p()); nodep->exprsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); if (vup->c()->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return } widthCheckFileDesc(nodep,nodep->filep()); } virtual void visit(AstSScanF* nodep, AstNUser* vup) { nodep->fromp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->exprsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); if (vup->c()->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return } } virtual void visit(AstSysIgnore* nodep, AstNUser* vup) { nodep->exprsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); } virtual void visit(AstSystemF* nodep, AstNUser*) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->dtypeSetSigned32(); // Spec says integer return } virtual void visit(AstSystemT* nodep, AstNUser*) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); } virtual void visit(AstReadMem* nodep, AstNUser*) { nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); if (!nodep->memp()->dtypep()->skipRefp()->castUnpackArrayDType()) { nodep->memp()->v3error("Unsupported: $readmem into other than unpacked array"); } nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->msbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); } virtual void visit(AstValuePlusArgs* nodep, AstNUser* vup) { nodep->exprsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->dtypeSetSigned32(); // Spec says integer return } virtual void visit(AstUCStmt* nodep, AstNUser*) { // TOP LEVEL NODE // Just let all arguments seek their natural sizes nodep->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p()); } virtual void visit(AstPslCover* nodep, AstNUser*) { // TOP LEVEL NODE nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); nodep->stmtsp()->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p()); widthCheckReduce(nodep,"Property",nodep->propp()); // it's like an if() condition. } virtual void visit(AstPslAssert* nodep, AstNUser*) { // TOP LEVEL NODE nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); widthCheckReduce(nodep,"Property",nodep->propp()); // it's like an if() condition. } virtual void visit(AstVAssert* nodep, AstNUser*) { // TOP LEVEL NODE nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); nodep->passsp()->iterateAndNext(*this); nodep->failsp()->iterateAndNext(*this); widthCheckReduce(nodep,"Property",nodep->propp()); // it's like an if() condition. } 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(ANYSIZE,0,BOTH).p()); } else if (!m_paramsOnly) { if (nodep->modVarp()->width()==0) { // 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(ANYSIZE,0,PRELIM).p()); int pinwidth = nodep->modVarp()->width(); int expwidth = nodep->exprp()->width(); bool inputPin = nodep->modVarp()->isInput(); int awidth; if (m_cellRangep) { int numInsts = m_cellRangep->elementsConst(); if (expwidth == pinwidth) { awidth = pinwidth; // Arrayed instants: widths match so connect to each instance } else if (expwidth == pinwidth*numInsts) { awidth = pinwidth; // Arrayed instants: one bit for each of the instants (each assign is 1 pinwidth wide) } else { // Must be a error according to spec // (Because we need to know if to connect to one or all instants) nodep->v3error("Port connection "<prettyName()<<" as part of a module instance array " <<" requires "<exprp()->prettyTypeName() <<" generates "<modVarp()->isTristate()) { if (pinwidth != expwidth) { nodep->v3error("Unsupported: Port connection "<prettyName()<<" to inout signal " <<" requires "<exprp()->prettyTypeName() <<" generates "<exprp()->dtypep()->skipRefp()->castUnpackArrayDType(); bool loArray = nodep->modVarp()->dtypep()->skipRefp()->castUnpackArrayDType(); if (loArray != hiArray) { nodep->v3error("Illegal port connection '"<prettyName()<<"'," <<" 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()->iterateAndNext(*this,WidthVP(awidth,awidth,FINAL).p()); if (!m_cellRangep) { AstNodeDType* expDTypep = nodep->findLogicDType(pinwidth, pinwidth, nodep->exprp()->dtypep()->numeric()); widthCheckPin(nodep, nodep->exprp(), expDTypep, inputPin); } } //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(ANYSIZE,0,BOTH).p()); } nodep->pinsp()->iterateAndNext(*this); } nodep->paramsp()->iterateAndNext(*this); m_cellRangep = 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) { 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->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->dtypeFrom(m_funcp->fvarp()); } } } 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) { // 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()) { 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; } 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(),BOTH).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()) { widthCheck(nodep,"Function Argument",pinp,portp->width(),portp->widthMin()); } } } } } nodep->didWidth(true); } virtual void visit(AstInitial* nodep, AstNUser*) { 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 if (vup->c()->prelim()) { // First stage evaluation nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->lhsp()); nodep->dtypeSetDouble(); widthCheck(nodep,"LHS",nodep->lhsp(),64,64); } } void visit_Or_Ls32(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: AstIToRD // Real: Output real if (vup->c()->prelim()) { // First stage evaluation nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtUS(nodep->lhsp()); nodep->dtypeSetDouble(); widthCheck(nodep,"LHS",nodep->lhsp(),32,32); } } void visit_Os32_Lr(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: RToI // Real: LHS real if (vup->c()->prelim()) { // First stage evaluation nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtD(nodep->lhsp()); nodep->dtypeSetSigned32(); } } void visit_Ou64_Lr(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: RealToBits // Real: LHS real if (vup->c()->prelim()) { // First stage evaluation nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtD(nodep->lhsp()); nodep->dtypeSetUInt64(); } } void visit_log_O1_L1rus(AstNode* nodep, AstNUser* vup) { // CALLER: LogNot, PslBool // Note AstPslBool isn't a AstNodeUniop, or we'd only allow that here // Widths: 1 bit out, 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 if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); if (vup->c()->prelim()) { nodep->op1p()->iterateAndNext(*this,WidthVP(1,0,BOTH).p()); spliceCvtCmpD0(nodep->op1p()); } nodep->dtypeSetLogicBool(); if (vup->c()->final()) { widthCheckReduce(nodep,"LHS",nodep->op1p()); } } void visit_log_O1_LR1rus(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: LogAnd, LogOr, LogIf, LogIff // Widths: 1 bit out, lhs 1 bit, rhs 1 bit if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(1,0,BOTH).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(1,0,BOTH).p()); spliceCvtCmpD0(nodep->lhsp()); spliceCvtCmpD0(nodep->rhsp()); } nodep->dtypeSetLogicBool(); if (vup->c()->final()) { widthCheckReduce(nodep,"LHS",nodep->lhsp()); widthCheckReduce(nodep,"RHS",nodep->rhsp()); } } void visit_red_O1_Lrus(AstNodeUniop* nodep, AstNUser* vup, bool realok) { // CALLER: RedAnd, RedOr, ..., IsUnknown // Widths: 1 bit out, Any width lhs // Signed: Output unsigned, Lhs/Rhs/etc non-real if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); } if (!realok) checkCvtUS(nodep->lhsp()); nodep->dtypeSetLogicBool(); } void visit_cmp_O1_DSreplace(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: AstEq, AstGt, ..., AstLtS // COMPARES // Widths: 1 bit out, lhs width == rhs width // Signed: if RHS&LHS signed, OPERATOR CHANGES to signed flavor // Real: allowed on RHS, if RHS|LHS is real, both become real, and OPERATOR CHANGES if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); } 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 } } 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()); nodep->dtypeSetLogicBool(); if (vup->c()->final()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(width,ewidth,FINAL).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(width,ewidth,FINAL).p()); widthCheck(nodep,"LHS",nodep->lhsp(),width,ewidth); widthCheck(nodep,"RHS",nodep->rhsp(),width,ewidth); } } void visit_cmp_O1_LRrus(AstNodeBiop* nodep, AstNUser* vup, bool real_lhs) { // CALLER: (real_lhs=true) EqD, LtD // CALLER: (real_lhs=false) EqCase, NeqCase // Widths: 1 bit out, lhs width == rhs width // Signed doesn't matter // Real if and only if real_lhs set if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); } if (real_lhs) { checkCvtD(nodep->lhsp()); checkCvtD(nodep->rhsp()); } else { checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); } int width = max(nodep->lhsp()->width(), nodep->rhsp()->width()); int ewidth = max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin()); nodep->dtypeSetLogicBool(); if (vup->c()->final()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(width,ewidth,FINAL).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(width,ewidth,FINAL).p()); widthCheck(nodep,"LHS",nodep->lhsp(),width,ewidth); widthCheck(nodep,"RHS",nodep->rhsp(),width,ewidth); } } void visit_math_Orus_Dreplace(AstNodeUniop* nodep, AstNUser* vup, bool real_ok) { // CALLER: (real_ok=false) Not // CALLER: (real_ok=true) Negate // Widths: out width = lhs width // Signed: From lhs // "Interim results shall take the max of operands, including LHS of assignments" if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,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 } } else { if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp()); nodep->dtypeChgSigned(nodep->lhsp()->isSigned()); // Note there aren't yet uniops that need version changes // So no need to call replaceWithUOrSVersion(nodep, nodep->isSigned()) } int width = max(vup->c()->width(), nodep->lhsp()->width()); int ewidth = max(vup->c()->widthMin(), nodep->lhsp()->widthMin()); nodep->dtypeFrom(nodep->lhsp()); nodep->dtypeChgWidth(width,ewidth); if (vup->c()->final()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(width,ewidth,FINAL).p()); widthCheck(nodep,"LHS",nodep->lhsp(),width,ewidth); } } void visit_Ous_Lus_Wforce(AstNodeUniop* nodep, AstNUser* vup, AstNumeric rs_out) { // CALLER: Signed, Unsigned // Widths: out width = lhs width // It always comes exactly from LHS; ignores any upper operand if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); checkCvtUS(nodep->lhsp()); } int width = nodep->lhsp()->width(); int ewidth = nodep->lhsp()->width(); // Not widthMin; force it. nodep->dtypeSetLogicSized(width,ewidth,rs_out); if (vup->c()->final()) { // Final call, so make sure children check their sizes nodep->lhsp()->iterateAndNext(*this,WidthVP(width,ewidth,FINAL).p()); widthCheck(nodep,"LHS",nodep->lhsp(),width,ewidth); } } void visit_shift_Ous_Lus_Rus32(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: ShiftL, ShiftR, ShiftRS // Widths: Output width from lhs, rhs<33 bits // Signed: Output signed iff LHS signed; unary operator shift_prelim(nodep,vup); nodep->dtypeChgSigned(nodep->lhsp()->isSigned()); AstNodeBiop* newp = shift_final(nodep,vup); nodep=NULL; if (newp) {} // Ununused } void shift_prelim(AstNodeBiop* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp()); checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); } int width = max(vup->c()->width(), nodep->lhsp()->width()); int ewidth = max(vup->c()->widthMin(), nodep->lhsp()->widthMin()); nodep->dtypeChgWidth(width,ewidth); } AstNodeBiop* shift_final(AstNodeBiop* nodep, AstNUser* vup) { // Nodep maybe edited if (vup->c()->final()) { // 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 } } int width=nodep->width(); int ewidth=nodep->widthMin(); nodep->lhsp()->iterateAndNext(*this,WidthVP(width,ewidth,FINAL).p()); widthCheck(nodep,"LHS",nodep->lhsp(),width,ewidth); 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_Ous_LRus(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: And, Or, Xor, ... // Widths: out width = lhs width = rhs width // Signed: if lhs & rhs signed 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(ANYSIZE,0,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); } int width = max(vup->c()->width(), max(nodep->lhsp()->width(), nodep->rhsp()->width())); int mwidth = max(vup->c()->widthMin(), max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin())); bool expSigned = (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); nodep->dtypeChgWidthSigned(width,mwidth, expSigned?AstNumeric::SIGNED : AstNumeric::UNSIGNED); if (vup->c()->final()) { // Final call, so make sure children check their sizes nodep->lhsp()->iterateAndNext(*this,WidthVP(width,mwidth,FINAL).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(width,mwidth,FINAL).p()); // Some warning suppressions bool lhsOk=false; bool rhsOk = false; if (nodep->castAdd() || nodep->castSub()) { lhsOk = (mwidth == (nodep->lhsp()->widthMin()+1)); // Ok if user wants extra bit from carry rhsOk = (mwidth == (nodep->rhsp()->widthMin()+1)); // Ok if user wants extra bit from carry } else if (nodep->castMul() || nodep->castMulS()) { lhsOk = (mwidth >= (nodep->lhsp()->widthMin())); rhsOk = (mwidth >= (nodep->rhsp()->widthMin())); } // Error report and change sizes for suboperands of this node. widthCheck(nodep,"LHS",nodep->lhsp(),nodep->dtypep(),lhsOk); widthCheck(nodep,"RHS",nodep->rhsp(),nodep->dtypep(),rhsOk); } } void visit_math_Orus_DSreplace(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 // // 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(ANYSIZE,0,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,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(); } else { if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp()); nodep->dtypeChgSigned(nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, nodep->isSigned())) { nodep=NULL; nodep = newp; // Process new node instead } } int width = max(vup->c()->width(), max(nodep->lhsp()->width(), nodep->rhsp()->width())); int mwidth = max(vup->c()->widthMin(), max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin())); nodep->dtypeChgWidth(width,mwidth); if (vup->c()->final()) { // Final call, so make sure children check their sizes nodep->lhsp()->iterateAndNext(*this,WidthVP(width,mwidth,FINAL).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(width,mwidth,FINAL).p()); // Some warning suppressions bool lhsOk=false; bool rhsOk = false; if (nodep->castAdd() || nodep->castSub()) { lhsOk = (mwidth == (nodep->lhsp()->widthMin()+1)); // Ok if user wants extra bit from carry rhsOk = (mwidth == (nodep->rhsp()->widthMin()+1)); // Ok if user wants extra bit from carry } else if (nodep->castMul() || nodep->castMulS()) { lhsOk = (mwidth >= (nodep->lhsp()->widthMin())); rhsOk = (mwidth >= (nodep->rhsp()->widthMin())); } // Error report and change sizes for suboperands of this node. widthCheck(nodep,"LHS",nodep->lhsp(),nodep->dtypep(),lhsOk); widthCheck(nodep,"RHS",nodep->rhsp(),nodep->dtypep(),rhsOk); } //if (debug()>=9) nodep->dumpTree(cout,"-rusou-"); } void visit_math_Or_LRr(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: AddD, MulD, ... if (vup->c()->prelim()) { // First stage evaluation nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtD(nodep->lhsp()); checkCvtD(nodep->rhsp()); nodep->dtypeSetDouble(); } } void visit_math_Or_Lr(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: Negate, Ceil, Log, ... if (vup->c()->prelim()) { // First stage evaluation nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); checkCvtD(nodep->lhsp()); nodep->dtypeSetDouble(); } } //---------------------------------------------------------------------- // LOWER LEVEL WIDTH METHODS (none iterate) bool widthBad (AstNode* nodep, int expWidth, int expWidthMin) { 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) { // Fix the width mismatch by extending or truncating bits // 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 UINFO(4," widthExtend_old: "<castConst(); int expWidth = expDTypep->width(); if (constp && !expDTypep->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); linker.relink(newp); nodep=newp; } else { // Extend AstNRelinker linker; nodep->unlinkFrBack(&linker); AstNode* newp = ((expDTypep->isSigned() && nodep->isSigned()) ? (new AstExtendS(nodep->fileline(), nodep))->castNode() : (new AstExtend (nodep->fileline(), nodep))->castNode()); linker.relink(newp); nodep=newp; } nodep->dtypeChgWidth(expWidth,expWidth); 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, expSigned?AstNumeric::SIGNED : AstNumeric::UNSIGNED); 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 widthCheckFileDesc (AstNode* nodep, AstNode* underp) { AstNodeDType* expDTypep = underp->findUInt32DType(); widthCheck(nodep,"file_descriptor",underp,expDTypep,false); } void widthCheck (AstNode* nodep, const char* side, AstNode* underp, int expWidth, int expWidthMin, bool ignoreWarn=false) { AstNodeDType* expDTypep = underp->findLogicDType(expWidth, expWidthMin, underp->dtypep()->numeric()); widthCheck(nodep,side,underp,expDTypep,ignoreWarn); } void widthCheck (AstNode* nodep, const char* side, AstNode* underp, AstNodeDType* expDTypep, bool ignoreWarn=false) { //UINFO(9,"wchk "<width(); int expWidthMin = expDTypep->widthMin(); if (expWidthMin==0) expWidthMin = expWidth; bool bad = widthBad(underp,expWidth,expWidthMin); 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. ignoreWarn = true; } 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 ignoreWarn = true; } if (bad && !ignoreWarn) { if (debug()>4) nodep->backp()->dumpTree(cout," back: "); nodep->v3warn(WIDTH,"Operator "<prettyTypeName() <<" expects "<prettyTypeName()<<" generates "<width() <<(underp->width()!=underp->widthMin() ?" or "+cvtToStr(underp->widthMin()):"") <<" bits."); } if (bad || underp->width()!=expWidth) { fixWidthExtend(underp, expDTypep); underp=NULL;//Changed } } void widthCheckReduce (AstNode* nodep, const char* side, AstNode* underp) { // Underp is used in a boolean context, reduce a multibit number to one bit // Before calling this, iterate into underp with FINAL state, so numbers get resized appropriately bool ignoreWarn = false; // Not used int expWidth = 1; int expWidthMin = 1; if (expWidth!=1) nodep->v3fatalSrc("Only for binary functions"); bool bad = widthBad(underp,expWidth,expWidthMin); if (bad) { if (!ignoreWarn) { 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 } } void widthCheckPin (AstNode* nodep, AstNode* underp, AstNodeDType* expDTypep, bool inputPin) { // Before calling this, iterate into underp with FINAL state, so numbers get resized appropriately int expWidth = expDTypep->width(); bool bad = widthBad(underp,expWidth,expWidth); if (bad && fixAutoExtend(underp/*ref*/,expWidth)) bad=false; // Changes underp if (bad) { nodep->v3warn(WIDTH,(inputPin?"Input":"Output") <<" port connection "<prettyName() <<" expects "<prettyTypeName()<<" generates "<width() <<(underp->width()!=underp->widthMin() ?" or "+cvtToStr(underp->widthMin()):"") <<" bits."); } // We only fix input mismatches if (bad && inputPin) { fixWidthExtend(underp, expDTypep); underp=NULL;//Changed } } //---------------------------------------------------------------------- // SIGNED/DOUBLE METHODS void checkCvtUS(AstNode* nodep) { if (nodep && nodep->isDouble()) { nodep->v3error("Expected integral (non-real) input to "<backp()->prettyTypeName()); spliceCvtS(nodep, false); nodep=NULL; } } void checkCvtD(AstNode* nodep) { if (nodep && !nodep->isDouble()) { nodep->v3error("Expected real input to "<backp()->prettyTypeName()); spliceCvtD(nodep); nodep=NULL; } } void spliceCvtCmpD0(AstNode* nodep) { // For DOUBLE under a logical op, add implied test against zero // Never a warning if (nodep && nodep->isDouble()) { UINFO(6," spliceCvtCmpD0: "<unlinkFrBack(&linker); AstNode* newp = new AstNeqD(nodep->fileline(), nodep, new AstConst(nodep->fileline(), AstConst::RealDouble(), 0.0)); linker.relink(newp); } } void 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); } } void spliceCvtS(AstNode* nodep, bool ignoreWarn) { if (nodep && nodep->isDouble()) { UINFO(6," spliceCvtS: "<unlinkFrBack(&linker); if (!ignoreWarn) nodep->v3warn(REALCVT,"Implicit conversion of real to integer"); AstNode* newp = new AstRToIRoundS(nodep->fileline(), nodep); linker.relink(newp); } } 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::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::atPOW: newp = new AstPowS (fl,lhsp,rhsp); break; case AstType::atPOWS: newp = new AstPow (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::atEQ: newp = new AstEqD (fl,lhsp,rhsp); break; case AstType::atNEQ: 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; } 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; } int 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; } int val = 0; if (attrType==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; } } else if (attrType==AstAttrType::DIM_HIGH) { val = !declRange.ranged() ? 0 : declRange.hi(); } else if (attrType==AstAttrType::DIM_LEFT) { val = !declRange.ranged() ? 0 : declRange.left(); } else if (attrType==AstAttrType::DIM_LOW) { val = !declRange.ranged() ? 0 : declRange.lo(); } else if (attrType==AstAttrType::DIM_RIGHT) { val = !declRange.ranged() ? 0 : declRange.right(); } else if (attrType==AstAttrType::DIM_INCREMENT) { val = (declRange.ranged() && declRange.littleEndian()) ? -1 : 1; } else if (attrType==AstAttrType::DIM_SIZE) { val = !declRange.ranged() ? 0 : declRange.elements(); } else { nodep->v3fatalSrc("Missing DIM ATTR type case"); } UINFO(9," $dimension "< dim = nodep->skipRefp()->dimensions(true); uint32_t maxdim = dim.first+dim.second; // AstInitArray* initp = new AstInitArray (nodep->fileline(), NULL); AstNodeDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(), nodep->findSigned32DType(), new AstRange(nodep->fileline(), maxdim, 0)); v3Global.rootp()->typeTablep()->addTypesp(vardtypep); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, "__Vdimtable" + 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(new AstConst(nodep->fileline(), AstConst::Signed32(), dimensionValue(nodep, attrType, 0))); for (unsigned i=1; iaddInitsp(new AstConst(nodep->fileline(), AstConst::Signed32(), dimensionValue(nodep, attrType, i))); } varp->iterate(*this); // May have already done $unit so must do this var return varp; } //---------------------------------------------------------------------- // METHODS - special type detection bool backRequiresUnsigned(AstNode* nodep) { // The spec doesn't state this, but if you have an array select where the selection // index is NOT wide enough, you do not sign extend, but always zero extend. return (nodep->castArraySel() || nodep->castSel()); } 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(ANYSIZE,0,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__<<": "< #include #include #include #include #include #include #include "V3Global.h" #include "V3String.h" #include "V3EmitC.h" #include "V3EmitCBase.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_STATIC, 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->isWide()?"W":(nodep->isQuad()?"Q":"I")); } void emitScIQW(AstVar* nodep) { 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())+"]"); } } // 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 (nodep->lhsp()->castVarRef() && nodep->lhsp()->castVarRef()->varp()->isSc()) { putbs("VL_ASSIGN_"); // Set a systemC variable emitScIQW(nodep->lhsp()->castVarRef()->varp()); emitIQW(nodep); puts("("); puts(cvtToStr(nodep->widthMin())+","); nodep->lhsp()->iterateAndNext(*this); puts(", "); } else if (nodep->rhsp()->castVarRef() && nodep->rhsp()->castVarRef()->varp()->isSc()) { putbs("VL_ASSIGN_"); // Get a systemC variable emitIQW(nodep); emitScIQW(nodep->rhsp()->castVarRef()->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 SystemPerl to // aggregate counts. This is because Verilator combines all // hiearchies itself, and if SystemPerl 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()) { putbs("(&(vlSymsp->__Vscope_"+nodep->scopeSymName()+"))"); } } 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; for (const char* cp = nodep->text().c_str(); *cp; cp++) { if (pct) { pct = false; switch (tolower(*cp)) { case '%': prefix += *cp; break; case 'd': // FALLTHRU case 'o': // FALLTHRU case 'h': // FALLTHRU case 'x': // FALLTHRU case 'b': // FALLTHRU case 's': got++; format = tolower(*cp); break; case 'e': // FALLTHRU case 'f': // FALLTHRU case 'g': got++; format = tolower(*cp); nodep->v3error("Unsupported $value$plusargs format qualifier: '"<<*cp<<"'"<v3error("Illegal $value$plusargs format qualifier: '"<<*cp<<"'"<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); } } // 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->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()) { ofp()->printf("%.17g", 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); //Unneeded-Causes %lx format warnings: // if (!nodep->num().isSigned() && (num & (1UL<<31))) 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, ""); } } virtual void visit(AstConstString* nodep, AstNUser*) { putsQuoted(nodep->name()); } // 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(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 virtual void visit(AstTypedef*, AstNUser*) {} // Nothing needed presently // 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) { static int addDoubleOr = 10; // Determined experimentally as best if (!changep->rhsp()) { if (!gotOne) gotOne = true; else puts(" | "); changep->lhsp()->iterateAndNext(*this); } else { AstNode* lhsp = changep->lhsp(); AstNode* rhsp = changep->rhsp(); 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)+"]"); 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 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"); 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); #ifndef NEW_ORDERING if (!m_blkChangeDetVec.empty()) emitChangeDet(); #endif 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("IData __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 { // 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)); 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_argsp; // Each argument to be printed vector m_argsFunc; // Function before each argument to be printed EmitDispState() { clear(); } void clear() { m_format = ""; m_argsp.clear(); m_argsFunc.clear(); } void pushFormat(const string& fmt) { m_format += fmt; } void pushFormat(char fmt) { m_format += fmt; } void pushArg(AstNode* nodep, const string& func) { 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(","); 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("&("); argp->iterate(*this); if (isScan) 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(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->basicp() && varp->basicp()->keyword() == AstBasicDTypeKwd::STRING) { // Constructor deals with it } else if (varp->isParam()) { if (!varp->hasSimpleInit()) nodep->v3fatalSrc("No init for a param?"); //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 { 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().c_str()[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 SP_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( "SP_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"); #ifndef NEW_ORDERING puts("int __VclockLoop = 0;\n"); puts("IData __Vchange=1;\n"); puts("while (VL_LIKELY(__Vchange)) {\n"); puts( "VL_DEBUG_IF(VL_PRINTF(\" Clock loop\\n\"););\n"); #endif puts( "vlSymsp->__Vm_activity = true;\n"); puts( "_eval(vlSymsp);\n"); #ifndef NEW_ORDERING 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"); #endif 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"); #ifndef NEW_ORDERING puts( "vlSymsp->__Vm_activity = true;\n"); puts( "int __VclockLoop = 0;\n"); puts( "IData __Vchange=1;\n"); puts( "while (VL_LIKELY(__Vchange)) {\n"); #endif puts( "_eval_settle(vlSymsp);\n"); puts( "_eval(vlSymsp);\n"); #ifndef NEW_ORDERING 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"); #endif 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; 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 \"SpCoverage.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()); } } } 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: 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 IData "+varp->name()+" //not simple value"); } 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"); } 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; string filenameNoExt = v3Global.opt.makeDir()+"/"+ modClassName(modp)+(m_fast ? "" : "__Slow"); 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); } 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->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->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->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->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 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: "<addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope(fl, m_scopep, newvarp); m_scopep->addVarp(newvscp); return newvscp; } AstNode* createSenItemEquation(AstSenItem* nodep) { // We know the var is clean, and one bit, so we use binary ops // for speed instead of logical ops. // POSEDGE: var & ~var_last // NEGEDGE: ~var & var_last // BOTHEDGE: var ^ var_last // HIGHEDGE: var // LOWEDGE: ~var AstNode* newp = NULL; AstVarScope* clkvscp = nodep->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; } void moveInitial(AstActive* nodep) { // Change to CFunc AstNode* stmtsp = nodep->stmtsp(); if (stmtsp) { if (!m_scopep) nodep->v3fatalSrc("Initial Active not under scope\n"); AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_initial__"+m_scopep->nameDotless(), m_scopep); funcp->argTypes(EmitCBaseVisitor::symClassVar()); funcp->symProlog(true); funcp->slow(true); stmtsp->unlinkFrBackWithNext(); funcp->addStmtsp(stmtsp); nodep->replaceWith(funcp); // Add top level call to it AstCCall* callp = new AstCCall(nodep->fileline(), funcp); callp->argTypes("vlSymsp"); m_initFuncp->addStmtsp(callp); } else { nodep->unlinkFrBack(); } 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 } 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 (nodep->hasInitial()) { moveInitial(nodep); } else 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 (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->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; } } #ifdef NEW_ORDERING virtual void visit(AstUntilStable* nodep, AstNUser*) { // Process any sub ACTIVE statements first UINFO(4," UNTILSTABLE "<iterateChildren(*this); m_untilp = lastUntilp; m_lastSenp = lastSenp; m_lastIfp = lastIfp; } // Set "unstable" to 100. (non-stabilization count) // int __VclockLoop = 0 // IData __Vchange = 1 // while (__Vchange) { // Save old values of each until stable variable // Evaluate the body // __Vchange = {change_detect} contribution // if (++__VclockLoop > 100) converge_error if (debug()>4) nodep->dumpTree(cout, " UntilSt-old: "); FileLine* fl = nodep->fileline(); if (nodep->bodysp()) fl = nodep->bodysp()->fileline(); // Point to applicable code... m_stableNum++; AstNode* origBodysp = nodep->bodysp(); if (origBodysp) origBodysp->unlinkFrBackWithNext(); AstVarScope* changeVarp = getCreateLocalVar(fl, "__Vchange"+cvtToStr(m_stableNum), NULL, 32); AstVarScope* countVarp = getCreateLocalVar(fl, "__VloopCount"+cvtToStr(m_stableNum), NULL, 32); AstWhile* untilp = new AstWhile(fl, new AstVarRef(fl, changeVarp, false), NULL); AstNode* preUntilp = new AstComment(fl, "Change loop "+cvtToStr(m_stableNum)); preUntilp->addNext(new AstAssign(fl, new AstVarRef(fl, changeVarp, true), new AstConst(fl, 1))); preUntilp->addNext(new AstAssign(fl, new AstVarRef(fl, countVarp, true), new AstConst(fl, 0))); // Add stable variables & preinits AstNode* setChglastp = NULL; for (AstVarRef* varrefp = nodep->stablesp(); varrefp; varrefp=varrefp->nextp()->castVarRef()) { AstVarScope* cmpvscp = getCreateLocalVar(varrefp->varp()->fileline(), "__Vchglast"+cvtToStr(m_stableNum)+"__"+varrefp->name(), varrefp->varp(), 0); varrefp->varScopep()->user2p(cmpvscp); setChglastp = setChglastp->addNext( new AstAssign(fl, new AstVarRef(fl, cmpvscp, true), new AstVarRef(fl, varrefp->varScopep(), false))); } if (!setChglastp) nodep->v3fatalSrc("UntilStable without any variables"); untilp->addBodysp(setChglastp); untilp->addBodysp(new AstComment(fl, "Change Loop body begin")); if (origBodysp) untilp->addBodysp(origBodysp); untilp->addBodysp(new AstComment(fl, "Change Loop body end")); // Add stable checks // The order of the variables doesn't matter, but it's more expensive to test // wide variables, and more so 64 bit wide ones. Someday it might be faster to // set the changed variable in a "distributed" fashion over the code, IE, // logic... logic.... a=....; Changed |= (a ^ old_a); more logic... Changed |=... // But then, one hopes users don't have much unoptimized logic AstNode* changeExprp = NULL; int doublecount = 0; for (int wide=0; wide<3; wide++) { // Adding backwards; wide, quad, then normal for (AstVarRef* varrefp = nodep->stablesp(); varrefp; varrefp=varrefp->nextp()->castVarRef()) { if (wide== ( varrefp->isQuad()?0:(varrefp->isWide() ? 1:2))) { AstVarScope* cmpvscp = (AstVarScope*)(varrefp->varScopep()->user2p()); if (!cmpvscp) varrefp->v3fatalSrc("should have created above"); AstChangeXor* changep = new AstChangeXor (fl, new AstVarRef(fl, varrefp->varScopep(), false), new AstVarRef(fl, cmpvscp, false)); if (!changeExprp) changeExprp = changep; else if (doublecount++ > DOUBLE_OR_RATE) { doublecount = 0; changeExprp = new AstLogOr (fl, changep, changeExprp); } else { changeExprp = new AstOr (fl, changep, changeExprp); } } } } if (!changeExprp) nodep->v3fatalSrc("UntilStable without any variables"); changeExprp = new AstAssign(fl, new AstVarRef(fl, changeVarp, true), changeExprp); untilp->addBodysp(changeExprp); // // Final body AstNode* ifstmtp = new AstAssign(fl, new AstVarRef(fl, countVarp, true), new AstAdd(fl, new AstConst(fl, 1), new AstVarRef(fl, countVarp, false))); ifstmtp->addNext(new AstIf(fl, new AstLt (fl, new AstConst(fl, 100), new AstVarRef(fl, countVarp, false)), (new AstDisplay (fl, AstDisplayType::DT_DISPLAY, "%%Error: Verilated model didn't converge", NULL, NULL)) ->addNext(new AstStop (fl)), NULL)); untilp->addBodysp(new AstIf(fl, new AstNeq(fl, new AstConst(fl, 0), new AstVarRef(fl, changeVarp, false)), ifstmtp, NULL)); // // Replace it preUntilp->addNext(untilp); if (debug()>4) preUntilp->dumpTreeAndNext(cout, " UntilSt-new: "); nodep->replaceWith(preUntilp); nodep->deleteTree(); nodep=NULL; } #endif //-------------------- // 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__<<": "< #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; } bool V3PreProc::optPsl() { return v3Global.opt.psl(); } //************************************************************************* // 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_PSL : return("PSL"); 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 const char* cp=refp->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; string prev; 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 || VP_PSL) { 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) fprintf (stderr,"%d: FIN: %-10s: %s\n", m_lexp->m_tokFilelinep->lineno(), tokenName(tok), V3PreLex::cleanDbgStrg(buf).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 (const char* cp = buf.c_str(); *cp; 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) { fprintf (stderr,"%d: GETFETC: %-10s: %s\n", m_lexp->m_tokFilelinep->lineno(), tokenName(tok), V3PreLex::cleanDbgStrg(buf).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 if (tok==VP_PSL) { m_lineChars.append(" psl "); } 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) fprintf (stderr,"%d: GETLINE: %s\n", m_lexp->m_tokFilelinep->lineno(), V3PreLex::cleanDbgStrg(theLine).c_str()); return theLine; } verilator-3.856/src/V3Subst.h0000664000177100017500000000230212306677750016006 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-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. // //************************************************************************* #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.856/src/V3Config.h0000664000177100017500000000235712306677750016125 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Configuration Files // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2010-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. // //************************************************************************* #ifndef _V3CONFIG_H_ #define _V3CONFIG_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.h" //###################################################################### class V3Config { public: static void addIgnore(V3ErrorCode code, string filename, int min, int max); static void applyIgnores(FileLine* filelinep); }; #endif // Guard verilator-3.856/src/V3EmitCInlines.cpp0000664000177100017500000000766312306677750017603 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-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 "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.856/src/V3String.cpp0000664000177100017500000000374512306677750016523 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Options parsing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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 "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.856/src/V3PreShell.cpp0000664000177100017500000001356212306677750016771 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Preprocessing wrapper // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-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 "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.856/src/V3Number.h0000664000177100017500000003255212306677750016150 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-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. // //************************************************************************* #ifndef _V3NUMBER_H_ #define _V3NUMBER_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.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_fromString:1; // True if from string 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 // METHODS V3Number& setSingleBits(char value); 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 = m_width-1; // We never sign extend return ( "00zx"[(((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))] ); } char bitIsExtend (int bit) const { if (bit>=m_width) { bit = m_width-1; // 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>=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>=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>=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>=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>=m_width) return bitIsXZ(m_width-1); return ( (m_valueX[bit/32] & (1UL<<(bit&31))) && 1); } bool bitIsZ (int bit) const { 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; 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 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); // 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& opSel (const V3Number& lhs, const V3Number& rhs, const V3Number& ths); V3Number& opSel (const V3Number& lhs, uint32_t rhs, uint32_t ths); 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); V3Number& opPowS (const V3Number& lhs, const V3Number& rhs); // Signed 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); // 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); }; 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: // STATE int m_likely; // Excuses for branch likely taken int m_unlikely; // Excuses for branch likely not taken // 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; } // VISITORS virtual void visit(AstNodeIf* nodep, AstNUser*) { UINFO(4," IF: "<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(AstNode* nodep, AstNUser*) { // Default: Just iterate if (nodep->isUnlikely()) { UINFO(4," UNLIKELY: "<iterateChildren(*this); } public: // CONSTUCTORS BranchVisitor(AstNetlist* rootp) { reset(); rootp->iterateChildren(*this); } 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* condBip = condp->castNodeBiop(); if (!condBip->rhsp()->castVarRef()) return cantUnroll(nodep, "no variable on rhs of condition"); if (condBip->rhsp()->castVarRef()->varp() != m_forVarp || condBip->rhsp()->castVarRef()->varScopep() != m_forVscp) return cantUnroll(nodep, "different variable in condition"); if (m_generate) V3Const::constifyParamsEdit(condBip->lhsp()); // rhsp may change AstConst* constStopp = condBip->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, condp, incp, bodysp, constInitp->num(), condBip, constStopp->num(), incInstrp, constIncp->num()); nodep = NULL; // Cleanup return true; } void forUnroller(AstNode* nodep, AstNode* initp, AstNode* precondsp, AstNode* condp, AstNode* incp, AstNode* bodysp, const V3Number& numInit, AstNodeBiop* cmpInstrp, const V3Number& numStop, 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); 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__<<": "<, 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()->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__<<": "< #include #include #include #include #include #include #include #include #if defined(__unix__) # define INFILTER_PIPE // Allow pipe filtering. Needs fork() #endif #ifdef INFILTER_PIPE # include #endif #include "V3Global.h" #include "V3File.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) { int err = stat(filename().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 auto_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) { 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 = AstNode::quoteName(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" //###################################################################### // Stats class functions class StatsVisitor : public AstNVisitor { private: // NODE STATE/TYPES // 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 type 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->iterateChildren(*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->iterateChildren(*this); m_counting = false; } } } } } virtual void visit(AstVar* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildren(*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); } ++ m_statVarWidths.at(nodep->width()); } } virtual void visit(AstVarScope* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildren(*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()->iterateAndNext(*this); // Track prediction if (m_counting) { ++m_statPred[nodep->branchPred()]; } if (!m_fast) { nodep->iterateChildren(*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()->iterateAndNext(*this); double instrIf = m_instrs; // Check else m_instrs = 0; nodep->elsesp()->iterateAndNext(*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()->iterateAndNext(*this); } else { nodep->ifsp()->iterateAndNext(*this); } } } } // While's we assume evaluate once. //virtual void visit(AstWhile* nodep, AstNUser*) { virtual void visit(AstCCall* nodep, AstNUser*) { //UINFO(4," CCALL "<iterateChildren(*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->iterateChildren(*this); m_cfuncp = NULL; } virtual void visit(AstNode* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildren(*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; i #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__<<": "< #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.856/src/V3Const.cpp0000664000177100017500000027423312307212521016323 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Constant folding // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* // 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 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 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()->toUInt() >= (uint32_t)(nodep->width()) && isTPure(nodep->lhsp())); } bool operandHugeShiftR(AstNodeBiop* nodep) { return (nodep->rhsp()->castConst() && nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->lhsp()->width()) && isTPure(nodep->lhsp())); } bool operandIsTwo(AstNode* nodep) { return (nodep->castConst() && 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->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->sameTree(node2p); } else if (node1p->castVarRef() && node2p->castVarRef()) { // Avoid comparing widthMin's, which results in lost optimization attempts // If cleanup sameTree to be smarter, this can be restored. //return node1p->sameTree(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->sameTree(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; } //---------------------------------------- // 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(), 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 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(); if (nodep->type()==lhsp->type()) { nodep->lhsp(ap); nodep->rhsp(new AstAdd(nodep->fileline(), shift1p, shift2p)); 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(); shift1p=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->sameTree(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 (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(AstVarRef* nodep, AstNUser*) { nodep->iterateChildren(*this); if (!nodep->varp()) nodep->v3fatalSrc("Not linked"); bool did=false; if (m_doV && nodep->varp()->hasSimpleInit() && !m_attrp) { //if (debug()) nodep->varp()->valuep()->dumpTree(cout," visitvaref: "); nodep->varp()->valuep()->iterateAndNext(*this); if (operandConst(nodep->varp()->valuep()) && !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()->isSigPublic()) || nodep->varp()->isParam())) { AstConst* constp = nodep->varp()->valuep()->castConst(); const V3Number& num = constp->num(); //UINFO(2,"constVisit "<<(void*)constp<<" "<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()->sameTree(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(); for (const char* inp = nodep->text().c_str(); *inp; inp++) { char ch = *inp; // Breaks with iterators... 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()); } } } // 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 // "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 {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstPowS {$lhsp.isZero, $rhsp}", "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<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 ("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 ("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstGteD {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 ("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstLteD {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 ("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())"); // 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)"); TREEOP ("AstXnor{operandShiftSame(nodep)}", "replaceShiftSame(nodep)"); // 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 // 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_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__<<": "< #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 }; 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 { 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) { // 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 @ (*) #ifndef NEW_ORDERING if (combo && sequent) { nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list"); sequent = false; } #endif 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) { 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()); } 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()); } 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__<<": "< #include #include #include #include #include "V3Error.h" #include "V3Global.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->updateLanguage(); 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; 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) { *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.856/src/V3Options.cpp0000664000177100017500000013136112306677750016704 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Options parsing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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 "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 "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) { // Split +define+foo=value into the appropriate parts and parse string def = defline; string value; string::size_type pos; if ( ((pos=defline.find("+")) != string::npos) || ((pos=defline.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); } } 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 && filename[0] != '/'); } bool V3Options::fileStatDir(const string& filename) { struct stat m_stat; // Stat information int err = stat(filename.c_str(), &m_stat); if (err!=0) return false; if (!S_ISDIR(m_stat.st_mode)) return false; return true; } bool V3Options::fileStatNormal(const string& filename) { struct stat m_stat; // Stat information int err = stat(filename.c_str(), &m_stat); if (err!=0) return false; if (S_ISDIR(m_stat.st_mode)) return false; return true; } void V3Options::fileNfsFlush(const string& filename) { // NFS caches stat() calls so to get up-to-date information must // do a open or opendir on the filename. // Faster to just try both rather than check if a file is a dir. if (DIR* dirp = opendir(filename.c_str())) { closedir(dirp); } else if (int fd = ::open(filename.c_str(), O_RDONLY)) { if (fd>0) ::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 = filenameDir(filename); string basename = 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 = 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 = 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 = 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 = 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; } void V3Options::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); } } //###################################################################### // Environment string V3Options::getenvStr(const string& envvar, const string& defaultValue) { if (const char* envvalue = getenv(envvar.c_str())) { return envvalue; } else { return defaultValue; } } void V3Options::setenvStr(const string& envvar, const string& value, const string& why) { if (why != "") { UINFO(1,"export "<(vareq.c_str())); #endif } string V3Options::getenvPERL() { return getenvStr("PERL","perl"); } string V3Options::getenvSYSTEMC() { string var = getenvStr("SYSTEMC",""); if (var == "" && string(DEFENV_SYSTEMC) != "") { var = DEFENV_SYSTEMC; setenvStr("SYSTEMC", var, "Hardcoded at build time"); } return var; } string V3Options::getenvSYSTEMC_ARCH() { string var = getenvStr("SYSTEMC_ARCH",""); if (var == "" && string(DEFENV_SYSTEMC_ARCH) != "") { var = DEFENV_SYSTEMC_ARCH; 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 setenvStr("SYSTEMC_ARCH", var,"From sysname '"+sysname+"'"); } return var; } string V3Options::getenvSYSTEMC_INCLUDE() { string var = getenvStr("SYSTEMC_INCLUDE",""); if (var == "" && string(DEFENV_SYSTEMC_INCLUDE) != "") { var = DEFENV_SYSTEMC_INCLUDE; 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 = getenvStr("SYSTEMC_LIBDIR",""); if (var == "" && string(DEFENV_SYSTEMC_LIBDIR) != "") { var = DEFENV_SYSTEMC_LIBDIR; 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 = getenvStr("SYSTEMPERL",""); if (var == "" && string(DEFENV_SYSTEMPERL) != "") { var = DEFENV_SYSTEMPERL; setenvStr("SYSTEMPERL", var, "Hardcoded at build time"); } return var; } string V3Options::getenvSYSTEMPERL_INCLUDE() { string var = getenvStr("SYSTEMPERL_INCLUDE",""); if (var == "") { string sp_src = V3Options::getenvSYSTEMPERLGuts()+"/src"; if (V3Options::fileStatNormal(sp_src+"/systemperl.h")) { var = sp_src; 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; 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: "< 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; string::size_type pos; 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 ((pos=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 ? V3Options::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 = V3Options::filenameNonDirExt(srcfile_path); DebugSrcMap::iterator iter = m_debugSrcs.find(srcfile); if (iter!=m_debugSrcs.end()) { return iter->second; } else { return default_level; } } 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; // And set specific optimization levels if (level >= 3) { m_inlineMult = -1; // Maximum inlining } } verilator-3.856/src/V3GraphAlg.h0000664000177100017500000000322712306677750016402 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-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. // //************************************************************************* #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.856/src/V3WidthCommit.h0000664000177100017500000001301512306677750017141 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-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. // //************************************************************************* #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; 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 ((nodep->dtypep()->width() != nodep->num().width()) || !nodep->num().sized()) { // Need to force the number rrom 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); 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.856/src/V3Gate.h0000664000177100017500000000226112306677750015572 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-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. // //************************************************************************* #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.856/src/V3Delayed.cpp0000664000177100017500000004576312306677750016632 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-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. // //************************************************************************* // 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*/) { // 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 (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()); 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()); 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, nodep->rhsp()->width()); 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); 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); 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__<<": "< #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()) { 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*) { 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*) { 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 { ofp()->printf("\t%c %-30s ", comma, scopep->nameDotless().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 optPsl() { return v3Global.opt.psl(); } 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 stateExitPsl(); // Parser -> lexer communication void statePushVlg(); // Parser -> lexer communication 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; } ~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.856/src/V3Changed.cpp0000664000177100017500000001522312306677750016600 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-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. // //************************************************************************* // 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" //###################################################################### // 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 AstNodeModule* m_topModp; // Top module AstScope* m_scopetopp; // Scope under TOPSCOPE AstCFunc* m_chgFuncp; // Change function we're building // CONSTANTS enum MiscConsts { DETECTARRAY_MAX_INDEXES = 256 // How many indexes before error // Ok to increase this, but may result in much slower model }; // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } AstNode* aselIfNeeded(bool isArray, int index, AstNode* childp) { if (isArray) { return new AstArraySel(childp->fileline(), childp, new AstConst(childp->fileline(), index)); } else { return childp; } } void genChangeDet(AstVarScope* vscp) { #ifdef NEW_ORDERING vscp->v3fatalSrc("Not applicable\n"); #endif AstVar* varp = vscp->varp(); vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<dtypeSkipRefp()->castUnpackArrayDType(); AstStructDType *structp = varp->dtypeSkipRefp()->castStructDType(); bool isArray = arrayp; bool isStruct = structp && structp->packedUnsup(); int elements = isArray ? arrayp->elementsConst() : 1; if (isArray && (elements > DETECTARRAY_MAX_INDEXES)) { vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect more than "<prettyName()<warnMore() <<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<dtypeSkipRefp()->castBasicDType()) { if (debug()) varp->dumpTree(cout,"-DETECTARRAY-"); vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<prettyName()); } else { string newvarname = "__Vchglast__"+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_topModp->addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp); m_scopetopp->addVarp(newvscp); for (int index=0; indexfileline(), aselIfNeeded(isArray, index, new AstVarRef(vscp->fileline(), vscp, false)), aselIfNeeded(isArray, index, new AstVarRef(vscp->fileline(), newvscp, false)), false); m_chgFuncp->addStmtsp(changep); AstAssign* initp = new AstAssign (vscp->fileline(), aselIfNeeded(isArray, index, new AstVarRef(vscp->fileline(), newvscp, true)), aselIfNeeded(isArray, index, new AstVarRef(vscp->fileline(), vscp, false))); m_chgFuncp->addFinalsp(initp); } } } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { UINFO(4," MOD "<isTop()) { 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_scopetopp = scopep; // Create change detection function m_chgFuncp = new AstCFunc(nodep->fileline(), "_change_request", scopep, "IData"); m_chgFuncp->argTypes(EmitCBaseVisitor::symClassVar()); m_chgFuncp->symProlog(true); m_chgFuncp->declPrivate(true); m_scopetopp->addActivep(m_chgFuncp); // We need at least one change detect so we know to emit the correct code 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); } } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ChangedVisitor(AstNetlist* nodep) { m_topModp = NULL; m_chgFuncp = NULL; m_scopetopp = NULL; nodep->accept(*this); } virtual ~ChangedVisitor() {} }; //###################################################################### // Changed class functions void V3Changed::changedAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<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 optPsl() { return V3PreProc::optPsl(); } 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); } static int pslParenLevel() { return LEXP->m_pslParenLevel; } static void pslParenLevelInc() { LEXP->m_pslParenLevel++; } static void pslParenLevelDec() { if (pslParenLevel()) LEXP->m_pslParenLevel--; } static bool pslMoreNeeded() { return LEXP->m_pslMoreNeeded; } static void pslMoreNeeded(bool flag) { LEXP->m_pslMoreNeeded = flag; } /**********************************************************************/ %} %x PSLONEM %x PSLONEE %x PSLMULM %x PSLMUL1 %x CMTONEM %x CMTBEGM %x CMTMODE %x STRMODE %x DEFFPAR %x DEFFORM %x DEFVAL %x DEFCMT %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] psl [p]sl /**************************************************************/ %% ^{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); } /* Optional directives we recognize */ "`__FILE__" { static string rtnfile; rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename().c_str(); 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); } "`error" { if (!pedantic()) return (VP_ERROR); else return(VP_DEFREF); } /* 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_formalLevel) { appendDefValue(yytext,yyleng); yyleng=0; } else return (VP_STRING); } /* Stringification */ {tickquote} { return VP_STRIFY; } "`\\`\"" { return VP_BACKQUOTE; } /* Protected blocks */ "`protected" { yy_push_state(PRTMODE); yymore(); } <> { linenoInc(); yyerrorf("EOF in `protected"); yyleng=0; yyterminate(); } {crnl} { linenoInc(); yymore(); } . { 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} { 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 */ [^\/\*\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}*{psl} { if (optPsl()) { pslMoreNeeded(true); yy_push_state(PSLONEM); return(VP_PSL); } else { yy_push_state(CMTONEM); yymore(); } } "//"{ws}*{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return (VP_WHITE); } "//" { if (pslMoreNeeded()) { pslMoreNeeded(true); yy_push_state(PSLONEM); return(VP_PSL); } else { yy_push_state(CMTONEM); yymore(); } } [^\n\r]* { yy_pop_state(); return (VP_COMMENT); } /* Psl oneline comments */ [{(] { pslParenLevelInc(); return (VP_TEXT); } [})] { pslParenLevelDec(); return (VP_TEXT); } [;] { if (!pslParenLevel()) {BEGIN PSLONEE; pslMoreNeeded(false);} return (VP_TEXT); } {crnl} { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); } /* Completed psl oneline comments */ {crnl} { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); } {ws}+ { yymore(); } . { yyerrorf("Unexpected text following psl assertion\n"); } /* C-style comments. */ /**** See also DEFCMT */ /* We distinguish between the start of a comment, and later, so we may find a "psl" prefix */ "/*" { yy_push_state(optPsl() ? CMTBEGM : CMTMODE); yymore(); } {psl} { yyleng -= 3; BEGIN PSLMUL1; return (VP_COMMENT); } {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(); } /* Non 'psl' beginning in comment */ . { yymore(); } /* Psl C-style comments. */ /* EOFs are normal because / * `foo(..) * / hits a unputString EOF */ .|{crnl} { yyless(0); BEGIN PSLMULM; return(VP_PSL); } "*/" { yy_pop_state(); return(VP_COMMENT); } "//"[^\n\r]* { return (VP_COMMENT); } /* Comments inside block comments get literal inclusion (later removal) */ /* 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 #include "V3LangCode.h" //###################################################################### 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 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 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", "CMPCONST", "COMBDLY", "DEFPARAM", "DECLFILENAME", "ENDLABEL", "GENCLK", "IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE", "INCABSPATH", "INITIALDLY", "LITENDIAN", "MODDUP", "MULTIDRIVEN", "PINMISSING", "PINNOCONNECT", "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 || m_e==SYMRSVDWORD); } // Warnings to mention manual bool mentionManual() const { return ( m_e==EC_FATALSRC || 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==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; // Default debugging level static int s_errCount; // Error count static int s_warnCount; // Error 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 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(); static void init(); static void abortIfErrors(); 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); } // These 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< 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); } void updateLanguage (); 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.856/src/V3ParseSym.h0000664000177100017500000001174312306677750016462 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Common header between parser and lex // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2009-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. // //************************************************************************* #ifndef _V3PARSESYM_H_ #define _V3PARSESYM_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Global.h" #include "V3SymTable.h" #include //###################################################################### // 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.856/src/V3LinkCells.cpp0000664000177100017500000003777312306677750017145 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-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. // //************************************************************************* // 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()) pinp->v3warn(PINNOCONNECT,"Cell pin is not connected: "<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.856/src/V3Clean.h0000664000177100017500000000224212306677750015733 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-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. // //************************************************************************* #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.856/src/V3Expand.cpp0000664000177100017500000010443312306677750016470 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-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. // //************************************************************************* // 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), nodep->width()); newp->dtypeFrom(nodep); 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); AstNode* newp = new AstOr (lhsp->fileline(), oldvalp, new AstShiftL (lhsp->fileline(), rhsp, lhsp->lsbp()->cloneTree(true), 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()->castVarRef()->varp()->isSc()) || nodep->lhsp()->castArraySel())) { if (AstConst* rhsp = nodep->rhsp()->castConst()) { did = expandWide(nodep,rhsp); } else if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) { if (rhsp->varp()->isSc()) { // Still need special access function } else { 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__<<": "< #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 (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); 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; } } } verilator-3.856/src/V3ActiveTop.h0000664000177100017500000000230512306677750016607 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-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. // //************************************************************************* #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.856/src/V3Unknown.cpp0000664000177100017500000004330412307211732016670 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add Unknown assigns // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* // 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; 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; int maxlsb = maxmsb - nodep->width() + 1; if (debug()>=9) nodep->dumpTree(cout,"sel_old: "); V3Number maxlsbnum (nodep->fileline(), nodep->lsbp()->width(), maxlsb); // See if the condition is constant true AstNode* condp = new AstGte (nodep->fileline(), new AstConst(nodep->fileline(), maxlsbnum), nodep->lsbp()->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) { // SEL(...) -> COND(LTE(bit<=maxlsb), 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()); 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__<<": "<) { # 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.856/src/V3LinkDot.cpp0000664000177100017500000024437612306677750016630 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-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. // //************************************************************************* // 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; // 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; // 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 auto_ptr logp (V3File::new_ofstream(filename)); if (logp->fail()) v3fatalSrc("Can't write "<first<<" -> "<second<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(); } static string ucfirst(const string& text) { string out = text; out[0] = toupper(out[0]); return out; } 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<<" "<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(varSymp, ifOrPortSymp); } m_ifaceVarSyms.clear(); } // Track and later insert scope aliases void insertScopeAlias(VSymEnt* lhsp, VSymEnt* rhsp) { // 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.find(srcp); if (it2 != m_scopeAliasMap.end()) { srcp = it2->second; continue; } else break; } UINFO(9," iiasa: Insert alias se"<nodep()<importFromIface(symsp(), srcp); } m_scopeAliasMap.clear(); } 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(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(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); m_statep->insertSym(m_curSymp, nodep->name(), ftaskp, NULL/*package*/); } 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); 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(LinkDotState::ucfirst(whatp)<<" not found: "<prettyName()); } else if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) { nodep->v3error(LinkDotState::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); } } nodep->iterateChildren(*this); } // 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; AstPackage* packagep = NULL; if (m_ds.m_dotPos == DP_PACKAGE) { // {package}::{a} 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(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 { 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.856/src/V3Coverage.cpp0000664000177100017500000003470012306677750017003 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-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. // //************************************************************************* // 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; } }; // 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: "<ifsp()->iterateAndNext(*this); if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it if (!nodep->backp()->castIf() || nodep->backp()->castIf()->elsesp()!=nodep) { // Ignore if else; did earlier UINFO(4," COVER: "<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: "<elsesp()->castIf()) { nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "v_line", "elsif")); } else { nodep->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__<<": "< #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 "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(); AstNodeDType* 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(), 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(); AstNodeDType* 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(), 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->sameTree(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__<<": "< #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::stateExitPsl() { BEGIN VLG; } //void V3ParseImp::statePushVlg() { yy_push_state(VLG); } //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); 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 SA9 PSL 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; } "bind" { FL; return yBIND; } "bit" { FL; return yBIT; } "break" { FL; return yBREAK; } "byte" { FL; return yBYTE; } "chandle" { FL; return yCHANDLE; } "clocking" { FL; return yCLOCKING; } "context" { FL; return yCONTEXT; } "continue" { FL; return yCONTINUE; } "do" { FL; return yDO; } "endclocking" { FL; return yENDCLOCKING; } "endpackage" { FL; return yENDPACKAGE; } "endinterface" { FL; return yENDINTERFACE; } "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; } "interface" { FL; return yINTERFACE; } "int" { FL; return yINT; } "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; } "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; } "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); } "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); } "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); } } /* SystemVerilog 2005 ONLY not PSL; different rules for PSL as specified below */ { /* Keywords */ "assert" { FL; return yASSERT; } "const" { FL; return yCONST__LEX; } "cover" { FL; return yCOVER; } "property" { FL; return yPROPERTY; } "union" { FL; return yUNION; } /* Generic unsupported warnings */ "assume" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext); } "before" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext); } "sequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext); } "within" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %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); } } /************************************************************************/ /* PSL */ /*Entry into PSL; mode change */ { "psl" { yy_push_state(PSL); FL; return yPSL; } } { /* Special things */ "psl" { ; } // 'psl' may occur in middle of statement, so easier just to suppress /* Keywords */ "assert" { FL; return yPSL_ASSERT; } "assume" { FL; return yPSL_ASSERT; } //==assert "before_!" { yyerrorf("Illegal syntax, use before!_ instead of %s",yytext); } "clock" { FL; return yPSL_CLOCK; } "countones" { FL; return yD_COUNTONES; } "cover" { FL; return yPSL_COVER; } "isunknown" { FL; return yD_ISUNKNOWN; } "onehot" { FL; return yD_ONEHOT; } "onehot0" { FL; return yD_ONEHOT0; } "until_!" { yyerrorf("Illegal syntax, use until!_ instead of %s",yytext); } "report" { FL; return yPSL_REPORT; } "true" { FL; return yTRUE; } /* Generic unsupported warnings */ /*"A" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */ /*"AF" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */ /*"AG" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */ /*"AX" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */ /*"E" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */ /*"EF" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */ /*"EG" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */ /*"EX" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */ /*"F" { FL; return yEVENTUALLYB; } */ /*"G" { FL; return yALWAYS; } */ /*"U" { FL; return yUNTILB; } */ /*"W" { FL; return yUNTIL; } */ /*"X" { FL; return yNEXT; } */ /*"X!" { FL; return yNEXTB; } */ /*"restrict" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } S09 instead */ /*"strong" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } S09 instead */ /*"until" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } S09 instead */ "%for" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "%if" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "abort" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "assume_guarantee" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools "before" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "before!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "before!_" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "before_" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "boolean" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "const" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "endpoint" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "eventually!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "fairness" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools "fell" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "forall" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools "in" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "inf" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "inherit" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools "never" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_a" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_a!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_e" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_e!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_event" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_event!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_event_a" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_event_a!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_event_e" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "next_event_e!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "prev" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "property" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "restrict_guarantee" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools "rose" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "sequence" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "stable" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "union" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "until!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "until!_" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "until_" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "vmode" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools "vprop" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools "vunit" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } "within" { yyerrorf("Unsupported: PSL 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 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; } } /* PSL Operators */ { "{" { FL; return yPSL_BRA; } // Avoid parser hitting concatenate. "}" { FL; return yPSL_KET; } // Avoid parser hitting concatenate. "<->" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } //Unsup in other tools "[*" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_STAR "[*]" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_STAR_KET "[+]" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_PLUS_KET "[->" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_MINUS_GT "[->]" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_MINUS_GT_KET "[=" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_EQ "|->" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_ORMINUSGT "|=>" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_OREQGT } /* 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" { } "`psl" { if (PARSEP->optPsl()) { BEGIN PSL; } else { BEGIN IGNORE; } } "`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(SA9); PARSEP->pushBeginKeywords(YY_START); } "`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);) { if (*sp != '_') *dp++ = *sp++; else sp++; } *dp++ = '\0'; char* endp = strgp; double d = strtod(strgp, &endp); size_t parsed_len = endp-strgp; if (parsed_len != length) { 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="< // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* //********************************************************************** //**** Version and host name // Autoconf substitutes this with the strings from AC_INIT. #define PACKAGE_STRING "Verilator 3.856 2014-03-11" #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.856/src/V3Hashed.h0000664000177100017500000000611712306677750016112 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-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. // //************************************************************************* #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.856/src/V3Task.h0000664000177100017500000000303612306677750015615 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Inlining of modules // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // //************************************************************************* #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.856/README0000664000177100017500000001671012307713746014422 0ustar wsnyderwsnyderNAME This is the Verilator Package README file. DISTRIBUTION This package is Copyright 2003-2014 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.) * If you will be using SystemPerl or coverage, download and install System-Perl, . Note you'll need to set a "SYSTEMPERL" environment variable to point to the downloaded kit. Optionally also set "SYSTEMPERL_INCLUDE" to point to the installed headers. * 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, SYSTEMC_LIBDIR, SYSTEMPERL, and SYSTEMPERL_INCLUDE 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_sp => Example Verilog->SystemPerl conversion test_vcs => Example Verilog->VCS conversion (test the test) test_verilated => Internal tests test_regress => Internal tests LIMITATIONS See verilator.txt (or execute "bin/verilator --help") for limitations. verilator-3.856/Makefile.in0000664000177100017500000004050712306677750015613 0ustar wsnyderwsnyder#***************************************************************************** # DESCRIPTION: Verilator top level: Makefile pre-configure version # # This file is part of Verilator. # # Author: Wilson Snyder # # Code available from: http://www.veripool.org/verilator # #***************************************************************************** # # Copyright 2003-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. # #****************************************************************************/ # # 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 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_sp test_regress test_vcs INFOS = README README.html README.pdf internals.txt internals.html \ internals.pdf verilator.txt verilator.html verilator.1 verilator.pdf # 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/.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_includer \ bin/verilator_profcfunc \ include/verilated.mk \ include/*.[chv]* \ include/vltstd/*.[chv]* \ INST_PROJ_BIN_FILES = \ verilator_bin \ verilator_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 verilator_exe verilator_bin verilator_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_vcs test_c test_sc test_sp test_verilated test_regress else test: test_c test_sc test_sp endif @echo "Tests passed!" @echo @echo "Type 'make install' to install documentation." @echo test_vcs: all_nomsg @(cd test_vcs && $(MAKE)) 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_sp: all_nomsg @(cd test_sp && $(MAKE)) test_sp_debug: all_nomsg @(cd test_sp && $(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. verilator.1: ${srcdir}/bin/verilator 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_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 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 \ test_sp/Makefile test_sp/Makefile_obj \ installbin: $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator ) ( 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 ) $(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_sp $(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 # 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) -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) 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* $(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* $(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 = cppcheck CPPCHECK_FLAGS = --enable=all --inline-suppr --suppress=unusedScopedObject --suppress=cstyleCast 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 "Fod 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 verilator_bin* TAGS 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.856/test_sp/0000775000177100017500000000000012307720634015210 5ustar wsnyderwsnyderverilator-3.856/test_sp/.gitignore0000664000177100017500000000006212111011552017157 0ustar wsnyderwsnyder*.old *.dmp *.log *.csrc *.vcd obj_* logs project verilator-3.856/test_sp/Makefile_obj0000664000177100017500000000232012306677750017510 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-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. # #***************************************************************************** default: simx include Vtop.mk ####################################################################### # Use sp_log.cpp, so we can get output in sim.log CPPFLAGS += -DUTIL_PRINTF=sp_log_printf CPPFLAGS += -Wno-deprecated CPPFLAGS += $(SYSTEMC_CXX_FLAGS) CPPFLAGS += $(OPT) 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.856/test_sp/Makefile0000664000177100017500000000470512306677750016667 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-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. # #****************************************************************************/ 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 --trace-dups ###################################################################### ifneq ($(SYSTEMPERL),) test_default: precopy prep preproc compile run coverage test_debug: precopy prep_dbg preproc compile_dbg run coverage test_nopublic: precopy prep_dbg_np preproc compile_dbg run coverage else test_default: nosp test_debug: nosp test_nopublic: nosp endif V_FLAGS = -f $(VERILATOR_ROOT)/test_v/input.vc # Note the --public --output-split-cfunc is here for testing only, # Avoid using these settings in real application Makefiles! VERILATOR_FLAGS = --public --output-split-cfuncs 1000 --output-split 1000 \ --sp --coverage --stats --trace $(V_FLAGS) top.v precopy: obj_dir obj_dir/sc_main.cpp obj_dir/sc_main.cpp: ../test_sc/sc_main.cpp mkdir -p obj_dir cp $^ $@ prep: $(PERL) $(VERILATOR_ROOT)/bin/verilator $(VERILATOR_FLAGS) prep_dbg: $(PERL) $(VERILATOR_ROOT)/bin/verilator $(DEBUG_ON) $(VERILATOR_FLAGS) prep_dbg_np: $(PERL) $(VERILATOR_ROOT)/bin/verilator $(DEBUG_ON) $(VERILATOR_FLAGS) --nopublic preproc: cd obj_dir ; $(MAKE) -j 1 -f ../Makefile_obj preproc compile: cd obj_dir ; $(MAKE) -j 3 -f ../Makefile_obj compile_dbg: cd obj_dir ; $(MAKE) OPT=-g -j 3 -f ../Makefile_obj run: obj_dir/simx coverage: vcoverage $(V_FLAGS) ###################################################################### obj_dir: mkdir $@ nosp: @echo @echo %Skip: SYSTEMPERL not in environment @echo ###################################################################### maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir *.log *.dmp *.vpd *.vcd core logs verilator-3.856/readme.pod0000664000177100017500000001567412306677750015516 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 This package is Copyright 2003-2014 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 If you will be using SystemPerl or coverage, download and install System-Perl, L. Note you'll need to set a C environment variable to point to the downloaded kit. Optionally also set C to point to the installed headers. =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, SYSTEMC_LIBDIR, SYSTEMPERL, and SYSTEMPERL_INCLUDE 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_sp => Example Verilog->SystemPerl conversion test_vcs => Example Verilog->VCS conversion (test the test) test_verilated => Internal tests test_regress => Internal tests =head1 LIMITATIONS See verilator.txt (or execute C) for limitations. verilator-3.856/test_c/0000775000177100017500000000000012307720634015010 5ustar wsnyderwsnyderverilator-3.856/test_c/.gitignore0000664000177100017500000000004712111011551016761 0ustar wsnyderwsnyder*.dmp *.log *.csrc *.vcd obj_* project verilator-3.856/test_c/Makefile_obj0000664000177100017500000000215612306677750017317 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-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. # #***************************************************************************** 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.856/test_c/sim_main.cpp0000664000177100017500000000445212306677750017326 0ustar wsnyderwsnyder// DESCRIPTION: Verilator Example: Top level main for invoking model // // Copyright 2003-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. #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.856/test_c/Makefile0000664000177100017500000000431512306677750016464 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-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. # #****************************************************************************/ 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.856/test_verilated/0000775000177100017500000000000012307720634016545 5ustar wsnyderwsnyderverilator-3.856/test_verilated/.gitignore0000664000177100017500000000006612111011552020520 0ustar wsnyderwsnyder*.old obj_dir vgen.v simv* *.key csrc *.log INCA_libs verilator-3.856/test_verilated/sim_main.v0000664000177100017500000000146712306677750020551 0ustar wsnyderwsnyder// DESCRIPTION: Verilator Test: Top level main for invoking model // // Copyright 2003-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. 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.856/test_verilated/Makefile_obj0000664000177100017500000000210512146701432021031 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.856/test_verilated/vgen.pl0000775000177100017500000012161712306677750020065 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);'}, 'VNEQ'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w);'}, 'VGT'=> {pl=>'VGT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w);'}, 'VGTE'=> {pl=>'VGE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w);'}, 'VLT'=> {pl=>'VLT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w);'}, 'VLTE'=> {pl=>'VLE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w);'}, 'VEQCASE'=> {pl=>'VEQ (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w);'}, 'VNEQCASE'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w);'}, '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); %2r=gen_leaf(width=>(%tw-$d));'}, 'VREPLIC'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'my $d=rnd_rep_width(%tw); %1r=val_leaf($d); %2r=gen_leaf(width=>(%tw/$d));'}, 'VREPLIC1W'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'%1r=val_leaf(%tw); %2r=gen_leaf(width=>1);'}, '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/%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/%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/%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-2014 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.856/test_verilated/sim_main.cpp0000664000177100017500000000223612306677750021061 0ustar wsnyderwsnyder// DESCRIPTION: Verilator Test: Top level main for invoking model // // Copyright 2003-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. #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.856/test_verilated/vgen.v0000664000177100017500000027462112307146674017715 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'hffffffffffffffffffffffffffffffff reg [ 3: 0] W0002 ; //=4'h0 reg signed [127: 0] W0003 /*verilator public*/; //=128'hffffffffffffffffffffffffffffffff reg [118: 0] W0004 /*verilator public*/; //=119'h2f54d600000000ffffffff00000000 reg [ 2: 0] W0005 /*verilator public*/; //=3'h1 reg signed [ 35: 0] W0006 /*verilator public*/; //=36'h000000001 reg signed [ 94: 0] W0007 ; //=95'h1feb10faffffffff00000000 reg [ 60: 0] W0008 /*verilator public*/; //=61'h1fffffffffffffff reg signed [101: 0] W0009 /*verilator public*/; //=102'h00000000000000000000000000 reg signed [ 62: 0] W0010 ; //=63'h0000000000000001 reg [ 6: 0] W0011 ; //=7'h7f reg [108: 0] W0012 /*verilator public*/; //=109'h1fffffffffffffffffffffffffff reg [108: 0] W0013 ; //=109'h1fffffffffffffffffffffffffff reg [ 66: 0] W0014 ; //=67'h00000000000000000 reg signed [ 7: 0] W0015 ; //=8'h00 reg signed [ 87: 0] W0016 /*verilator public*/; //=88'h0000000000000000000000 reg signed [ 31: 0] W0017 /*verilator public*/; //=32'hffffffff reg signed [123: 0] W0018 ; //=124'h0000000000000000000000000000000 reg signed [ 96: 0] W0019 ; //=97'h000000001abf37a3000000001 reg signed [ 96: 0] W0020 ; //=97'h1ffffffffffffffffffffffff reg signed [125: 0] W0021 /*verilator public*/; //=126'h3fffffffffffffffffffffffffffffff reg signed [122: 0] W0022 ; //=123'h7ffffffbce03e2bdb14609fe7e28b41 reg signed [ 83: 0] W0023 ; //=84'h0000000000000e1fe9094 reg signed [ 83: 0] W0024 ; //=84'h0f66afffffffe308b3d7c reg [ 74: 0] W0025 ; //=75'h0000000000000000000 reg signed [ 38: 0] W0026 ; //=39'h005f38482c reg signed [ 6: 0] W0027 ; //=7'h7f reg signed [ 38: 0] W0028 ; //=39'h005f38482c reg signed [ 94: 0] W0029 ; //=95'h000000000000000000000000 reg signed [ 94: 0] W0030 ; //=95'h3691dbd700000000ffffffff reg signed [ 63: 0] W0031 ; //=64'hfffffffe00000001 reg signed [ 63: 0] W0032 ; //=64'hfffffffe00000001 reg [ 31: 0] W0033 /*verilator public*/; //=32'hffffffff reg [ 94: 0] W0034 /*verilator public*/; //=95'h7fffffffdccdbaa8bfb519ef reg signed [ 89: 0] W0035 /*verilator public*/; //=90'h0000000ae9a2f0b00000000 reg [ 94: 0] W0036 ; //=95'h7fffffffdccdbaa8bfb519ef reg signed [ 30: 0] W0037 ; //=31'h7fffffff reg signed [ 2: 0] W0038 ; //=3'h0 reg signed [ 66: 0] W0039 ; //=67'h200000001fc7de7a7 reg signed [ 3: 0] W0040 ; //=4'h0 reg signed [ 30: 0] W0041 ; //=31'h00000000 reg signed [ 6: 0] W0042 ; //=7'h7f reg signed [ 98: 0] W0043 ; //=99'h7ffffffffffffffffffffffff reg [ 84: 0] W0044 ; //=85'h0000000000000000000000 reg [106: 0] W0045 ; //=107'h000000000000000000000000000 reg [ 84: 0] W0046 ; //=85'h0000000000000000000000 reg signed [ 95: 0] W0047 ; //=96'hffffffffffffffffffffffff reg [ 62: 0] W0048 ; //=63'h00000001bf003b47 reg signed [ 50: 0] W0049 ; //=51'h0000000000000 reg signed [107: 0] W0050 ; //=108'h0170f5f330fffffffff5d6adc0b reg signed [107: 0] W0051 ; //=108'h0170f5f330fffffffff5d6adc0b reg signed [ 1: 0] W0052 /*verilator public*/; //=2'h0 reg signed [ 1: 0] W0053 ; //=2'h0 reg signed [ 1: 0] W0054 /*verilator public*/; //=2'h0 reg signed [ 70: 0] W0055 ; //=71'h000000000000000000 reg signed [ 19: 0] W0056 ; //=20'h00000 reg [ 52: 0] W0057 ; //=53'h0a9dcf00000001 reg [ 98: 0] W0058 ; //=99'h0000000000000000000000000 reg signed [ 84: 0] W0059 ; //=85'h1fffffffffffffc422fb6e reg [127: 0] W0060 ; //=128'h00000000000000000000000000000000 reg [ 0: 0] W0061 ; //=1'h1 reg signed [ 60: 0] W0062 ; //=61'h1fffffffffffffff reg signed [ 27: 0] W0063 ; //=28'h0000000 reg signed [ 24: 0] W0064 ; //=25'h1ffffff reg signed [127: 0] W0065 ; //=128'hffffffffffffffffffffffffffffffff reg signed [ 7: 0] W0066 ; //=8'h00 reg [ 50: 0] W0067 ; //=51'h0000000000000 reg signed [ 14: 0] W0068 ; //=15'h0000 reg [122: 0] W0069 /*verilator public*/; //=123'h0000000000000000000000000000000 reg [122: 0] W0070 ; //=123'h0000000000000000000000000000000 reg [122: 0] W0071 ; //=123'h0000000000000000000000000000000 reg signed [125: 0] W0072 ; //=126'h00000000000000000000000000000000 reg signed [ 50: 0] W0073 ; //=51'h7ffffffffffff reg signed [ 38: 0] W0074 ; //=39'h0000000000 reg [125: 0] W0075 ; //=126'h00000000000000000000000000000000 reg [125: 0] W0076 ; //=126'h00000000000000000000000000000000 reg signed [ 98: 0] W0077 ; //=99'h7ffffffffffffffffffffffff reg [ 23: 0] W0078 ; //=24'hffffff reg [125: 0] W0079 ; //=126'h00000000000000000000000000000000 reg [ 7: 0] W0080 ; //=8'h00 reg signed [110: 0] W0081 /*verilator public*/; //=111'h5d8cffffffff9b20638fffffffff reg signed [ 13: 0] W0082 /*verilator public*/; //=14'h0000 reg signed [ 31: 0] W0083 ; //=32'h00000000 reg signed [ 5: 0] W0084 ; //=6'h30 reg signed [ 89: 0] W0085 /*verilator public*/; //=90'h3ffffffffffffffffffffff reg signed [ 50: 0] W0086 ; //=51'h0000000000000 reg signed [ 25: 0] W0087 ; //=26'h0000001 reg [ 67: 0] W0088 /*verilator public*/; //=68'h00000000000000000 reg signed [ 78: 0] W0089 ; //=79'h00000000000000000000 reg signed [ 5: 0] W0090 ; //=6'h1b reg signed [ 77: 0] W0091 /*verilator public*/; //=78'h3fffffffffffffffffff reg signed [ 77: 0] W0092 ; //=78'h3fffffffffffffffffff reg signed [127: 0] W0093 ; //=128'hffffffffffffffffffffffffffffffff reg signed [126: 0] W0094 ; //=127'h00000000000000000000000000000000 reg signed [ 18: 0] W0095 ; //=19'h7ffff reg signed [ 7: 0] W0096 ; //=8'h00 reg signed [127: 0] W0097 ; //=128'hffffffffffffffffffffffffffffffff reg signed [127: 0] W0098 ; //=128'hffffffffffffffffffffffffffffffff reg signed [ 19: 0] W0099 /*verilator public*/; //=20'h00000 reg signed [ 19: 0] W0100 ; //=20'hfffff reg signed [ 74: 0] W0101 /*verilator public*/; //=75'h7ff7e019ac646679f3d reg signed [ 85: 0] W0102 ; //=86'h3fffffffffffffffffffff reg signed [121: 0] W0103 ; //=122'h3ffffffffffffffffffffffffffffff reg signed [121: 0] W0104 ; //=122'h3ffffffffffffffffffffffffffffff reg signed [ 3: 0] W0105 ; //=4'h0 reg signed [ 88: 0] W0106 ; //=89'h0000000fb47be1e00000001 reg signed [ 88: 0] W0107 /*verilator public*/; //=89'h1ffffff04b841e1ffffffff reg signed [ 66: 0] W0108 ; //=67'h00000000000000000 reg signed [ 66: 0] W0109 ; //=67'h00000000000000000 reg signed [ 60: 0] W0110 ; //=61'h0000000000000000 reg signed [ 6: 0] W0111 ; //=7'h01 reg [ 39: 0] W0112 ; //=40'h0000000000 reg [ 39: 0] W0113 ; //=40'h0000000000 reg signed [ 78: 0] W0114 ; //=79'h0001ffffffff00000000 reg signed [ 78: 0] W0115 /*verilator public*/; //=79'h0001ffffffff00000000 reg [ 80: 0] W0116 ; //=81'h000000000000000000001 reg signed [ 87: 0] W0117 ; //=88'h0000000000000000000000 reg signed [ 87: 0] W0118 ; //=88'h0000000000000000000000 reg [ 98: 0] W0119 ; //=99'h0ffffffffdc3c268800000000 reg [ 0: 0] W0120 ; //=1'h0 reg [ 39: 0] W0121 ; //=40'h0000000000 reg signed [ 37: 0] W0122 ; //=38'h0000000000 reg signed [ 45: 0] W0123 ; //=46'h000000000000 reg [ 70: 0] W0124 /*verilator public*/; //=71'h7fffffffffffffffff reg [ 7: 0] W0125 /*verilator public*/; //=8'h00 reg signed [ 82: 0] W0126 ; //=83'h7ffff00000000397f927d reg signed [ 75: 0] W0127 ; //=76'hfffffffffffffffffff reg signed [ 14: 0] W0128 ; //=15'h0000 reg [ 51: 0] W0129 ; //=52'hfffffffffffff reg signed [127: 0] W0130 /*verilator public*/; //=128'hffffffffffffffffffffffffffffffff reg signed [ 66: 0] W0131 ; //=67'h00000000000000001 reg signed [125: 0] W0132 ; //=126'h3ee9a075ffffffffef0f331858d8680b reg signed [ 62: 0] W0133 ; //=63'h7fffffffffffffff reg [ 39: 0] W0134 ; //=40'hffffffffff reg signed [111: 0] W0135 ; //=112'hffffffffffffffffffffffffffff reg [ 76: 0] W0136 ; //=77'h00000000000000000000 reg [ 0: 0] W0137 /*verilator public*/; //=1'h1 reg [113: 0] W0138 ; //=114'h3ffffffffffffffffffffffffffff reg signed [114: 0] W0139 ; //=115'h7ffffffffffffffffffffffffffff reg signed [ 41: 0] W0140 /*verilator public*/; //=42'h00000000000 reg signed [ 6: 0] W0141 /*verilator public*/; //=7'h7f reg [126: 0] W0142 ; //=127'h00000000000000000000000000000000 reg signed [127: 0] W0143 /*verilator public*/; //=128'h00000000000000000000000000000000 reg signed [ 90: 0] W0144 /*verilator public*/; //=91'h0fc147500000000a1a6dc1c reg signed [ 90: 0] W0145 ; //=91'h0fc147500000000a1a6dc1c reg signed [ 52: 0] W0146 ; //=53'h1fffffffffffff reg signed [ 75: 0] W0147 ; //=76'hbc2ffffffff61887cef reg signed [ 95: 0] W0148 ; //=96'hfffffffffffffffffffffffe reg signed [ 95: 0] W0149 ; //=96'hfffffffffffffffffffffffe reg signed [ 94: 0] W0150 ; //=95'h496e2428ffffffff00000001 reg signed [ 5: 0] W0151 /*verilator public*/; //=6'h00 reg [ 31: 0] W0152 /*verilator public*/; //=32'he0000000 reg signed [ 34: 0] W0153 ; //=35'h700000000 reg signed [ 34: 0] W0154 ; //=35'h700000000 reg signed [ 34: 0] W0155 ; //=35'h000000000 reg signed [120: 0] W0156 ; //=121'h000000003d719e8ffffffffffffffff reg [106: 0] W0157 ; //=107'h000000000000000000000000000 reg signed [107: 0] W0158 /*verilator public*/; //=108'h000000000000000000000000001 reg signed [ 59: 0] W0159 ; //=60'h000000000000001 reg [ 6: 0] W0160 ; //=7'h7f reg [ 95: 0] W0161 /*verilator public*/; //=96'hfffffffffffffffffffffffd reg signed [116: 0] W0162 ; //=117'h1fffffffffffffffffffffffffffff reg [ 86: 0] W0163 /*verilator public*/; //=87'h7fffffffffffffffffffff reg signed [127: 0] W0164 /*verilator public*/; //=128'hffffffffffffffffffffffffffffffff reg [ 64: 0] W0165 ; //=65'h00000000004000000 reg signed [ 86: 0] W0166 /*verilator public*/; //=87'h0000000000000000000000 reg signed [ 17: 0] W0167 /*verilator public*/; //=18'h00002 reg signed [ 17: 0] W0168 ; //=18'h00002 reg signed [ 95: 0] W0169 ; //=96'h2eb5a3fd79a326f8a74f99be reg signed [117: 0] W0170 ; //=118'h3fffffffffffffffffffffffffffff reg signed [ 96: 0] W0171 ; //=97'h1ffffffffffffffffffffffff reg [ 94: 0] W0172 /*verilator public*/; //=95'h000000000000000000000000 reg [116: 0] W0173 /*verilator public*/; //=117'h000000000000000000000000000000 reg [116: 0] W0174 ; //=117'h1fffffffffffffffffffffffffffff reg [ 22: 0] W0175 ; //=23'h000000 reg [ 0: 0] W0176 ; //=1'h1 reg [ 37: 0] W0177 /*verilator public*/; //=38'h3c00000003 reg signed [ 67: 0] W0178 /*verilator public*/; //=68'hf00000000ffffffff reg signed [ 67: 0] W0179 ; //=68'h00000000000000000 reg signed [ 7: 0] W0180 ; //=8'hff reg [ 34: 0] W0181 ; //=35'h7ffffffff reg signed [127: 0] W0182 ; //=128'hffffffffffffffffffffffffffffffff reg signed [ 58: 0] W0183 ; //=59'h7ffffffffffffff reg [ 42: 0] W0184 ; //=43'h7ffffffffff reg [ 4: 0] W0185 /*verilator public*/; //=5'h01 reg [119: 0] W0186 /*verilator public*/; //=120'h000000000000000000000000000000 reg signed [120: 0] W0187 /*verilator public*/; //=121'h1ffffff000000000000000064c42d4b reg signed [127: 0] W0188 ; //=128'h00000000000000000000000000000000 reg [104: 0] W0189 /*verilator public*/; //=105'h1ffffffc1e7d361800000002660 reg signed [122: 0] W0190 ; //=123'h7ffffff079f4d86000000009983636f reg [ 8: 0] W0191 ; //=9'h000 reg signed [ 2: 0] W0192 ; //=3'h7 reg signed [ 1: 0] W0193 ; //=2'h0 reg signed [ 34: 0] W0194 ; //=35'h600000000 reg signed [ 30: 0] W0195 ; //=31'h00000000 reg [ 0: 0] W0196 ; //=1'h1 reg signed [110: 0] W0197 ; //=111'h0000000000000000000000000000 reg [ 14: 0] W0198 ; //=15'h0000 reg signed [ 24: 0] W0199 /*verilator public*/; //=25'h1930f53 reg [ 0: 0] W0200 ; //=1'h0 reg signed [ 61: 0] W0201 /*verilator public*/; //=62'h3fffffffffffffff reg signed [127: 0] W0202 ; //=128'h00000000000000000000000000000000 reg [ 82: 0] W0203 ; //=83'h7b3155312a8ed00000000 reg [ 28: 0] W0204 ; //=29'h1f3fc1c3 reg [ 3: 0] W0205 ; //=4'h0 reg signed [ 98: 0] W0206 ; //=99'h0000000000000000000000000 reg signed [124: 0] W0207 ; //=125'h00000000000000000000000000000001 reg signed [104: 0] W0208 ; //=105'h000000000000000000000000000 reg signed [100: 0] W0209 ; //=101'h1fffffffff0000000000000001 reg [ 1: 0] W0210 ; //=2'h0 reg signed [110: 0] W0211 /*verilator public*/; //=111'h0000000000000000000000000000 reg [ 62: 0] W0212 /*verilator public*/; //=63'h7fffffffffffffff reg signed [ 97: 0] W0213 ; //=98'h0000000000000000000000001 reg signed [100: 0] W0214 /*verilator public*/; //=101'h1fffffffff0000000000000001 reg [ 5: 0] W0215 ; //=6'h00 reg [ 14: 0] W0216 /*verilator public*/; //=15'h0000 reg signed [102: 0] W0217 ; //=103'h00000000000000000000000000 reg signed [102: 0] W0218 ; //=103'h0085bac6fde88fbe57a202d84c reg signed [102: 0] W0219 /*verilator public*/; //=103'h00000000000000000000000001 reg signed [ 34: 0] W0220 /*verilator public*/; //=35'h0fffffffe reg signed [104: 0] W0221 ; //=105'h18b7e03b2359874995a00000000 reg signed [ 98: 0] W0222 ; //=99'h0000000000000000000000000 reg [124: 0] W0223 /*verilator public*/; //=125'h04000000000000000000000000000000 reg [ 98: 0] W0224 ; //=99'h7ffffffffffffffffffffffff reg signed [102: 0] W0225 ; //=103'h7fffffffffffffffffffffffff reg signed [ 4: 0] W0226 ; //=5'h00 reg signed [ 4: 0] W0227 ; //=5'h1f reg signed [ 4: 0] W0228 ; //=5'h10 reg signed [ 2: 0] W0229 /*verilator public*/; //=3'h3 reg [ 0: 0] W0230 ; //=1'h0 reg [127: 0] W0231 ; //=128'h00000000000000000000000000000000 reg [ 94: 0] W0232 ; //=95'h000000000000000000000000 reg signed [ 13: 0] W0233 ; //=14'h0000 reg signed [126: 0] W0234 /*verilator public*/; //=127'h00000000000000000000000000000000 reg signed [ 7: 0] W0235 ; //=8'hff reg signed [ 36: 0] W0236 /*verilator public*/; //=37'h1fffffffff reg [ 0: 0] W0237 ; //=1'h0 reg signed [118: 0] W0238 ; //=119'h7fffff00000000ffffffffffffffff reg signed [122: 0] W0239 ; //=123'h53fb225d8fa2187ffffffffffffffff reg signed [ 49: 0] W0240 ; //=50'h0000000000000 reg signed [ 66: 0] W0241 ; //=67'h7ffffffffee0efff1 reg signed [ 5: 0] W0242 /*verilator public*/; //=6'h3f reg [ 31: 0] W0243 ; //=32'hffffffff reg signed [ 7: 0] W0244 ; //=8'h73 reg signed [ 3: 0] W0245 ; //=4'hf reg signed [ 2: 0] W0246 ; //=3'h7 reg signed [ 74: 0] W0247 /*verilator public*/; //=75'h0000000000000000000 reg signed [ 27: 0] W0248 ; //=28'h0000000 reg [ 42: 0] W0249 /*verilator public*/; //=43'h7ffffffffff reg signed [ 92: 0] W0250 ; //=93'h000000000000000000000000 reg [ 54: 0] W0251 ; //=55'h00000000000000 reg [ 95: 0] W0252 ; //=96'h000000000000000000000000 reg signed [ 38: 0] W0253 ; //=39'h005f38482c reg signed [ 78: 0] W0254 ; //=79'h7fff87182181ffffffff reg [126: 0] W0255 /*verilator public*/; //=127'h00000000000000000000000000000000 reg signed [ 77: 0] W0256 ; //=78'h000200000002951e42d6 reg [ 0: 0] W0257 ; //=1'h1 reg [112: 0] W0258 ; //=113'h00000000000000000000000000000 reg signed [ 80: 0] W0259 /*verilator public*/; //=81'h1ffffffffffffffffffff reg [ 35: 0] W0260 ; //=36'h000000000 reg [102: 0] W0261 /*verilator public*/; //=103'h00000000000000000000000000 reg signed [113: 0] W0262 ; //=114'h00000000000000000000000000000 reg [ 47: 0] W0263 ; //=48'h000000000000 reg signed [127: 0] W0264 /*verilator public*/; //=128'h00000000000000000000000000000000 reg signed [ 34: 0] W0265 ; //=35'h000000000 reg signed [ 30: 0] W0266 /*verilator public*/; //=31'h7fffffff reg [ 90: 0] W0267 ; //=91'h73a41afffffffffffffffff reg signed [ 50: 0] W0268 ; //=51'h00000e748356c reg signed [127: 0] W0269 ; //=128'hffffffffffffffffffffffffffffffff reg signed [ 18: 0] W0270 ; //=19'h00000 reg signed [ 53: 0] W0271 ; //=54'h00000000000001 reg [ 82: 0] W0272 /*verilator public*/; //=83'h51274ffffffffffffffff reg [ 34: 0] W0273 ; //=35'h000000001 reg [ 16: 0] W0274 /*verilator public*/; //=17'h00000 reg signed [ 66: 0] W0275 /*verilator public*/; //=67'h00000000000000000 reg signed [102: 0] W0276 /*verilator public*/; //=103'h00000000000000000000000001 reg [ 5: 0] W0277 ; //=6'h3f reg signed [ 9: 0] W0278 ; //=10'h3ff reg signed [122: 0] W0279 /*verilator public*/; //=123'h0000000feefe6b4ffffffffc7107e4a reg [ 0: 0] W0280 /*verilator public*/; //=1'h0 reg [ 49: 0] W0281 ; //=50'h0000000000000 reg [ 49: 0] W0282 /*verilator public*/; //=50'h0000000000000 reg [ 78: 0] W0283 ; //=79'h7fffffffffffffffff84 reg [127: 0] W0284 ; //=128'hfffffffffffffffffffffffe101dee12 reg [ 94: 0] W0285 ; //=95'h7fffffffffffffffffffffff reg signed [ 66: 0] W0286 /*verilator public*/; //=67'h00000000000000000 reg [ 0: 0] W0287 ; //=1'h0 reg signed [ 1: 0] W0288 ; //=2'h3 reg signed [124: 0] W0289 ; //=125'h00000000000000000000000000000000 reg [112: 0] W0290 /*verilator public*/; //=113'h00000000000000006d1262eca71c0 reg signed [120: 0] W0291 ; //=121'h1906da100000001ffffffff00000000 reg signed [120: 0] W0292 /*verilator public*/; //=121'h1906da100000001ffffffff00000000 reg [120: 0] W0293 /*verilator public*/; //=121'h0000000000000001fffffffffc05c47 reg signed [127: 0] W0294 ; //=128'h0000000000000000fffffffffe02e239 reg signed [127: 0] W0295 /*verilator public*/; //=128'h0000000100000000d0ed7551a8e8b0f8 reg [121: 0] W0296 ; //=122'h3ffffffffffffffffffffffffffffff reg [ 58: 0] W0297 ; //=59'h7ffffffffffffff reg signed [ 78: 0] W0298 ; //=79'h7fffffffffffffffffff reg signed [110: 0] W0299 /*verilator public*/; //=111'h7fffffffffffffffffffffffffff reg signed [ 54: 0] W0300 ; //=55'h00000000000000 reg signed [ 26: 0] W0301 ; //=27'h7ffffff reg signed [ 17: 0] W0302 ; //=18'h00002 reg signed [ 6: 0] W0303 ; //=7'h7f reg [110: 0] W0304 ; //=111'h0000000000000000000000000000 reg [ 96: 0] W0305 ; //=97'h0000000000000000000374acf reg signed [115: 0] W0306 /*verilator public*/; //=116'h000004a144132ffffffffffffffff reg [ 19: 0] W0307 ; //=20'h00000 reg signed [ 22: 0] W0308 /*verilator public*/; //=23'h283d11 reg [ 85: 0] W0309 ; //=86'h0000000000000000000000 reg signed [127: 0] W0310 ; //=128'hffffffffffffffffffffffffffffffff reg signed [127: 0] W0311 ; //=128'hffffffffffffffffffffffffffffffff reg [ 53: 0] W0312 /*verilator public*/; //=54'h00000000000000 reg signed [110: 0] W0313 ; //=111'h0000000000000000000000000000 reg signed [110: 0] W0314 ; //=111'h0000000000000000000000000000 reg signed [110: 0] W0315 ; //=111'h0000000000000000000000000000 reg signed [127: 0] W0316 /*verilator public*/; //=128'hffffffffffffffffffffffffffffffff reg signed [ 80: 0] W0317 ; //=81'h13544d664fd48350489be reg signed [ 80: 0] W0318 ; //=81'h000006ff7e650350489be //============================================================ always @(check) begin : Block1 W0003 = 128'shffffffffffffffffffffffffffffffff; W0002 = (4'hf << {1'h1,2'h3}); W0001 = W0003; if (96'sh0 != 96'sh0) if (check) $stop; if (W0001[W0002+:96] != 96'hffffffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check) begin : Block2 if ((~ {4'h0,((59'h0 >> 7'h7f) ^ (1'h0 ? 59'h0 : 59'h7ffffffffffffff))}) != 63'h7800000000000000) if (check) $stop; if ((((((100'shfffffffff17d4750300000000 >>> 8'sh0) & (100'sh000000000ffffffff68138f72 >>> 8'shff)))==100'h0 ? 100'sh0:(100'sh14bb5d8e3ffffffffeda1130c / ((100'shfffffffff17d4750300000000 >>> 8'sh0) & (100'sh000000000ffffffff68138f72 >>> 8'shff)))) >>> (- ((8'shb3 >>> 4'sh1) <<< 4'sh0))) != 100'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0007 <= 95'sh1feb10faffffffff00000000; end always @(posedge clk) begin W0006 <= 36'sh000000001; end always @(posedge clk) begin W0005 <= ((3'h7)==3'h0 ? 3'h0:(3'h1 % 3'h7)); end always @(posedge clk) begin W0004 <= 119'h2f54d600000000ffffffff00000000; end always @(posedge clk) begin if (W0004[5'h0+:64] != 64'hffffffff00000000) if (check) $stop; if ($unsigned((W0005[2+:1] ? W0006[35:34] : {1'h0,W0007[6'h3f]})) != 2'h1) if (check) $stop; end //============================================================ always @(check) begin : Block4 W0008 = 61'h1fffffffffffffff; if (2'sh3 != 2'sh3) if (check) $stop; if ((~ ((W0008[60:60])==1'h0 ? 1'h0:((((65'sh0ffffffffffffffff)==65'h0 ? 65'sh0:(65'sh0 % 65'sh0ffffffffffffffff)) !== (65'sh00000000000000001 >>> 8'shff)) / W0008[60:60]))) != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0013 <= 109'h1fffffffffffffffffffffffffff; end always @(posedge clk) begin W0012 <= W0013; end always @(posedge clk) begin W0011 <= W0012[108:102]; end always @(posedge clk) begin W0010 <= ((63'sh7fffffffffffffff)==63'h0 ? 63'sh0:(63'sh7fffffffffffffff / 63'sh7fffffffffffffff)); end always @(posedge clk) begin W0009 <= ((102'sh3f3ec596b700000000d12d2796)==102'h0 ? 102'sh0:(102'sh0 % 102'sh3f3ec596b700000000d12d2796)); end always @(posedge clk) begin if ((((~ W0009))==102'h0 ? 102'sh0:(102'sh00ffffffffffffffff38390476 % (~ W0009))) != 102'sh0) if (check) $stop; if ((((61'h0000000180c90692)==61'h0 ? 61'h0:(W0010[2+:61] / 61'h0000000180c90692)) >> W0011) != 61'h0) if (check) $stop; end //============================================================ always @(check) begin : Block6 W0017 = (($unsigned(1'h1) ? (32'shffffffff >>> 6'sh0) : (32'shffffffff | 32'shffffffff)) + ((32'shca1cfecf <<< 6'sh3f) <<< 6'sh0a)); W0016 = 88'sh0; W0015 = 8'sh0; W0014 = (((~ W0016[87:21]))==67'h0 ? 67'h0:({W0015,59'sh0} % (~ W0016[87:21]))); if (W0014[62-:63] != 63'h0) if (check) $stop; if (W0017 != 32'shffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0020 <= 97'sh1ffffffffffffffffffffffff; end always @(posedge clk) begin W0019 <= (97'sh000000001abf37a3000000000 + 97'sh0000000000000000000000001); end always @(posedge clk) begin W0018 <= ((((124'shfffffffffffffffffffffffffffffff)==124'h0 ? 124'sh0:(124'shfffffffffffffffffffffffffffffff / 124'shfffffffffffffffffffffffffffffff)) >>> 8'shff) >>> 8'sh68); end always @(posedge clk) begin if (W0018[123:123] != 1'h0) if (check) $stop; if (((W0020)==97'h0 ? 97'sh0:(((W0019)==97'h0 ? 97'sh0:((~ 97'sh0ffffffffffffffff648b6e1f) % W0019)) / W0020)) != 97'sh00000000119d226becb67d8c4) if (check) $stop; end //============================================================ always @(posedge clk) begin W0022 <= 123'sh7ffffffbce03e2bdb14609fe7e28b41; end always @(posedge clk) begin W0021 <= 126'sh3fffffffffffffffffffffffffffffff; end always @(posedge clk) begin if (W0021[125:125] != 1'h1) if (check) $stop; if (W0022[94-:95] != 95'h3ce03e2bdb14609fe7e28b41) if (check) $stop; end //============================================================ always @(check) begin : Block9 if (102'sh3fffffffffffffffffffffffff != 102'sh3fffffffffffffffffffffffff) if (check) $stop; if (9'h1ff != 9'h1ff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0030 <= 95'sh3691dbd700000000ffffffff; end always @(posedge clk) begin W0029 <= (((95'sh7fffffffffffffffffffffff <<< 8'shff))==95'h0 ? 95'sh0:(W0030 / (95'sh7fffffffffffffffffffffff <<< 8'shff))); end always @(posedge clk) begin W0028 <= (- 39'sh7fa0c7b7d4); end always @(posedge clk) begin W0027 <= (7'sh7f >>> 4'sh1); end always @(posedge clk) begin W0026 <= W0028; end always @(posedge clk) begin W0025 <= W0029[94:20]; end always @(posedge clk) begin W0024 <= ((~ 84'shf099500000001cf74c284) - 84'shfffffffffffffffffffff); end always @(posedge clk) begin W0023 <= (~ 84'shfffffffffffff1e016f6b); end always @(posedge clk) begin if (((W0024)==84'h0 ? 84'sh0:($signed(W0023) % W0024)) != 84'sh0000000000000e1fe9094) if (check) $stop; if (W0025[W0026[W0027[2+:5]+:6]+:2] != 2'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0032 <= (64'sh00000001ffffffff * 64'shffffffffffffffff); end always @(posedge clk) begin W0031 <= (W0032 >>> ((1'h0 ? 7'sh4d : 7'sh27) & (~ 7'sh7f))); end always @(posedge clk) begin if (W0031 != 64'shfffffffe00000001) if (check) $stop; if (2'sh1 != 2'sh1) if (check) $stop; end //============================================================ always @(check) begin : Block12 W0033 = 32'hffffffff; if (((((~ $signed(2'h0)) >>> (2'sh0 >>> (2'sh1 >>> 2'sh3))))==2'h0 ? 2'sh0:(2'sh3 % ((~ $signed(2'h0)) >>> (2'sh0 >>> (2'sh1 >>> 2'sh3))))) != 2'sh0) if (check) $stop; if (((W0033[31:31])==1'h0 ? 1'h0:(1'h1 % W0033[31:31])) != 1'h0) if (check) $stop; end //============================================================ always @(check or W0009 or W0017) begin : Block13 end always @(posedge clk) begin : Block13Check if (W0009 != 102'sh0) if (check) $stop; if (W0017 != 32'shffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0038 <= ((3'sh0)==3'h0 ? 3'sh0:(3'sh7 % 3'sh0)); end always @(posedge clk) begin W0037 <= 31'sh7fffffff; end always @(posedge clk) begin W0036 <= (95'h7fffffffffffffffffffffff - 95'h0000000023324557404ae610); end always @(posedge clk) begin W0035 <= (90'sh3ffffff5165d0f4ffffffff ^ 90'sh3ffffffffffffffffffffff); end always @(posedge clk) begin W0034 <= W0036; end always @(posedge clk) begin if (((60'sh000000000000001 === (((1'h0 ? 60'sh0 : 60'sh0))==60'h0 ? 60'sh0:(((60'sh000000000000001)==60'h0 ? 60'sh0:(60'shff9e16800000000 % 60'sh000000000000001)) / (1'h0 ? 60'sh0 : 60'sh0)))) ? W0034[W0035[89:84]+:1] : (~ (W0037 && W0032))) != 1'h0) if (check) $stop; if (W0038[2:2] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((1'h1 ? 72'shff55c5414cc8a8bf33 : 72'shffffffffffffffffff) != 72'shff55c5414cc8a8bf33) if (check) $stop; if ((110'sh0000000000000000000000000001 >>> ((8'shff)==8'h0 ? 8'sh0:(($signed(8'sh0) >>> (4'shf <<< 3'sh7)) % 8'shff))) != 110'sh0000000000000000000000000001) if (check) $stop; end //============================================================ always @(posedge clk) begin W0040 <= ((4'sh0)==4'h0 ? 4'sh0:(4'sh1 % 4'sh0)); end always @(posedge clk) begin W0039 <= (67'sh200000001fc7de7a7 <<< ((W0015)==8'h0 ? 8'sh0:(W0015 / W0015))); end always @(posedge clk) begin if (W0039[3+:64] != 64'h400000003f8fbcf4) if (check) $stop; if ((((W0030)==95'h0 ? 95'sh0:(W0030 % W0030)) <<< (W0015 >>> W0040)) != 95'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (1'h0 != 1'h0) if (check) $stop; if ((28'sh0000001 <<< ((((6'sh0 >>> 4'shf))==6'h0 ? 6'sh0:((6'sh0 >>> 4'sh1) / (6'sh0 >>> 4'shf))) | (6'sh3f <<< ((4'sh0)==4'h0 ? 4'sh0:(4'shf / 4'sh0))))) != 28'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (W0037 != 31'sh7fffffff) if (check) $stop; if (60'h0 != 60'h0) if (check) $stop; end //============================================================ always @(check or W0037) begin : Block19 W0043 = 99'sh7ffffffffffffffffffffffff; W0042 = 7'sh7f; W0041 = (31'sh7fffffff - W0037); if ((~ W0041) != 31'sh7fffffff) if (check) $stop; if ((((((44'sh0 >>> 7'sh01) >>> W0042) >>> (W0043[27-:1] ? ((7'sh01)==7'h0 ? 7'sh0:(7'sh0 % 7'sh01)) : (7'sh0 >>> 4'shf))))==44'h0 ? 44'sh0:((((1'h1 ? 44'sh0 : 44'sh928eff62598) >>> 7'sh7f) <<< (7'sh01 >>> (4'shf >>> 3'sh0))) % (((44'sh0 >>> 7'sh01) >>> W0042) >>> (W0043[27-:1] ? ((7'sh01)==7'h0 ? 7'sh0:(7'sh0 % 7'sh01)) : (7'sh0 >>> 4'shf))))) != 44'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0046 <= (85'h1fffffffffffffffffffff << 8'hd9); end always @(posedge clk) begin W0045 <= (107'h0 << 8'hff); end always @(posedge clk) begin W0044 <= ((W0046)==85'h0 ? 85'h0:(W0045[106:22] % W0046)); end always @(posedge clk) begin if (($signed((((5'h1f << 4'hf))==5'h0 ? 5'h0:(((5'h1f)==5'h0 ? 5'h0:(5'h0 / 5'h1f)) % (5'h1f << 4'hf)))) <<< (W0040 >>> (((3'sh7)==3'h0 ? 3'sh0:(3'sh0 % 3'sh7)) >>> (3'sh7 >>> 3'sh0)))) != 5'sh0) if (check) $stop; if (W0044[84:83] != 2'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (42'h0 != 42'h0) if (check) $stop; if (1'h1 != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0047 <= (96'shffffffffffffffffffffffff <<< W0015); end always @(posedge clk) begin if (W0047 != 96'shffffffffffffffffffffffff) if (check) $stop; if (1'h0 != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0049 <= ((((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 W0048 <= 63'h00000001bf003b47; end always @(posedge clk) begin if (W0048[62:53] != 10'h0) if (check) $stop; if (W0049[50:50] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0051 <= (108'sh0170f5f330fffffffff5d6adc0c + 108'shfffffffffffffffffffffffffff); end always @(posedge clk) begin W0050 <= (((1'h0 ? 108'sh0 : 108'sh0) <<< ((8'sh0)==8'h0 ? 8'sh0:(8'sh0 % 8'sh0))) | W0051); end always @(posedge clk) begin if (W0050[107:40] != 68'h0170f5f330fffffff) if (check) $stop; if (31'h7fffffff != 31'h7fffffff) if (check) $stop; end //============================================================ always @(check) begin : Block25 W0054 = (2'sh3 - 2'sh3); W0053 = (2'sh0 >>> 2'sh0); W0052 = (((2'sh0)==2'h0 ? 2'sh0:(2'sh3 / 2'sh0)) ^ (2'sh3 <<< 2'sh2)); if ((((W0053 >>> (((2'sh3)==2'h0 ? 2'sh0:(2'sh0 / 2'sh3)) <<< ((2'sh3)==2'h0 ? 2'sh0:(2'sh0 / 2'sh3)))))==2'h0 ? 2'sh0:(W0052 / (W0053 >>> (((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:((W0054 <<< (2'sh0 <<< (2'sh1 >>> 2'sh0))) / 2'sh3)) != 2'sh0) if (check) $stop; end //============================================================ always @(check or W0052) begin : Block26 if (99'sh153fb34be2a39f49d00000000 != 99'sh153fb34be2a39f49d00000000) if (check) $stop; if ((W0052 | 2'sh0) != 2'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0057 <= (- 53'h156230ffffffff); end always @(posedge clk) begin W0056 <= 20'sh0; end always @(posedge clk) begin W0055 <= 71'sh0; end always @(posedge clk) begin if ((W0055[W0056[19:14]+:1] | (& W0057[52:52])) != 1'h0) if (check) $stop; if (((((40'sh0 <<< 7'sh7f) <<< ((((7'sh51)==7'h0 ? 7'sh0:(7'sh7f % 7'sh51)))==7'h0 ? 7'sh0:(((7'sh7f)==7'h0 ? 7'sh0:(7'sh7f % 7'sh7f)) / ((7'sh51)==7'h0 ? 7'sh0:(7'sh7f % 7'sh51))))))==40'h0 ? 40'sh0:(40'shffffffffff / ((40'sh0 <<< 7'sh7f) <<< ((((7'sh51)==7'h0 ? 7'sh0:(7'sh7f % 7'sh51)))==7'h0 ? 7'sh0:(((7'sh7f)==7'h0 ? 7'sh0:(7'sh7f % 7'sh7f)) / ((7'sh51)==7'h0 ? 7'sh0:(7'sh7f % 7'sh51))))))) != 40'sh0) if (check) $stop; end //============================================================ always @(check or W0032) begin : Block28 W0060 = 128'h0; W0059 = $signed(85'sh1fffffffffffffc422fb6e); W0058 = ((W0060[4'h5+:99])==99'h0 ? 99'h0:(99'h7ffffffffffffffffffffffff % W0060[4'h5+:99])); end always @(posedge clk) begin : Block28Check if ((~ W0058[W0059[84:80]+:64]) != 64'hffffffffffffffff) if (check) $stop; if (W0032 != 64'shfffffffe00000001) if (check) $stop; end //============================================================ always @(posedge clk) begin W0064 <= 25'sh1ffffff; end always @(posedge clk) begin W0063 <= 28'sh0; end always @(posedge clk) begin W0062 <= 61'sh1fffffffffffffff; end always @(posedge clk) begin W0061 <= W0062[60:60]; end always @(posedge clk) begin if (W0061 != 1'h1) if (check) $stop; if ((W0063[27:27] & W0064[24:24]) != 1'h0) if (check) $stop; end //============================================================ always @(check or W0042) begin : Block30 W0068 = (15'sh0 + 15'sh0); W0067 = 51'h0; W0066 = (8'sh1e >>> 4'shf); W0065 = (128'shffffffffffffffffffffffffffffffff <<< 8'sh0); end always @(posedge clk) begin : Block30Check if ((({(45'sh1fffffffffff >>> W0042),W0067})==96'h0 ? 96'h0:(W0065[W0066[7:4]+:96] / {(45'sh1fffffffffff >>> W0042),W0067})) != 96'h000000000000000000000001) if (check) $stop; if (((((~ (15'sh0001 >>> 5'sh1f)))==15'h0 ? 15'sh0:(W0068 % (~ (15'sh0001 >>> 5'sh1f)))) >>> 5'sh1f) != 15'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0072 <= ((126'sh3fffffffffffffffffffffffffffffff)==126'h0 ? 126'sh0:(126'sh00000000000000000000000000000001 % 126'sh3fffffffffffffffffffffffffffffff)); end always @(posedge clk) begin W0071 <= 123'h0; end always @(posedge clk) begin W0070 <= W0071; end always @(posedge clk) begin W0069 <= (W0070 + W0072[125:3]); end always @(posedge clk) begin if (21'h0 != 21'h0) if (check) $stop; if (W0069 != 123'h0) if (check) $stop; end //============================================================ always @(check) begin : Block32 W0077 = 99'sh7ffffffffffffffffffffffff; W0076 = (126'h3fffffff000000015e4ef77c00000000 >> W0077[61-:8]); W0075 = W0076[125:0]; W0074 = ((((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)))); W0073 = 51'sh7ffffffffffff; end always @(posedge clk) begin : Block32Check if (W0073[W0074[31-:5]+:1] != 1'h1) if (check) $stop; if (W0075[125:30] != 96'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0078 <= {4{((1'h0 ? 6'sh06 : 6'sh01) | (6'sh3f >>> 4'shb))}}; end always @(posedge clk) begin if (W0078[23:23] != 1'h1) if (check) $stop; if (((16'shffff <= ((16'sh0042 >>> 5'sh0) >>> ((5'sh0)==5'h0 ? 5'sh0:(5'sh1f / 5'sh0)))) >> ((^~ (41'h0 | 41'h1ff2efa1bb2)) === ({7'h0,111'h767cffffffff3d032af100000000} || (~ 10'sh0)))) != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0081 <= 111'sh5d8cffffffff9b20638fffffffff; end always @(posedge clk) begin W0080 <= 8'h0; end always @(posedge clk) begin W0079 <= ((({64'sh1e9f5381b93a757b,62'sh0} << W0080))==126'h0 ? 126'h0:($unsigned((126'sh00000000000000000000000000000001 & 126'sh0)) % ({64'sh1e9f5381b93a757b,62'sh0} << W0080))); end always @(posedge clk) begin if (W0079 != 126'h0) if (check) $stop; if (W0081[110:79] != 32'hbb19ffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0082 <= 14'sh0; end always @(posedge clk) begin if ((! W0082) != 1'h1) if (check) $stop; if (113'h00000ffffffff07a5ea017b37c2ff != 113'h00000ffffffff07a5ea017b37c2ff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0084 <= 6'sh30; end always @(posedge clk) begin W0083 <= 32'sh0; end always @(posedge clk) begin if (((W0047)==96'h0 ? 96'sh0:(W0047 % W0047)) != 96'sh0) if (check) $stop; if ((((((W0017 >>> W0084))==32'h0 ? 32'sh0:(W0083 % (W0017 >>> W0084))))==32'h0 ? 32'sh0:((W0017 | ((((32'sh0)==32'h0 ? 32'sh0:(32'sh0 % 32'sh0)))==32'h0 ? 32'sh0:((~ 32'sha60d289a) / ((32'sh0)==32'h0 ? 32'sh0:(32'sh0 % 32'sh0))))) / (((W0017 >>> W0084))==32'h0 ? 32'sh0:(W0083 % (W0017 >>> W0084))))) != 32'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((((((17'sh1ffff)==17'h0 ? 17'sh0:((~ 17'sh0) % 17'sh1ffff)) <<< 6'sh3f))==17'h0 ? 17'sh0:(17'sh0973d / (((17'sh1ffff)==17'h0 ? 17'sh0:((~ 17'sh0) % 17'sh1ffff)) <<< 6'sh3f))) != 17'sh0) if (check) $stop; if (15'sh7fff != 15'sh7fff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0090 <= (((6'sh3f)==6'h0 ? 6'sh0:(6'sh0 / 6'sh3f)) + 6'sh1b); end always @(posedge clk) begin W0089 <= 79'sh0; end always @(posedge clk) begin W0088 <= W0089[78:11]; end always @(posedge clk) begin W0087 <= 26'sh0000001; end always @(posedge clk) begin W0086 <= (51'sh0 & 51'sh0); end always @(posedge clk) begin W0085 <= ((90'sh3ffffffffffffffffffffff <<< 8'sh0) >>> (1'h1 ? 8'shff : 8'sh0)); end always @(posedge clk) begin if (((((W0088[67:66])==2'h0 ? 2'h0:(W0086[W0087[25:21]+:2] % W0088[67:66])))==2'h0 ? 2'h0:(W0085[89:88] / ((W0088[67:66])==2'h0 ? 2'h0:(W0086[W0087[25:21]+:2] % W0088[67:66])))) != 2'h0) if (check) $stop; if ((18'sh3ffff >>> W0090) != 18'sh3ffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if (72'shffffffffffffffffff != 72'shffffffffffffffffff) if (check) $stop; if (98'sh000000001cf98bdd8ed1bf345 != 98'sh000000001cf98bdd8ed1bf345) if (check) $stop; end //============================================================ always @(posedge clk) begin W0092 <= 78'sh3fffffffffffffffffff; end always @(posedge clk) begin W0091 <= (W0092 >>> (8'sh0 <<< 4'sh0)); end always @(posedge clk) begin if (((W0091)==78'h0 ? 78'sh0:((((((78'sh0)==78'h0 ? 78'sh0:(78'sh3fffffffffff64616519 / 78'sh0)) >>> W0015))==78'h0 ? 78'sh0:((78'sh3fffffffffffffffffff <<< ((8'sh01)==8'h0 ? 8'sh0:(8'shff % 8'sh01))) / (((78'sh0)==78'h0 ? 78'sh0:(78'sh3fffffffffff64616519 / 78'sh0)) >>> W0015))) / W0091)) != 78'sh0) if (check) $stop; if ((- ($signed(((49'sh0)==49'h0 ? 49'sh0:(49'sh1ffffffffffff % 49'sh0))) >>> 7'sh6b)) != 49'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0093 <= W0003; end always @(posedge clk) begin if (W0093[99-:95] != 95'h7fffffffffffffffffffffff) if (check) $stop; if (W0047 != 96'shffffffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check) begin : Block42 W0095 = 19'sh7ffff; W0094 = (((127'sh0 >>> 8'sh0))==127'h0 ? 127'sh0:(((127'sh7fffffffffffffffffffffffffffffff)==127'h0 ? 127'sh0:(127'sh00000000000000000000000000000001 / 127'sh7fffffffffffffffffffffffffffffff)) % (127'sh0 >>> 8'sh0))); if (106'sh3ffc3b5c523ffffffffffffffff != 106'sh3ffc3b5c523ffffffffffffffff) if (check) $stop; if ((W0094[126:15] << W0095[12-:8]) != 112'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0098 <= W0003; end always @(posedge clk) begin W0097 <= W0003; end always @(posedge clk) begin W0096 <= W0015; end always @(posedge clk) begin if ((((80'shffff41044a6b00000001 >>> (8'shff >>> 4'sh0)) | (~ 80'sh0)) >>> W0096) != 80'shffffffffffffffffffff) if (check) $stop; if (((W0098[4'h0+:97])==97'h0 ? 97'h0:(((W0097[4'h1+:97])==97'h0 ? 97'h0:({1{(97'sh0 <<< 8'shff)}} % W0097[4'h1+:97])) / W0098[4'h0+:97])) != 97'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0100 <= (1'h1 ? 20'shfffff : 20'sh0); end always @(posedge clk) begin W0099 <= (((20'sh0 >>> (6'sh3f >>> 4'sh0)))==20'h0 ? 20'sh0:(W0100 / (20'sh0 >>> (6'sh3f >>> 4'sh0)))); end always @(posedge clk) begin if ((- 86'sh0) != 86'sh0) if (check) $stop; if (W0099 != 20'sh0) if (check) $stop; end //============================================================ always @(check or W0061) begin : Block45 W0101 = ((75'sh7ff7e019ac646679f3d >>> 8'sh0) ^ 75'sh0); end always @(posedge clk) begin : Block45Check if ($signed(W0101[74:16]) != 59'sh7ff7e019ac64667) if (check) $stop; if (W0061 != 1'h1) if (check) $stop; end //============================================================ always @(check or W0096) begin : Block46 W0104 = (122'sh3ffffff000000010000000000000001 >>> 8'shff); W0103 = (W0104 >>> W0096); W0102 = ((((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 (W0102 != 86'sh3fffffffffffffffffffff) if (check) $stop; if (W0103[121:91] != 31'h7fffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((53'sh000000391b7da7 ^ (~ ((53'sh1fffffffffffff)==53'h0 ? 53'sh0:((1'h0 ? 53'sh000000ffffffff : 53'sh1fffffffffffff) % 53'sh1fffffffffffff)))) != 53'sh1fffffc6e48258) if (check) $stop; if ((~ 5'h0) != 5'h1f) if (check) $stop; end //============================================================ always @(check or W0031 or W0096) begin : Block48 W0107 = 89'sh1ffffff04b841e1ffffffff; W0106 = ((89'sh0 >>> W0096) - W0107); W0105 = (4'shf & 4'sh0); if (((W0031 >>> (((7'sh7f)==7'h0 ? 7'sh0:(7'sh0 / 7'sh7f)) >>> 4'shf)) >>> (((7'sh0 & 7'sh7f) | (7'sh0 <<< 4'sh4)) <<< W0105)) != 64'shfffffffe00000001) if (check) $stop; if (W0106 != 89'sh0000000fb47be1e00000001) if (check) $stop; end //============================================================ always @(posedge clk) begin 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 : Block50 W0109 = (((67'sh7ffffffffffffffff)==67'h0 ? 67'sh0:(67'sh7ffffffffffffffff / 67'sh7ffffffffffffffff)) * (67'sh0ffffffff29ed52ab >>> 8'shff)); W0108 = W0109; if (W0108[1'h0+:63] != 63'h0) if (check) $stop; if (29'sh0 != 29'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0110 <= $signed(61'h0); end always @(posedge clk) begin if (W0110 != 61'sh0) if (check) $stop; if (((115'sh7ffffffffffffffffffff00000000 >>> (((8'sh01)==8'h0 ? 8'sh0:(8'shff % 8'sh01)) <<< W0040)) >>> 8'shff) != 115'sh7ffffffffffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check or W0061) begin : Block52 W0113 = 40'h0; W0112 = $unsigned(W0113); W0111 = 7'sh01; end always @(posedge clk) begin : Block52Check if ((((~ ((63'sh000000001976eaa4 >>> 7'sh7c) >>> 7'sh01)))==63'h0 ? 63'sh0:((63'sh0 & ((1'h1 ? 63'sh0 : 63'sh0) >>> W0111)) % (~ ((63'sh000000001976eaa4 >>> 7'sh7c) >>> 7'sh01)))) != 63'sh0) if (check) $stop; if ((W0061 >> W0112[39:39]) != 1'h1) if (check) $stop; end //============================================================ always @(check or W0080 or W0083) begin : Block53 W0118 = 88'sh0; W0117 = W0118; W0116 = (81'h000000000000000000001 << 8'h0); W0115 = 79'sh0001ffffffff00000000; W0114 = W0115; if (W0083 != 32'sh0) if (check) $stop; if ((((W0117[87:13] << W0080))==75'h0 ? 75'h0:(((W0116[80:6])==75'h0 ? 75'h0:(W0114[78:4] / W0116[80:6])) / (W0117[87:13] << W0080))) != 75'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0122 <= (38'sh3fffffffff + 38'sh0000000001); end always @(posedge clk) begin W0121 <= 40'h0; end always @(posedge clk) begin W0120 <= W0121[39:39]; end always @(posedge clk) begin W0119 <= (99'h1ffffffffb8784d1000000001 >> 8'h01); end always @(posedge clk) begin if (((W0119[27-:1] < W0120) ? ((~ (63'sh7fffffffffffffff <<< 7'sh0)) >>> W0111) : (~ (63'sh0 >>> (7'sh7f >>> 4'shf)))) != 63'sh7fffffffffffffff) if (check) $stop; if (((~ W0122) <<< 7'sh65) != 38'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0123 <= 46'sh0; end always @(posedge clk) begin if ((((((1'h0 ? 46'sh0 : 46'sh353300000000) >>> (1'h0 ? 7'sh0 : 7'sh0)) >>> $signed(W0111)))==46'h0 ? 46'sh0:((((W0123 >>> W0042))==46'h0 ? 46'sh0:(($signed(46'sh0) >>> W0111) % (W0123 >>> W0042))) % (((1'h0 ? 46'sh0 : 46'sh353300000000) >>> (1'h0 ? 7'sh0 : 7'sh0)) >>> $signed(W0111)))) != 46'sh0) if (check) $stop; if (((1'h1)==1'h0 ? 1'h0:(1'h0 % 1'h1)) != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0125 <= W0080; end always @(posedge clk) begin W0124 <= {1{71'sh7fffffffffffffffff}}; end always @(posedge clk) begin if (84'sh00000ffffffff00000000 != 84'sh00000ffffffff00000000) if (check) $stop; if ((((W0124 >> W0125))==71'h0 ? 71'h0:(((71'h000000000000000001)==71'h0 ? 71'h0:(71'h05ffffffff00000000 % 71'h000000000000000001)) % (W0124 >> W0125))) != 71'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0127 <= (76'sh0 - 76'sh0000000000000000001); end always @(posedge clk) begin W0126 <= (83'sh7ffff00000000397f927d >>> 8'sh0); end always @(posedge clk) begin if ((1'h1 ? (^ W0126[82:20]) : 1'h0) != 1'h0) if (check) $stop; if (((W0127 ^ (((76'sh0000000000000000001 >>> 8'sh69))==76'h0 ? 76'sh0:(76'shd6f3f197a9e00000000 / (76'sh0000000000000000001 >>> 8'sh69)))) >>> (8'shff | W0096)) != 76'shfffffffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0130 <= 128'shffffffffffffffffffffffffffffffff; end always @(posedge clk) begin W0129 <= 52'hfffffffffffff; end always @(posedge clk) begin W0128 <= W0068; end always @(posedge clk) begin if (W0128[12-:13] != 13'h0) if (check) $stop; if ({((38'h1d69b1ac3b)==38'h0 ? 38'h0:(((W0130[6'h0+:38])==38'h0 ? 38'h0:(W0129[51:14] / W0130[6'h0+:38])) % 38'h1d69b1ac3b)),26'h0} != 64'h0000000004000000) if (check) $stop; end //============================================================ always @(posedge clk) begin W0132 <= (~ 126'sh01165f8a0000000010f0cce7a72797f4); end always @(posedge clk) begin W0131 <= 67'sh00000000000000001; end always @(posedge clk) begin if ((((66'sh3ffffffffffffffff >>> (8'sh32 <<< 4'shf)) & (W0131[6'h19] ? (66'sh1169fc5f7822a56b4 <<< 8'shff) : (~ 66'sh3ffffffffffffffff))) >>> (W0096 <<< W0040)) != 66'sh0) if (check) $stop; if ((~ $signed(W0132[125:3])) != 123'sh022cbf140000000021e199cf4e4f2fe) if (check) $stop; end //============================================================ always @(posedge clk) begin if (((((111'sh0 | 111'sh0) <<< W0096) | ((((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:((W0015 <<< (4'shf & 4'sh5)) / 8'sh0))) != 111'sh0) if (check) $stop; if (58'sh000000021435d6c != 58'sh000000021435d6c) if (check) $stop; end //============================================================ always @(check or W0015 or W0111 or W0040) begin : Block61 W0133 = ((63'sh7fffffffffffffff & 63'sh7fffffffffffffff) >>> (1'h1 ? 7'sh0 : 7'sh0a)); if (((((((~ 101'sh1fffffffffffffffffffffffff))==101'h0 ? 101'sh0:(((101'sh07801e45c800000000ffffffff)==101'h0 ? 101'sh0:(101'sh1fffffffffffffffffffffffff / 101'sh07801e45c800000000ffffffff)) / (~ 101'sh1fffffffffffffffffffffffff))) <<< (W0015 >>> W0040)))==101'h0 ? 101'sh0:(101'sh00000000000000000000000001 % ((((~ 101'sh1fffffffffffffffffffffffff))==101'h0 ? 101'sh0:(((101'sh07801e45c800000000ffffffff)==101'h0 ? 101'sh0:(101'sh1fffffffffffffffffffffffff / 101'sh07801e45c800000000ffffffff)) / (~ 101'sh1fffffffffffffffffffffffff))) <<< (W0015 >>> W0040)))) != 101'sh0) if (check) $stop; if ((W0133 >>> (((W0111)==7'h0 ? 7'sh0:((7'sh7f >>> 4'shd) % W0111)) >>> W0040)) != 63'sh7fffffffffffffff) if (check) $stop; end //============================================================ always @(check or W0061) begin : Block62 W0136 = (1'h1 ? 77'h0 : ((77'h0)==77'h0 ? 77'h0:(77'h1fffffffffffffffffff % 77'h0))); W0135 = 112'shffffffffffffffffffffffffffff; W0134 = W0135[111:72]; if (((((({8{5'sh01}})==40'h0 ? 40'h0:((40'h0 & 40'h0bd1a118bf) % {8{5'sh01}})))==40'h0 ? 40'h0:(W0134 % (({8{5'sh01}})==40'h0 ? 40'h0:((40'h0 & 40'h0bd1a118bf) % {8{5'sh01}})))) & W0136[76:37]) != 40'h0) if (check) $stop; if (W0061 != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0139 <= 115'sh7ffffffffffffffffffffffffffff; end always @(posedge clk) begin W0138 <= W0139[114:1]; end always @(posedge clk) begin W0137 <= (W0120 - W0138[113:113]); end always @(posedge clk) begin if (((((25'sh0 >>> 6'sh0) >>> (6'sh3f <<< 4'sh2)) >>> (W0090 <<< (4'sh7 >>> 3'sh7))) <= (((25'sh0 <<< 6'sh3f) >>> (6'sh0 >>> 4'shf)) >>> W0090)) != 1'h1) if (check) $stop; if (W0137 != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0143 <= ((128'sh0 >>> 8'sh01) >>> 8'sh01); end always @(posedge clk) begin W0142 <= W0143[126-:127]; end always @(posedge clk) begin W0141 <= (~ 7'sh0); end always @(posedge clk) begin W0140 <= ((((42'sh3ff00000000)==42'h0 ? 42'sh0:(42'sh00000000001 / 42'sh3ff00000000)) <<< 7'sh7f) <<< W0141); end always @(posedge clk) begin if (W0140[41:40] != 2'h0) if (check) $stop; if (W0142[126:95] != 32'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0145 <= 91'sh0fc147500000000a1a6dc1c; end always @(posedge clk) begin W0144 <= W0145; end always @(posedge clk) begin if ($signed((W0144[90:90] ? 95'sh000000000000000000000001 : 95'sh0)) != 95'sh0) if (check) $stop; if (84'shfffffffffffffffffffff != 84'shfffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check or W0015) begin : Block66 W0146 = 53'sh1fffffffffffff; if (((((98'sh3ffffffffffffffffffffffff)==98'h0 ? 98'sh0:((98'sh2fffffffffffffffff4e32117 >>> 8'sh45) % 98'sh3ffffffffffffffffffffffff)) >>> (($signed(8'hff))==8'h0 ? 8'sh0:(W0015 % $signed(8'hff)))) >>> 8'sh0) != 98'sh0) if (check) $stop; if ({1{(((W0146 | ((53'sh1fffffffffffff)==53'h0 ? 53'sh0:(53'sh0 / 53'sh1fffffffffffff))))==53'h0 ? 53'sh0:((($signed(53'h0ba454f928a5aa))==53'h0 ? 53'sh0:((~ 53'sh0) % $signed(53'h0ba454f928a5aa))) % (W0146 | ((53'sh1fffffffffffff)==53'h0 ? 53'sh0:(53'sh0 / 53'sh1fffffffffffff)))))}} != 53'h0) if (check) $stop; end //============================================================ always @(check) begin : Block67 if ((((((18'sh3ffff <<< 6'sh01))==18'h0 ? 18'sh0:((18'sh0 >>> 6'sh01) % (18'sh3ffff <<< 6'sh01))) <<< (((6'sh01)==6'h0 ? 6'sh0:(6'sh3f / 6'sh01)) <<< 4'shc)) === (18'h0 << ((1'h0 ? 6'h01 : 6'h0) >> (~ 4'h2)))) != 1'h1) if (check) $stop; if (32'hda3f2a15 != 32'hda3f2a15) if (check) $stop; end //============================================================ always @(posedge clk) begin W0147 <= (76'shbc2ffffffff61887cef >>> W0096); end always @(posedge clk) begin if (57'sh1ded308896e764f != 57'sh1ded308896e764f) if (check) $stop; if ((W0147[75:41] << 7'h0) != 35'h5e17fffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0149 <= (96'shffffffffffffffffffffffff + 96'shffffffffffffffffffffffff); end always @(posedge clk) begin W0148 <= (W0149 >>> (W0096 <<< W0105)); end always @(posedge clk) begin if ($signed(W0053) != 2'sh0) if (check) $stop; if (W0148[95:17] != 79'h7fffffffffffffffffff) if (check) $stop; end //============================================================ always @(check or W0053 or W0030 or W0002) begin : Block70 W0150 = (- W0030); if (W0053 != 2'sh0) if (check) $stop; if (((64'hffffffffffffffff)==64'h0 ? 64'h0:(W0150[((1'h0 < 1'h0) ? W0002 : W0002)+:64] / 64'hffffffffffffffff)) != 64'h0) if (check) $stop; end //============================================================ always @(check or W0120) begin : Block71 W0151 = 6'sh0; if ((~ (31'sh00000001 >>> (W0151 >>> ((4'shf)==4'h0 ? 4'sh0:(4'sh0 % 4'shf))))) != 31'sh7ffffffe) if (check) $stop; if (W0120 != 1'h0) if (check) $stop; end //============================================================ always @(check) begin : Block72 W0155 = ((((35'sh7ffffffff <<< 7'sh01) & (35'sh7ffffffff | 35'sh0)))==35'h0 ? 35'sh0:(((((35'sh75f98c1bf)==35'h0 ? 35'sh0:(35'sh4233277ef / 35'sh75f98c1bf)))==35'h0 ? 35'sh0:(((35'sh6ffffffff)==35'h0 ? 35'sh0:(35'sh1e1da29e7 % 35'sh6ffffffff)) % ((35'sh75f98c1bf)==35'h0 ? 35'sh0:(35'sh4233277ef / 35'sh75f98c1bf)))) / ((35'sh7ffffffff <<< 7'sh01) & (35'sh7ffffffff | 35'sh0)))); W0154 = 35'sh700000000; W0153 = W0154; W0152 = W0153[3+:32]; end always @(posedge clk) begin : Block72Check if (((W0152[31:0])==32'h0 ? 32'h0:(32'h5d01711b / W0152[31:0])) != 32'h0) if (check) $stop; if (W0155[5'h0+:1] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (W0137 != 1'h1) if (check) $stop; if (W0032 != 64'shfffffffe00000001) if (check) $stop; end //============================================================ always @(posedge clk) begin W0158 <= 108'sh000000000000000000000000001; end always @(posedge clk) begin W0157 <= W0158[107:1]; end always @(posedge clk) begin W0156 <= ((121'sh1ffffffb6cbffd8ffffffff00000001)==121'h0 ? 121'sh0:(121'sh000000003d719e8ffffffffffffffff % 121'sh1ffffffb6cbffd8ffffffff00000001)); end always @(posedge clk) begin if (W0037 != 31'sh7fffffff) if (check) $stop; if (({43'h0,(1'h1 ? W0133 : W0133)} & (W0156[120:15] >> W0157[40-:8])) != 106'h0000000000033d1ffffffffffff) if (check) $stop; end //============================================================ always @(check or W0003 or W0011) begin : Block75 W0164 = W0003; W0163 = W0164[99-:87]; W0162 = 117'sh1fffffffffffffffffffffffffffff; W0161 = ((96'hffffffffffffffffffffffff << 8'h01) + W0162[116:21]); W0160 = W0011; W0159 = ((60'sh000000000000001)==60'h0 ? 60'sh0:(60'sh000000000000001 / 60'sh000000000000001)); end always @(posedge clk) begin : Block75Check if (((W0159[59:17] >> W0160) || 64'h000000000432c7fd) != 1'h1) if (check) $stop; if ((W0161 || W0163[3+:84]) != 1'h1) if (check) $stop; end //============================================================ always @(check or W0061) begin : Block76 W0168 = (18'sh00001 - 18'sh3ffff); W0167 = (W0061 ? W0168 : (((18'sh0 & 18'sh17c61))==18'h0 ? 18'sh0:(18'sh0d0f6 / (18'sh0 & 18'sh17c61)))); W0166 = (87'sh0 >>> 8'shff); W0165 = {W0166[86:63],((41'sh1ffffffffff)==41'h0 ? 41'sh0:((41'sh1ffffffffff <<< 7'sh1a) / 41'sh1ffffffffff))}; end always @(posedge clk) begin : Block76Check if (W0165[64:64] != 1'h0) if (check) $stop; if (W0167[17:17] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0171 <= (97'sh1ffffffffffffffffffffffff >>> (8'shff <<< 4'shf)); end always @(posedge clk) begin W0170 <= (~ (118'sh0 >>> 8'sh01)); end always @(posedge clk) begin W0169 <= (96'sh2eb5a3feffffffffa74f99bd - 96'sh00000001865cd906ffffffff); end always @(posedge clk) begin if ((((W0169)==96'h0 ? 96'sh0:((96'sh13b76419e266c572464d6815 ^ W0149) / W0169)) <<< W0015) != 96'sh0) if (check) $stop; if (((W0171[96:33])==64'h0 ? 64'h0:(W0170[117:54] % W0171[96:33])) != 64'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0174 <= 117'h1fffffffffffffffffffffffffffff; end always @(posedge clk) begin W0173 <= (((117'h000000000000000000000000000001)==117'h0 ? 117'h0:(117'h0 / 117'h000000000000000000000000000001)) & W0174); end always @(posedge clk) begin W0172 <= W0173[116:22]; end always @(posedge clk) begin if (W0137 != 1'h1) if (check) $stop; if (W0172[6'h01] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0178 <= 68'shf00000000ffffffff; end always @(posedge clk) begin W0177 <= W0178[67:30]; end always @(posedge clk) begin W0176 <= W0177[37:37]; end always @(posedge clk) begin W0175 <= (({23{1'h1}})==23'h0 ? 23'h0:((~ 23'h7fffff) / {23{1'h1}})); end always @(posedge clk) begin 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; if ((W0175[16-:1] >> W0176) != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0180 <= 8'shff; end always @(posedge clk) begin W0179 <= ((W0120 ? (68'sh0 <<< 8'sh01) : (68'sh0 >>> 8'shff)) >>> (((8'shff)==8'h0 ? 8'sh0:(8'shff % 8'shff)) & W0180)); end always @(posedge clk) begin if (105'sh1ffffffffffffffffffffffffff != 105'sh1ffffffffffffffffffffffffff) if (check) $stop; if (W0179[67:8] != 60'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0185 <= 5'h01; end always @(posedge clk) begin W0184 <= 43'h7ffffffffff; end always @(posedge clk) begin W0183 <= 59'sh7ffffffffffffff; end always @(posedge clk) begin W0182 <= (~ 128'sh0); end always @(posedge clk) begin W0181 <= W0182[W0183[52-:6]+:35]; end always @(posedge clk) begin if ((W0047 >>> W0015) != 96'shffffffffffffffffffffffff) if (check) $stop; if ((W0181[25-:1] ^ W0184[(W0185 ^ ((5'h1f)==5'h0 ? 5'h0:(5'h01 / 5'h1f)))+:1]) != 1'h0) if (check) $stop; end //============================================================ always @(check) begin : Block82 W0186 = (((120'h0 << (8'h0 | 8'h0)))==120'h0 ? 120'h0:(120'h000000ec84af558ee1d84a00000000 % (120'h0 << (8'h0 | 8'h0)))); if (38'sh3fffffffff != 38'sh3fffffffff) if (check) $stop; if (W0186[119:13] != 107'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (W0168 != 18'sh00002) if (check) $stop; if ((($signed((((124'h9b9af1e694338baffffffffdbdf2475 << 8'hff))==124'h0 ? 124'h0:((1'h1 ? 124'hfffffffffffffffffffffffffffffff : 124'h9ecb5e63d0fd22700000000d6312ec0) % (124'h9b9af1e694338baffffffffdbdf2475 << 8'hff)))))==124'h0 ? 124'sh0:(((((124'sh0)==124'h0 ? 124'sh0:(124'sh0 / 124'sh0)) ^ ((124'sh000000000000000ffffffff00000001)==124'h0 ? 124'sh0:(124'sh0 / 124'sh000000000000000ffffffff00000001))) >>> W0180) / $signed((((124'h9b9af1e694338baffffffffdbdf2475 << 8'hff))==124'h0 ? 124'h0:((1'h1 ? 124'hfffffffffffffffffffffffffffffff : 124'h9ecb5e63d0fd22700000000d6312ec0) % (124'h9b9af1e694338baffffffffdbdf2475 << 8'hff)))))) != 124'sh0) if (check) $stop; end //============================================================ always @(check or W0015) begin : Block84 W0187 = (- ((121'sh0000000ffffffffffffffff00000000 | 121'sh00000000000000027ab4e109b3bd2b5) >>> W0015)); if (W0187[120:49] != 72'hffffff800000000000) if (check) $stop; if (((109'sh0d0ad5a17d4e2105991700000000)==109'h0 ? 109'sh0:(109'sh0 / 109'sh0d0ad5a17d4e2105991700000000)) != 109'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (28'hfffffff != 28'hfffffff) if (check) $stop; if (W0032 != 64'shfffffffe00000001) if (check) $stop; end //============================================================ always @(posedge clk) begin W0192 <= (3'sh7 | 3'sh0); end always @(posedge clk) begin W0191 <= (~ 9'h1ff); end always @(posedge clk) begin W0190 <= 123'sh7ffffff079f4d86000000009983636f; end always @(posedge clk) begin W0189 <= W0190[122:18]; end always @(posedge clk) begin W0188 <= (~ 128'shffffffffffffffffffffffffffffffff); end always @(posedge clk) begin if ((W0188[113-:80] << (W0189[104:97] << W0191[8:5])) != 80'h0) if (check) $stop; if ((~ W0192[0-:1]) != 1'h0) if (check) $stop; end //============================================================ always @(check or W0054) begin : Block87 W0193 = (((31'sh7fffffff > 31'h7fffffff) ? W0054 : W0054) - W0054); if (((28'shbf65019)==28'h0 ? 28'sh0:(28'sh0 / 28'shbf65019)) != 28'sh0) if (check) $stop; if (W0193 != 2'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0195 <= (31'sh00000001 >>> W0084); end always @(posedge clk) begin W0194 <= 35'sh600000000; end always @(posedge clk) begin if (W0194[6-:1] != 1'h0) if (check) $stop; if (W0195 != 31'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0196 <= W0176; end always @(posedge clk) begin if (W0196 != 1'h1) if (check) $stop; if (W0032 != 64'shfffffffe00000001) if (check) $stop; end //============================================================ always @(posedge clk) begin if (31'sh7fffffff != 31'sh7fffffff) if (check) $stop; if (((~ W0133) | ((W0133)==63'h0 ? 63'sh0:(((W0133)==63'h0 ? 63'sh0:((63'sh0000000000000001 <<< 7'sh53) % W0133)) % W0133))) != 63'sh0) if (check) $stop; end //============================================================ always @(check or W0196 or W0002 or W0042) begin : Block91 W0198 = 15'h0; W0197 = 111'sh0; if ((((W0196 << W0196))==1'h0 ? 1'h0:(1'h0 % (W0196 << W0196))) != 1'h0) if (check) $stop; if ((({{22{W0198[3'h7]}},(((64'shffffffffffffffff)==64'h0 ? 64'sh0:(64'sh2aafe03affffffff / 64'shffffffffffffffff)) >>> W0042)})==86'h0 ? 86'h0:(W0197[W0002+:86] % {{22{W0198[3'h7]}},(((64'shffffffffffffffff)==64'h0 ? 64'sh0:(64'sh2aafe03affffffff / 64'shffffffffffffffff)) >>> W0042)})) != 86'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0199 <= 25'sh1930f53; end always @(posedge clk) begin if ((((W0199)==25'h0 ? 25'sh0:(((95'h1792207dffffffff00000000 !== 95'sh7fffffffffffffffffffffff) ? ((25'sh0000001)==25'h0 ? 25'sh0:(25'sh0 / 25'sh0000001)) : (1'h1 ? 25'sh1ffffff : 25'sh0)) % W0199)) <<< W0151) != 25'sh0) if (check) $stop; if (75'h45708c934aad6da79b4 != 75'h45708c934aad6da79b4) if (check) $stop; end //============================================================ always @(posedge clk) begin W0201 <= 62'sh3fffffffffffffff; end always @(posedge clk) begin W0200 <= (1'h0 << 1'h1); end always @(posedge clk) begin if ((((W0200)==1'h0 ? 1'h0:(1'h1 / W0200)) ? ((62'sh3fffffffffffffff)==62'h0 ? 62'sh0:((W0201 >>> W0042) % 62'sh3fffffffffffffff)) : 62'sh0000000100000000) != 62'sh0000000100000000) if (check) $stop; if ((W0037 >>> W0084) != 31'sh7fffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0207 <= ((125'sh0 >>> (8'sh94 <<< 4'sh1)) - ((~ 125'sh0) >>> (8'sh0 >>> 4'sh6))); end always @(posedge clk) begin W0206 <= 99'sh0; end always @(posedge clk) begin W0205 <= W0206[79-:4]; end always @(posedge clk) begin W0204 <= 29'h1f3fc1c3; end always @(posedge clk) begin W0203 <= {28'shf662aa6,55'sh12a8ed00000000}; end always @(posedge clk) begin W0202 <= (($signed(128'hffffffffffffffffffffffffffffffff))==128'h0 ? 128'sh0:((128'shffffffffffffffffffffffffffffffff >>> 8'shff) % $signed(128'hffffffffffffffffffffffffffffffff))); end always @(posedge clk) begin if ((W0202[((((4'h0)==4'h0 ? 4'h0:(4'hf / 4'h0)))==4'h0 ? 4'h0:(((4'h0)==4'h0 ? 4'h0:(4'h1 % 4'h0)) % ((4'h0)==4'h0 ? 4'h0:(4'hf / 4'h0))))+:109] >> (W0203[W0204[28:23]+:8] << W0205)) != 109'h0) if (check) $stop; if (W0207 != 125'sh00000000000000000000000000000001) if (check) $stop; end //============================================================ always @(check or W0151 or W0036 or W0017 or W0105) begin : Block95 W0208 = (((105'sh000ffffffffffffffff50906cd4 <<< 8'sh0))==105'h0 ? 105'sh0:(((105'sh1ff84dad3b87c263736062a0982)==105'h0 ? 105'sh0:(105'sh1ffffffffff74d9a69a78dbe00c / 105'sh1ff84dad3b87c263736062a0982)) / (105'sh000ffffffffffffffff50906cd4 <<< 8'sh0))); if ((W0017 <<< (((W0151)==6'h0 ? 6'sh0:(6'sh01 % W0151)) >>> W0105)) != 32'shffffffff) if (check) $stop; if (((W0036)==95'h0 ? 95'h0:(W0208[104:10] % W0036)) != 95'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0209 <= (((101'sh0)==101'h0 ? 101'sh0:(101'sh0 / 101'sh0)) - 101'sh0000000000ffffffffffffffff); end always @(posedge clk) begin if (((~ (W0196 << 1'h1)) ? 101'sh008767606855af5f46ffffffff : W0209) != 101'sh008767606855af5f46ffffffff) if (check) $stop; if (W0083 != 32'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block97 end always @(posedge clk) begin : Block97Check if (32'sh0 != 32'sh0) if (check) $stop; if (96'shffffffffffffffffffffffff != 96'shffffffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check or W0196) begin : Block98 W0211 = ((~ 1'h0) ? (111'sh0 >>> 8'sh0) : (111'sh0000ef79dda4ffffffffffffffff >>> 8'shff)); W0210 = W0211[110:109]; end always @(posedge clk) begin : Block98Check if (W0196 != 1'h1) if (check) $stop; if (W0210 != 2'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0216 <= 15'h0; end always @(posedge clk) begin W0215 <= W0216[9-:6]; end always @(posedge clk) begin W0214 <= W0209; end always @(posedge clk) begin W0213 <= 98'sh0000000000000000000000001; end always @(posedge clk) begin W0212 <= {63{W0214[100:100]}}; end always @(posedge clk) begin if (W0212[(W0213[97:93] << 4'h0)+:1] != 1'h1) if (check) $stop; if ((((~ W0215[5:5]))==1'h0 ? 1'h0:((W0037 == W0037) % (~ W0215[5:5]))) != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0219 <= 103'sh00000000000000000000000001; end always @(posedge clk) begin W0218 <= 103'sh0085bac6fde88fbe57a202d84c; end always @(posedge clk) begin W0217 <= ((((W0219)==103'h0 ? 103'sh0:((103'sh0 >>> 8'shff) % W0219)))==103'h0 ? 103'sh0:(((1'h1 | 1'h1) ? W0218 : (103'sh0 <<< 8'sh01)) / ((W0219)==103'h0 ? 103'sh0:((103'sh0 >>> 8'shff) % W0219)))); end always @(posedge clk) begin if (W0133 != 63'sh7fffffffffffffff) if (check) $stop; if (W0217[102:102] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0223 <= {3'h1,122'sh0}; end always @(posedge clk) begin W0222 <= ((((99'sh7ffffffff00000000ffffffff)==99'h0 ? 99'sh0:(99'sh1ffffffffb5bae196a0f8ef2e % 99'sh7ffffffff00000000ffffffff)))==99'h0 ? 99'sh0:((1'h1 ? 99'sh0 : 99'sh0000000000000000000000001) % ((99'sh7ffffffff00000000ffffffff)==99'h0 ? 99'sh0:(99'sh1ffffffffb5bae196a0f8ef2e % 99'sh7ffffffff00000000ffffffff)))); end always @(posedge clk) begin W0221 <= 105'sh18b7e03b2359874995a00000000; end always @(posedge clk) begin W0220 <= (~ 35'sh700000001); end always @(posedge clk) begin if ((W0220[(W0221[104:104] ? W0185 : ((5'h1f)==5'h0 ? 5'h0:(5'h0 % 5'h1f)))+:1] >> W0222[28-:1]) != 1'h1) if (check) $stop; if (W0223[124:61] != 64'h2000000000000000) if (check) $stop; end //============================================================ always @(check or W0200) begin : Block102 W0225 = (1'h0 ? 103'sh7f0000000000000000a932571f : 103'sh7fffffffffffffffffffffffff); W0224 = W0225[99-:99]; if (((W0224[94-:95])==95'h0 ? 95'h0:(95'h7fffffffffffffffffffffff / W0224[94-:95])) != 95'h000000000000000000000001) if (check) $stop; if (W0200 != 1'h0) if (check) $stop; end //============================================================ always @(check or W0160) begin : Block103 end always @(posedge clk) begin : Block103Check if ((((~ 119'sh7fffffffffffffffffffffffffffff) | (~ ((119'sh558215000000000000000000000001)==119'h0 ? 119'sh0:(119'sh6160ec5908bbfcffffffff19180b72 / 119'sh558215000000000000000000000001)))) & 119'sh0) != 119'sh0) if (check) $stop; if ((64'hffffffffffffffff << W0160) != 64'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (15'sh39b6 != 15'sh39b6) if (check) $stop; if (W0133 != 63'sh7fffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0228 <= 5'sh10; end always @(posedge clk) begin W0227 <= 5'sh1f; end always @(posedge clk) begin W0226 <= 5'sh0; end always @(posedge clk) begin if (52'sh0 != 52'sh0) if (check) $stop; if (((((W0227 <<< (4'shf >>> 3'sh1)) | (- W0228)))==5'h0 ? 5'sh0:(((W0226 >>> W0040) >>> W0105) / ((W0227 <<< (4'shf >>> 3'sh1)) | (- W0228)))) != 5'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block106 W0230 = (& (14'sh0001 >>> 5'sh1f)); W0229 = 3'sh3; if ((W0229[(1'h0 ? {1{1'h0}} : (1'h1 | 1'h1))] << ({6'h0,4'sh1} !== 10'sh0)) != 1'h0) if (check) $stop; if ({1{W0230}} != 1'h0) if (check) $stop; end //============================================================ always @(check) begin : Block107 W0232 = 95'h0; W0231 = 128'h0; if (W0231 != 128'h0) if (check) $stop; if (((W0232[94:63])==32'h0 ? 32'h0:(32'hffffffff / W0232[94:63])) != 32'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0233 <= ((((14'sh3fff)==14'h0 ? 14'sh0:(14'sh0 % 14'sh3fff)))==14'h0 ? 14'sh0:(14'sh0 % ((14'sh3fff)==14'h0 ? 14'sh0:(14'sh0 % 14'sh3fff)))); end always @(posedge clk) begin if (32'sh0 != 32'sh0) if (check) $stop; if ((14'sh3fff | W0233) != 14'sh3fff) if (check) $stop; end //============================================================ always @(check or W0180) begin : Block109 W0235 = W0180; W0234 = ($signed(((127'sh000000010000000065c23b2a00000001)==127'h0 ? 127'sh0:(127'sh00000000000000018a995eff00000000 / 127'sh000000010000000065c23b2a00000001))) >>> W0235); end always @(posedge clk) begin : Block109Check if (($signed(96'hffffffffffffffffffffffff) >>> W0180) != 96'shffffffffffffffffffffffff) if (check) $stop; if (W0234[126:126] != 1'h0) if (check) $stop; end //============================================================ always @(check) begin : Block110 W0236 = 37'sh1fffffffff; end always @(posedge clk) begin : Block110Check if (((((((W0236)==37'h0 ? 37'sh0:((37'sh137942ceb2 <<< 7'sh01) % W0236)))==37'h0 ? 37'sh0:(37'sh0 / ((W0236)==37'h0 ? 37'sh0:((37'sh137942ceb2 <<< 7'sh01) % W0236)))))==37'h0 ? 37'sh0:(37'sh1fffffffff / ((((W0236)==37'h0 ? 37'sh0:((37'sh137942ceb2 <<< 7'sh01) % W0236)))==37'h0 ? 37'sh0:(37'sh0 / ((W0236)==37'h0 ? 37'sh0:((37'sh137942ceb2 <<< 7'sh01) % W0236)))))) != 37'sh0) if (check) $stop; if ((47'sh627035bf7a97 & ((((47'sh7fff00000000 >>> 7'sh7f) >>> (7'sh7f | 7'sh0)))==47'h0 ? 47'sh0:(47'sh7fffffffffff / ((47'sh7fff00000000 >>> 7'sh7f) >>> (7'sh7f | 7'sh0))))) != 47'sh000000000001) if (check) $stop; end //============================================================ always @(posedge clk) begin W0239 <= 123'sh53fb225d8fa2187ffffffffffffffff; end always @(posedge clk) begin W0238 <= (119'sh000000ffffffff0000000000000000 ^ 119'sh7fffffffffffffffffffffffffffff); end always @(posedge clk) begin W0237 <= W0238[68-:1]; end always @(posedge clk) begin if ((W0237 ? 21'sh000001 : (~ $signed(21'sh000001))) != 21'sh1ffffe) if (check) $stop; if ((~ W0239[122:60]) != 63'h2c04dda2705de780) if (check) $stop; end //============================================================ always @(posedge clk) begin if (W0031 != 64'shfffffffe00000001) if (check) $stop; if (((~| ((110'h0 >> 8'h0) != (110'sh00000000000000000000ffffffff >>> 8'shff))) << 1'h0) != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0242 <= 6'sh3f; end always @(posedge clk) begin W0241 <= 67'sh7ffffffffee0efff1; end always @(posedge clk) begin W0240 <= 50'sh0; end always @(posedge clk) begin if ((((50'sh0000078a01e1c)==50'h0 ? 50'sh0:((W0240 >>> ((7'sh7f)==7'h0 ? 7'sh0:(7'sh01 % 7'sh7f))) % 50'sh0000078a01e1c)) ^ (((50'sh2b919ca68fa68 | ((50'sh0)==50'h0 ? 50'sh0:(50'sh0000000000001 / 50'sh0))))==50'h0 ? 50'sh0:((W0241[66:66] ? ((50'sh0)==50'h0 ? 50'sh0:(50'sh00000ffffffff / 50'sh0)) : ((50'sh0)==50'h0 ? 50'sh0:(50'sh0 / 50'sh0))) / (50'sh2b919ca68fa68 | ((50'sh0)==50'h0 ? 50'sh0:(50'sh0000000000001 / 50'sh0)))))) != 50'sh0) if (check) $stop; if (((((26'sh3ffffff <<< 6'sh01) >>> W0242) <<< (W0151 | W0090)) <<< 6'sh0) != 26'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0243 <= (W0061 ? (1'h1 ? 32'hffffffff : 32'h2c0ee208) : ((32'h0)==32'h0 ? 32'h0:(32'h0 % 32'h0))); end always @(posedge clk) begin if (W0031 != 64'shfffffffe00000001) if (check) $stop; if ((W0243 << 6'h3f) != 32'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0247 <= ((75'sh0)==75'h0 ? 75'sh0:(75'sh0 % 75'sh0)); end always @(posedge clk) begin W0246 <= 3'sh7; end always @(posedge clk) begin W0245 <= 4'shf; end always @(posedge clk) begin W0244 <= (8'sh0 - 8'sh8d); end always @(posedge clk) begin if ((((- (1'h0 ? 109'sh00005cd67561a89d641e00000001 : 109'sh0000000000000000000000000001)) <<< W0235) >>> (W0244 >>> (W0245 <<< W0246))) != 109'sh0) if (check) $stop; if ((82'sh3ffffffffffffffffffff <<< (W0247[(6'h0 >> 4'h0)+:1] ? (((8'shff)==8'h0 ? 8'sh0:(8'sh5b % 8'shff)) >>> (~ 4'sh0)) : ((W0015)==8'h0 ? 8'sh0:((8'sh01 >>> 4'shf) / W0015)))) != 82'sh3ffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check or W0237) begin : Block116 if (W0237 != 1'h0) if (check) $stop; if (57'sh0 != 57'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block117 if ({8'h0,((56'sh00000000000001)==56'h0 ? 56'sh0:(((56'sh00000000000001 >>> 7'sh7f) <<< (7'sh3f >>> 4'sh0)) / 56'sh00000000000001))} != 64'h0) if (check) $stop; if (63'sh0 != 63'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (W0052 != 2'sh0) if (check) $stop; if (((96'shffffffffffffffffffffffff)==96'h0 ? 96'sh0:(W0047 % 96'shffffffffffffffffffffffff)) != 96'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0252 <= 96'h0; end always @(posedge clk) begin W0251 <= W0252[95:41]; end always @(posedge clk) begin W0250 <= 93'sh0; end always @(posedge clk) begin W0249 <= 43'h7ffffffffff; end always @(posedge clk) begin W0248 <= (((28'shfffffff <<< 6'sh3f) >>> (- 6'sh1c)) * (- (28'shfffffff >>> 6'sh0))); end always @(posedge clk) begin if (W0248 != 28'sh0) if (check) $stop; if ((W0249[42:29] & ((((1'h0 ? 14'h3fff : 14'h0))==14'h0 ? 14'h0:(W0250[92:79] % (1'h0 ? 14'h3fff : 14'h0))) >> W0251[54:50])) != 14'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0254 <= 79'sh7fff87182181ffffffff; end always @(posedge clk) begin W0253 <= W0028; end always @(posedge clk) begin if (W0253[W0254[78:74]] != 1'h0) if (check) $stop; if ((W0195 >>> W0151) != 31'sh0) if (check) $stop; end //============================================================ always @(check or W0137) begin : Block121 W0255 = (((~ (127'h0 << 8'hd7)))==127'h0 ? 127'h0:(127'h0 % (~ (127'h0 << 8'hd7)))); if (W0255[126:0] != 127'h0) if (check) $stop; if (W0137 != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0259 <= ((81'sh1ffffffffffffffffffff >>> 8'shff) >>> ((8'shff)==8'h0 ? 8'sh0:(8'sh01 / 8'shff))); end always @(posedge clk) begin W0258 <= ((~ 113'h1ffffffffffffffffffffffffffff) >> W0125); end always @(posedge clk) begin W0257 <= W0196; end always @(posedge clk) begin W0256 <= (78'sh0001000000014a8f216b <<< 8'sh01); end always @(posedge clk) begin if ($unsigned($signed(W0256)) != 78'h000200000002951e42d6) if (check) $stop; if ((W0257 ? W0258[112:49] : W0259[80:17]) != 64'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0260 <= $unsigned((((36'sh9627e9d6a)==36'h0 ? 36'sh0:(36'sh0a9f0c0a5 / 36'sh9627e9d6a)) & (1'h1 ? 36'sh0 : 36'sh6ffffffff))); end always @(posedge clk) begin if (W0133 != 63'sh7fffffffffffffff) if (check) $stop; if (W0260[35:21] != 15'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0262 <= (114'sh0 >>> 8'shff); end always @(posedge clk) begin W0261 <= W0262[113:11]; end always @(posedge clk) begin if ($signed(W0261[102:71]) != 32'sh0) if (check) $stop; if (20'sh0 != 20'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0266 <= 31'sh7fffffff; end always @(posedge clk) begin W0265 <= 35'sh0; end always @(posedge clk) begin W0264 <= ((128'sh62aa887fd0add0ee000000009f6f690b)==128'h0 ? 128'sh0:(128'sh00000000000000000000000000000001 / 128'sh62aa887fd0add0ee000000009f6f690b)); end always @(posedge clk) begin W0263 <= (W0264[59-:48] * (((48'hffffffffffff >> 7'h77))==48'h0 ? 48'h0:((~ 48'h0) % (48'hffffffffffff >> 7'h77)))); end always @(posedge clk) begin if (W0263 != 48'h0) if (check) $stop; if ((~ W0265[W0266[11-:5]+:1]) != 1'h1) if (check) $stop; end //============================================================ always @(check or W0243 or W0242) begin : Block126 W0269 = (128'shffffffffffffffffffffffffffffffff >>> 8'sh0); W0268 = (1'h1 ? 51'sh00000e748356c : 51'sh7ffff00000000); W0267 = {W0268[(4'h9 | 4'h0)+:23],W0269[5'h01+:68]}; end always @(posedge clk) begin : Block126Check if ((W0243 >> $unsigned((~ W0242))) != 32'hffffffff) if (check) $stop; if (W0267[17-:1] != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0270 <= (((((19'sh7ffff >>> 6'sh3f))==19'h0 ? 19'sh0:(((19'sh0)==19'h0 ? 19'sh0:(19'sh00001 / 19'sh0)) / (19'sh7ffff >>> 6'sh3f))))==19'h0 ? 19'sh0:(19'sh0 / (((19'sh7ffff >>> 6'sh3f))==19'h0 ? 19'sh0:(((19'sh0)==19'h0 ? 19'sh0:(19'sh00001 / 19'sh0)) / (19'sh7ffff >>> 6'sh3f))))); end always @(posedge clk) begin if ($signed(W0161) != 96'shfffffffffffffffffffffffd) if (check) $stop; if (W0270[17-:18] != 18'h0) if (check) $stop; end //============================================================ always @(check or W0196 or W0219) begin : Block128 W0277 = 6'h3f; W0276 = W0219; W0275 = (((67'sh7ffffffffffffffff >>> 8'shff))==67'h0 ? 67'sh0:(67'sh7ffffffffffffffff % (67'sh7ffffffffffffffff >>> 8'shff))); W0274 = (((17'h0)==17'h0 ? 17'h0:(17'h0 / 17'h0)) * 17'h1ffff); W0273 = 35'h000000001; W0272 = 83'h51274ffffffffffffffff; W0271 = 54'sh00000000000001; end always @(posedge clk) begin : Block128Check if (((W0274)==17'h0 ? 17'h0:((((W0273[5'h01] ? (17'h0 >> 6'h24) : (17'h00001 >> 6'h30)))==17'h0 ? 17'h0:(((W0272[6'h3f+:17])==17'h0 ? 17'h0:(W0271[53:37] / W0272[6'h3f+:17])) % (W0273[5'h01] ? (17'h0 >> 6'h24) : (17'h00001 >> 6'h30)))) / W0274)) != 17'h0) if (check) $stop; if ((W0275[W0276[W0277+:6]+:1] << W0196) != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0280 <= W0120; end always @(posedge clk) begin W0279 <= (123'sh000000096e9e0b0ffffffff00000000 | 123'sh0000000fec7862400000000c7107e4a); end always @(posedge clk) begin W0278 <= (W0279[(6'h0 << 4'hf)+:1] ? ((1'h1 ? 10'sh3ff : 10'sh0) <<< W0228) : 10'sh3ff); end always @(posedge clk) begin if (W0278[9:9] != 1'h1) if (check) $stop; if (W0280[0:0] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0282 <= {28'h0,22'h0}; end always @(posedge clk) begin W0281 <= W0282; end always @(posedge clk) begin if (((1'h1)==1'h0 ? 1'h0:(W0281[49:49] % 1'h1)) != 1'h0) if (check) $stop; if ((- (~ 73'sh1ff0000000100000000)) != 73'sh1ff0000000100000001) if (check) $stop; end //============================================================ always @(check or W0244 or W0015) begin : Block131 if (95'h0 != 95'h0) if (check) $stop; if (((- ((1'h0 ? 69'sh1f000000005f6fd955 : 69'sh0) <<< W0015)) & (((69'sh1fffffffff6a435651 >>> W0244))==69'h0 ? 69'sh0:(((69'sh1fffffffffffffffff >>> 8'sh01) >>> (8'sh01 >>> 4'sh0)) % (69'sh1fffffffff6a435651 >>> W0244)))) != 69'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0285 <= 95'h7fffffffffffffffffffffff; end always @(posedge clk) begin W0284 <= {W0285,(33'h0ffffffff & 33'h1101dee12)}; end always @(posedge clk) begin W0283 <= W0284[(- 5'h06)+:79]; end always @(posedge clk) begin if (W0283[W0277] != 1'h1) if (check) $stop; if (54'sh00000000000001 != 54'sh00000000000001) if (check) $stop; end //============================================================ always @(posedge clk) begin W0288 <= 2'sh3; end always @(posedge clk) begin W0287 <= 1'h0; end always @(posedge clk) begin W0286 <= W0109; end always @(posedge clk) begin if ({41{W0286[20-:1]}} != 41'h0) if (check) $stop; if (((((19'sh43ea7)==19'h0 ? 19'sh0:((19'sh0 >>> 6'sh0) % 19'sh43ea7)) && (W0287 ? ((64'sh0)==64'h0 ? 64'sh0:(64'sh2117d19387012c11 % 64'sh0)) : (64'sh0 >>> 7'sh6b))) ? W0288 : W0054) != 2'sh0) if (check) $stop; end //============================================================ always @(check or W0207 or W0099) begin : Block134 W0289 = (((W0207 >>> (8'sh0 | 8'she4)))==125'h0 ? 125'sh0:(125'sh1fffffff000000012f126cb600000000 % (W0207 >>> (8'sh0 | 8'she4)))); if (W0099 != 20'sh0) if (check) $stop; if (W0289[124:34] != 91'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((((((- 31'sh00000001) >>> 6'sh0))==31'h0 ? 31'sh0:((((31'sh7fffffff | 31'sh7fffffff))==31'h0 ? 31'sh0:((31'sh00000001 >>> 6'sh12) / (31'sh7fffffff | 31'sh7fffffff))) / ((- 31'sh00000001) >>> 6'sh0))) >>> W0090) != 31'sh0) if (check) $stop; if (52'shfffff00000000 != 52'shfffff00000000) if (check) $stop; end //============================================================ always @(check or W0104 or W0015) begin : Block136 W0296 = $unsigned(W0104); W0295 = (128'sh0000000100000000d0ed7551a8e8b0f8 >>> W0015); W0294 = 128'sh0000000000000000fffffffffe02e239; W0293 = W0294[2'h3+:121]; W0292 = 121'sh1906da100000001ffffffff00000000; W0291 = W0292; W0290 = ((W0293[120:8])==113'h0 ? 113'h0:(W0291[120:8] % W0293[120:8])); if (W0290[112:112] != 1'h0) if (check) $stop; if ((W0295[122-:121] ^ W0296[121:1]) != 121'h1ffffffbfffffffcbc4a2ab95c5d3c1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0303 <= 7'sh7f; end always @(posedge clk) begin W0302 <= W0168; end always @(posedge clk) begin W0301 <= (~ 27'sh0); end always @(posedge clk) begin W0300 <= ((((55'sh655f9bffffffff)==55'h0 ? 55'sh0:(55'sh7fffff7d8969a5 / 55'sh655f9bffffffff)) <<< W0303) <<< W0141); end always @(posedge clk) begin W0299 <= ((111'sh7fff000000010000000065b2bace ^ 111'sh0) >>> (8'shba <<< 4'sh0)); end always @(posedge clk) begin W0298 <= 79'sh7fffffffffffffffffff; end always @(posedge clk) begin W0297 <= W0298[78:20]; end always @(posedge clk) begin if (((W0196 ? ((((59'h7ffffffffffffff)==59'h0 ? 59'h0:(59'h0 % 59'h7ffffffffffffff)))==59'h0 ? 59'h0:((59'h0 << 7'h01) / ((59'h7ffffffffffffff)==59'h0 ? 59'h0:(59'h0 % 59'h7ffffffffffffff)))) : W0297) | W0299[(- (5'h0 >> 4'h1))+:59]) != 59'h7ffffffffffffff) if (check) $stop; if (W0300[((W0302[17:14])==4'h0 ? 4'h0:(W0301[26:23] / W0302[17:14]))+:32] != 32'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0304 <= (($unsigned((111'h7fffffffffffffffffffffffffff | 111'h7fffffffffffffffffffffffffff)))==111'h0 ? 111'h0:(111'h7fffffffffffffffffffffffffff % $unsigned((111'h7fffffffffffffffffffffffffff | 111'h7fffffffffffffffffffffffffff)))); end always @(posedge clk) begin if (W0304[110:7] != 104'h0) if (check) $stop; if (W0037 != 31'sh7fffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((((W0133 <<< ((W0111)==7'h0 ? 7'sh0:((7'sh01 ^ 7'sh7f) / W0111))))==63'h0 ? 63'sh0:((W0133 >>> (W0111 <<< (4'sh0 | 4'shf))) % (W0133 <<< ((W0111)==7'h0 ? 7'sh0:((7'sh01 ^ 7'sh7f) / W0111))))) != 63'sh0) if (check) $stop; if ($unsigned((((21'sh0 | 21'sh000001) <<< W0090) <<< 6'sh3f)) != 21'h0) if (check) $stop; end //============================================================ always @(check) begin : Block140 W0306 = 116'sh000004a144132ffffffffffffffff; W0305 = (((W0306[115:19])==97'h0 ? 97'h0:(97'h1ffffffffffffffffffffffff / W0306[115:19])) ^ {66'h0,31'sh0}); if (W0305[96:54] != 43'h0) if (check) $stop; if (69'sh000000000000000001 != 69'sh000000000000000001) if (check) $stop; end //============================================================ always @(posedge clk) begin if (((W0032)==64'h0 ? 64'sh0:(64'sh7e2aefddd3bac6f5 / W0032)) != 64'shffffffffc0ea8811) if (check) $stop; if ((W0109 >>> 8'sh0) != 67'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (32'shffffffff != 32'shffffffff) if (check) $stop; if (2'sh0 != 2'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0308 <= 23'sh283d11; end always @(posedge clk) begin W0307 <= (W0308[4'h0] ? (20'h0 << 6'h0) : {15'h0,5'h0}); end always @(posedge clk) begin if (W0120 != 1'h0) if (check) $stop; if ((W0307[19:19] && (W0195 >>> W0084)) != 1'h0) if (check) $stop; end //============================================================ always @(check or W0003) begin : Block144 W0311 = W0003; W0310 = W0311; W0309 = 86'h0; if (W0309 != 86'h0) if (check) $stop; if (W0310[2+:126] != 126'h3fffffffffffffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check) begin : Block145 if (63'sh0 != 63'sh0) if (check) $stop; if (100'sh0 != 100'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block146 W0312 = (1'h1 ? {52'h0,(2'sh3 <<< 2'sh3)} : ((54'h3fffff5dd55547 << 7'h7f) << 7'h0)); if (97'sh1ffffffffd48a45d68db4e037 != 97'sh1ffffffffd48a45d68db4e037) if (check) $stop; if (W0312 != 54'h0) if (check) $stop; end //============================================================ always @(check) begin : Block147 W0315 = (111'sh0 * 111'sh0); W0314 = ((111'sh4ee300000000ffffffff00000000)==111'h0 ? 111'sh0:(111'sh0 / 111'sh4ee300000000ffffffff00000000)); W0313 = (W0314 + W0315); if ((~ 95'h7fffffffffffffffffffffff) != 95'h0) if (check) $stop; if (W0313 != 111'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (((W0169)==96'h0 ? 96'sh0:(W0149 / W0169)) != 96'sh0) if (check) $stop; if (64'shffffffffffffffff != 64'shffffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if (1'h0 != 1'h0) if (check) $stop; if (((W0292 >>> ((8'sh82)==8'h0 ? 8'sh0:(W0180 / 8'sh82))) <<< ((((8'shff <<< 4'sh1))==8'h0 ? 8'sh0:(W0096 / (8'shff <<< 4'sh1))) >>> ((W0105)==4'h0 ? 4'sh0:(4'sh0 % W0105)))) != 121'sh1906da100000001ffffffff00000000) if (check) $stop; end //============================================================ always @(check or W0003) begin : Block150 W0318 = (81'sh00000000000009787cfbe - 81'sh1ffff900819b062834600); W0317 = (W0318 - 81'sh0cabb9992e90800000000); W0316 = W0003; if (W0316[123-:124] != 124'hfffffffffffffffffffffffffffffff) if (check) $stop; if (W0317 != 81'sh13544d664fd48350489be) 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*/ = 205; endmodule verilator-3.856/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.856/Changes0000664000177100017500000021253512307720320015022 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.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-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. Local variables: mode: outline paragraph-separate: "[ \f\n]*$" end: verilator-3.856/test_vcs/0000775000177100017500000000000012307720634015361 5ustar wsnyderwsnyderverilator-3.856/test_vcs/.gitignore0000664000177100017500000000013312146701432017342 0ustar wsnyderwsnyder*.old *.dmp *.log *.csrc *.vcd csrc vcs.key ucli.key *.daidir simv obj_* project INCA_libs verilator-3.856/test_vcs/bench.v0000664000177100017500000000410412111011552016607 0ustar wsnyderwsnyder// DESCRIPTION: Verilator Test: Top level testbench for VCS or other fully Verilog compliant simulators // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. `timescale 1 ns / 1ns module bench; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [39:0] out_quad; // From top of top.v wire [1:0] out_small; // From top of top.v wire [69:0] out_wide; // From top of top.v wire passed; // From top of top.v // End of automatics reg clk; reg fastclk; reg reset_l; reg [1:0] in_small; reg [39:0] in_quad; reg [69:0] in_wide; // Test cases top top (/*AUTOINST*/ // Outputs .passed (passed), .out_small (out_small[1:0]), .out_quad (out_quad[39:0]), .out_wide (out_wide[69:0]), // Inputs .clk (clk), .fastclk (fastclk), .reset_l (reset_l), .in_small (in_small[1:0]), .in_quad (in_quad[39:0]), .in_wide (in_wide[69:0])); //surefire lint_off STMINI //surefire lint_off STMFVR //surefire lint_off DLYONE integer fh; // surefire lint_off CWECBB initial begin reset_l = 1'b1; // Want to catch negedge fastclk = 0; clk = 0; forever begin in_small = 0; in_wide = 0; $write("[%0t] %x %x %x %x %x\n", $time, clk, reset_l, passed, out_small, out_wide); if (($time % 10) == 3) clk = 1'b1; if (($time % 10) == 8) clk = 1'b0; if ($time>10) reset_l = 1'b1; else if ($time > 1) reset_l = 1'b0; if ($time>60 || passed === 1'b1) begin if (passed !== 1'b1) begin $write("A Test failed!!!\n"); $stop; end else begin $write("*-* All Finished *-*\n"); // Magic if using perl's Log::Detect fh = $fopen("test_passed.log"); $fclose(fh); end $finish; end #1; fastclk = !fastclk; end end endmodule // Local Variables: // verilog-library-directories:("." "../test_v") // compile-command: "vlint --brief -f ../test_v/input.vc bench.v" // End: verilator-3.856/test_vcs/Makefile0000664000177100017500000000415612306677750017040 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-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. # #****************************************************************************/ 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 ###################################################################### V_FILES := $(wildcard *.v ../test_v/*.v) ###################################################################### ifneq ($(VCS_HOME),) test:: vcs else test:: novcs endif ifneq ($(NC_ROOT),) test:: nc else test:: nonc endif ###################################################################### novcs: @echo "No VCS simulator installed." @echo "Not running VCS regression test." vcs: vcs_passed.log simv: $(V_FILES) ../test_v/input.vc vcs +cli -I -sverilog +define+VCS+1 -f ../test_v/input.vc -q bench.v vcs_passed.log : simv -rm -f test_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: $(V_FILES) ../test_v/input.vc ncverilog +define+ncverilog=1 +licqueue -f ../test_v/input.vc -q bench.v -rm -f nc_passed.log grep -q Finished ncverilog.log && grep Finished ncverilog.log > nc_passed.log ###################################################################### maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir *.log *.dmp *.vpd simv* *.key csrc INCA_libs verilator-3.856/README.pdf0000664000177100017500000033401012307720632015156 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 217 /Filter /FlateDecode >> stream xÚ-Ž=KÄ@†ûüŠ)³ÅNvf¿¯SÌ‚.Zˆ…pÑ „˃ÁïnöšáxÞûÔtGr@™¬ôZŽàŒA§Ò ÞÛWáC;,ãô¹Î‹št«1XWås÷ðÔW}§A|¤Ç룵\b½Ê ¤QŒ©©oãô3_²]ûrìÛ¿Ó°7H¶è²S’Æh|åÏY×ë¡ë¶mÃßòæQW!³˜ëp^¾÷mÑFR êÖÈŠŒTZÝ6Zˆ»2‘3¸OŒ„muì`Ó§æBG“ 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ÚuR[OÂ0~߯ècû@íéÙzy£˜¸v&„ø`Ш$þ};:¼ûÔ“ô»öt²‹)Är«¤"န<'Z*n,’pO6ôš¤Û—Ýþ–=²Ч8¼°bN‘›Bõ#ÒÖ•“…Kót·ß²›0»˜¢ø¢Ž ¸’@DR®–MpMð=2s!{Îú+Aà#ršÜ²Í ÷ñjFGkÈÛ x ¨4—qÚŸ]eã¾4r޹’Ÿ…”1=2ŒU¶ñôøš‚Jû%¨ ±7ØÈÊ‚6å©€ÒTö¤$œL¸IíC[»P/6’JÈð8à¯Úzu†À:Ohß­VË–YEƒ›Ä8q9~íƒ[øH#Ôß^Eb×=·œÏË“Æ9£1ÎoS•h/Jzé’ádYu‹¸¹“Ò§ XeuÌù‡½>?Mëªâ¯‡ð¡í¥»*tm”—B"¦ýÅ$‰y½¨¿÷ŵL¬ŸÚˆBr­à¼ÐáǽB­ 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 1821 /Filter /FlateDecode >> stream xÚXIwÛ8 ¾çWè6òK¬h³–™“ë:©ûše,¥i_gŠÄ؜ʒG¢êz~ýä%u—‹ ‚@ЯҳË+gdÄV¸‘>ŽëZ¾ºÅž‘Æ'óý òLÑÈ28¦ ³¢ =Ï7=+Hzæ|:~}3%úJ–bðwúöòʳ´»^lyadؤÙe¶m›ÉÃýýÝ|ùfŠê§¯IIò1I§7 ê9›¦gÿž9°Ð6œ“žåØ¡‘¯Î>ýmL½5lË‹#c£W†„– Ti$gž½Âݺ‘áø–çî~»AY¾’S¸^™·cØŒÞÂQ€l|³ÂÐ'ét)[ò¶ÿê-1ïqS:vªæˆÝÜÈÌrüý<f¶4q¿¿lÏ/…Eö]|N‡ÝuÙÝ׳$Ï^=¤³»Û_uÛu]s½seD®à`?9©×8¹mäb9pCÜ»¶í ]Ûñ‰}Ò2D?ʲ­+¢“ ×l ÑXƒ¡o‡°«‘=k˜ÌºaeOÝ‚­©š!ã8îÙ±å8a™¥Rëß//7›õâʺà74ëҪѓfqy"€ËÝ^¾8(ÑtˉbcxŠŸaÞöé¤áûÜAT[?+4½ÑgÛˆ?`Øñ!&è\G2yVшB¶ª‘OÒË:Šf²ª¸¬ÙȪÖ[+äó–­*î*( ©%ÛW¢Y±Sõ³Þœ·ãXñhDûd€´ ˆëÛ"ÞÁÞDÛâ6Å>µ¯E%š¬dÔvO¥ÌY\æ¢jY #¼•xêº"Ч~iMã^4¬oÜ(ÂK'<ç“èõ{¦kÙ'ß×pJgšêS® ÀåÝJThRejçÛ3yåAt›^\¨ 0»ÇƒÍ@pŽ<4×M½h²2‘Ùî² Y‘ûšËš@ʬZfŠU´ÜȲ¤é§CÙ®Ï]yA2`ƒˆÇYúæî!%‘ñíÇSQ{8ŽcŽçóñmúÐèÆ!QË•¸1Xø¢£¢©]ÍBF®Ö¥ÄíèE„è&«(ÿ9Óa€¦5ÝLç8:y¦ð¬Æ¯fïféGjHèj–Oùy;MØÈ$P \šÓç^ë›ão:›<¼óôýÃüþ.™ZÄF}È `#F@kãÂÅ@ïQ ã„{ßÂäG9¢E^_‘§Éd>»ÿIAþé% u$¯5’¿àèýhD ã™í–`¾­ü/{*­ÁäXP—[’¬jEs=ÈàÌQQ¦•ËDuháCõ‚r.H‚XI€¨‰›œŸ“êq hwɶUb5¡PîqÏÔáê³›0õòH¡ø Z¹Bw;}£^Њºöx‰¼¶ZÂ:ÊéŸw‡‹»£÷Ç!¯?ë\)hÓˆ¨uåkx ¸F:Y•|¯'"jžH¶U½n·ío¼ð½N Ä"NÇ¾È @dŸ€gË•%—Ø/PŠ^œ ì®Ã›%íMµÄJ…ã¾×-¨×X28ÀgEÁ²yÍQÁRÎKLB>ÑÀ†\¨ÔF ‚[e`ëÄFôÝB¤;µî´_ÀXùzTÄŽáÐ’¾ÔA6Gap`¦öP¦79ô¢ˆD§„/DdDߌÄw­¬§¼ß]=­%YS*@¿„àX§¯¬¼ÞN¼íJ…V4Ë»$&kX¬UDåàä´Ú 4‘‚ ãY8î^9\& ‹5RíÔÒ§”}*(½å–~E¶f¬¬“äévyp™-¥n)1Œ1 ‹œÌ´]UKê6ˆÁ+‰’¯¥’ؾêJ¬U°¡Àõû 9æ‚ûÇq “ôœ£‘sö‹­ÈªÏè{áü>l)öƒ¯yoÀoËKÚ/;8NdÅW‘wŠ+4ðý¥ï›k>¢A¸uMPÐrÕQvTú =å*òù*âV pЫ <|\ýø©ðýj Z6x A`}ûH×TYó® š¦è±ÌxÁº‘«¬ÙÀàH£Û5ø>·4Aê=xÈU….ö›–øÝ2“íb#+ˆÉȦºyª=\ïEîîÝ®Ü ð~½~$Nw*˜Ã9ñÃUU‘ÕV°#ÁÓoÒ”R-'õPï}³e’ª%4­º´ï›ýC§s*#ü’ï=ò&¡;š ?Dl;â$­¸*TbCW#Õ'ràíj Geâþ½ÎgüÊs 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 453.386 null] >> endobj 14 0 obj << /D [60 0 R /XYZ 122.4 229.316 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 1983 /Filter /FlateDecode >> stream xÚ•XYoãF~÷¯ f†B¬Ù¼³ØíÁ*ðŒ³¶6@ZlI\S¢–MJãüú­êª¦(›³À<±úª®ã«£ùaq1ûèGN&²XÆÎbåøRŠÐId,Ò,p…ó›ûË$ \Õ”U>ñÝv2õ݈f2 ‚Ð DÅHîÃíÕͧ[¢?–•šü±øiö1ðÜe‹D¦ŽGœ#`æyž;ÿü¸˜¤¡{uww…—-æ÷ŸñôÅíââ¿>l÷¿-¾—8ËíÅoxNK?9ž²Ô9š['ˆ!ªœÇ‹]|@áN?AË“’qšŠ0HN¢øV”L’(ðµ¢¼2“瀚"IB:ý¥®Ò}[7ЍBµyYihe-âež³ÌdÓ¶ûg³ãñ(`ñýd*S°öT&n]‰z£f=ÛO`ÜÔÿQËVÏ Îik3=;–Ï0SÎæ;ÝæUUîÖ#òËÐ1HÏ÷ Ü‚*Iá'3g>-ÍW ¾”î ^^w48–ÜQÑàÉH‰*K”7£¢\½àÍfÃ/è[E26—8"»„Ùù®ÞÔ]UÐæN+"Ú ³|·.Ûw4·Uí†ÌÁ»sMß²¥½ KU©ö\pÔÜæû"‹"Ò­mò%®>“‡–(Ó&ß­•&ƒÈPd^ìLÃL¤>GÃbÃÎm”n‰>àIÕè²ÞÑDÉNÏ‘ýaE.!ªølÞŽ@ÁCûÉ÷aá ¬ïa8âh?ôD¯-ÓH ˜‰,dGßÇ]UçIÙn0ØGÔÝ[³¡^kÞ°jê­=—óF]¶ê’UÞ”1 µ¬·ûFi22Aéò$ó$»)‡ÈŠdä~=üµ"ʪݠ„_dzÑ®ÿ1ÁÔò̧ap‚µ °Æ¡©Ó8è´2’/ºUÛküîEÞA­KåzƒÜZš¹þá$ /tí¾ka³¦‘t‹3K¿ak ù»ñxhszi11†U„û4NÎZUEâLÀ>>F]ÙYRÉ[ƒj;ÓtKœÐÌãWã£u²R;¥ ‚š½ú<ðjŒM̉-¿>.n?]AwÎ!µ|¾¾û÷Í-¥ »™# Ü±‘qήq²€ÀÛ-«®àAQ6#ëæ…KD´¹—-¶Ë %Æp¬Z„n”0t£“”wó7óš3€SÏ¥ÓÃE+º~ ̳D@Uå“*§­ÀiL¸ †¡ß}U(®Ãì,0ñ—¦Ù­É?/¶qT²´…ãò¤ÜÕž¹þ''2d°À*“QlÅ "‘Æñ)œ"/:…Hõá„'$ ÷?ã!Õð^Œiü.kÊ&³B–gDab‚'éƒ7 °6°žŽÙÐÞw9ePù ý¾LŽ£ETc$þ"l• â/Ó®[„…'m5|oŠŒMøÊ ȳ΃‰|$iúÇã,¶ìÉ“?ß>ÜfCh9½4ZÛL&¶h ` Úêµ—æ¸í¶èÂỾ푭{Æ›9ò=L¸“ ‚^:èWÊ‚ç6”|hÀ¹î½íö×5‹tÂŽ"†«ŽÐ=°'o¶ê›p°ù ;3šÒ„¤FzhœzêʪÐDFH,»¦é£XJìO£BªãõzÅünæüâºøbòþýýâ’ÎØz€±aát9–LÏk"VLxE‘'LŽ–Y6X郔6húj4e¯ò®j{0¼úª–]‹Ù‰;NmwxN^ÙpWn}m\°µkp4ವêt¿ß½ \w ¸š|• @&AV?%Y}Èsï;l¤Àð”!W`‚£©ÕI„º)Ñ¿8‹8Æ/ bVGÜa ù¢i®év´©ƒ©ù5ßE]¸a²QtâG8sŠ%8IÒûÒ¼ÇÏl½0ñ$Sh|loÈcX»*×¥y à¬újK_ik÷Œ†ˆ·Ã¤\ÐÑn¿nò˜oÊÌ·ïûÛtM{ú0ÃÁ¶Öí$noðª+ö1ý– ÂÌ8©­Xðrùû0¦C2â †¿£ Àcä ìrÙç³öëìñ‡‰~åz´Ë…²ªv‡o]Góß¼ßïhðÿsïrüZ1ƒZ•Aj¬9 ‡†Hާ…IÞ`Ú0Øëª~âÜ £ú”`”ÓçÝ2/ðB¦ÔÏ4ÉÝ7P[<¦Ü›:ÌPv0ÏJMçð§×ŠHNëÔÅ{æ.¼Ë·1Ÿ 4=ƒ ~—ô3mˆ±}näŠ[d\üÄÿ;ºJé™ý»ƒå¶ø‘®  Hcc;Ï>oûûìëø)Ê 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 208.393 null] >> endobj 70 0 obj << /D [65 0 R /XYZ 122.4 120.445 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 1784 /Filter /FlateDecode >> stream xÚåXYoÛF~÷¯Ò¡kÅåòL_ªÆvâ´±][ P$C‰+‰0…‡¤ùïÙê°é"ècû"Î^3³s|3«_'{£cé "ùŽ?˜ÌÒq„;_„‘L’ÁGëÃ~¨,]¥Y¼/­f(­ˆj¨”k)z>’ʺ8¾;"ú8ÍôþçÉÛѱ²·¸;Ž;°‰1œ“¶m[ï/ÇûNh½æ³‡g¯Þ¿;: Ø1þLN@Þ >Ež{G“½¯{¸Ø¹VX iƒY¾÷ñ³=H`éíÀ* ·fc>P~  ²ÁåÞ{¿âÍ•³}óÈÒ•? …«R±-j WöÏúptqòûxrvŠ\]œM@]éFÖO´žÎé{_¶QõRg/ÖôÆõïz ¥‘çmÉÑÅͶ(”âX”ôD¹VŠKs¢ïCþAä¬_"k}\òÉf©™ˆ«iœe4jký`ýFWµQ ,Hƒm>ÕÌ)-êFÇ J¶Ê"e3&ºžUéT÷é$F³²˜§‹¶bYÃá ™WzžÞÑÌèÕøðêðäò·Ñ IŠÇjôå±3ú‹í¢YŸguw°4œ¯F£g_Öº@4`0 .ãy³}!°Hj.ºØ1û‹ÎÚ·qÁòcúäeÒf¬Ä<í¨,½~hÏy™eåmZ,^î¨Á&Y‡+qU•Fñ†Ô!ýÐ$`Žo8oîç•ÇϬ°ßõv]¬0ü™ +y }×U®šã! ç0bðËâxÐЦEUbâÜ#dÐj[ƒ_iC³RVy̧ë{H•œh¸å²~É ¹ L;ª{ÿu\ÚÆ€ô£Ë~g²Eܤ7XN4xb¨`úGeKƒY\0QŸlåÖàDL:œ¿£Q³ÄØCjãuܦø„ÜW-äF¯Û¾×´–—5%ˆtDà„»÷|}ú~VÈ"ã0«Û3­š¾pplÉàÿO•HÖ ô ?ĺ<9;í  óq@T¸ ‘PÉ5ê/pìlÂ)*4–¤Ð‘†G’Ð RÌÄâF9£ØSˆ×AÌù¦÷y#ÌÆ!tN‘„Rt\!ë¼ï)Zt_¨x"P²k·òøº/¥W8Êï6uÌÊ|eª6 Üõq‘ÚÑ‘û¯Õ¡R¨)O(æAÿ:C!K ŸÀºæ ê •”ŽºYËÀRª-_í$~€ÉÜ,{´õCÂQÿÉv<]ÄÓL3S€‹ª]÷è9 ‚îà,“—F 53È#%ú-ï7ìÙ< ¸t’¤Cº•ô%´¶:Ãx鮬¬bc¥ë}Ú‘…f`Écã*GS’EƒJmÓ ã÷‘Ædך-ËÊt!»±æŸ&+€JPˆH®2 ~tU!c33%€kÚÊ;šíøIôœf ¨½tÆìæÄŵZÈ!×(çª;nh%èš”Þ)¸™LKÏZ@œNÄò©ìóP"ZÆÅBÓ˜Zµ^ͬ9æ[· ªkìœC ´S,BÛ›~©ã|õ­Ÿ kº(L§ £¬äéÃ`¼vH×þùûÚ'ʡϱp 7Ø@ZÓ;®O÷Á)ðÐ5n`O Ç5YBçšÆÌïEÅ瓲бγΫrQÅyM õ²l³„iÝÛ%%\¨–Ú\ç&­Ê"'}gà;ji•bÒÑÖN_Eg­+®ô…/×Îté[ƒPYbµÁ™$­x$´˜5O¨‡‚´-}§g­IV<ïWñ|é±³Ü.S,:Î}PAEB4áØòTÙ§ÔºëÄ¢Ó¥+rÊtorb(nu@0 8@Šq3Üîy`T3Äæ¦ŸQt¬8qK«II߸2%Àmh{¾kžƒ¥­‘u'0˜¼Ð2O–SµÌ š- ¤Ñ —I Ïs`£ x/ØåAS๸º':œÁ ñÁ‡_6Ø®Í8ãƒ<›B ××±tœUðfvS.ŒfÐT-SØá—Þ Oe z€"n³¦«uë2òå!y\$Ø_“U¸§¬êwSþó›ZD|ËÔÝ …5º‚|Ý«t…r}‡š(WD¶M€+Â(Øü›#ùß%éß?Øü›9`µzÅþÆÌ6½}pèê&†þƒo“P> 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 568.665 null] >> endobj 76 0 obj << /D [72 0 R /XYZ 122.4 504.904 null] >> endobj 22 0 obj << /D [72 0 R /XYZ 122.4 154.873 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 924 /Filter /FlateDecode >> stream xÚ•V]oÛ6}÷¯Ð£´BŒDêsÀ ¤®3¸X×ÍV3 ]1(Ö×DÚMþý.IQ–§I_ì+‘<<çÜK^½ËfW7~h¥(pdeËÇVŒ#”¤ÄÊJë‹}ë$Ħ=«rÇ·…ãúv A︄6AIÉØ«Åõû ß°Š:_³W7Ä› ã$D~[žFNÌó<û·åÇeæ$}-·Ê–Ÿ~_ËųE6ûoæÃlÏòGfù^lõìËWÏ*aèƒå!’&Ö75±¶H# Qe­gÎÞI‰O%?²¢$A‰5•;Ö\´H(ZâÐvÝ-­:­äÄ'{(P‹’xpªíµúžæ%kîõÃÁÁ±¶P‘xú5kô¿ØRð¼¦ÚÓ’i}›BPÀ²G=s³†ñ©çHÄ hC$ˆ°dèYn@1àÙöûåj1Ï>­œÛHÛëlåßþ<Ï>¯´zJe)3ŒKÖSÉŽQ>Õ5íØ 6ß:˜SRWäýhOÞÓSq›¶ªZ'ö7þóPBÓì]òýBòb´y«³8oë rÈé_}Þuæ5‡v§¬.å‹À¸ŠoÕ€JÕÓ‹¶Tu-=ñ}”†¡fÀš¢Ú—ôJt&ãÎòpŠm.tÄ·í¾*u|G ýÿØîMé-Í–’¼f¢ßt¹Ø~ÄÊÙšvù*ºœõƒtdõkÕÞÉ)y¥Ÿûv/X3mõÅš!gÞéqVïUIÿ“­ã~zÊÃpØÂ™¡=?A‹¾ƒ†C’ ØZìïtTÒÍQÍÆe#dÕ½–.ªwgt¡ŒêvÈSï`–K¼/d1à0ÇõYŸ7üì‚á`hñBq ÊÅ¿y~ÃàXZ‹‡¼îªaé­¬Òö~‚s*¾…#9„mð‰ù=ݯxÍ~îÛù›7fÓæ@եŘt! –+\“p×\ùDëùÿ ö”2ï~ûÚW¯†?üüx_Æ—à·óõ`õüzǨ›Òd†üçw—èêÐ yUÅd’še·kcN’œþ|^{zß«2ç &!é‹(ç}eì|ª»$ÇNîZ˵ü;ù3 e¸¾×”Ž­2yÒ*e™i­ô{A/48kÈ'©ù¶8ö}£÷Æ~>ÓÒÓ‘˜õ*CC¾u*èÆ¬f"M®š.¸ WÀŒõÚÐ|½ü&S| endstream endobj 78 0 obj << /Type /Page /Contents 79 0 R /Resources 77 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> 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 637.618 null] >> endobj 30 0 obj << /D [78 0 R /XYZ 122.4 369.38 null] >> endobj 77 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 68 0 R /F28 56 0 R >> /ProcSet [ /PDF /Text ] >> endobj 81 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 83 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0´TÐ5W02S0µPH1ä*ä2 (˜™Be’s¹œ<¹ôÃ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. (\®ž\\&Q# endstream endobj 84 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 85 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 86 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 87 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UеP0¶TÐ5RH1ä*ä26 (˜A$’s¹œ<¹ôÃŒ¹ô≠ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿÏÄÿа—«'W *› endstream endobj 88 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 89 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 90 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 91 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 92 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F †† )†\…\@Ú$l‘IÎåròäÒ pé{€IO_…’¢ÒT.}§g ßE!¨'–ËÓEAžÁ¾¡þÀÿ0XÀ¾AžËÕ“+ ‰;“ endstream endobj 93 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 94 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F Æf )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêüƒõìäðì:¸\=¹¹{-= endstream endobj 95 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V04S01T06QH1ä*ä26 (Z@d’s¹œ<¹ôÌ͹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿÿÿÄÿ °‘§\®ž\\ºâAŠ endstream endobj 96 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 97 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 98 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 99 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 100 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 101 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 102 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 103 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 104 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 105 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 106 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 107 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 109 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 110 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 111 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 112 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 113 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 114 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 115 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 116 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 117 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 118 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 119 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 120 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 121 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 122 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 123 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 124 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 125 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 126 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 127 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 128 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 129 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 130 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 131 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 132 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 133 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 134 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 135 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 136 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 137 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 138 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 139 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 141 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 142 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 143 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 144 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 145 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 146 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 147 0 R /Encoding 148 0 R /CharProcs 149 0 R >> endobj 147 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 43.59 43.59 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 43.59 43.59 43.59 0 43.59 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 148 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 34/a34/a35/a36 37/.notdef 39/a39/a40/a41/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/a85/a86/a87 88/.notdef 89/a89 90/.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 149 0 obj << /a21 98 0 R /a34 99 0 R /a35 100 0 R /a36 101 0 R /a39 88 0 R /a40 81 0 R /a41 82 0 R /a42 89 0 R /a43 90 0 R /a44 91 0 R /a45 97 0 R /a46 92 0 R /a47 93 0 R /a58 94 0 R /a61 95 0 R /a62 84 0 R /a65 102 0 R /a67 103 0 R /a68 104 0 R /a69 105 0 R /a70 106 0 R /a71 107 0 R /a72 108 0 R /a73 109 0 R /a75 110 0 R /a76 111 0 R /a77 112 0 R /a78 113 0 R /a79 114 0 R /a80 115 0 R /a82 116 0 R /a83 117 0 R /a84 118 0 R /a85 119 0 R /a86 120 0 R /a87 121 0 R /a89 122 0 R /a95 87 0 R /a96 96 0 R /a97 123 0 R /a98 124 0 R /a99 125 0 R /a100 126 0 R /a101 127 0 R /a102 128 0 R /a103 129 0 R /a104 130 0 R /a105 131 0 R /a107 132 0 R /a108 133 0 R /a109 134 0 R /a110 135 0 R /a111 136 0 R /a112 137 0 R /a114 138 0 R /a115 139 0 R /a116 140 0 R /a117 141 0 R /a118 142 0 R /a119 143 0 R /a120 144 0 R /a121 145 0 R /a122 146 0 R /a123 85 0 R /a124 83 0 R /a125 86 0 R >> endobj 150 0 obj << /Length 85 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3s…C®B.ˆMÎåròäÒW0çÒ÷ž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ €ËÕ“+ hz¯ endstream endobj 151 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 152 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3cs…C®B.ˆOÎåròäÒW0çÒ÷ ré{ú*”•¦ré;8+ré»(D*Äryº(üƒì*ËåêÉÈžã: endstream endobj 153 0 obj << /Length 88 /Filter /FlateDecode >> stream xÚ32Ö30W0PaC3S …C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ“ ¸\=¹¹¢9K% endstream endobj 154 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 155 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 156 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 157 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 159 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bCSs…C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þC¨'p¹zrr4ö+³ endstream endobj 160 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 161 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 162 0 obj << /Length 89 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bC3…C®B.s ×ĉ'çr9yré‡+˜sé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þQ¸\=¹¹6VLÖ endstream endobj 163 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 164 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 165 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 166 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 167 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 168 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 169 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0TÐ5T0²P01WH1ä*ä22 (˜X@d’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒˆÁÿÿÿÇÀÄê¥ÿch`üÇØÀðŸýÐR®ÿÏÀ`””ÀÀåêÉÈ|Q  endstream endobj 170 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 171 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 173 0 R /Encoding 174 0 R /CharProcs 175 0 R >> endobj 173 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 174 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 175 0 obj << /a46 150 0 R /a47 151 0 R /a58 152 0 R /a73 153 0 R /a97 154 0 R /a99 155 0 R /a101 156 0 R /a103 157 0 R /a104 158 0 R /a105 159 0 R /a106 160 0 R /a107 161 0 R /a108 162 0 R /a109 163 0 R /a110 164 0 R /a111 165 0 R /a112 166 0 R /a114 167 0 R /a115 168 0 R /a116 169 0 R /a118 170 0 R /a119 171 0 R /a121 172 0 R >> endobj 176 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 177 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 178 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 179 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 180 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 181 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 183 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 184 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 186 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 187 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 188 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 189 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 190 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 191 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 192 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 193 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 194 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 195 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 197 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 198 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 199 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 201 0 R /Encoding 202 0 R /CharProcs 203 0 R >> endobj 201 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 202 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 203 0 obj << /a49 193 0 R /a50 194 0 R /a51 195 0 R /a52 196 0 R /a53 197 0 R /a54 198 0 R /a55 199 0 R /a56 200 0 R /a65 176 0 R /a66 177 0 R /a67 178 0 R /a68 179 0 R /a69 180 0 R /a71 181 0 R /a73 182 0 R /a76 183 0 R /a77 184 0 R /a78 185 0 R /a79 186 0 R /a80 187 0 R /a82 188 0 R /a83 189 0 R /a84 190 0 R /a85 191 0 R /a89 192 0 R >> endobj 204 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 205 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 206 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 207 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 208 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 209 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 210 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bS #…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿA ÉÀþÿÃ(9THü±ÉåêÉÈ’:Õ° endstream endobj 211 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 212 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 213 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 214 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 215 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 216 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 218 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 219 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 220 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 221 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 222 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 223 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 225 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 226 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 227 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 228 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 229 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 230 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 232 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 233 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 234 0 R /Encoding 235 0 R /CharProcs 236 0 R >> endobj 234 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 235 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 236 0 obj << /a49 226 0 R /a50 227 0 R /a51 228 0 R /a52 229 0 R /a53 230 0 R /a54 231 0 R /a55 232 0 R /a56 233 0 R /a65 204 0 R /a66 205 0 R /a67 206 0 R /a68 207 0 R /a69 208 0 R /a71 209 0 R /a73 210 0 R /a76 211 0 R /a77 212 0 R /a78 213 0 R /a79 214 0 R /a80 215 0 R /a82 216 0 R /a83 217 0 R /a84 218 0 R /a85 219 0 R /a89 220 0 R /a101 221 0 R /a110 222 0 R /a111 223 0 R /a115 224 0 R /a116 225 0 R >> endobj 237 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 238 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 239 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 240 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 242 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 243 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 244 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 246 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 247 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 248 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 250 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 251 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 252 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 253 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 254 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 256 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 257 0 R /Encoding 258 0 R /CharProcs 259 0 R >> endobj 257 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 258 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 259 0 obj << /a52 253 0 R /a53 254 0 R /a54 255 0 R /a56 256 0 R /a65 237 0 R /a67 238 0 R /a68 239 0 R /a69 240 0 R /a71 241 0 R /a73 242 0 R /a76 243 0 R /a77 244 0 R /a78 245 0 R /a79 246 0 R /a80 247 0 R /a82 248 0 R /a83 249 0 R /a84 250 0 R /a85 251 0 R /a89 252 0 R >> endobj 260 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 261 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 262 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 263 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 264 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 265 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 266 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 267 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 268 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 269 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 270 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 271 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 272 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 273 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 274 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 275 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 276 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 277 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 278 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 279 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 280 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 281 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 283 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 284 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 285 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 286 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 287 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 288 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 289 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 290 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 291 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 292 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 293 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 294 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 295 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 296 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 298 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 299 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 300 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 301 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 302 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 303 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 304 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 305 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 306 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 308 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 309 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 310 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 311 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 312 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 313 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 314 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 315 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 318 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 320 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 321 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 322 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 323 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 325 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 326 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 327 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 328 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 329 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 330 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 331 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 332 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Ú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 334 0 R /Encoding 335 0 R /CharProcs 336 0 R >> endobj 334 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 41.52 0 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 335 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/a54 55/.notdef 56/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 336 0 obj << /a28 276 0 R /a29 277 0 R /a34 273 0 R /a36 274 0 R /a39 265 0 R /a40 260 0 R /a41 261 0 R /a43 266 0 R /a44 267 0 R /a45 272 0 R /a46 268 0 R /a47 269 0 R /a48 326 0 R /a49 327 0 R /a50 328 0 R /a51 329 0 R /a52 330 0 R /a53 331 0 R /a54 332 0 R /a56 333 0 R /a58 270 0 R /a59 271 0 R /a64 275 0 R /a65 278 0 R /a66 279 0 R /a67 280 0 R /a68 281 0 R /a69 282 0 R /a70 283 0 R /a71 284 0 R /a72 285 0 R /a73 286 0 R /a76 287 0 R /a77 288 0 R /a78 289 0 R /a79 290 0 R /a80 291 0 R /a82 292 0 R /a83 293 0 R /a84 294 0 R /a85 295 0 R /a86 296 0 R /a87 297 0 R /a88 298 0 R /a89 299 0 R /a95 264 0 R /a97 300 0 R /a98 301 0 R /a99 302 0 R /a100 303 0 R /a101 304 0 R /a102 305 0 R /a103 306 0 R /a104 307 0 R /a105 308 0 R /a106 309 0 R /a107 310 0 R /a108 311 0 R /a109 312 0 R /a110 313 0 R /a111 314 0 R /a112 315 0 R /a113 316 0 R /a114 317 0 R /a115 318 0 R /a116 319 0 R /a117 320 0 R /a118 321 0 R /a119 322 0 R /a120 323 0 R /a121 324 0 R /a122 325 0 R /a123 262 0 R /a125 263 0 R >> endobj 337 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 338 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 339 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 340 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 341 0 obj << /Length 289 /Filter /FlateDecode >> stream xÚeÐ;NÃ@àßrai›=‚ç`;qѰR. ¢@T@I‚.J|®²7aàÒˆÈÃÎ$ÊCi>˳óØI}^M©¤ ¨¾ iI/•y7õ8KšŽ6'ÏofÖ˜âê±)nbØÍ-}~|½šbvwE•)æôXQùdš9!a¤€åŽûè€Á"é‘[dÙ72ô¶•ÜÃEW¸Œ:,wæX¨ë¨=0;rØ™nåW-¤·WƒèzUR‘³„,k–Ÿ”9¶M˜¥<êåÜI÷z°Ö:©HxÛDL¹ÕÎc¿ŸêÔ|c=1;2œØ‰^´¾ßÛê]ÚA·Äº7™¿Ä_l´Æo'kïH;tÎÛ€_Ñ"èÅ=\lh®soþWŽŠÐ endstream endobj 342 0 obj << /Length 333 /Filter /FlateDecode >> stream xÚÒAKÃ0ð „±^{û¾€6L»SaN°AOD¨GaŠž—–R¿Aa—‚£ñ½Ô‰®.x ?’ðþ¼dJg9*ãѧ9žäøÉg9ЦÂÓ¯“û'9+ezƒÓ‰L/h[¦å%¾¾¼=Êtvu†™Lçx›¡º“å­µ0°¶È¶ûØ ±`ka5@´!FðÖ ¡%¡£­£¬è~°Ùñð· CnɱÇÔCÈ…sŠÛZí¸¦npIm‡²Ø1õu°2ÎÜcÌ!æ/WÎÜ£¢¡÷[P `¿ùQ ½ÖÂPá{¥…&{6¦Gq.LÀ!qÏÙvNªC”ÏQí&²ðyи‰¯7<…w砳é$kgÑòDÖÐ3ÿ¸èÃ,O¤õûû7y\páÆïC^êxÙÙMŸGž—òZ~GÈ endstream endobj 343 0 obj << /Length 212 /Filter /FlateDecode >> stream xڽϱ‚0à’$7À ˜x/ ¥$N$ˆ‰ &:9'utÐèf,Æ£ðŒ F¼‚†ÆÕÄßp×öþ ü¡ ÑÃ$ÇÜK8¯‹†ïÎîq b~bNeé/çëD¼œ¢‘àF¢·…4AFGi¢ú[«‘µª?«2’×%éæ72byg6ù ã•Nh—:¡]hÝB¿íçQÖ©L›)õ϶ÿ˜?›Í$nþIØd¦ä¼Ô[Xm”ÑFŽÊiÇžzÒÕŠäuA63`– ^¶Ñj» endstream endobj 344 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 345 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ¿NÃ0Æ?+C$/~„Ü @pK§V*E"L02€`«÷ÉÈ£Dâ`ž”7Ѭ$7ëãî¨d¸¬*¦ ¯:}§¿$ X endstream endobj 346 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 347 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 348 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 349 0 obj << /Length 159 /Filter /FlateDecode >> stream xÚ35Ñ34W0P0bSC…C®B.˜ˆ ’HÎåròäÒW01çÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(0þaüÇÀðÿûÿ@RŽý´`üÁÀþ§€ñóŸ ÿ`ø$@äÿ†z É€ ÿa/É òmÃÿÿ?ìÿÿC&¹\=¹¹?qjS endstream endobj 350 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 351 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 352 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 353 0 obj << /Length 213 /Filter /FlateDecode >> stream xÚMͱNÃ@б\DÚæÚTdëä""R.HE¨€’’‹ˆøÓü)÷ ‡h®°¼Œ!Åkfg´¾:[œë\½ž–ê—ºXêS)¯âK†såí÷òø"›ZŠ;õ¥׌¥¨oôýíãYŠÍí¥2Ýê=7Roë0ͬ¯&aÖ8äéYZi4 % :šŽú£¬1X[ÀÌz83L̺ܘE†œ[yß!8}†?£øË+–÷ÔðO2dñ»ÍÃWtm8 è\„\Õ²“uYÛ endstream endobj 354 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 355 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 357 0 obj << /Length 248 /Filter /FlateDecode >> stream xÚeпJÄ@ðo \`^›B¼yÝÍ] ç ¦´²á@-íÄÛG²´Ì£äR^w¢ùÃÙüŠ™]¾™9ŽŽâ„ Oùpj8>åxƽPS5œÌþZ÷O´LIßpœ¾puÒé%¿½¾?’^^qDzÅ·›;JW\×…ªË¡~ lr¯&V‰÷g¸î¾{„'À´N2¬;säÀ8GÖêÊvn=§·õЪÊQoåb]pл ~‹‹¯^¶ã8ëõí®Ø:úg00ìœ7~Êžî¿®JT¥Ä٠Ͼüœ4s”M^!ÒyJ×ô[ÍX' endstream endobj 358 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 359 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 360 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 361 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚmÁJÄ0†'ô˜ƒyÅÎ h[éÖÞ ë ö ¸'âiõ(¨èÕöÑò(y„sÆ™ì$ä;dfþò·ýùåšjjéì‚Ú5u=5ø†mMrºþPÙ¿àfÄêžÚ«~Æj¼¥÷Ïg¬6wWÔ`µ¥‡†êG·*€‰`ˆß‹Z@y˜æÂÂ`5@éNŽ0Þ8FéÁ„ Ê ðÒxÖ‘õPºŒÁ fÆÄ¾ŠÍ¡HmVJ[ù\8ô¥ )ƒqYT‹‘Nà K†Jˆ¿8L3#Úÿ±Ä™g¾DïU”kñèÙ-¬Ä2¥¡gþBá8&%ÁÃ1DñÂëwø>³vq endstream endobj 362 0 obj << /Length 206 /Filter /FlateDecode >> stream xÚ¥ÐÍjÂ@Àñ„@CÐkBç º·‚Ð õäA ¶GAEÏæÍÌ£äMbö/hèµûƒÙf–Éf¯Ó±Zµ'›èdª?©$¶¹u©{øÞÉ<³Ñl(æ½½“èéxþ3ÿ\h*f©ÛTí—äKõ> /FirstChar 45 /LastChar 121 /Widths 363 0 R /Encoding 364 0 R /CharProcs 365 0 R >> endobj 363 0 obj [32.5 27.08 48.75 48.75 48.75 48.75 48.75 48.75 0 0 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 54.17 0 0 0 100.18 0 0 0 0 0 0 0 0 0 0 0 0 54.17 43.33 0 48.75 54.17 27.08 0 0 27.08 0 54.17 48.75 54.17 0 37.92 38.46 37.92 0 51.46 70.42 0 51.46 ] endobj 364 0 obj << /Type /Encoding /Differences [45/a45/a46/a47/a48/a49/a50/a51/a52 53/.notdef 58/a58 59/.notdef 83/a83 84/.notdef 87/a87 88/.notdef 100/a100/a101 102/.notdef 103/a103/a104/a105 106/.notdef 108/a108 109/.notdef 110/a110/a111/a112 113/.notdef 114/a114/a115/a116 117/.notdef 118/a118/a119 120/.notdef 121/a121] >> endobj 365 0 obj << /a45 340 0 R /a46 337 0 R /a47 338 0 R /a48 358 0 R /a49 359 0 R /a50 360 0 R /a51 361 0 R /a52 362 0 R /a58 339 0 R /a83 341 0 R /a87 342 0 R /a100 343 0 R /a101 344 0 R /a103 345 0 R /a104 346 0 R /a105 347 0 R /a108 348 0 R /a110 349 0 R /a111 350 0 R /a112 351 0 R /a114 352 0 R /a115 353 0 R /a116 354 0 R /a118 355 0 R /a119 356 0 R /a121 357 0 R >> endobj 366 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×31R0P0F¦ :Å« Ì ƒYɹ\Nž\úá@—¾˜ôôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàg°?Pÿàÿ¬`€ŸËÕ“+ è±"g endstream endobj 367 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 369 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 370 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 371 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 373 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 374 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 376 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 378 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 379 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 380 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 381 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 382 0 obj << /Length 312 /Filter /FlateDecode >> stream xÚÍÒ»JÄ@à˜&o°™Ð\ØÍ"uSne!Vj)¨(X9y´ˆ…¥o ó)S„gΉ²¢…¥Ó|äÌ%s~¦˜ïLMjæf;7Ejv§æ"Ó7z–S‘> ™9¿Ò‹J''f–ëäÊ:©ŽÌÝíý¥NÇû&ÓÉÒœf&=ÓÕÒ¨À”#&Pñ5AOt°A£œÐ`ÖmUï~Ô³Ÿ‚jÊ–þJ.óuË—ê•oåÅÁ¯5Jjó ˆ©éˆZŽ'¤@Z‰Ç}AýÑ|*OêMìHó ·Iù+íˆk†O%3Œ´?q2'X74BÍ\ËG¤‡‘=éÏCÝNÀ½{‚5""ìÕœRØpf“é·”'zÉÃJV¥‹¨€ˆ_~=´@ò‹}MTz¥?Î×À¥ endstream endobj 383 0 obj << /Length 348 /Filter /FlateDecode >> stream xÚÒ½JÄ@à A"Ûì#d_@“È]äªÀy‚)­,ÄJ--í„ÝG[¹ÂÎÚÂ"2EÈ83»ÂqœbùÂþÌÎîl}|83¥©ÍÁ‘©+³˜™»J=ª97–fQ‡žÛµlUqeæ3UœQ³*Úsóüôr¯Šåʼn©T±2ו)oT»2MÀOƒžAìé›"Ž„îl:hë@;AS$ÔŸzH€=Y/£tG£:È ¤9>à &A¢[ϱhX:J"‘lØDGz!ß­ÿ+”Ô¾ ¤˜ñö¬Ï™WÎÑúžÇ·ŽwƒkÙ®çƒï”+~PŒˆü’3‡ŸŒÇA•CÌ#ý݃ w2J)¶±ÿ'Diþ ëm!y:¤É"ac‘TðR*ë’@(ª¼\X*8w4r‚{)%ÝŽK¿|;Ò)A'—¥Jré@ËyAÂmê´U—ê|Aæ endstream endobj 384 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 385 0 R /Encoding 386 0 R /CharProcs 387 0 R >> endobj 385 0 obj [37.42 0 0 0 0 67.4 0 67.4 67.4 0 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 386 0 obj << /Type /Encoding /Differences [46/a46 47/.notdef 51/a51 52/.notdef 53/a53/a54 55/.notdef 56/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 387 0 obj << /a46 366 0 R /a51 381 0 R /a53 382 0 R /a54 383 0 R /a56 384 0 R /a65 367 0 R /a68 368 0 R /a69 369 0 R /a70 370 0 R /a77 371 0 R /a82 372 0 R /a86 373 0 R /a97 374 0 R /a101 375 0 R /a105 376 0 R /a108 377 0 R /a111 378 0 R /a114 379 0 R /a116 380 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 388 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 388 0 R /Prev 27 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 388 0 R /Prev 23 0 R /Next 31 0 R >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 388 0 R /Prev 19 0 R /Next 27 0 R >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 388 0 R /Prev 15 0 R /Next 23 0 R >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 388 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 388 0 R /Prev 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 388 0 R /Prev 3 0 R /Next 11 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R /Parent 388 0 R /Next 7 0 R >> endobj 389 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 390 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 391 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 392 0 obj << /Names [(section.5) 14 0 R (section.6) 18 0 R] /Limits [(section.5) (section.6)] >> endobj 393 0 obj << /Kids [389 0 R 390 0 R 391 0 R 392 0 R] /Limits [(Doc-Start) (section.6)] >> endobj 394 0 obj << /Dests 393 0 R >> endobj 395 0 obj << /Type /Catalog /Pages 42 0 R /Outlines 388 0 R /Names 394 0 R /PageMode/UseOutlines/PageLabels<>1<>]>> /OpenAction 33 0 R >> endobj 396 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.10)/Keywords() /CreationDate (D:20140311195154-04'00') /ModDate (D:20140311195154-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 397 0000000000 65535 f 0000000015 00000 n 0000005462 00000 n 0000103235 00000 n 0000000060 00000 n 0000000084 00000 n 0000005517 00000 n 0000103151 00000 n 0000000129 00000 n 0000000161 00000 n 0000005574 00000 n 0000103065 00000 n 0000000206 00000 n 0000000238 00000 n 0000005632 00000 n 0000102977 00000 n 0000000284 00000 n 0000000322 00000 n 0000008025 00000 n 0000102889 00000 n 0000000368 00000 n 0000000401 00000 n 0000010461 00000 n 0000102801 00000 n 0000000448 00000 n 0000000488 00000 n 0000011795 00000 n 0000102713 00000 n 0000000535 00000 n 0000000575 00000 n 0000011853 00000 n 0000102638 00000 n 0000000622 00000 n 0000000654 00000 n 0000001001 00000 n 0000001223 00000 n 0000000704 00000 n 0000001109 00000 n 0000001167 00000 n 0000101349 00000 n 0000093569 00000 n 0000084106 00000 n 0000102470 00000 n 0000001965 00000 n 0000002115 00000 n 0000002264 00000 n 0000002415 00000 n 0000002566 00000 n 0000002717 00000 n 0000002869 00000 n 0000003021 00000 n 0000003289 00000 n 0000001789 00000 n 0000001317 00000 n 0000003173 00000 n 0000063385 00000 n 0000055687 00000 n 0000003231 00000 n 0000044452 00000 n 0000005690 00000 n 0000005296 00000 n 0000003395 00000 n 0000005404 00000 n 0000035983 00000 n 0000008197 00000 n 0000007859 00000 n 0000005796 00000 n 0000007967 00000 n 0000028348 00000 n 0000008081 00000 n 0000008139 00000 n 0000010519 00000 n 0000010179 00000 n 0000008315 00000 n 0000010287 00000 n 0000010345 00000 n 0000010403 00000 n 0000011910 00000 n 0000011629 00000 n 0000010625 00000 n 0000011737 00000 n 0000012016 00000 n 0000012288 00000 n 0000012555 00000 n 0000012731 00000 n 0000012973 00000 n 0000013228 00000 n 0000013479 00000 n 0000013663 00000 n 0000013891 00000 n 0000014142 00000 n 0000014338 00000 n 0000014554 00000 n 0000014733 00000 n 0000014970 00000 n 0000015157 00000 n 0000015347 00000 n 0000015572 00000 n 0000015755 00000 n 0000015938 00000 n 0000016135 00000 n 0000016384 00000 n 0000016716 00000 n 0000016981 00000 n 0000017280 00000 n 0000017544 00000 n 0000017772 00000 n 0000017998 00000 n 0000018306 00000 n 0000018507 00000 n 0000018696 00000 n 0000018995 00000 n 0000019199 00000 n 0000019457 00000 n 0000019732 00000 n 0000019983 00000 n 0000020238 00000 n 0000020516 00000 n 0000020833 00000 n 0000021038 00000 n 0000021286 00000 n 0000021556 00000 n 0000021834 00000 n 0000022107 00000 n 0000022379 00000 n 0000022647 00000 n 0000022910 00000 n 0000023184 00000 n 0000023466 00000 n 0000023701 00000 n 0000024035 00000 n 0000024277 00000 n 0000024490 00000 n 0000024769 00000 n 0000024965 00000 n 0000025217 00000 n 0000025453 00000 n 0000025717 00000 n 0000025998 00000 n 0000026237 00000 n 0000026503 00000 n 0000026739 00000 n 0000026968 00000 n 0000027235 00000 n 0000027490 00000 n 0000027773 00000 n 0000028091 00000 n 0000028598 00000 n 0000029092 00000 n 0000029609 00000 n 0000030495 00000 n 0000030661 00000 n 0000030890 00000 n 0000031064 00000 n 0000031233 00000 n 0000031497 00000 n 0000031757 00000 n 0000032031 00000 n 0000032346 00000 n 0000032568 00000 n 0000032744 00000 n 0000032953 00000 n 0000033230 00000 n 0000033400 00000 n 0000033646 00000 n 0000033864 00000 n 0000034135 00000 n 0000034405 00000 n 0000034619 00000 n 0000034888 00000 n 0000035102 00000 n 0000035365 00000 n 0000035682 00000 n 0000036233 00000 n 0000036492 00000 n 0000036794 00000 n 0000037133 00000 n 0000037470 00000 n 0000037759 00000 n 0000038103 00000 n 0000038380 00000 n 0000038645 00000 n 0000038988 00000 n 0000039170 00000 n 0000039389 00000 n 0000039723 00000 n 0000040065 00000 n 0000040395 00000 n 0000040641 00000 n 0000040955 00000 n 0000041299 00000 n 0000041532 00000 n 0000041809 00000 n 0000042110 00000 n 0000042313 00000 n 0000042625 00000 n 0000042943 00000 n 0000043212 00000 n 0000043522 00000 n 0000043838 00000 n 0000044119 00000 n 0000044699 00000 n 0000044899 00000 n 0000045140 00000 n 0000045488 00000 n 0000045896 00000 n 0000046244 00000 n 0000046663 00000 n 0000047002 00000 n 0000047311 00000 n 0000047741 00000 n 0000047927 00000 n 0000048165 00000 n 0000048557 00000 n 0000048954 00000 n 0000049360 00000 n 0000049650 00000 n 0000050021 00000 n 0000050448 00000 n 0000050705 00000 n 0000051019 00000 n 0000051385 00000 n 0000051710 00000 n 0000051975 00000 n 0000052287 00000 n 0000052627 00000 n 0000052894 00000 n 0000053112 00000 n 0000053494 00000 n 0000053880 00000 n 0000054186 00000 n 0000054552 00000 n 0000054947 00000 n 0000055267 00000 n 0000055936 00000 n 0000056216 00000 n 0000056529 00000 n 0000056947 00000 n 0000057261 00000 n 0000057608 00000 n 0000057930 00000 n 0000058241 00000 n 0000058592 00000 n 0000058834 00000 n 0000059111 00000 n 0000059497 00000 n 0000059863 00000 n 0000060206 00000 n 0000060494 00000 n 0000060824 00000 n 0000061171 00000 n 0000061450 00000 n 0000061771 00000 n 0000062094 00000 n 0000062389 00000 n 0000062712 00000 n 0000063044 00000 n 0000063632 00000 n 0000063807 00000 n 0000064056 00000 n 0000064339 00000 n 0000064609 00000 n 0000064878 00000 n 0000065136 00000 n 0000065391 00000 n 0000065575 00000 n 0000065786 00000 n 0000065972 00000 n 0000066184 00000 n 0000066359 00000 n 0000066593 00000 n 0000066775 00000 n 0000066996 00000 n 0000067171 00000 n 0000067374 00000 n 0000067718 00000 n 0000068094 00000 n 0000068347 00000 n 0000068581 00000 n 0000068897 00000 n 0000069187 00000 n 0000069528 00000 n 0000069803 00000 n 0000070065 00000 n 0000070312 00000 n 0000070647 00000 n 0000070853 00000 n 0000071040 00000 n 0000071261 00000 n 0000071586 00000 n 0000071910 00000 n 0000072230 00000 n 0000072478 00000 n 0000072780 00000 n 0000073117 00000 n 0000073348 00000 n 0000073620 00000 n 0000073941 00000 n 0000074329 00000 n 0000074689 00000 n 0000075001 00000 n 0000075286 00000 n 0000075565 00000 n 0000075828 00000 n 0000076107 00000 n 0000076377 00000 n 0000076599 00000 n 0000076917 00000 n 0000077153 00000 n 0000077356 00000 n 0000077587 00000 n 0000077864 00000 n 0000078053 00000 n 0000078311 00000 n 0000078539 00000 n 0000078808 00000 n 0000079085 00000 n 0000079368 00000 n 0000079589 00000 n 0000079865 00000 n 0000080097 00000 n 0000080331 00000 n 0000080595 00000 n 0000080909 00000 n 0000081200 00000 n 0000081500 00000 n 0000081764 00000 n 0000082033 00000 n 0000082235 00000 n 0000082544 00000 n 0000082860 00000 n 0000083129 00000 n 0000083436 00000 n 0000083760 00000 n 0000084356 00000 n 0000084865 00000 n 0000085413 00000 n 0000086423 00000 n 0000086599 00000 n 0000086846 00000 n 0000087032 00000 n 0000087207 00000 n 0000087577 00000 n 0000087991 00000 n 0000088284 00000 n 0000088575 00000 n 0000088931 00000 n 0000089179 00000 n 0000089385 00000 n 0000089576 00000 n 0000089816 00000 n 0000090106 00000 n 0000090405 00000 n 0000090630 00000 n 0000090924 00000 n 0000091165 00000 n 0000091448 00000 n 0000091775 00000 n 0000092104 00000 n 0000092392 00000 n 0000092604 00000 n 0000092944 00000 n 0000093282 00000 n 0000093818 00000 n 0000094096 00000 n 0000094425 00000 n 0000094801 00000 n 0000094978 00000 n 0000095427 00000 n 0000095793 00000 n 0000096117 00000 n 0000096400 00000 n 0000096797 00000 n 0000097191 00000 n 0000097646 00000 n 0000098014 00000 n 0000098362 00000 n 0000098585 00000 n 0000098789 00000 n 0000099119 00000 n 0000099385 00000 n 0000099657 00000 n 0000100066 00000 n 0000100459 00000 n 0000100888 00000 n 0000101599 00000 n 0000101834 00000 n 0000102194 00000 n 0000102564 00000 n 0000103306 00000 n 0000103469 00000 n 0000103633 00000 n 0000103815 00000 n 0000103919 00000 n 0000104016 00000 n 0000104054 00000 n 0000104220 00000 n trailer << /Size 397 /Root 395 0 R /Info 396 0 R /ID [ ] >> startxref 104546 %%EOF verilator-3.856/configure.ac0000664000177100017500000001210512307720341016007 0ustar wsnyderwsnyder# DESCRIPTION: Process this file with autoconf to produce a configure script. # # Copyright 2003-2014 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.856 2014-03-11]) AC_CONFIG_HEADER(src/config_build.h) AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h) 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 $1 -Werror" AC_MSG_CHECKING([whether $CXX accepts $1]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([],[])], [_my_result=yes], [_my_result=no]) AC_MSG_RESULT($_my_result) if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED $1" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" ])# _MY_CXX_CHECK_OPT # For example, -Wno-div-by-zero isn't in 4.1.2 _MY_CXX_CHECK_OPT(-Wno-char-subscripts) # 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(-Wno-sign-compare) _MY_CXX_CHECK_OPT(-Wno-uninitialized) _MY_CXX_CHECK_OPT(-Wno-unused-parameter) _MY_CXX_CHECK_OPT(-Wno-unused-variable) _MY_CXX_CHECK_OPT(-Wno-unused-but-set-variable) AC_SUBST(CFG_CXXFLAGS_NO_UNUSED) # Checks for library functions. # Checks for system services # Other install directories pkgdatadir=${datadir}/verilator AC_SUBST(pkgdatadir) AC_OUTPUT AC_MSG_RESULT([]) AC_MSG_RESULT([Now type 'make' (or sometimes 'gmake') to build Verilator.]) AC_MSG_RESULT([]) verilator-3.856/test_v/0000775000177100017500000000000012307720634015033 5ustar wsnyderwsnyderverilator-3.856/test_v/t.v0000664000177100017500000000324412111011552015451 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; // Combine passed signals from each sub signal // verilator lint_off MULTIDRIVEN wire [20:0] passedv; // verilator lint_on MULTIDRIVEN wire passed = &passedv; assign passedv[0] = 1'b1; assign passedv[1] = 1'b1; assign passedv[2] = 1'b1; assign passedv[3] = 1'b1; assign passedv[4] = 1'b1; assign passedv[5] = 1'b1; t_inst tinst (.passed (passedv[6]), /*AUTOINST*/ // Inputs .clk (clk), .fastclk (fastclk)); t_param tparam (.passed (passedv[7]), /*AUTOINST*/ // Inputs .clk (clk)); assign passedv[8] = 1'b1; assign passedv[9] = 1'b1; assign passedv[10] = 1'b1; t_clk tclk (.passed (passedv[11]), /*AUTOINST*/ // Inputs .fastclk (fastclk), .clk (clk), .reset_l (reset_l)); assign passedv[12] = 1'b1; assign passedv[13] = 1'b1; t_chg tchg (.passed (passedv[14]), /*AUTOINST*/ // Inputs .clk (clk), .fastclk (fastclk)); assign passedv[15] = 1'b1; assign passedv[16] = 1'b1; assign passedv[17] = 1'b1; assign passedv[18] = 1'b1; assign passedv[19] = 1'b1; t_netlist tnetlist (.passed (passedv[20]), .also_fastclk (fastclk), /*AUTOINST*/ // Inputs .fastclk (fastclk)); endmodule verilator-3.856/test_v/t_param_b.v0000664000177100017500000000066312111011552017134 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_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.856/test_v/t_inst_a.v0000664000177100017500000000141312111011552017002 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_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.856/test_v/t_clk_two.v0000664000177100017500000000166012111011552017173 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_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.856/test_v/t_param.v0000664000177100017500000001070012111011552016624 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(/*AUTOARG*/ // Outputs passed, // Inputs clk ); input clk; output passed; reg passed; initial passed = 0; reg _ranit; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [4:0] par1; // From a1 of t_param_a.v wire [4:0] par2; // From a2 of t_param_a.v wire [4:0] par3; // From a3 of t_param_a.v wire [4:0] par4; // From a4 of t_param_a.v wire [1:0] varwidth1; // From a1 of t_param_a.v wire [2:0] varwidth2; // From a2 of t_param_a.v wire [3:0] varwidth3; // From a3 of t_param_a.v wire [3:0] varwidth4; // From a4 of t_param_a.v // End of automatics /*t_param_a AUTO_TEMPLATE ( .par (par@[])); .varwidth (varwidth@[])); */ parameter XX = 2'bXX; parameter THREE = 3; t_param_a #(1,5) a1 ( // Outputs .varwidth (varwidth1[1:0]), /*AUTOINST*/ // Outputs .par (par1[4:0])); // Templated t_param_a #(2,5) a2 ( // Outputs .varwidth (varwidth2[2:0]), /*AUTOINST*/ // Outputs .par (par2[4:0])); // Templated t_param_a #(THREE,5) a3 ( // Outputs .varwidth (varwidth3[3:0]), /*AUTOINST*/ // Outputs .par (par3[4:0])); // Templated t_param_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("[%0t] t_param: Passed\n", $time); passed <= 1'b1; end end endmodule verilator-3.856/test_v/t_chg.v0000664000177100017500000000344312111011552016273 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_chg (/*AUTOARG*/ // Outputs passed, // Inputs clk, fastclk ); input clk; input fastclk; // surefire lint_off_line UDDIXN output passed; reg passed; initial passed = 0; 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("[%0t] t_chg: Passed\n", $time); passed <= 1'b1; 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.856/test_v/t_inst_b.v0000664000177100017500000000147112111011552017007 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_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.856/test_v/input.vc0000664000177100017500000000011412111011552016501 0ustar wsnyderwsnyder +librescan +libext+.v -y ../test_v +incdir+../test_v +incdir+../include verilator-3.856/test_v/top.v0000664000177100017500000000156512111011552016014 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}}; // Test cases t t (/*AUTOINST*/ // Outputs .passed (passed), // Inputs .clk (clk), .fastclk (fastclk), .reset_l (reset_l)); endmodule verilator-3.856/test_v/t_clk_flop.v0000664000177100017500000000102412111011552017314 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_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 verilator-3.856/test_v/t_inst.v0000664000177100017500000000706212111011552016510 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(/*AUTOARG*/ // Outputs passed, // Inputs clk, fastclk ); input clk; input fastclk; output passed; reg passed; initial passed = 0; genvar unused; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire o_com; // From b of t_inst_b.v wire o_seq_d1r; // From b of t_inst_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_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_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("[%0t] t_inst: Passed\n", $time); passed <= 1'b1; 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.856/test_v/t_netlist.v0000664000177100017500000000235412111011552017214 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_netlist (/*AUTOARG*/ // Outputs passed, // Inputs fastclk, also_fastclk ); // surefire lint_off ASWEMB input fastclk; input also_fastclk; output passed; reg passed; initial passed = 0; 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("[%0t] t_netlist: Passed\n",$time); passed <= 1'd1; end _mode <= _mode + 1; end endmodule verilator-3.856/test_v/t_param_a.v0000664000177100017500000000122212111011552017123 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_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_b.v output [X:0] varwidth; // From b of t_param_b.v // End of automatics t_param_b #(X,FIVE,TWO) b (/*AUTOINST*/ // Outputs .par (par[4:0]), .varwidth (varwidth[X:0])); endmodule verilator-3.856/test_v/t_clk.v0000664000177100017500000000565412111011552016311 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 (/*AUTOARG*/ // Outputs passed, // Inputs fastclk, clk, reset_l ); input fastclk; input clk; input reset_l; output passed; reg passed; initial passed = 0; // 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 //$write("CLK1 %x\n", reset_l); 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; $write("[%0t] t_clk: Running\n",$time); reset_int_ <= 1; end end end reg [7:0] sig_rst; always @ (posedge clk or negedge reset_l) begin //$write("CLK2 %x sr=%x\n", reset_l, sig_rst); 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 //$write("CLK3 %x cc=%x sr=%x\n", reset_l, clk_clocks, sig_rst); 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; passed <= 1'b1; $write("[%0t] t_clk: Passed\n",$time); end end end reg [7:0] resetted; always @ (posedge clk or negedge reset_int_) begin //$write("CLK4 %x\n", reset_l); 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 verilator-3.856/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.856/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.856/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.856/verilator.html0000664000177100017500000052771112307713747016450 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 and Sugar/PSL assertions, into C++, SystemC or SystemPerl code. It is not a complete simulator, just 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. For SystemPerl format, it outputs .sp files for the SystemPerl preprocessor, which greatly simplifies writing SystemC code and is available at http://www.veripool.org.

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
    --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 PSL/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
     -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-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
    --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
    --psl                       Enable PSL parsing
    --public                    Debugging; see docs
    --report-unoptflat          Extra diagnostics for UNOPTFLAT
    --savable                   Enable model save-restore
    --sc                        Create SystemC output
    --sp                        Create SystemPerl output
    --stats                     Create statistics file
     -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-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, includes enabling the --psl flag. (If psl is not desired, but other assertions are, use --assert --nopsl.)

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 and --sp.

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

--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 PSL which must be separately enabled with --psl.

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

   // psl default clock = posedge clk;
   // psl cover {cyc==9} report "DefaultClock,expect=1";
-Dvar=value

Defines the given preprocessor symbol. Same as +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, debugging messages, and intermediate form dump files.

--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 source file to the specified level. Higher levels produce more detailed messages (plain --debug is equivalent to --debugi 4).

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

Defines the given preprocessor symbol. Same as -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>

Rarely needed. Enable writing .tree debug files with a specific dumping level, 0 disbles dumps and is equivelent 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-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. This 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.

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

--psl

Enable PSL parsing. Without this switch, PSL meta-comments are ignored. See the --assert flag to enable all assertions, and --coverage-user to enable functional coverage.

--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 analysing 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 and -sp.

--sp

Specifies SystemPerl output mode; see also --cc and -sc.

--stats

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

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

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

-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-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-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 behaviour. 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 SystemPerl.

    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 --sp our.v

Then we convert the SystemPerl output to SystemC.

    cd obj_dir
    export SYSTEMPERL=/path/to/where/systemperl/kit/came/from
    $SYSTEMPERL/sp_preproc --preproc *.sp

(You can also skip the above sp_preproc by getting pure SystemC from Verilator by replacing the verilator --sp flag in the previous step with -sc.)

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
    # 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_sp 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.

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

For -sp mode, instead of .cpp and .h it creates:

    {prefix}.sp                         // Top level SystemC file
    {prefix}{each_verilog_module}.sp    // Lower level internal SC 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

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.

SYSTEMPERL

Specifies the directory containing the SystemPerl distribution kit. This is used to find the SystemPerl library and include files. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). See also SYSTEMPERL_INCLUDE.

SYSTEMPERL_INCLUDE

Specifies the directory containing the Verilog-Perl include .cpp files, from the src/ directory of the SystemPerl kit. If not specified, it will be computed from the SYSTEMPERL environment variable if it is set, and if SYSTEMPERL is not set SYSTEMPERL_INCLUDE will come from a default optionally specified at configure time (before Verilator was compiled).

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).

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 equivelents 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.

Sugar/PSL Support

Most future work is being directed towards improving SystemVerilog assertions instead of PSL. If you are using these PSL features, please contact the author as they may be depreciated in future versions.

With the --assert switch, Verilator enables support of the Property Specification Language (PSL), specifically the simple PSL subset without time-branching primitives. Verilator currently only converts PSL assertions to simple "if (...) error" statements, and coverage statements to increment the line counters described in the coverage section.

Verilator implements these keywords: assert, assume (same as assert), default (for clocking), countones, cover, isunknown, onehot, onehot0, report, and true.

Verilator implements these operators: -> (logical if).

Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. PSL vmode/vprop/vunits are not supported. PSL statements must be in the module they reference, at the module level where you would put an initial... statement.

Verilator only supports (posedge CLK) or (negedge CLK), where CLK is the name of a one bit signal. You may not use arbitrary expressions as assertion clocks.

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 statements. However, "unique if" and "priority if" are 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.

_(expr)

A underline followed by an expression in parenthesis returns a Verilog expression. This is different from normal parenthesis in special contexts, such as PSL expressions, and can be used to embed bit concatenation ({}) inside of PSL statements.

$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 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. SystemPerl when tracing such signals 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*/ (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. Often this is placed just after a primitive's module statement, so that the entire module is not traced.

/*verilator tracing_on*/

Re-enable waveform tracing for all future signals 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. Unititialized 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 passed to DPI imports.

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.

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 +include used on the command line to specify the top include source directory.

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.

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

Error 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 error message as you would disable warnings, 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 copyright?

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.

Note also older versions of Verilator used the SystemPerl package and SpTraceVcdC class. This still works, but is depreciated as it requires strong coupling between the Verilator and SystemPerl versions.

    #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_sp/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. Both require the SystemPerl package to be installed but do not require use of the SystemPerl output mode.

First, run verilator with the --coverage option. If you're using your own makefile, compile the model with the GCC flag -DSP_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, the vcoverage utility (from the SystemPerl package) is executed. Vcoverage 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_sp/logs/coverage_source 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.


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 Cavium Networks, Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems, Nauticus Networks, and SiCortex Inc.

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

Some of the people who have provided ideas and feedback for Verilator include: David Addison, Vasu Arasanipalai, Jens Arm, J Baxter, Jeremy Bennett, David Black, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee, Lawrence Butcher, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike Denio, John Deroo, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic, Alex Duller, Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete, Andrea Foletto, Bob Fredieu, Shankar Giri, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Thomas Hawkins, David Hewson, Jae Hossell, Ben Jackson, Iztok Jeras, Christophe Joly, Mike Kagen, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki, David Kravitz, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber, John Li, Charlie Lind, Andrew Ling, Paul Liu, Dan Lussier, Fred Ma, Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, Dominic Plunkett, Niranjan Prabhu, Usha Priyadharshini, Alberto Del Rio, Oleg Rodionov, John Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Brian Small, Alex Solomatnikov, Art Stamness, John Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Stefan Thiede, Gary Thomas, Steve Tong, Hans Van Antwerpen, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston, Joshua Wise, Johan Wouters, and Ding Xiaoliang.

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


DISTRIBUTION

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

Copyright 2003-2014 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.


AUTHORS

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

Wilson Snyder <wsnyder@wsnyder.org>

Major concepts by Paul Wasson and Duane Galbi.


SEE ALSO

verilator_profcfunc, systemperl, vcoverage, make,

verilator --help which is the source for this document,

and internals.txt in the distribution.

verilator-3.856/internals.txt0000664000177100017500000007057212307713746016310 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 psudo-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 psudo-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 "op1p" to give the pointer to the AST for the "then" block, while "elsesp" calls "op2p" 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. "AstNVistor" 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 provided 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 no deprecated and should 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. 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 convenition have the suffix "_bad" in their name, and include "fails => 1" in either their "compile" or "execute" step as appropriate. 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 additonal 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 and SystemPerl tests also run the tests in the "test_vcs", "test_verilated" and "test_regress" directories when using *make test*. This is disabled by default as SystemC/SystemPerl 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 * The regression tests will assume that you have a version of SystemPerl to match. Typically if working on Verilator from git, also use SystemPerl from git. * 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 numberic, it then prints the width of the item. This field is a squence 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-2014 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.856/configure0000775000177100017500000046037312307720354015452 0ustar wsnyderwsnyder#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for Verilator 3.856 2014-03-11. # # # 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.856 2014-03-11' PACKAGE_STRING='Verilator 3.856 2014-03-11' 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 pkgdatadir CFG_CXXFLAGS_NO_UNUSED 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.856 2014-03-11 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.856 2014-03-11:";; 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.856 2014-03-11 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.856 2014-03-11, 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" { $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 # 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 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" # 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 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 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-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 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 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 -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 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" # Checks for library functions. # Checks for system services # Other install directories pkgdatadir=${datadir}/verilator 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.856 2014-03-11, 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.856 2014-03-11 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" ;; *) 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.856/include/0000775000177100017500000000000012307720633015151 5ustar wsnyderwsnyderverilator-3.856/include/verilated_vpi.cpp0000664000177100017500000002222212306677750020524 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-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. // //========================================================================= /// /// \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) $(SP_INCLUDER) $^ > $@ 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 ###################################################################### ### Detect out of date files and rebuild. DEPS := $(wildcard *.d) ifneq ($(DEPS),) include $(DEPS) endif verilator-3.856/include/.gitignore0000664000177100017500000000004012151516614017132 0ustar wsnyderwsnyderverilated.mk verilated_config.h verilator-3.856/include/verilated.v0000664000177100017500000000217612306677750017337 0ustar wsnyderwsnyder//************************************************************************* // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-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. // // 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.856/include/verilated.cpp0000664000177100017500000011736712306677750017665 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-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. // //========================================================================= /// /// \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(); 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) { // 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 int data = (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff; return data; } } static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp) { while (1) { int c = _vl_vsss_peek(fp, floc, fromp); if (c==EOF || !isspace(c)) return; _vl_vsss_advance(fp, floc); } } static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, 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); 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 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)); 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); } else if (!inPct) { // Expected Format _vl_vsss_skipspace(fp,floc,fromp); int c = _vl_vsss_peek(fp,floc,fromp); 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); 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); _vl_vsss_read(fp,floc,fromp, 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); _vl_vsss_read(fp,floc,fromp, 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); _vl_vsss_read(fp,floc,fromp, 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); _vl_vsss_read(fp,floc,fromp, 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); _vl_vsss_read(fp,floc,fromp, 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); _vl_vsss_read(fp,floc,fromp, 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, 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; } 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; ibegin(); it != varsp()->end(); ++it) { VL_PRINTF(" VAR %p: %s\n", &(it->second), it->first); } } } //=========================================================================== verilator-3.856/include/verilated_dpi.h0000664000177100017500000000473212306677750020155 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-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. // //************************************************************************* /// /// \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 #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 msg = (string)"Can't deserialize save-restore file as was made from different model"; vl_fatal(filename().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 msg = (string)"Can't deserialize; file has wrong header signature"; vl_fatal(filename().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 msg = (string)"Can't deserialize; file has wrong end-of-file signature"; vl_fatal(filename().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.856/include/verilated_dpi.cpp0000664000177100017500000002322412306677750020505 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-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. // //========================================================================= /// /// \file /// \brief Verilator: DPI implementation code /// /// This file must be compiled and linked against all objects /// created from Verilator or called by Verilator that use the DPI. /// /// Code available from: http://www.veripool.org/verilator /// //========================================================================= #define _VERILATED_DPI_CPP_ #include "verilatedos.h" #include "verilated_dpi.h" #include "verilated_imp.h" // On MSVC++ we need svdpi.h to declare exports, not imports #define DPI_PROTOTYPES #define XXTERN DPI_EXTERN DPI_DLLESPEC #define EETERN DPI_EXTERN DPI_DLLESPEC #include "vltstd/svdpi.h" //====================================================================== // Internal macros // Not supported yet #define _VL_SVDPI_UNIMP() \ vl_fatal(__FILE__,__LINE__,"",(string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str()) // Function requires a "context" in the import declaration #define _VL_SVDPI_CONTEXT_WARN() \ VL_PRINTF("%%Warning: DPI C Function called by Verilog DPI import with missing 'context' keyword.\n"); //====================================================================== //====================================================================== //====================================================================== // DPI ROUTINES const char* svDpiVersion() { return "1800-2005"; } //====================================================================== // Bit-select utility functions. svBit svGetBitselBit(const svBitVecVal* s, int i) { _VL_SVDPI_UNIMP(); return 0; } svLogic svGetBitselLogic(const svLogicVecVal* s, int i) { _VL_SVDPI_UNIMP(); return 0; } void svPutBitselBit(svBitVecVal* d, int i, svBit s) { _VL_SVDPI_UNIMP(); } void svPutBitselLogic(svLogicVecVal* d, int i, svLogic s) { _VL_SVDPI_UNIMP(); } void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w) { _VL_SVDPI_UNIMP(); } void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w) { _VL_SVDPI_UNIMP(); } void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w) { _VL_SVDPI_UNIMP(); } void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal s, int i, int w) { _VL_SVDPI_UNIMP(); } //====================================================================== // Open array querying functions int svLeft(const svOpenArrayHandle h, int d) { _VL_SVDPI_UNIMP(); return 0; } int svRight(const svOpenArrayHandle h, int d) { _VL_SVDPI_UNIMP(); return 0; } int svLow(const svOpenArrayHandle h, int d) { _VL_SVDPI_UNIMP(); return 0; } int svHigh(const svOpenArrayHandle h, int d) { _VL_SVDPI_UNIMP(); return 0; } int svIncrement(const svOpenArrayHandle h, int d) { _VL_SVDPI_UNIMP(); return 0; } int svDimensions(const svOpenArrayHandle h) { _VL_SVDPI_UNIMP(); return 0; } void *svGetArrayPtr(const svOpenArrayHandle) { _VL_SVDPI_UNIMP(); return NULL; } int svSizeOfArray(const svOpenArrayHandle) { _VL_SVDPI_UNIMP(); return 0; } void *svGetArrElemPtr(const svOpenArrayHandle, int indx1, ...) { _VL_SVDPI_UNIMP(); return NULL; } void *svGetArrElemPtr1(const svOpenArrayHandle, int indx1) { _VL_SVDPI_UNIMP(); return NULL; } void *svGetArrElemPtr2(const svOpenArrayHandle, int indx1, int indx2) { _VL_SVDPI_UNIMP(); return NULL; } void *svGetArrElemPtr3(const svOpenArrayHandle, int indx1, int indx2, int indx3) { _VL_SVDPI_UNIMP(); return NULL; } //====================================================================== // s=source, d=destination // From user space into simulator storage void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, ...) { _VL_SVDPI_UNIMP(); } void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1) { _VL_SVDPI_UNIMP(); } void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2) { _VL_SVDPI_UNIMP(); } void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2, int indx3) { _VL_SVDPI_UNIMP(); } void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, ...) { _VL_SVDPI_UNIMP(); } void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1) { _VL_SVDPI_UNIMP(); } void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, int indx2) { _VL_SVDPI_UNIMP(); } void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, int indx2, int indx3) { _VL_SVDPI_UNIMP(); } //====================================================================== // From simulator storage into user space void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, ...) { _VL_SVDPI_UNIMP(); } void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1) { _VL_SVDPI_UNIMP(); } void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) { _VL_SVDPI_UNIMP(); } void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3) { _VL_SVDPI_UNIMP(); } void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, ...) { _VL_SVDPI_UNIMP(); } void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1) { _VL_SVDPI_UNIMP(); } void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) { _VL_SVDPI_UNIMP(); } void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3) { _VL_SVDPI_UNIMP(); } svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) { _VL_SVDPI_UNIMP(); return 0; } svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1) { _VL_SVDPI_UNIMP(); return 0; } svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2) { _VL_SVDPI_UNIMP(); return 0; } svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) { _VL_SVDPI_UNIMP(); return 0; } svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...) { _VL_SVDPI_UNIMP(); return sv_x; } svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1) { _VL_SVDPI_UNIMP(); return sv_x; } svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2) { _VL_SVDPI_UNIMP(); return sv_x; } svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) { _VL_SVDPI_UNIMP(); return sv_x; } void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...) { _VL_SVDPI_UNIMP(); } void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1) { _VL_SVDPI_UNIMP(); } void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2) { _VL_SVDPI_UNIMP(); } void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2, int indx3) { _VL_SVDPI_UNIMP(); } void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) { _VL_SVDPI_UNIMP(); } void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1) { _VL_SVDPI_UNIMP(); } void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1, int indx2) { _VL_SVDPI_UNIMP(); } void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1, int indx2, int indx3) { _VL_SVDPI_UNIMP(); } //====================================================================== // Functions for working with DPI context svScope svGetScope() { if (VL_UNLIKELY(!Verilated::dpiInContext())) { _VL_SVDPI_CONTEXT_WARN(); return NULL; } return (svScope)Verilated::dpiScope(); } svScope svSetScope(const svScope scope) { const VerilatedScope* prevScopep = Verilated::dpiScope(); const VerilatedScope* vscopep = (const VerilatedScope*)(scope); Verilated::dpiScope(vscopep); return (svScope)prevScopep; } const char* svGetNameFromScope(const svScope scope) { const VerilatedScope* vscopep = (const VerilatedScope*)(scope); return vscopep->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.856/include/verilated_sc.h0000664000177100017500000000360512306677750020004 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-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. // //************************************************************************* /// /// \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.856/include/verilatedos.h0000664000177100017500000002454412306677750017666 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-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. // //************************************************************************* /// /// \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 //========================================================================= // 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 # ifdef __uint32_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 // 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 //========================================================================= // 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.856/include/verilated_syms.h0000664000177100017500000000667512306677750020404 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-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. // //************************************************************************* /// /// \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.856/include/verilated_vcd_c.h0000664000177100017500000004122312306677750020453 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-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. // // 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 /// /// AUTHOR: Wilson Snyder /// //============================================================================= // 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 //============================================================================= // 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: bool m_isOpen; ///< True indicates open file bool m_evcd; ///< True for evcd format int m_fd; ///< File descriptor we're writing to 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_writep; ///< Write pointer into output buffer 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 inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation inline static size_t bufferInsertSize() { return 16*1024; } void bufferFlush(); 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_wrBufp+(bufferSize()-bufferInsertSize())))) { 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 () : m_isOpen(false), m_rolloverMB(0), m_modDepth(0), m_nextCode(1) { m_wrBufp = new char [bufferSize()]; m_writep = m_wrBufp; m_namemapp = NULL; m_timeRes = m_timeUnit = 1e-9; m_timeLastDump = 0; m_sigs_oldvalp = NULL; m_evcd = false; m_scopeEscape = '.'; // Backward compatibility m_wroteBytes = 0; m_fd = 0; m_fullDump = true; } ~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) #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.856/include/vltstd/vpi_user.h0000664000177100017500000013061112151516723020500 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) #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.856/include/verilated_vcd_c.cpp0000664000177100017500000005430712306677750021015 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-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. // // 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 /// /// AUTHOR: Wilson Snyder /// //============================================================================= // 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 SystemPerl 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) {}; }; //============================================================================= //============================================================================= //============================================================================= // Opening/Closing 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 m_fd = ::open (m_filename.c_str(), 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_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 char* hiername = (*it).first.c_str(); if (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(); // 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; ::close(m_fd); } 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; ::close(m_fd); // 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::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 = write (m_fd, 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) { string unitstr (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 "); printStr(doubleToTimescale(m_timeRes).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 char* hiername = (*it).first.c_str(); const char* decl = (*it).second.c_str(); // Determine difference between the old and new names 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); } 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 (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 } // 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; we have at least bufferInsertSize() bytes (>>>16 bytes) 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; we have at least bufferInsertSize() bytes (>>>16 bytes) 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 && g++ -DVERILATED_VCD_TEST ../src/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd" // End: verilator-3.856/include/verilated_imp.h0000664000177100017500000002271712306677750020171 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-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. // //========================================================================= /// /// \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.856/include/verilated_vpi.h0000664000177100017500000015443112306677750020201 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-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. // //========================================================================= /// /// \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() { return 0; } virtual const VerilatedRange* rangep() { return 0; } 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; bool 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() { // 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() { return get_range().elements(); } virtual const VerilatedRange* rangep() { 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() { return varp()->range().elements(); } virtual const VerilatedRange* rangep() { 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())) { if (VL_UNLIKELY(!m_started)) { m_it = m_scopep->varsp()->begin(); m_started=true; } else if (VL_UNLIKELY(m_it == m_scopep->varsp()->end())) return 0; else ++m_it; if (m_it == m_scopep->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); \ 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 *file, PLI_INT32 line) { m_errorInfo.message = message; m_errorInfo.file = file; m_errorInfo.line = line; m_errorInfo.code = NULL; do_callbacks(); } void setError(PLI_BYTE8 *message, PLI_BYTE8 *code, PLI_BYTE8 *file, PLI_INT32 line) { setError( message, file, 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_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, ...) { _VL_VPI_ERROR_SET; m_errorInfo.state = vpiPLI; setError((PLI_BYTE8*)m_buff, (PLI_BYTE8*)file.c_str(), line); } void setMessage(PLI_BYTE8 *code, PLI_BYTE8 *file, PLI_INT32 line, string message, ...) { _VL_VPI_ERROR_SET; m_errorInfo.state = vpiPLI; setError((PLI_BYTE8*)message.c_str(), code, file, 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 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 int)*((CData*)(vop->varDatap()))); return; case VLVT_UINT16: snprintf(outStr, outStrSz+1, "%hu", (unsigned int)*((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.856/include/verilated.h0000664000177100017500000021126312307212144017277 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-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. // //************************************************************************* /// /// \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, 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,rd); \ _bvtemp.set_word(1,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); } // 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]<= obits) { 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 ((int)rd >= obits) { 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 ((int)rd >= 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((int)rd>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.856/include/verilated_vcd_sc.cpp0000664000177100017500000001335512306677750021176 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-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. // // 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 SystemPerl Tracing in VCD Format /// /// AUTHOR: Wilson Snyder /// //============================================================================= // 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.856/include/verilated_heavy.h0000664000177100017500000000360712306677750020515 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-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. // //************************************************************************* /// /// \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_NQ(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); } extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...); extern string VL_SFORMATF_NX(const char* formatp, ...); #endif // Guard verilator-3.856/include/verilated_vcd_sc.h0000664000177100017500000001670012306677750020640 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-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. // // 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 SystemPerl tracing in VCD format /// /// AUTHOR: Wilson Snyder /// //============================================================================= // SPDIFF_OFF #ifndef _VERILATED_VCD_SC_H_ #define _VERILATED_VCD_SC_H_ 1 #include "verilated_sc.h" #include "verilated_vcd_c.h" // SPDIFF_ON //============================================================================= // VerilatedVcdSc /// /// This class is passed to the SystemC simulation kernel, just like a /// documented SystemC trace format. class VerilatedVcdSc : sc_trace_file , public VerilatedVcdC { public: VerilatedVcdSc() { sc_get_curr_simcontext()->add_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