verilator-3.916/0000775000177100017500000000000013206353162013521 5ustar wsnyderwsnyderverilator-3.916/TODO0000775000177100017500000001375013205574202014221 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: List of To Do issues. // // Copyright 2004-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. Language support: * Fix ordering of each bit separately in a signal (mips) assign b[3:0] = b[7:4]; assign b[7:4] = in; * Support UDP gate primitives/ cell libraries (have code for combos - problem is sequential udps) * Function to eval combo logic after /*verilator public*/ functions [gwaters] * Support generated clocks (correctness) * Real numbers * Recursive functions * Verilog configuration files * Structs/unions (have starting point) * DPI to define C/C++ calls from Verilog * Expression coverage (see notes) * Better tristate support Long-term Features * Assertions * Tristate support * Multithreaded execution Configure/Make/Install * Full MSVC++ compilation (does scons support this?) (4.000?) * Distribute with flex/bison already expanded? Flex library not needed. Probably too difficult to be worth it. Testing: * Move test_c/sp/v/verilated into test_regress format (4.000?) * Capture all inputs into global "rerun it" file * Code to make wrapper that sets signals, so can do comparison checks * New random program generator * Better graph viewer with search and zoom * Port and test against opencores.org code * // verilator debug in code so can see only tree affecting those nodes Usability: * Detect and pre-remove most UNOPTFLATs (4.000) * Better reporting of unopt problems, including what lines of code * Report more errors (all of them?) before exiting [Eugene Weber] * Auto-create scons config files * Print version/etc message at runtime. (4.000?) Include number of lines of code, percent comments, code complexity measurement <-80chars-------------------------------------------------------------------> Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2013. Verilated #### modules, #### instances, ##### sigs, #### non-comment lines, ##### ops, ### KB model size * Default the --l2name to remove extra "v" level of hierarchy (flag to make "top") Lint: * CDCRSTLOGIC should allow filtering with paths "waive CDCRSTLOGIC --from a.b.sig --to a.c.sig --via OR" Internal Code: * Eliminate the AstNUser* passed to all visitors; its only needed in V3Width, and removing it will speed up and simplify all the other code. * V3Graph should be templated container type, taking in Vertex + Edge types * Rename V3PreLex etc to match VerilogPerl filenames * Instead of string, have an VEncodedString/VIdString which contains __DOT__ish things, to reduce bugs. Also add _20 trailing space to \ encoded names. (4.000) Runtime: * New evalulation loop ~/src/verilator/notes/event_loop.txt (4.000?) * Remove all private internal functions from top level wrapper header, move to new level (4.000?) * Completely standalone simulation (4.000) main() records arguments for $test$plusvars instantiates top, does tracing (support $dump?) calls top->simulateForever() exits Performance: * Latch optimizations * Constant propagation Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF)) Extra shift (perhaps due to clean): if (1 & CAST (VARREF >> #)) * Gated clock and latch conversion to flops. [JeanPaul Vanitegem] Could propagate the AND into pos/negedges and let domaining optimize. * Negedge reset Switch to remove negedges that don't matter Can't remove async resets from control flops (like in syncronizers) * If all references to array have a constant index, blow up into separate signals-per-index * Bit-multiply for faster bit swapping and a=b[1,3,2] random bit reorderings. * Move _last sets and all other combo logic inside master if() that triggers on all possible sense items * Rewrite and combine V3Life, V3Subst If block temp only ever set in one place to constant, propagate it Used in t_mem for array delayed assignments Replace variables if set later in same cfunc branch See for example duplicate sets of _narrow in cycle 90/91 of t_select_plusloop * Same assignment on both if branches "if (a) { ... b=2; } else { ... b=2;}" -> "b=2; if ..." Careful though, as b could appear in the statement or multiple times in statement (Could just require exatly two 'b's in statement) * Simplify XOR/XNOR/AND/OR bit selection trees Foo = A[1] ^ A[2] ^ A[3] etc are better as ^ ( A & 32'b...1110 ) * Combine variables into wider elements Parallel statements on different bits should become single signal Variables that are always consumed in "parallel" can be joined * Duplicate assignments in gate optimization Common to have many separate posedge blocks, each with identical reset_r <= rst_in * If signal is used only once (not counting trace), always gate substitute Don't merge if any combining would form circ logic (out goes back to in) * Multiple assignments each bit can become single assign with concat Make sure a SEL of a CONCAT can get the single bit back. * Usually blocks/values Enable only after certain time, so VL_TIME_I(32) > 0x1e gets eliminated out * Better ordering of a<=b, b<=c, put all refs to 'b' next to each other to optimize caching * Allow Split of case statements without a $display/$stop * I-cache packing improvements (what/how?) * Data cache organization (order of vars in class) First have clocks, then bools instead of uint32_t's then based on what sense list they come from, all outputs, then all inputs finally have any signals part of a "usually" block, or constant. * Rather then tracking widths, have a MSB...LSB of this expression (or better, a bitmask of bits relevant in this expression) * Track recirculation and convert into clock-enables * Clock enables should become new clocking domains for speed * If floped(a) & flopped(b) and no other a&b, then instead flop(a&b). * Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal) verilator-3.916/bin/0000775000177100017500000000000013206353162014271 5ustar wsnyderwsnyderverilator-3.916/bin/verilator_difftree0000775000177100017500000001532513205574202020103 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-2017 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.916/bin/verilator_coverage0000775000177100017500000002026313205574202020103 0ustar wsnyderwsnyder: # -*-Mode: perl;-*- use perl, wherever it is eval 'exec perl -wS $0 ${1+"$@"}' if 0; ###################################################################### # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you # can redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ###################################################################### require 5.006_001; use warnings; BEGIN { if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) { # Magic to allow author testing of perl packages in local directory require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT}; } } use Getopt::Long; use FindBin qw($RealBin $RealScript); use IO::File; use Pod::Usage; use Cwd qw(abs_path getcwd); use strict; use vars qw ($Debug @Opt_Verilator_Sw); ####################################################################### ####################################################################### # main autoflush STDOUT 1; autoflush STDERR 1; $Debug = 0; # No arguments can't do anything useful. Give help if ($#ARGV < 0) { pod2usage(-exitstatus=>2, -verbose=>0); } # We sneak a look at the flags so we can do some pre-environment checks # All flags will hit verilator... foreach my $sw (@ARGV) { $sw = "'$sw'" if $sw =~ m![^---a-zA-Z0-9_/\\:.+]!; push @Opt_Verilator_Sw, $sw; } Getopt::Long::config ("no_auto_abbrev","pass_through"); if (! GetOptions ( # Major operating modes "help" => \&usage, "debug:s" => \&debug, # "version!" => \&version, # Also passthru'ed # Additional parameters "<>" => sub {}, # Ignored )) { pod2usage(-exitstatus=>2, -verbose=>0); } # Normal, non gdb run (verilator_coverage_bin() ." ".join(' ',@Opt_Verilator_Sw)); #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); } sub debug { shift; my $level = shift; $Debug = $level||3; } ####################################################################### ####################################################################### # Builds sub verilator_coverage_bin { my $bin = ""; # Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path my $basename = ($ENV{VERILATOR_COVERAGE_BIN} || "verilator_coverage_bin_dbg"); if (defined($ENV{VERILATOR_ROOT})) { my $dir = $ENV{VERILATOR_ROOT}; if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT $bin = "$dir/bin/$basename"; } else { $bin = "$dir/$basename"; # From pointing to kit directory } } else { if (-x "$RealBin/$basename") { $bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed } else { $bin = $basename; # Find in PATH } # Note we don't look under bin/$basename which would be right if running # in the kit dir. Running that would likely break, since # VERILATOR_ROOT wouldn't be set and Verilator won't find internal files. } return $bin; } ####################################################################### ####################################################################### # Utilities sub run { # Run command, check errors my $command = shift; $! = undef; # Cleanup -x print "\t$command\n" if $Debug>=3; system($command); my $status = $?; if ($status) { if ($! =~ /no such file or directory/i) { warn "%Error: verilator_coverage: Misinstalled, or VERILATOR_ROOT might need to be in environment\n"; } if ($Debug) { # For easy rerunning warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n"; warn "%Error: $command\n"; } if ($status & 127) { if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV warn "%Error: Verilator_coverage internal fault, sorry.\n" if !$Debug; } elsif (($status & 127) == 6) { # SIGABRT warn "%Error: Verilator_coverage aborted.\n" if !$Debug; } else { warn "%Error: Verilator_coverage threw signal $status.\n" if !$Debug; } } die "%Error: Command Failed $command\n"; } } ####################################################################### ####################################################################### package main; __END__ =pod =head1 NAME verilator_coverage - Verilator coverage analyzer =head1 SYNOPSIS verilator_coverage --help verilator_coverage --version verilator_coverage --annotate verilator_coverage -write merged.dat -read ... Verilator_coverage processes Verilator coverage reports. With --anotate, it reads the specified data file and generates annotated source code with coverage metrics annotated. If multiple coverage points exist on the same line, additional lines will be inserted to report the additional points. Additional Verilog-standard arguments specify the search paths necessary to find the source code that the coverage analysis was performed on. To get correct coverage percentages, you may wish to read logs/coverage.dat into Emacs and do a M-x keep-lines to include only those statistics of interest. For Verilog conditions that should never occur, you should add a $stop statement. This will remove the coverage during the next build. =head1 ARGUMENTS =over 4 =item I Specify input data file, may be repeated to read multiple inputs. If no data file is specified, by default coverage.dat is read. =item --annotate I Sprcifies the directory name that source files with annotated coverage data should be written to. =item --annotate-all Specifies all files should be shown. By default, only those source files which have low coverage are written to the output directory. =item --annotate-min I Specifies the minimum occurrence count that should be flagged if the coverage point does not include a specified threshold. Defaults to 10. =item --help Displays this message and program version and exits. =item --rank Print an experimental report listing the relative importance of each test in covering all of the coverage points. The report shows "Covered" which indicates the number of points that test covers; a test is considered to cover a point if it has a bucket count of at least 1. The "rank" column has a higher number t indicate the test is more important, and rank 0 means the test does not need to be run to cover the points. "RankPts" indicates the number of coverage points this test will contribute to overall coverage if all tests are run in the order of highest to lowest rank. =item --unlink When using --write to combine coverage data, unlink all input files after the output has been created. =item --version Displays program version and exits. =item --write I Specifies the aggregate coverage results, summed across all the files, should be written to the given filename. This is useful in scripts to combine many sequential runs into one master coverage file. =back =head1 VERILOG ARGUMENTS The following arguments are compatible with GCC, VCS and most Verilog programs. =over 4 =item +libext+I+I... Defines the extensions for Verilog files. =item +define+I+I =item -DI=I Defines the given variable. =item +incdir+I =item -II Specifies a directory for finding include files. =item -f I Specifies a file containing additional command line arguments. =item -y I Specifies a module search directory. =back =head1 DISTRIBUTION The latest version is available from L. Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO C L which is the source for this document. =cut ###################################################################### verilator-3.916/bin/verilator_profcfunc0000775000177100017500000001452713205574202020303 0ustar wsnyderwsnyder: # -*-Mode: perl;-*- use perl, wherever it is eval 'exec perl -wS $0 ${1+"$@"}' if 0; # See copyright, etc in below POD section. ###################################################################### require 5.006_001; use warnings; use Getopt::Long; use IO::File; use Pod::Usage; eval { use Data::Dumper; $Data::Dumper::Indent = 1; }; # Debug, ok if missing use strict; use vars qw ($Debug); #====================================================================== #====================================================================== # main $Debug = 0; my $Opt_File; autoflush STDOUT 1; autoflush STDERR 1; Getopt::Long::config ("no_auto_abbrev"); if (! GetOptions ( "help" => \&usage, "debug" => \&debug, "<>" => \¶meter, )) { die "%Error: Bad usage, try 'verilator_profcfunc --help'\n"; } defined $Opt_File or die "%Error: No filename given\n"; profcfunc($Opt_File); #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } sub debug { $Debug = 1; } sub parameter { my $param = shift; if (!defined $Opt_File) { $Opt_File = $param; } else { die "%Error: Unknown parameter: $param\n"; } } ####################################################################### sub profcfunc { my $filename = shift; # Remove hex numbers before diffing my $fh = IO::File->new ($filename) or die "%Error: $! $filename,"; my %funcs; while (defined (my $line=$fh->getline())) { # %time cumesec selfsec calls {stuff} name if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) { my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4; $funcs{$func}{pct} += $pct; $funcs{$func}{sec} += $sec; $funcs{$func}{calls} += $calls; } } $fh->close; # Find modules my %pointer_mods; my %verilated_mods; foreach my $func (keys %funcs) { if ($func =~ /(.*)::_eval\(([a-zA-Z_0-9]+__Syms).*\)$/) { $verilated_mods{$1} = qr/^$1/; $pointer_mods{$2} = $1; } } #print Dumper(\%pointer_mods, \%verilated_mods); # Resort by Verilog name my %vfuncs; my %groups; foreach my $func (keys %funcs) { my $pct = $funcs{$func}{pct}; my $vfunc = $func; my $design; if ($func =~ /\(([a-zA-Z_0-9]+__Syms)/) { $design = $pointer_mods{$1}; } foreach my $vde (keys %verilated_mods) { last if $design; if ($func =~ /$verilated_mods{$vde}/) { $design=$vde; last; } } if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__l?([0-9]+)\(/) { $vfunc = sprintf("VBlock %s:%d", $1, $2); $groups{type}{"Verilog Blocks under $design"} += $pct; $groups{design}{$design} += $pct; $groups{module}{$1} += $pct; } else { if ($design) { $vfunc = sprintf("VCommon %s", $func); $groups{type}{"Common code under $design"} += $pct; $groups{design}{$design} += $pct; $groups{module}{$design." common code"} += $pct; } elsif ($func =~ /^VL_[A-Z0-9_]+/ || $func =~ /^_?vl_[a-zA-Z0-9_]+/ || $func =~ /^verilated/i) { $vfunc = sprintf("VLib %s", $func); $groups{type}{'VLib'} += $pct; $groups{design}{'VLib'} += $pct; $groups{module}{'VLib'} += $pct; } elsif ($func =~ /^_mcount_private/) { $vfunc = sprintf("Prof %s", $func); $groups{type}{'Prof'} += $pct; $groups{design}{'Prof'} += $pct; $groups{module}{'Prof'} += $pct; } else { $vfunc = sprintf("C++ %s", $func); $groups{type}{'C++'} += $pct; $groups{design}{'C++'} += $pct; $groups{module}{'C++'} += $pct; } } $vfuncs{$vfunc} = $funcs{$func}; } foreach my $type (qw(type design module)) { my $missing = 100; foreach (sort (keys %{$groups{$type}})) { $missing -= $groups{$type}{$_}; } if ($missing) { $groups{$type}{"\377Unaccounted for/rounding error"} = $missing; } print("Overall summary by $type:\n"); printf(" %-6s %s\n","% time",$type); foreach my $what (sort (keys %{$groups{$type}})) { (my $pwhat = $what) =~ s/^\377//; # Just used to establish sort order printf(" %6.2f %s\n", $groups{$type}{$what}, $pwhat); } print("\n"); } print("Verilog code profile:\n"); print(" These are split into three categories:\n"); print(" C++: Time in non-Verilated C++ code\n"); print(" Prof: Time in profile overhead\n"); print(" VBlock: Time attributable to a block in a Verilog file and line\n"); print(" VCommon: Time in a Verilated module, due to all parts of the design\n"); print(" VLib: Time in Verilated common libraries, called by the Verilated code\n"); print("\n"); print(" % cumulative self \n"); print(" time seconds seconds calls type filename and line number\n"); my $cume = 0; foreach my $func (sort {$vfuncs{$b}{sec} <=> $vfuncs{$a}{sec} || $a cmp $b} (keys %vfuncs)) { $cume += $vfuncs{$func}{sec}; printf +("%6.2f %9.2f %8.2f %8d %s\n", $vfuncs{$func}{pct}, $cume, $vfuncs{$func}{sec}, $vfuncs{$func}{calls}, $func); } } ####################################################################### __END__ =pod =head1 NAME verilator_profcfunc - Read gprof report created with --profile-cfuncs =head1 SYNOPSIS verilator --profile-cfuncs .... gcc --ggdb -pg .... {run executable} gprof verilator_profcfuncs gprof.out =head1 DESCRIPTION Verilator_profcfunc reads a profile report created by gprof. The names of the functions are then transformed, assuming the user used verilator's --profile-cfuncs, and a report printed showing the percentage of time, etc, in each Verilog block. =head1 ARGUMENTS =over 4 =item --help Displays this message and program version and exits. =back =head1 DISTRIBUTION The latest version is available from L. Copyright 2007-2017 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.916/bin/verilator0000775000177100017500000047147513205574202016247 0ustar wsnyderwsnyder: # -*-Mode: perl;-*- use perl, wherever it is eval 'exec perl -wS $0 ${1+"$@"}' if 0; ###################################################################### # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you # can redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ###################################################################### require 5.006_001; use warnings; BEGIN { if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) { # Magic to allow author testing of perl packages in local directory require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT}; } } use Getopt::Long; use FindBin qw($RealBin $RealScript); use IO::File; use Pod::Usage; use strict; use vars qw ($Debug @Opt_Verilator_Sw); ####################################################################### ####################################################################### # main autoflush STDOUT 1; autoflush STDERR 1; $Debug = 0; my $opt_gdb; my $opt_gdbbt; # No arguments can't do anything useful. Give help if ($#ARGV < 0) { pod2usage(-exitstatus=>2, -verbose=>0); } # Insert debugging options up front push @ARGV, (split ' ',$ENV{VERILATOR_TEST_FLAGS}||""); # We sneak a look at the flags so we can do some pre-environment checks # All flags will hit verilator... foreach my $sw (@ARGV) { # Some special treatment for parameters to allow verilog literals for numbers if ((substr($sw, 0, 2) eq "-G") || (substr($sw, 0, 8) eq "-pvalue+")) { # If there is a single quote in the parameter put it double quotes , # else just put it in double quotes if ($sw =~ m![\']!) { $sw = "\"$sw\""; } else { $sw = "'$sw'"; } } else { $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) == 4 # SIGILL || ($status & 127) == 8 # SIGFPA || ($status & 127) == 11) { # 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] [source_files.v]... [opt_c_files.cpp/c/cc/a/o/so] verilator --sc [options] [source_files.v]... [opt_c_files.cpp/c/cc/a/o/so] verilator --lint-only [source_files.v]... =head1 DESCRIPTION Verilator converts synthesizable (not behavioral) Verilog code, plus some Synthesis, SystemVerilog and a small subset of Verilog AMS assertions, into C++ or SystemC code. It is not a complete simulator, but a compiler. Verilator is invoked with parameters similar to GCC, Cadence Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage and waveform tracing code. For C++ and SystemC formats, it outputs .cpp and .h files. The files created by Verilator are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module, and passes this filename on the command line. These C files are compiled in C++, and linked with the Verilated files. The resulting executable will perform the actual simulation. To get started, jump down to "EXAMPLE C++ EXECUTION". =head1 ARGUMENT SUMMARY This is a short summary of the arguments to Verilator. See the detailed descriptions in the next sections for more information. {file.v} Verilog package, module and top module filenames {file.c/cc/cpp} Optional C++ files to compile in {file.a/o/so} Optional C++ files to link in +1364-1995ext+ Use Verilog 1995 with file extension +1364-2001ext+ Use Verilog 2001 with file extension +1364-2005ext+ Use Verilog 2005 with file extension +1800-2005ext+ Use SystemVerilog 2005 with file extension +1800-2009ext+ Use SystemVerilog 2009 with file extension +1800-2012ext+ Use SystemVerilog 2012 with file extension --assert Enable all assertions --autoflush Flush streams after all $displays --bbox-sys Blackbox unknown $system calls --bbox-unsup Blackbox unsupported language features --bin Override Verilator binary -CFLAGS C++ Compiler flags for makefile --cc Create C++ output --cdc Clock domain crossing analysis --clk Mark specified signal as clock --compiler Tune for specified C++ compiler --converge-limit Tune convergence settle time --coverage Enable all coverage --coverage-line Enable line coverage --coverage-toggle Enable toggle coverage --coverage-user Enable SVL user coverage --coverage-underscore Enable coverage of _signals -D[=] Set preprocessor define --debug Enable debugging --debug-check Enable debugging assertions --debugi Enable debugging at a specified level --debugi- Enable debugging a source file at a level --default-language Default language to parse +define+= Set preprocessor define --dump-tree Enable dumping .tree files --dump-treei Enable dumping .tree files at a level --dump-treei- Enable dumping .tree file at a source file at a level -E Preprocess, but do not compile --error-limit Abort after this number of errors --exe Link to create executable -F Parse options from a file, relatively -f Parse options from a file -FI Force include of a file -G= Overwrite toplevel parameter --gdb Run Verilator under GDB interactively --gdbbt Run Verilator under GDB for backtrace --getenv Get environment variable with defaults --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 --l2-name Verilog scope name of the top module --language Default language standard to parse +libext++[ext]... Extensions for finding modules --lint-only Lint, but do not make output --MMD Create .d dependency files --MP Create phony dependency targets --Mdir Name of output object directory --mod-prefix Name to prepend to lower classes --no-clk Prevent marking specified signal as clock --no-decoration Disable comments and symbol decorations --no-pins64 Don't use vluint64_t's for 33-64 bit sigs --no-skip-identical Disable skipping identical output +notimingchecks Ignored -O0 Disable optimizations -O3 High performance optimizations -O Selectable optimizations -o Name of final executable --no-order-clock-delay Disable ordering clock enable assignments --output-split Split .cpp files into pieces --output-split-cfuncs Split .cpp functions --output-split-ctrace Split tracing functions -P Disable line numbers and blanks with -E --pins-bv Specify types for top level ports --pins-sc-uint Specify types for top level ports --pins-sc-biguint Specify types for top level ports --pins-uint8 Specify types for top level ports --pipe-filter Filter all input through a script --prefix Name of top level class --profile-cfuncs Name functions for profiling --private Debugging; see docs --public Debugging; see docs -pvalue+= Overwrite toplevel parameter --relative-includes Resolve includes relative to current file --no-relative-cfuncs Disallow 'this->' in generated functions --report-unoptflat Extra diagnostics for UNOPTFLAT --savable Enable model save-restore --sc Create SystemC output --stats Create statistics file --stats-vars Provide statistics on variables -sv Enable SystemVerilog parsing +systemverilogext+ Synonym for +1800-2012ext+ --top-module Name of top level input module --trace Enable waveform creation --trace-depth Depth of tracing --trace-max-array Maximum bit width for tracing --trace-max-width Maximum array depth for tracing --trace-params Enable tracing parameters --trace-structs Enable tracing structure names --trace-underscore Enable tracing of _signals -U Undefine preprocessor define --unroll-count Tune maximum loop iterations --unroll-stmts Tune maximum loop body size --unused-regexp Tune UNUSED lint signals -V Verbose version and config -v Verilog library +verilog1995ext+ Synonym for +1364-1995ext+ +verilog2001ext+ Synonym for +1364-2001ext+ --vpi Enable VPI compiles -Wall Enable all style warnings -Werror- Convert warnings to errors -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 Assign non-initial Xs to this value --x-initial Assign initial 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. =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, the cmos and tran gate primitives, deassign statements, and mixed edge errors. This may enable linting the rest of the design even when unsupported constructs are present. =item --bin I Rarely needed. Override the default filename for Verilator itself. When a dependency (.d) file is created, this filename will become a source dependency, such that a change in this binary will have make rebuild the output files. =item -CFLAGS I Add specified C compiler flags to the generated makefiles. When make is run on the generated makefile these will be passed to the C++ compiler (gcc/g++/msvc++). =item --cc Specifies C++ without SystemC output mode; see also --sc. =item --cdc Experimental. Perform some clock domain crossing checks and issue related warnings (CDCRSTLOGIC) and then exit; if warnings other than CDC warnings are needed make a second run with --lint-only. Additional warning information is also written to the file {prefix}__cdc.txt. Currently only checks some items that other CDC tools missed; if you have interest in adding more traditional CDC checks, please contact the authors. =item --clk I Sometimes it is quite difficult for Verilator to distinguish clock signals from other data signals. Occasionally the clock signals can end up in the checking list of signals which determines if further evaluation is needed. This will heavily degrade the performance of a Verilated model. With --clk , user can specified root clock into the model, then Verilator will mark the signal as clocker and propagate the clocker attribute automatically to other signals derived from that. In this way, Verilator will try to avoid taking the clocker signal into checking list. Note signal-name is specified by the RTL hierarchy path. For example, v.foo.bar. If the signal is the input to top-module, the directly the signal name. If you find it difficult to find the exact name, try to use C in RTL file to mark the signal directly. If clock signals are assigned to vectors and then later used individually, Verilator will attempt to decompose the vector and connect the single-bit clock signals directly. This should be transparent to the user. =item --compiler I Enables tunings and workarounds 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.dat. Verilator automatically disables coverage of branches that have a $stop in them, as it is assumed $stop branches contain an error check that should not occur. A /*verilator coverage_block_off*/ comment will perform a similar function on any code in that block or below, or /*verilator coverage_on/coverage_off*/ will disable coverage around lines of code. Note Verilator may over-count combinatorial (non-clocked) blocks when those blocks receive signals which have had the UNOPTFLAT warning disabled; for most accurate results do not disable this warning when using coverage. =item --coverage-toggle Specifies signal toggle coverage analysis code should be inserted. Every bit of every signal in a module has a counter inserted. The counter will increment on every edge change of the corresponding bit. Signals that are part of tasks or begin/end blocks are considered local variables and are not covered. Signals that begin with underscores, are integers, or are very wide (>256 bits total storage across all dimensions) are also not covered. Hierarchy is compressed, such that if a module is instantiated multiple times, coverage will be summed for that bit across ALL instantiations of that module with the same parameter set. A module instantiated with different parameter values is considered a different module, and will get counted separately. Verilator makes a minimally-intelligent decision about what clock domain the signal goes to, and only looks for edges in that clock domain. This means that edges may be ignored if it is known that the edge could never be seen by the receiving logic. This algorithm may improve in the future. The net result is coverage may be lower than what would be seen by looking at traces, but the coverage is a more accurate representation of the quality of stimulus into the design. There may be edges counted near time zero while the model stabilizes. It's a good practice to zero all coverage just before releasing reset to prevent counting such behavior. A /*verilator coverage_off/on */ comment pair can be used around signals that do not need toggle analysis, such as RAMs and register files. =item --coverage-underscore Enable coverage of signals that start with an underscore. Normally, these signals are not covered. See also --trace-underscore. =item --coverage-user Enables user inserted functional coverage. Currently, all functional coverage points are specified using SVA which must be separately enabled with --assert. For example, the following statement will add a coverage point, with the comment "DefaultClock": DefaultClock: cover property (@(posedge clk) cyc==3); =item -DI=I Defines the given preprocessor symbol, without allowing. Similar to +define; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility. =item --debug Select the debug built image of Verilator (if available), and enable more internal assertions (equivalent to C<--debug-check>), debugging messages (equivalent to C<--debugi 4>), and intermediate form dump files (equivalent to C<--dump-treei 3>). =item --debug-check Rarely needed. Enable internal debugging assertion checks, without changing debug verbosity. Enabled automatically when --debug specified. =item --debugi =item --debugi- Rarely needed - for developer use. Set internal debugging level globally to the specified debug level (1-10) or set the specified Verilator source file to the specified level (e.g. C<--debugi-V3Width 9>). Higher levels produce more detailed messages. =item --default-language I Select the language to be used by default when first processing each Verilog file. The language value must be "1364-1995", "1364-2001", "1364-2005", "1800-2005", "1800-2009" or "1800-2012". Any language associated with a particular file extension (see the various +Iext+ options) will be used in preference to the language specified by --default-language. The --default-language flag is only recommended for legacy code using the same language in all source files, as the preferable option is to edit the code to repair new keywords, or add appropriate C<`begin_keywords>. For legacy mixed language designs, the various +Iext+ options should be used. If no language is specified, either by this flag or +Iext+ options, then the latest SystemVerilog language (IEEE 1800-2012) is used. =item +define+I=I =item +define+I=I+I=I... Defines the given preprocessor symbol, or multiple symbols if separated by plusses. Similar to -D; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility. =item --dump-tree Rarely needed. Enable writing .tree debug files with dumping level 3, which dumps the standard critical stages. For details on the format see the Verilator Internals manual. --dump-tree is enabled automatically with --debug, so "--debug --no-dump-tree" may be useful if the dump files are large and not desired. =item --dump-treei =item --dump-treei- Rarely needed - for developer use. Set internal tree dumping level globally to a specific dumping level or set the specified Verilator source file to the specified tree dumping level (e.g. C<--dump-treei-V3Order 9>). Level 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9 enables dumping of every stage. =item -E Preprocess the source code, but do not compile, as with 'gcc -E'. Output is written to standard out. Beware of enabling debugging messages, as they will also go to standard out. =item --error-limit After this number of errors or warnings are encountered, exit. Defaults to 50. =item --exe Generate an executable. You will also need to pass additional .cpp files on the command line that implement the main loop for your simulation. =item -F I Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the directory containing the specified file. See also -f. Note -F is fairly standard across Verilog tools. =item -f I Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the current directory. See also -F. Note -f is fairly standard across Verilog tools. The file may contain // comments which are ignored to the end of the line. Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment variable. =item -FI Force include of the specified C++ header file. All generated C++ files will insert a #include of the specified file before any other includes. The specified file might be used to contain define prototypes of custom VL_VPRINTF functions, and may need to include verilatedos.h as this file is included before any other standard includes. =item -GI=I Overwrites the given parameter of the toplevel module. The value is limited to basic data literals: =over 4 =item Verilog integer literals The standard verilog integer literals are supported, so values like 32'h8, 2'b00, 4 etc. are allowed. Care must be taken that the single quote (I') is properly escaped in an interactive shell, e.g., as -GWIDTH=8\'hx. =item C integer literals It is also possible to use C integer notation, including hexadecimal (0x..), octal (0..) or binary (0b..) notation. =item Double literals Double literals must contain a dot (.) and/or an exponent (e). =item Strings String must in double quotes ("). On the command line it is required to escape them properly, e.g. as -GSTR="\"My String\"" or -GSTR='"My String"'. =back =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 --getenv I If the variable is declared in the environment, print it and exit immediately. Otherwise, if it's built into Verilator (e.g. VERILATOR_ROOT), print that and exit immediately. Otherwise, print a newline and exit immediately. This can be useful in makefiles. See also -V, and the various *.mk files. =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 --l2-name I Instead of using the module name when showing Verilog scope, use the name provided. This allows simplifying some Verilator-embedded modeling methodologies. Default is an l2-name matching the top module. The default before 3.884 was "--l2-name v" For example, the program "module t; initial $display("%m"); endmodule" will show by default "t". With "--l2-name v" it will print "v". =item --language I A synonym for C<--default-language>, for compatibility with other tools and earlier versions of Verilator. =item +libext+I+I... Specify the extensions that should be used for finding modules. If for example module I is referenced, look in I.I. Note +libext+ is fairly standard across Verilog tools. Defaults to .v and .sv. =item --lint-only Check the files for lint violations only, do not create any other output. You may also want the -Wall option to enable messages that are considered stylistic and not enabled by default. If the design is not to be completely Verilated see also the --bbox-sys and --bbox-unsup options. =item --MMD Enable creation of .d dependency files, used for make dependency detection, similar to gcc -MMD option. On by default, use --no-MMD to disable. =item --MP When creating .d dependency files with --MMD, make phony targets. Similar to gcc -MP option. =item --Mdir I Specifies the name of the Make object directory. All generated files will be placed in this directory. If not specified, "obj_dir" is used. The directory is created if it does not exist and the parent directories exist; otherwise manually create the Mdir before calling Verilator. =item --mod-prefix I Specifies the name to prepend to all lower level classes. Defaults to the same as --prefix. =item --no-clk Prevent the specified signal from being marked as clock. See C<--clk>. =item --no-decoration When creating output Verilated code, minimize comments, whitespace, symbol names and other decorative items, at the cost of greatly reduced readability. This may assist C++ compile times. This will not typically change the ultimate model's performance, but may in some cases. =item --no-pins64 Backward compatible alias for "--pins-bv 33". =item --no-relative-cfuncs Disable 'this->' references in generated functions, and instead Verilator will generate absolute references starting from 'vlTOPp->'. This prevents V3Combine from merging functions from multiple instances of the same module, so it can grow the instruction stream. This is a work around for old compilers. Don't set this if your C++ compiler supports __restrict__ properly, as GCC 4.5.x and newer do. For older compilers, test if this switch gives you better performance or not. Compilers which don't honor __restrict__ will suspect that 'this->' references and 'vlTOPp->' references may alias, and may write slow code with extra loads and stores to handle the (imaginary) aliasing. Using only 'vlTOPp->' references allows these old compilers to produce tight code. =item --no-skip-identical Rarely needed. Disables skipping execution of Verilator if all source files are identical, and all output files exist with newer dates. =item +notimingchecks Ignored for compatibility with other simulators. =item -O0 Disables optimization of the model. =item -O3 Enables slow optimizations for the code Verilator itself generates (as opposed to "-CFLAGS -O3" which effects the C compiler's optimization. -O3 may reduce simulation runtimes at the cost of compile time. This currently sets --inline-mult -1. =item -OI Rarely needed. Enables or disables a specific optimizations, with the optimization selected based on the letter passed. A lowercase letter disables an optimization, an upper case letter enables it. This is intended for debugging use only; see the source code for version-dependent mappings of optimizations to -O letters. =item -o Specify the name for the final executable built if using --exe. Defaults to the --prefix if not specified. =item --no-order-clock-delay Rarely needed. Disables a bug fix for ordering of clock enables with delayed assignments. This flag should only be used when suggested by the developers. =item --output-split I Enables splitting the output .cpp 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 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 files into multiple functions. Defaults to same setting as --output-split-cfuncs. =item -P With -E, disable generation of `line markers and blank lines, similar to GCC -P flag. =item --pins64 Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64. =item --pins-bv I Specifies SystemC inputs/outputs of greater than or equal to I bits wide should use sc_bv's instead of uint32/vluint64_t's. The default is "--pins-bv 65", and the value must be less than or equal to 65. Versions before Verilator 3.671 defaulted to "--pins-bv 33". The more sc_bv is used, the worse for performance. Use the "/*verilator sc_bv*/" attribute to select specific ports to be sc_bv. =item --pins-sc-uint Specifies SystemC inputs/outputs of greater than 2 bits wide should use sc_uint between 2 and 64. When combined with the "--pins-sc-biguint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. =item --pins-sc-biguint Specifies SystemC inputs/outputs of greater than 65 bits wide should use sc_biguint between 65 and 512, and sc_bv from 513 upwards. When combined with the "--pins-sc-uint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. =item --pins-uint8 Specifies SystemC inputs/outputs that are smaller than the --pins-bv setting and 8 bits or less should use uint8_t instead of uint32_t. Likewise pins of width 9-16 will use uint16_t instead of uint32_t. =item --pipe-filter I Rarely needed and experimental. Verilator will spawn the specified command as a subprocess pipe, to allow the command to perform custom edits on the Verilog code before it reaches Verilator. Before reading each Verilog file, Verilator will pass the file name to the subprocess' stdin with 'read_verilog ""'. The filter may then read the file and perform any filtering it desires, and feeds the new file contents back to Verilator on stdout with 'Content-Length'. Output to stderr from the filter feeds through to Verilator's stdout and if the filter exits with non-zero status Verilator terminates. See the t/t_pipe_filter test for an example. To debug the output of the filter, try using the -E option to see preprocessed output. =item --prefix I Specifies the name of the top level class and makefile. Defaults to V prepended to the name of the --top-module switch, or V prepended to the first Verilog filename passed on the command line. =item --profile-cfuncs Modify the created C++ functions to support profiling. The functions will be minimized to contain one "basic" statement, generally a single always block or wire statement. (Note this will slow down the executable by ~5%.) Furthermore, the function name will be suffixed with the basename of the Verilog module and line number the statement came from. This allows gprof or oprofile reports to be correlated with the original Verilog source statements. =item --private Opposite of --public. Is the default; this option exists for backwards compatibility. =item --public This is only for historical debug use. Using it may result in mis-simulation of generated clocks. Declares all signals and modules public. This will turn off signal optimizations as if all signals had a /*verilator public*/ comments and inlining. This will also turn off inlining as if all modules had a /*verilator public_module*/, unless the module specifically enabled it with /*verilator inline_module*/. =item -pvalue+I=I Overwrites the given parameter(s) of the toplevel module. See -G for a detailed description. =item --relative-includes When a file references an include file, resolve the filename relative to the path of the referencing file, instead of relative to the current directory. =item --report-unoptflat Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the 10 widest variables in the loop, and the 10 most fanned out variables in the loop. These are candidates for splitting into multiple variables to break the loop. In addition produces a GraphViz DOT file of the entire strongly connected components within the source associated with each loop. This is produced irrespective of whether --dump-tree is set. Such graphs may help in analyzing the problem, but can be very large indeed. Various commands exist for viewing and manipulating DOT files. For example the I command can be used to convert a DOT file to a PDF for printing. For example: dot -Tpdf -O Vt_unoptflat_simple_2_35_unoptflat.dot will generate a PDF Vt_unoptflat_simple_2_35_unoptflat.dot.pdf from the DOT file. =item --savable Enable including save and restore functions in the generated model. The user code must create a VerilatedSerialize or VerilatedDeserialze object then calling the << or >> operators on the generated model and any other data the process needs saved/restored. For example: void save_model(const char* filenamep) { VerilatedSave os; os.open(filenamep); os << main_time; // user code must save the timestamp, etc os << *topp; } void restore_model(const char* filenamep) { VerilatedRestore os; os.open(filenamep); os >> main_time; os >> *topp; } =item --sc Specifies SystemC output mode; see also --cc. =item --stats Creates a dump file with statistics on the design in {prefix}__stats.txt. =item --stats-vars Creates more detailed statistics including a list of all the variables by size (plain --stats just gives a count). See --stats, which is implied by this. =item -sv Specifies SystemVerilog language features should be enabled; equivalent to "--language 1800-2005". This option is selected by default, it exists for compatibility with other simulators. =item +systemverilogext+I A synonym for C<+1800-2012ext+>I. =item --top-module I When the input Verilog contains more than one top level module, specifies the name of the top level Verilog module to become the top, and sets the default for if --prefix is not used. This is not needed with standard designs with only one top. =item --trace Adds waveform tracing code to the model. Verilator will generate additional {prefix}__Trace*.cpp files that will need to be compiled. In addition verilated_vcd_sc.cpp (for SystemC traces) or verilated_vcd_c.cpp (for both) must be compiled and linked in. If using the Verilator generated Makefiles, these will be added as source targets for you. If you're not using the Verilator makefiles, you will need to add these to your Makefile manually. Having tracing compiled in may result in some small performance losses, even when waveforms are not turned on during model execution. =item --trace-depth I Specify the number of levels deep to enable tracing, for example --trace-level 1 to only see the top level's signals. Defaults to the entire model. Using a small number will decrease visibility, but greatly improve runtime and trace file size. =item --trace-max-array I Rarely needed. Specify the maximum array depth of a signal that may be traced. Defaults to 32, as tracing large arrays may greatly slow traced simulations. =item --trace-max-width I Rarely needed. Specify the maximum bit width of a signal that may be traced. Defaults to 256, as tracing large vectors may greatly slow traced simulations. =item --no-trace-params Disable tracing of parameters. =item --trace-structs Enable tracing to show the name of packed structure, union, and packed array fields, rather than a simgle combined packed bus. Due to VCD file format constraints this may result in significantly slower trace times and larger trace files. =item --trace-underscore Enable tracing of signals that start with an underscore. Normally, these signals are not output during tracing. See also --coverage-underscore. =item -UI Undefines the given preprocessor symbol. =item --unroll-count I Rarely needed. Specifies the maximum number of loop iterations that may be unrolled. See also BLKLOOPINIT warning. =item --unroll-stmts I Rarely needed. Specifies the maximum number of statements in a loop for that loop to be unrolled. See also BLKLOOPINIT warning. =item --unused-regexp I Rarely needed. Specifies a simple regexp with * and ? that if a signal name matches will suppress the UNUSED warning. Defaults to "*unused*". Setting it to "" disables matching. =item -V Shows the verbose version, including configuration information compiled into Verilator. (Similar to perl -V.) See also --getenv. =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 --vpi Enable use of VPI and linking against the verilated_vpi.cpp files. =item -Wall Enable all code style warnings, including code style warnings that are normally disabled by default. Equivelent to "-Wwarn-lint -Wwarn-style". Excludes some specialty warnings, i.e. IMPERFECTSCH. =item -Werror-I Convert the specified warning message into an error message. This is generally to discourage users from violating important site-wide rules, for example C<-Werror-NOUNOPTFLAT>. =item -Wfuture-I Rarely needed. Suppress unknown Verilator comments or warning messages with the given message code. This is used to allow code written with pragmas for a later version of Verilator to run under a older version; add -Wfuture- arguments for each message code or comment that the new version supports which the older version does not support. =item -Wno-I Disable the specified warning message. This will override any lint_on directives in the source, i.e. the warning will still not be printed. =item -Wno-lint Disable all lint related warning messages, and all style warnings. This is equivalent to "-Wno-ALWCOMBORDER -Wno-BSSPACE -Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEWITHX -Wno-CMPCONST -Wno-COLONPLUS -Wno-ENDLABEL -Wno-IMPLICIT -Wno-LITENDIAN -Wno-PINCONNECTEMPTY -Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED -Wno-WIDTH" plus the list shown for Wno-style. It is strongly recommended you cleanup your code rather than using this option, it is only intended to be use when running test-cases of code received from third parties. =item -Wno-style Disable all code style related warning messages (note by default they are already disabled). This is equivalent to "-Wno-DECLFILENAME -Wno-DEFPARAM -Wno-INCABSPATH -Wno-PINCONNECTEMPTY -Wno-PINNOCONNECT -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNUSED -Wno-VARHIDDEN". =item -Wno-fatal When warnings are detected, print them, but do not exit the simulator. Having warning messages in builds is sloppy. It is strongly recommended you cleanup your code, use inline lint_off, or use -Wno-... flags rather than using this option. =item -Wwarn-I Enables the specified warning message. =item -Wwarn-lint Enable all lint related warning messages (note by default they are already enabled), but do not affect style messages. This is equivalent to "-Wwarn-ALWCOMBORDER -Wwarn-BSSPACE -Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX -Wwarn-CMPCONST -Wwarn-COLONPLUS -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 controlled with --x-initial. =item --x-initial 0 =item --x-initial fast =item --x-initial unique (default) Controls the two-state value that is used to initialize variables that are not otherwise initialized. --x-initial=0, initializes all otherwise uninitialized variables to zero. --x-initial=unique, the default, initializes variables using a function, which determines the value to use each initialization. This gives greatest flexibility and allows finding reset bugs. See L --x-initial=fast, is best for performance, and initializes all variables to a state Verilator determines is optimal. This may allow further code optimizations, but will likely hide any code bugs relating to missing resets. B This option applies only to initial values of variables. Initial values of clocks are set to 0 unless --x-initial-edge is specified. =item --x-initial-edge Enables emulation of event driven simulators which generally trigger an edge on a transition from X to 1 (C) or X to 0 (C). Thus the following code, where C is uninitialized would set C to C<1'b1> when C is first set to zero: reg res_n = 1'b0; always @(negedge rst_n) begin if (rst_n == 1'b0) begin res_n <= 1'b1; end end In Verilator, by default, uninitialized clocks are given a value of zero, so the above C block would not trigger. While it is not good practice, there are some designs that rely on X E 0 triggering a C, particularly in reset sequences. Using --x-initial-edge with Verilator will replicate this behavior. It will also ensure that X E 1 triggers a C. B Some users have reported that using this option can affect convergence, and that it may be necessary to use --converge-limit to increase the number of convergence iterations. This may be another indication of problems with the modelled design that should be addressed. =item -y I Add the directory to the list of directories that should be searched for include files or libraries. The three flags -y, +incdir and -I have similar effect; +incdir and +y are fairly standard across Verilog tools while -I is an alias for GCC compatibility. Verilator defaults to the current directory ("-y .") and any specified --Mdir, though these default paths are used after any user specified directories. This allows '-y "$(pwd)"' to be used if absolute filenames are desired for error messages instead of relative filenames. =back =head1 EXAMPLE C++ EXECUTION We'll compile this example into C++. mkdir test_our cd test_our cat <our.v module our; initial begin $display("Hello World"); $finish; end endmodule EOF cat <sim_main.cpp #include "Vour.h" #include "verilated.h" int main(int argc, char** argv, char** env) { Verilated::commandArgs(argc, argv); Vour* top = new Vour; while (!Verilated::gotFinish()) { top->eval(); } delete top; exit(0); } EOF See the README in the source kit for various ways to install or point to Verilator binaries. In brief, if you are running Verilator that came from your operating system (as an RPM), or did a "make install" to place Verilator into your default path, you do not need anything special in your environment, and should not have VERILATOR_ROOT set. However, if you installed Verilator from sources and want to run Verilator out of where you compiled Verilator, you need to point to the kit: # See above; don't do this if using an OS-distributed Verilator 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 make -j -C obj_dir -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 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; to aid this Verilator can create a makefile dependency file. See the examples directory in the distribution. =head1 EXAMPLE SYSTEMC EXECUTION This is an example similar to the above, but using SystemC. mkdir test_our_sc cd test_our_sc cat <our.v module our (clk); input clk; // Clock is required to get initial activation always @ (posedge clk) begin $display("Hello World"); $finish; end endmodule EOF cat <sc_main.cpp #include "Vour.h" int sc_main(int argc, char **argv) { Verilated::commandArgs(argc, argv); sc_clock clk ("clk",10, 0.5, 3, true); Vour* top; top = new Vour("top"); top->clk(clk); while (!Verilated::gotFinish()) { sc_start(1, SC_NS); } delete top; exit(0); } EOF See the README in the source kit for various ways to install or point to Verilator binaries. In brief, if you are running Verilator that came from your operating system (as an RPM), or did a "make install" to place Verilator into your default path, you do not need anything special in your environment, and should not have VERILATOR_ROOT set. However, if you installed Verilator from sources and want to run Verilator out of where you compiled Verilator, you need to point to the kit: # See above; don't do this if using an OS-distributed Verilator export VERILATOR_ROOT=/path/to/where/verilator/was/installed export PATH=$VERILATOR_ROOT/bin:$PATH Now we run Verilator on our little example. verilator -Wall --sc our.v We then can compile it cd obj_dir make -j -f Vour.mk Vour__ALL.a make -j -f Vour.mk ../sc_main.o verilated.o And link with SystemC. Note your path to the libraries may vary, depending on the operating system. export SYSTEMC_LIBDIR=/path/to/where/libsystemc.a/exists export LD_LIBRARY_PATH=$SYSTEMC_LIBDIR:$LD_LIBRARY_PATH # Might be needed if SystemC 2.3.0 export SYSTEMC_CXX_FLAGS=-pthread g++ -L$SYSTEMC_LIBDIR ../sc_main.o Vour__ALL*.o verilated.o \ -o Vour -lsystemc And now we run it cd .. obj_dir/Vour And we get the same output as the C++ example: Hello World - our.v:2: Verilog $finish Really, you're better off using a Makefile to do all this for you. Then, when your source changes it will automatically run all of these steps. See the examples directory in the distribution. =head1 BENCHMARKING & OPTIMIZATION For best performance, run Verilator with the "-O3 --x-assign=fast --x-initial=fast --noassert" flags. The -O3 flag will require longer compile times, and --x-assign=fast --x-initial=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 -fno-stack-protector" -f Vour.mk Vour__ALL.a OPT_FAST specifies optimizations for those programs that are part of the fast path, mostly code that is executed every cycle. OPT_SLOW specifies optimizations for slow-path files (plus tracing), which execute only rarely, yet take a long time to compile with optimization on. OPT specifies overall optimization and affects all compiles, including those OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2", and link with "-static". Nearly the same results can be had with much better compile times with OPT_FAST="-O1 -fstrict-aliasing". Higher optimization such as "-O3" may help, but gcc compile times may be excessive under O3 on even medium sized designs. Alternatively, some larger designs report better performance using "-Os". Unfortunately, using the optimizer with SystemC files can result in compiles taking several minutes. (The SystemC libraries have many little inlined functions that drive the compiler nuts.) For best results, use GCC 3.3 or newer. GCC 3.2 and earlier have optimization bugs around pointer aliasing detection, which can result in 2x performance losses. If you will be running many simulations on a single compile, investigate feedback driven compilation. With GCC, using -fprofile-arcs, then -fbranch-probabilities will yield another 15% or so. Modern compilers also support link-time optimization (LTO), which can help especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in both compilation and link. Note LTO may cause excessive compile times on large designs. If you are using your own makefiles, you may want to compile the Verilated code with -DVL_INLINE_OPT=inline. This will inline functions, however this requires that all cpp files be compiled in a single compiler run. You may uncover further tuning possibilities by profiling the Verilog code. Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run either oprofile or gprof to see where in the C++ code the time is spent. Run the gprof output through verilator_profcfunc and it will tell you what Verilog line numbers on which most of the time is being spent. When done, please let the author know the results. I like to keep tabs on how Verilator compares, and may be able to suggest additional improvements. =head1 FILES All output files are placed in the output directory name specified with the -Mdir option, or "obj_dir" if not specified. Verilator creates the following files in the output directory: {prefix}.mk // Make include file for compiling {prefix}_classes.mk // Make include file with class names For -cc and -sc mode, it also creates: {prefix}.cpp // Top level C++ file {prefix}.h // Top level header {prefix}{each_verilog_module}.cpp // Lower level internal C++ files {prefix}{each_verilog_module}.h // Lower level internal header files In certain optimization modes, it also creates: {prefix}__Dpi.h // DPI import and export declarations {prefix}__Inlines.h // Inline support functions {prefix}__Slow.cpp // Constructors and infrequent routines {prefix}__Syms.cpp // Global symbol table C++ {prefix}__Syms.h // Global symbol table header {prefix}__Trace.cpp // Wave file generation code (--trace) {prefix}__cdc.txt // Clock Domain Crossing checks (--cdc) {prefix}__stats.txt // Statistics (--stats) It also creates internal files that can be mostly ignored: {each_verilog_module}.vpp // Post-processed verilog (--debug) {prefix}.flags_vbin // Verilator dependencies {prefix}.flags_vpp // Pre-processor dependencies {prefix}__verFiles.dat // Timestamps for skip-identical {prefix}{misc}.d // Make dependencies (-MMD) {prefix}{misc}.dot // Debugging graph files (--debug) {prefix}{misc}.tree // Debugging files (--debug) After running Make, the C++ compiler should produce the following: {prefix} // Final executable (w/--exe argument) {prefix}__ALL.a // Library of all Verilated objects {prefix}{misc}.o // Intermediate objects =head1 ENVIRONMENT =over 4 =item LD_LIBRARY_PATH A generic Linux/OS variable specifying what directories have shared object (.so) files. This path should include SystemC and any other shared objects needed at runtime. =item OBJCACHE Optionally specifies a caching or distribution program to place in front of all runs of the C++ Compiler. For example, "objcache --read --write", or "ccache". If using distcc, it would generally be run under either objcache or ccache; see the documentation for those programs. =item SYSTEMC Deprecated. Used only if SYSTEMC_INCLUDE or SYSTEMC_LIBDIR is not set. If set, specifies the directory containing the SystemC distribution. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). =item SYSTEMC_ARCH Deprecated. Used only if SYSTEMC_LIBDIR is not set. Specifies the architecture name used by the SystemC kit. This is the part after the dash in the lib-{...} directory name created by a 'make' in the SystemC distribution. If not set, Verilator will try to intuit the proper setting, or use the default optionally specified at configure time (before Verilator was compiled). =item SYSTEMC_CXX_FLAGS Specifies additional flags that are required to be passed to GCC when building the SystemC model. System 2.3.0 may need this set to "-pthread". =item SYSTEMC_INCLUDE If set, specifies the directory containing the systemc.h header file. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/include. =item SYSTEMC_LIBDIR If set, specifies the directory containing the libsystemc.a library. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/lib-SYSTEMC_ARCH. =item VCS_HOME If set, specifies the directory containing the Synopsys VCS distribution. When set, a 'make test' in the Verilator distribution will also run VCS baseline regression tests. =item VERILATOR_BIN If set, specifies an alternative name of the Verilator binary. May be used for debugging and selecting between multiple operating system builds. =item VERILATOR_GDB If set, the command to run when using the --gdb option, such as "ddd". If not specified, it will use "gdb". =item VERILATOR_ROOT Specifies the directory containing the distribution kit. This is used to find the executable, Perl library, and include files. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). It should not be specified if using a pre-compiled Verilator RPM as the hardcoded value should be correct. =back =head1 CONNECTING TO C++ Verilator creates a .h and .cpp file for the top level module and all modules under it. See the examples directory in the kit for examples. 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 // Need std::cout #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. VPI is enabled with the verilator --vpi switch. 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 (i.e. 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 its 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. For signal callbacks to work the main loop of the program must call VerilatedVpi::callValueCbs(). =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. cat <our.v module our (input clk); reg readme /*verilator public_flat_rd*/; reg writeme /*verilator public_flat_rw @(posedge clk) */; initial $finish; endmodule EOF There are many online tutorials and books on the VPI, but an example that accesses the above signal "readme" would be: cat <sim_main.cpp #include "Vour.h" #include "verilated.h" #include "verilated_vpi.h" // Required to get definitions vluint64_t main_time = 0; // See comments in first example double sc_time_stamp () { return main_time; } void read_and_check() { vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"TOP.our.readme", NULL); if (!vh1) { vl_fatal(__FILE__, __LINE__, "sim_main", "No handle found"); } const char* name = vpi_get_str(vpiName, vh1); printf("Module name: %s\n", name); // 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" } int main(int argc, char** argv, char** env) { Verilated::commandArgs(argc, argv); Vour* top = new Vour; Verilated::internalsDump(); // See scopes to help debug while (!Verilated::gotFinish()) { top->eval(); VerilatedVpi::callValueCbs(); // For signal callbacks read_and_check(); } delete top; exit(0); } EOF =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_on [-file "" [-lines [ - ]]] =item coverage_off [-file "" [-lines [ - ]]] Enable/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_on [-msg ] [-file "" [-lines [ - ]]] =item lint_off [-msg ] [-file "" [-lines [ - ]]] Enable/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). With lint_off using '*' will override any lint_on directives in the source, i.e. the warning will still not be printed. If the -msg is omitted, all lint warnings (see list in -Wno-lint) are enabled/disabled. This will override all later lint warning enables for the specified region. =item tracing_on [-file "" [-lines [ - ]]] =item tracing_off [-file "" [-lines [ - ]]] Enable/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). For tracing_off, cells below any module in the files/ranges specified will also not be traced. =back =head1 LANGUAGE STANDARD SUPPORT =head2 Verilog 2001 (IEEE 1364-2001) Support Verilator supports most Verilog 2001 language features. This includes signed numbers, "always @*", generate statements, multidimensional arrays, localparam, and C-style declarations inside port lists. =head2 Verilog 2005 (IEEE 1364-2005) Support Verilator supports most Verilog 2005 language features. This includes the `begin_keywords and `end_keywords compiler directives, $clog2, and the uwire keyword. =head2 SystemVerilog 2005 (IEEE 1800-2005) Support Verilator supports ==? and !=? operators, ++ and -- in some contexts, $bits, $countones, $error, $fatal, $info, $isunknown, $onehot, $onehot0, $unit, $warning, always_comb, always_ff, always_latch, bit, byte, chandle, const, do-while, enum, export, final, import, int, interface, logic, longint, modport, package, program, shortint, struct, time, typedef, union, var, void, priority case/if, and unique case/if. It also supports .name and .* interconnection. Verilator partially supports concurrent assert and cover statements; see the enclosed coverage tests for the syntax which is allowed. =head2 SystemVerilog 2012 (IEEE 1800-2012) Support Verilator implements a full SystemVerilog 2012 preprocessor, including function call-like preprocessor defines, default define arguments, `__FILE__, `__LINE__ and `undefineall. Verilator currently has some support for SystemVerilog synthesis constructs. As SystemVerilog features enter common usage they are added; please file a bug if a feature you need is missing. =head2 Verilog AMS Support Verilator implements a very small subset of Verilog AMS (Verilog Analog and Mixed-Signal Extensions) with the subset corresponding to those VMS keywords with near equivalents in the Verilog 2005 or SystemVerilog 2009 languages. AMS parsing is enabled with "--language VAMS" or "--language 1800+VAMS". At present Verilator implements ceil, exp, floor, ln, log, pow, sqrt, string, and wreal. =head2 Synthesis Directive Assertion Support With the --assert switch, Verilator reads any "//synopsys full_case" or "//synopsys parallel_case" directives. The same applies to any "//ambit synthesis", "//cadence" or "//pragma" directives of the same form. When these synthesis directives are discovered, Verilator will either formally prove the directive to be true, or failing that, will insert the appropriate code to detect failing cases at runtime and print an "Assertion failed" error message. Verilator likewise also asserts any "unique" or "priority" SystemVerilog keywords on case statement, as well as "unique" on if statements. However, "priority if" is currently simply ignored. =head1 LANGUAGE EXTENSIONS The following additional constructs are the extensions Verilator supports on top of standard Verilog code. Using these features outside of comments or `ifdef's may break other tools. =over 4 =item `__FILE__ The __FILE__ define expands to the current filename as a string, like C++'s __FILE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!) =item `__LINE__ The __LINE__ define expands to the current filename as a string, like C++'s __LINE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!) =item `error I This will report an error when encountered, like C++'s #error. =item $c(I, ...); The string will be embedded directly in the output C++ code at the point where the surrounding Verilog code is compiled. It may either be a standalone statement (with a trailing ; in the string), or a function that returns up to a 32-bit number (without a trailing ;). This can be used to call C++ functions from your Verilog code. String arguments will be put directly into the output C++ code. Expression arguments will have the code to evaluate the expression inserted. Thus to call a C++ function, $c("func(",a,")") will result in 'func(a)' in the output C++ code. For input arguments, rather than hard-coding variable names in the string $c("func(a)"), instead pass the variable as an expression $c("func(",a,")"). This will allow the call to work inside Verilog functions where the variable is flattened out, and also enable other optimizations. If you will be reading or writing any Verilog variables inside the C++ functions, the Verilog signals must be declared with /*verilator public*/. You may also append an arbitrary number to $c, generally the width of the output. [signal_32_bits = $c32("...");] This allows for compatibility with other simulators which require a differently named PLI function name for each different output width. =item $display, $write, $fdisplay, $fwrite, $sformat, $swrite Format arguments may use C fprintf sizes after the % escape. Per the Verilog standard, %x prints a number with the natural width, and %0x prints a number with minimum width. Verilator extends this so %5x prints 5 digits per the C standard (it's unspecified in Verilog). =item `coverage_block_off Specifies the entire begin/end block should be ignored for coverage analysis. Must be inside a basic block, e.g. within a begin/end pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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 was specified. =item /*verilator clock_enable*/ Used after a signal declaration to indicate the signal is used to gate a clock, and the user takes responsibility for insuring there are no races related to it. (Typically by adding a latch, and running static timing analysis.) For example: reg enable_r /*verilator clock_enable*/; wire gated_clk = clk & enable_r; always_ff @ (posedge clk) enable_r <= enable_early; The clock_enable attribute will cause the clock gate to be ignored in the scheduling algorithm, sometimes required for correct clock behavior, and always improving performance. It's also a good idea to enable the IMPERFECTSCH warning, to insure all clock enables are properly recognized. =item /*verilator clocker*/ =item /*verilator no_clocker*/ Used after a signal declaration to indicate the signal is used as clock or not. This information is used by Verilator to mark the signal as clocker and propagate the clocker attribute automatically to derived signals. See C<--clk> for more information. =item /*verilator coverage_block_off*/ Specifies the entire begin/end block should be ignored for coverage analysis purposes. =item /*verilator coverage_off*/ Specifies that following lines of code should have coverage disabled. Often used to ignore an entire module for coverage analysis purposes. =item /*verilator coverage_on*/ Specifies that following lines of code should have coverage re-enabled (if appropriate --coverage flags are passed) after being disabled earlier with /*verilator coverage_off*/. =item /*verilator inline_module*/ Specifies the module the comment appears in may be inlined into any modules that use this module. This is useful to speed up simulation time with some small loss of trace visibility and modularity. Note signals under inlined submodules will be named I__DOT__I as C++ does not allow "." in signal names. When tracing such signals the tracing routines will replace the __DOT__ with the period. =item /*verilator isolate_assignments*/ Used after a signal declaration to indicate the assignments to this signal in any blocks should be isolated into new blocks. When there is a large combinatorial block that is resulting in a UNOPTFLAT warning, attaching this to the signal causing a false loop may clear up the problem. IE, with the following reg splitme /* verilator isolate_assignments*/; // Note the placement of the semicolon above always @* begin if (....) begin splitme = ....; other assignments end end Verilator will internally split the block that assigns to "splitme" into two blocks: It would then internally break it into (sort of): // All assignments excluding those to splitme always @* begin if (....) begin other assignments end end // All assignments to splitme always @* begin if (....) begin splitme = ....; end end =item /*verilator lint_off I*/ Disable the specified warning message for any warnings following the comment. =item /*verilator lint_on I*/ Re-enable the specified warning message for any warnings following the comment. =item /*verilator lint_restore*/ After a /*verilator lint_save*/, pop the stack containing lint message state. Often this is useful at the bottom of include files. =item /*verilator lint_save*/ Push the current state of what lint messages are turned on or turned off to a stack. Later meta-comments may then lint_on or lint_off specific messages, then return to the earlier message state by using /*verilator lint_restore*/. For example: // verilator lint_save // verilator lint_off SOME_WARNING ... // code needing SOME_WARNING turned off // verilator lint_restore If SOME_WARNING was on before the lint_off, it will now be restored to on, and if it was off before the lint_off it will remain off. =item /*verilator no_inline_module*/ Specifies the module the comment appears in should not be inlined into any modules that use this module. This is useful especially at the top level module to reduce the size of the interface class, to aid compile time at a small performance loss. =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*/ (parameter) Used after a parameter declaration to indicate the emitted C code should have the parameter values visible. Due to C++ language restrictions, this may only be used on 64-bit or narrower integral enumerations. parameter [2:0] PARAM /*verilator public*/ = 2'b0; =item /*verilator public*/ (typedef enum) Used after an enum typedef declaration to indicate the emitted C code should have the enum values visible. Due to C++ language restrictions, this may only be used on 64-bit or narrower integral enumerations. typedef enum logic [2:0] { ZERO = 3'b0 } pub_t /*verilator public*/; =item /*verilator public*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will also declare this module public, otherwise use /*verilator public_flat*/. Instead of using public variables, consider instead making a DPI or public function that accesses the variable. This is nicer as it provides an obvious entry point that is also compatible across simulators. =item /*verilator public*/ (task/function) Used inside the declaration section of a function or task declaration to indicate the function or task should be made into a C++ function, public to outside callers. Public tasks will be declared as a void C++ function, public functions will get the appropriate non-void (bool, uint32_t, etc) return type. Any input arguments will become C++ arguments to the function. Any output arguments will become C++ reference arguments. Any local registers/integers will become function automatic variables on the stack. Wide variables over 64 bits cannot be function returns, to avoid exposing complexities. However, wide variables can be input/outputs; they will be passed as references to an array of 32-bit numbers. Generally, only the values of stored state (flops) should be written, as the model will NOT notice changes made to variables in these functions. (Same as when a signal is declared public.) You may want to use DPI exports instead, as it's compatible with other simulators. =item /*verilator public_flat*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will not declare this module public, which means the name of the signal or path to it may change based upon the module inlining which takes place. =item /*verilator public_flat_rd*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat (see above), but read-only. =item /*verilator public_flat_rw @() */ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat_rd (see above), and also writable, where writes should be considered to have the timing specified by the given sensitivity edge list. =item /*verilator public_module*/ Used after a module statement to indicate the module should not be inlined (unless specifically requested) so that C code may access the module. Verilator automatically sets this attribute when the module contains any public signals or `systemc_ directives. Also set for all modules when using the --public switch. =item /*verilator sc_clock*/ Rarely needed. Used after an input declaration to indicate the signal should be declared in SystemC as a sc_clock instead of a bool. This was needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require clock pins to be sc_clocks and this is no longer needed. =item /*verilator sc_bv*/ Used after a port declaration. It sets the port to be of sc_bv> type, instead of bool, vluint32_t or vluint64_t. This may be useful if the port width is parametrized and different of such modules interface a templated module (such as a transactor) or for other reasons. In general you should avoid using this attribute when not necessary as with increasing usage of sc_bv the performance increases significantly. =item /*verilator sformat*/ Attached to the final input of a function or task "input string" to indicate the function or task should pass all remaining arguments through $sformatf. This allows creation of DPI functions with $display like behavior. See the test_regress/t/t_dpi_display.v file for an example. =item /*verilator tag */ Attached after a variable or structure member to indicate opaque (to Verilator) text that should be passed through to the XML output as a tag, for use by downstream applications. =item /*verilator tracing_off*/ Disable waveform tracing for all future signals that are declared in this module, or cells below this module. Often this is placed just after a primitive's module statement, so that the entire module and cells below it are not traced. =item /*verilator tracing_on*/ Re-enable waveform tracing for all future signals or cells that are declared. =back =head1 LANGUAGE LIMITATIONS There are some limitations and lack of features relative to a commercial simulator, by intent. User beware. It is strongly recommended you use a lint tool before running this program. Verilator isn't designed to easily uncover common mistakes that a lint program will find for you. =head2 Synthesis Subset Verilator supports only the Synthesis subset with a few minor additions such as $stop, $finish and $display. That is, you cannot use hierarchical references, events or similar features of the Verilog language. It also simulates as Synopsys's Design Compiler would; namely a block of the form: always @ (x) y = x & z; This will recompute y when there is even a potential for change in x or a change in z, that is when the flops computing x or z evaluate (which is what Design Compiler will synthesize.) A compliant simulator would only calculate y if x changes. Use Verilog-Mode's /*AS*/ or Verilog 2001's always @* to reduce missing activity items. Avoid putting $displays in combo blocks, as they may print multiple times when not desired, even on compliant simulators as event ordering is not specified. =head2 Signal Naming To avoid conflicts with C symbol naming, any character in a signal name that is not alphanumeric nor a single underscore will be replaced by __0hh where hh is the hex code of the character. To avoid conflicts with Verilator's internal symbols, any double underscore are replaced with ___05F (5F is the hex code of an underscore.) =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, depending on --x-initial setting, are typically 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 (since typically control signals are active-high). --x-assign applies to variables explicitly initialized or assigned to X. Uninitialized clocks are initialized to zero, while all other state holding variables are initialized to a random value. Event driven simulators will generally trigger an edge on a transition from X to 1 (C) or X to 0 (C). However, by default, since clocks are initialized to zero, Verilator will not trigger an initial negedge. Some code (particularly for reset) may rely on X->0 triggering an edge. The --x-initial-edge switch enables 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 buses [0:15] are not supported as they aren't easily made compatible with C++. =head2 Gate Primitives The 2-state gate primitives (and, buf, nand, nor, not, or, xnor, xor) are directly converted to behavioral equivalents. The 3-state and MOS gate primitives are not supported. Tables are not supported. =head2 Specify blocks All specify blocks and timing checks are ignored. =head2 Array Initialization When initializing a large array, you need to use non-delayed assignments. Verilator will tell you when this needs to be fixed; see the BLKLOOPINIT error for more information. =head2 Array Out of Bounds Writing a memory element that is outside the bounds specified for the array may cause a different memory element inside the array to be written instead. For power-of-2 sized arrays, Verilator will give a width warning and the address. For non-power-of-2-sizes arrays, index 0 will be written. Reading a memory element that is outside the bounds specified for the array will give a width warning and wrap around the power-of-2 size. For non-power-of-2 sizes, it will return a unspecified constant of the appropriate width. =head2 Assertions Verilator is beginning to add support for assertions. Verilator currently only converts assertions to simple "if (...) error" statements, and coverage statements to increment the line counters described in the coverage section. Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. (Arguably SEREs are much of the point, but one must start somewhere.) =head2 Language Keyword Limitations This section describes specific limitations for each language keyword. =over 4 =item `__FILE__, `__LINE__, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `define, `else, `elsif, `end_keywords, `endif, `error, `ifdef, `ifndef, `include, `line, `systemc_ctor, `systemc_dtor, `systemc_header, `systemc_imp_header, `systemc_implementation, `systemc_interface, `timescale, `undef, `verilog Fully supported. =item always, always_comb, always_ff, always_latch, and, assign, begin, buf, byte, case, casex, casez, default, defparam, do-while, else, end, endcase, endfunction, endgenerate, endmodule, endspecify, endtask, final, for, function, generate, genvar, if, initial, inout, input, int, integer, localparam, logic, longint, macromodule, module, nand, negedge, nor, not, or, output, parameter, posedge, reg, scalared, shortint, signed, supply0, supply1, task, time, tri, typedef, var, vectored, while, wire, xnor, xor Generally supported. =item ++, -- operators Increment/decrement can only be used as standalone statements or in for loops. They cannot be used as side effect operators inside more complicate expressions ("a = b++;"). =item '{} operator Assignment patterns with order based, default, constant integer (array) or member identifier (struct/union) keys are supported. Data type keys and keys which are computed from a constant expression are not supported. =item cast operator Casting is supported only between simple scalar types, signed and unsigned, not arrays nor structs. =item chandle Treated as a "longint"; does not yet warn about operations that are specified as illegal on chandles. =item disable Disable statements may be used only if the block being disabled is a block the disable statement itself is inside. This was commonly used to provide loop break and continue functionality before SystemVerilog added the break and continue keywords. =item inside Inside expressions may not include unpacked array traversal or $ as an upper bound. Case inside and case matches are also unsupported. =item interface Interfaces and modports, including with generated data types are supported. Generate blocks around modports are not supported, nor are virtual interfaces nor unnamed interfaces. =item priority if, unique if Priority and unique if's are treated as normal ifs and not asserted to be full nor unique. =item specify specparam All specify blocks and timing checks are ignored. =item string String is supported only to the point that they can be assigned, concatenated, compared, and passed to DPI imports. Standard method calls on strings are not supported. =item timeunit, timeprecision All timing control statements are ignored. =item uwire Verilator does not perform warning checking on uwires, it treats the uwire keyword as if it were the normal wire keyword. =item $bits, $countones, $error, $fatal, $finish, $info, $isunknown, $onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time, $unsigned, $warning. Generally supported. =item $display, $write, $fdisplay, $fwrite, $swrite $display and friends must have a constant format string as the first argument (as with C's printf). The rare usage which lists variables standalone without a format is not supported. =item $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc The sized display functions are rarely used and so not supported. Replace them with a $write with the appropriate format specifier. =item $finish, $stop The rarely used optional parameter to $finish and $stop is ignored. =item $fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fscanf, $fwrite File descriptors passed to the file PLI calls must be file descriptors, not MCDs, which includes the mode parameter to $fopen being mandatory. =item $fscanf, $sscanf Only integer formats are supported; %e, %f, %m, %r, %v, and %z are not supported. =item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal, $setup, $setuphold, $skew, $timeskew, $width All specify blocks and timing checks are ignored. =item $random $random does not support the optional argument to set the seed. Use the srand function in C to accomplish this, and note there is only one random number generator (not one per module). =item $readmemb, $readmemh Read memory commands should work properly. Note Verilator and the Verilog specification does not include support for readmem to multi-dimensional arrays. =item $test$plusargs, $value$plusargs Supported, but the instantiating C++/SystemC testbench must call Verilated::commandArgs(argc, argv); to register the command line before calling $test$plusargs or $value$plusargs. =item $timeformat Not supported as Verilator needs to determine all formatting at compile time. Generally you can just ifdef them out for no ill effect. Note also VL_TIME_MULTIPLER can be defined at compile time to move the decimal point when displaying all times, model wide. =back =head1 ERRORS AND WARNINGS Warnings may be disabled in three 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 Second, warnings may be disabled using a configuration file with a lint_off command. This is useful when a script is suppressing warnings and the Verilog source should not be changed. 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] = ... It is also possible to disable this error when one of the assignments is inside a public task. This is not illegal in SystemVerilog, but a violation of good coding practice. Verilator reports this as an error, because 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 BSSPACE Warns that a backslash is followed by a space then a newline. Likely the intent was to have a backslash directly followed by a newline (e.g. when making a `define) and there's accidentally whitespace at the end of the line. If the space is not accidental, suggest removing the backslash in the code as it serves no function. Ignoring this warning will only suppress the lint check, it will simulate correctly. =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 COLONPLUS Warns that a :+ is seen. Likely the intent was to use +: to select a range of bits. If the intent was a range that is explicitly positive, suggest adding a space, e.g. use ": +". Ignoring this warning will only suppress the lint check, it will simulate correctly. =item CDCRSTLOGIC With --cdc only, warns that asynchronous flop reset terms come from other than primary inputs or flopped outputs, creating the potential for reset glitches. =item CLKDATA Warns that clock signal is mixed used with/as data signal. The checking for this warning is enabled only if user has explicitly marked some signal as clocker using command line option or in-source meta comment (see C<--clk>). The warning can be disabled without affecting the simulation result. But it is recommended to check the warning as this may degrade the performance of the Verilated model. =item CMPCONST Warns that you are comparing a value in a way that will always be constant. For example "X > 1" will always be true when X is a single bit wide. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item COMBDLY Warns that you have a delayed assignment inside of a combinatorial block. Using delayed assignments in this way is considered bad form, and may lead to the simulator not matching synthesis. If this message is suppressed, Verilator, like synthesis, will convert this to a non-delayed assignment, which may result in logic races or other nasties. See L Ignoring this warning may make Verilator simulations differ from other simulators. =item DECLFILENAME Warns that a module or other declaration's name doesn't match the filename with path and extension stripped that it is declared in. The filename a modules/interfaces/programs is declared in should match the name of the module etc. so that -y directory searching will work. This warning is printed for only the first mismatching module in any given file, and -v library files are ignored. Disabled by default as this is a code style warning; it will simulate correctly. =item DEFPARAM Warns that the "defparam" statement was deprecated in Verilog 2001 and all designs should now be using the #(...) format to specify parameters. Disabled by default as this is a code style warning; it will simulate correctly. =item DETECTARRAY Error when Verilator tries to deal with a combinatorial loop that could not be flattened, and which involves a datatype which Verilator cannot handle, such as an unpacked struct or a large unpacked array. This typically ocurrs when -Wno-UNOPTFLAT has been used to override an UNOPTFLAT warning (see below). The solution is to break the loop, as described for UNOPTFLAT. =item ENDLABEL Warns that a label attached to a "end"-something statement does not match the label attached to the block start. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item GENCLK Warns that the specified signal is generated, but is also being used as a clock. Verilator needs to evaluate sequential logic multiple times in this situation. In somewhat contrived cases having any generated clock can reduce performance by almost a factor of two. For fastest results, generate ALL clocks outside in C++/SystemC and make them primary inputs to your Verilog model. (However once need to you have even one, don't sweat additional ones.) Ignoring this warning may make Verilator simulations differ from other simulators. =item IFDEPTH Warns that if/if else statements have exceeded the depth specified with --if-depth, as they are likely to result in slow priority encoders. Unique and priority if statements are ignored. Solutions include changing the code to a case statement, or a SystemVerilog 'unique if' or 'priority if'. Disabled by default as this is a code style warning; it will simulate correctly. =item IMPERFECTSCH Warns that the scheduling of the model is not absolutely perfect, and some manual code edits may result in faster performance. This warning defaults to off, is not part of -Wall, and must be turned on explicitly before the top module statement is processed. =item IMPLICIT Warns that a wire is being implicitly declared (it is a single bit wide output from a sub-module.) While legal in Verilog, implicit declarations only work for single bit wide signals (not buses), do not allow using a signal before it is implicitly declared by a cell, and can lead to dangling nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for Emacs, available from L Ignoring this warning will only suppress the lint check, it will simulate correctly. =item IMPURE Warns that a task or function that has been marked with /*verilator no_inline_task*/ references variables that are not local to the task. Verilator cannot schedule these variables correctly. Ignoring this warning may make Verilator simulations differ from other simulators. =item INCABSPATH Warns that an `include filename specifies an absolute path. This means the code will not work on any other system with a different file system layout. Instead of using absolute paths, relative paths (preferably without any directory specified whatever) should be used, and +incdir used on the command line to specify the top include source directories. Disabled by default as this is a code style warning; it will simulate correctly. =item INITIALDLY Warns that you have a delayed assignment inside of an initial or final block. If this message is suppressed, Verilator will convert this to a non-delayed assignment. See also the COMBDLY warning. Ignoring this warning may make Verilator simulations differ from other simulators. =item LITENDIAN Warns that a packed vector is declared with little endian bit numbering (i.e. [0:7]). Big endian bit numbering is now the overwhelming standard, and little numbering is now thus often due to simple oversight instead of intent. Also warns that a cell is declared with little endian range (i.e. [0:7] or [7]) and is connected to a N-wide signal. Based on IEEE the bits will likely be backwards from what you expect (i.e. cell [0] will connect to signal bit [N-1] not bit [0]). Ignoring this warning will only suppress the lint check, it will simulate correctly. =item MODDUP Error that a module has multiple definitions. Generally this indicates a coding error, or a mistake in a library file and it's good practice to have one module per file to avoid these issues. For some gate level netlists duplicates are unavoidable, and this error may be disabled. =item MULTIDRIVEN Warns that the specified signal comes from multiple always blocks. This is often unsupported by synthesis tools, and is considered bad style. It will also cause longer runtimes due to reduced optimizations. Ignoring this warning will only slow simulations, it will simulate correctly. =item MULTITOP Error that there are multiple top level modules, that is modules not instantiated by any other module. Verilator only supports a single top level, if you need more, create a module that wraps all of the top modules. Often this error is because some low level cell is being read in, but is not really needed. The best solution is to insure that each module is in a unique file by the same name. Otherwise, make sure all library files are read in as libraries with -v, instead of automatically with -y. =item PINCONNECTEMPTY Warns that a cell instantiation has a pin which is connected to .pin_name(), e.g. not another signal, but with an explicit mention of the pin. It may be desirable to disable PINCONNECTEMPTY, as this indicates intention to have a no-connect. Disabled by default as this is a code style warning; it will simulate correctly. =item PINMISSING Warns that a module has a pin which is not mentioned in a cell instantiation. If a pin is not missing it should still be specified on the cell declaration with a empty connection, using "(.pin_name())". Ignoring this warning will only suppress the lint check, it will simulate correctly. =item PINNOCONNECT Warns that a cell instantiation has a pin which is not connected to another signal. Disabled by default as this is a code style warning; it will simulate correctly. =item REALCVT Warns that a real number is being implicitly rounded to an integer, with possible loss of precision. =item REDEFMACRO Warns that you have redefined the same macro with a different value, for example: `define MACRO def1 //... `define MACRO otherdef The best solution is to use a different name for the second macro. If this is not possible, add a undef to indicate the code is overriding the value: `define MACRO def1 //... `undef MACRO `define MACRO otherdef =item SELRANGE Warns that a selection index will go out of bounds: wire vec[6:0]; initial out = vec[7]; // There is no 7 Verilator will assume zero for this value, instead of X. Note that in some cases this warning may be false, when a condition upstream or downstream of the access means the access out of bounds will never execute or be used. wire vec[6:0]; initial begin seven = 7; ... if (seven != 7) out = vec[seven]; // Never will use vec[7] =item STMTDLY Warns that you have a statement with a delayed time in front of it, for example: #100 $finish; Ignoring this warning may make Verilator simulations differ from other simulators. =item SYMRSVDWORD Warning that a symbol matches a C++ reserved word and using this as a symbol name would result in odd C compiler errors. You may disable this warning, but the symbol will be renamed by Verilator to avoid the conflict. =item SYNCASYNCNET Warns that the specified net is used in at least two different always statements with posedge/negedges (i.e. a flop). One usage has the signal in the sensitivity list and body, probably as an async reset, and the other usage has the signal only in the body, probably as a sync reset. Mixing sync and async resets is usually a mistake. The warning may be disabled with a lint_off pragma around the net, or either flopped block. Disabled by default as this is a code style warning; it will simulate correctly. =item TASKNSVAR Error when a call to a task or function has a output from that task tied to a non-simple signal. Instead connect the task output to a temporary signal of the appropriate width, and use that signal to set the appropriate expression as the next statement. For example: task foo; output sig; ... endtask always @* begin foo(bus_we_select_from[2]); // Will get TASKNSVAR error end Change this to: reg foo_temp_out; always @* begin foo(foo_temp_out); bus_we_select_from[2] = foo_temp_out; end Verilator doesn't do this conversion for you, as some more complicated cases would result in simulator mismatches. =item UNDRIVEN Warns that the specified signal is never sourced. Verilator is fairly liberal in the usage calculations; making a signal public, or loading only a single array element marks the entire signal as driven. Disabled by default as this is a code style warning; it will simulate correctly. =item UNOPT Warns that due to some construct, optimization of the specified signal or block is disabled. The construct should be cleaned up to improve runtime. A less obvious case of this is when a module instantiates two submodules. Inside submodule A, signal I is input and signal O is output. Likewise in submodule B, signal O is an input and I is an output. A loop exists and a UNOPT warning will result if AI & AO both come from and go to combinatorial blocks in both submodules, even if they are unrelated always blocks. This affects performance because Verilator would have to evaluate each submodule multiple times to stabilize the signals crossing between the modules. Ignoring this warning will only slow simulations, it will simulate correctly. =item UNOPTFLAT Warns that due to some construct, optimization of the specified signal is disabled. The signal specified includes a complete scope to the signal; it may be only one particular usage of a multiply instantiated block. The construct should be cleaned up to improve runtime; two times better performance may be possible by fixing these warnings. Unlike the UNOPT warning, this occurs after netlist flattening, and indicates a more basic problem, as the less obvious case described under UNOPT does not apply. Often UNOPTFLAT is caused by logic that isn't truly circular as viewed by synthesis which analyzes interconnection per-bit, but is circular to simulation which analyzes per-bus: wire [2:0] x = {x[1:0],shift_in}; This statement needs to be evaluated multiple times, as a change in "shift_in" requires "x" to be computed 3 times before it becomes stable. This is because a change in "x" requires "x" itself to change value, which causes the warning. For significantly better performance, split this into 2 separate signals: wire [2:0] xout = {x[1:0],shift_in}; and change all receiving logic to instead receive "xout". Alternatively, change it to wire [2:0] x = {xin[1:0],shift_in}; and change all driving logic to instead drive "xin". With this change this assignment needs to be evaluated only once. These sort of changes may also speed up your traditional event driven simulator, as it will result in fewer events per cycle. The most complicated UNOPTFLAT path we've seen was due to low bits of a bus being generated from an always statement that consumed high bits of the same bus processed by another series of always blocks. The fix is the same; split it into two separate signals generated from each block. The UNOPTFLAT warning may also be due to clock enables, identified from the reported path going through a clock gating cell. To fix these, use the clock_enable meta comment described above. The UNOPTFLAT warning may also occur where outputs from a block of logic are independent, but occur in the same always block. To fix this, use the isolate_assignments meta comment described above. To assist in resolving UNOPTFLAT, the option C<--report-unoptflat> can be used, which will provide suggestions for variables that can be split up, and a graph of all the nodes connected in the loop. See the L section for more details. Ignoring this warning will only slow simulations, it will simulate correctly. =item UNPACKED Warns that unpacked structs and unions are not supported. Ignoring this warning will make Verilator treat the structure as packed, which may make Verilator simulations differ from other simulators. =item UNSIGNED Warns that you are comparing a unsigned value in a way that implies it is signed, for example "X < 0" will always be true when X is unsigned. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item UNUSED Warns that the specified signal is never sinked. Verilator is fairly liberal in the usage calculations; making a signal public, a signal matching --unused-regexp ("*unused*") or accessing only a single array element marks the entire signal as used. Disabled by default as this is a code style warning; it will simulate correctly. A recommended style for unused nets is to put at the bottom of a file code similar to the following: wire _unused_ok = &{1'b0, sig_not_used_a, sig_not_used_yet_b, // To be fixed 1'b0}; The reduction AND and constant zeros mean the net will always be zero, so won't use simulation time. The redundant leading and trailing zeros avoid syntax errors if there are no signals between them. The magic name "unused" (-unused-regexp) is recognized by Verilator and suppresses warnings; if using other lint tools, either teach to tool to ignore signals with "unused" in the name, or put the appropriate lint_off around the wire. Having unused signals in one place makes it easy to find what is unused, and reduces the number of lint_off pragmas, reducing bugs. =item USERINFO, USERWARN, USERERROR, USERFATAL A SystemVerilog elaboration-time assertion print was executed. =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 also compiles under Microsoft Visual C++ Version 7 or newer, but this is not tested every release. =item Can you provide binaries? Verilator is available as a RPM for Debian/Ubuntu, 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-commercial-simulator)? Generally, the implied part is of the question is "... with all of the manpower they can put into developing it." Most commercial simulators have to be Verilog compliant, meaning event driven. This prevents them from being able to reorder blocks and make netlist-style optimizations, which are where most of the gains come from. Non-compliance shouldn't be scary. Your synthesis program isn't compliant, so your simulator shouldn't have to be -- and Verilator is closer to the synthesis interpretation, so this is a good thing for getting working silicon. =item Will Verilator output remain under my own license? Yes, it's just like using GCC on your programs; this is why Verilator uses the "GNU *Lesser* Public License Version 3" instead of the more typical "GNU Public License". See the licenses for details, but in brief, if you change Verilator itself or the header files Verilator includes, you must make the source code available under the GNU Lesser Public License. However, Verilator output (the Verilated code) only "include"s the licensed files, and so you are NOT required to release any output from Verilator. You also have the option of using the Perl Artistic License, which again does not require you release your Verilog or generated code, and also allows you to modify Verilator for internal use without distributing the modified version. But please contribute back to the community! One limit is that you cannot under either license release a commercial Verilog simulation product incorporating Verilator without making the source code available. As is standard with Open Source, contributions back to Verilator will be placed under the Verilator copyright and LGPL/Artistic license. Small test cases will be released into the public domain so they can be used anywhere, and 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 generated 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, and very large commercial designs have topped 16GB. =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 examples/tracing_c/sim_main.cpp file of the distribution. You also need to compile verilated_vcd_c.cpp and add it to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag. Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file. #include "verilated_vcd_c.h" ... int main(int argc, char** argv, char** env) { ... Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd"); ... while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += #; tfp->dump (main_time); } tfp->close(); } =item How do I generate waveforms (traces) in SystemC? Add the --trace switch to Verilator, and in your top level C sc_main code, include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then create a VerilatedVcdSc object as you would create a normal SystemC trace file. For an example, see the call to VerilatedVcdSc in the examples/tracing_sc/sc_main.cpp file of the distribution, and below. Alternatively you may use the C++ trace mechanism described in the previous question, however the timescale and timeprecision will not inherited from your SystemC settings. You also need to compile verilated_vcd_sc.cpp and verilated_vcd_c.cpp and add them to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag. Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file. #include "verilated_vcd_sc.h" ... int main(int argc, char** argv, char** env) { ... Verilated::traceEverOn(true); VerilatedVcdSc* tfp = new VerilatedVcdSc; topp->trace (tfp, 99); tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd"); ... sc_start(1); ... tfp->close(); } =item How do I view waveforms (traces)? Verilator makes standard VCD (Value Change Dump) files. They are viewable with the public domain GtkWave (recommended) or Dinotrace (legacy) 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 solid-state disk, instead of to a network disk. Network disks are generally far slower. =item How do I do coverage analysis? Verilator supports both block (line) coverage and user inserted functional coverage. First, run verilator with the --coverage option. If you're using your own makefile, compile the model with the GCC flag -DVM_COVERAGE (if using Verilator's, it will do this for you.) At the end of your test, call VerilatedCov::write passing the name of the coverage data file (typically "logs/coverage.dat"). Run each of your tests in different directories. Each test will create a logs/coverage.dat file. After running all of your tests, verilator_coverage is executed. Verilator_coverage reads the logs/coverage.dat 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 examples/tracing_c/logs directory. Grep for lines starting with '%' to see what lines Verilator believes need more coverage. =item Where is the translate_off command? (How do I ignore a construct?) Translate on/off pragmas are generally a bad idea, as it's easy to have mismatched pairs, and you can't see what another tool sees by just preprocessing the code. Instead, use the preprocessor; Verilator defines the "VERILATOR" define for you, so just wrap the code in an ifndef region: `ifndef VERILATOR Something_Verilator_Dislikes; `endif Most synthesis tools similarly define SYNTHESIS for you. =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. If you use --exe, this is done for you. =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? Use a recent compiler. Newer compilers tend do be faster, with the now relatively old GCC 3.0 to 3.3 being horrible. Compile in parallel on many machines and use caching; see 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. Also see the --output-split option. To reduce the compile time of classes that use a Verilated module (e.g. a top CPP file) you may wish to add /*verilator no_inline_module*/ to your top level module. This will decrease the amount of code in the model's Verilated class, improving compile times of any instantiating top level C++ code, at a relatively small cost of execution performance. =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->our->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 Verilator 3.000 by rewriting Verilator from scratch in C++. This added many optimizations, yielding about a 2-5x performance gain. In 2009, major SystemVerilog and DPI language support was added. Currently, various language features and performance enhancements are added as the need arises. Verilator is now about 3x faster than in 2002, and is faster than many popular commercial simulators. =head1 AUTHORS When possible, please instead report bugs to L. Wilson Snyder Major concepts by Paul Wasson, Duane Galbi and Jie Xu. =head1 CONTRIBUTORS Many people have provided ideas and other assistance with Verilator. The major corporate sponsors of Verilator, by providing significant contributions of time or funds include include Atmel Corporation, Cavium Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc., and SiCortex Inc. The people who have contributed major functionality are Byron Bradley, Jeremy Bennett, Jie Xu, Lane Brooks, John Coiner, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers included Jeff Dutton, Jonathon Donaldson, Ralf Karge, David Hewson, Iztok Jeras, Wim Michiels, Alex Solomatnikov, Sebastien Van Cauwenberghe, Gene Weber, and Clifford Wolf. Some of the people who have provided ideas and feedback for Verilator include: Ahmed El-Mahmoudy, David Addison, Tariq B. Ahmad, Nikana Anastasiadis, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad Bagri, Andrew Bardsley, Matthew Barr, Geoff Barrett, Julius Baxter, Jeremy Bennett, Michael Berman, David Binderman, Johan Bjork, David Black, Daniel Bone, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Charlie Brej, J Briquet, Lane Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Ted Campbell, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Enzo Chi, Robert A. Clark, Allan Cochrane, John Coiner, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, John Demme, Mike Denio, John Deroo, Philip Derrick, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic, Jonathon Donaldson, Sebastian Dressler, Alex Duller, Jeff Dutton, Usuario Eda, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete, Fabrizio Ferrandi, Brian Flachs, Andrea Foletto, Bob Fredieu, Christian Gelinek, Glen Gibb, Shankar Giri, Dan Gisselquist, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Xuan Guo, Neil Hamilton, Jannis Harder, Junji Hashimoto, Thomas Hawkins, Robert Henry, David Hewson, Jamey Hicks, Hiroki Honda, Alex Hornung, David Horton, Jae Hossell, Alan Hunter, Jamie Iles, Ben Jackson, Shareef Jalloq, Krzysztof Jankowski, HyungKi Jeong, Iztok Jeras, James Johnson, Christophe Joly, Franck Jullien, Mike Kagen, Arthur Kahlich, Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Olof Kindgren, Sobhan Klnv, Gernot Koch, Soon Koh, Steve Kolecki, Brett Koonce, Wojciech Koszek, Varun Koyyalagunta, David Kravitz, Roland Kruse, Sergey Kvachonok, Ed Lander, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber, Igor Lesik, John Li, Eivind Liland, Charlie Lind, Andrew Ling, Paul Liu, Derek Lockhart, Arthur Low, Stefan Ludwig, Dan Lussier, Fred Ma, Duraid Madina, Mark Marshall, Alfonso Martinez, Yves Mathieu, Patrick Maupin, Jason McMullan, Elliot Mednick, Wim Michiels, Miodrag Milanovic, Wai Sum Mong, Sean Moore, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Bob Newgard, Cong Van Nguyen, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, James Pallister, Brad Parker, Maciej Piechotka, David Pierce, Dominic Plunkett, David Poole, Mike Popoloski, Rich Porter, Niranjan Prabhu, Usha Priyadharshini, Mark Jackson Pulver, Prateek Puri, Chris Randall, Anton Rapp, Odd Magne Reitan, Frederic Requin, Alberto Del Rio, Oleg Rodionov, Paul Rolfe, Jan Egil Ruud, John Sanguinetti, Galen Seitz, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Steven Slatter, Brian Small, Alex Solomatnikov, Wei Song, Art Stamness, John Stevenson, Rob Stoddard, Todd Strader, John Stroebel, Sven Stucki, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu Takatsukasa, Peter Tengstrand, Wesley Terpstra, Stefan Thiede, Gary Thomas, Kevin Thompson, Ian Thompson, Mike Thyer, Hans Tichelaar, Steve Tong, Michael Tresidder, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Thomas J Whatson, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston, Joshua Wise, Clifford Wolf, Johan Wouters, Ding Xiaoliang, Jie Xu, Mandy Xu, Luke Yang, and Amir Yazdanbakhsh. Thanks to them, and all those we've missed including above. =head1 DISTRIBUTION The latest version is available from L. Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. =head1 SEE ALSO L, L, L, L which is the source for this document, and internals.txt in the distribution. =cut ###################################################################### verilator-3.916/bin/verilator_includer0000775000177100017500000000130713205574202020113 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-2017 by Wilson Snyder. This package is free software; you can # redistribute it and/or modify it under the terms of either the GNU Lesser # General Public License Version 3 or the Perl Artistic License Version 2.0. ###################################################################### require 5.005; use warnings; print "// DESCR"."IPTION: Generated by verilator_includer via makefile\n"; foreach my $param (@ARGV) { if ($param =~ /^-D([^=]+)=(.*)/) { print "#define $1 $2\n" } else { print "#include \"$param\"\n" } } verilator-3.916/MANIFEST.SKIP0000664000177100017500000000104513205574202015416 0ustar wsnyderwsnyder^CVS/ /CVS/ \.git/ \.svn/ \.(bak|old)/ \.(bak|old)$ \.tar\. .*\.tgz .*\.log \..*\.swp .*\.tmp .*\.tex .*\.key .*\.vcd .*\.1 /obj_dir/ /obj_dbg/ /obj_opt/ /INCA_libs/ /cov_work/ /logs/ ^Makefile$ bin/verilator_bin.* bin/verilator_coverage_bin.* src/Makefile$ src/Makefile_obj$ include/verilated.mk$ test_regress/.gdbinit$ config.cache$ config.status$ verilator.log verilator.tex verilator.pc$ verilator_bin.* verilator_coverage_bin.* .vcsmx_rebuild$ autom4te\.cache/ nodist/ /simv$ /simv.daidir/ /vc_hdrs.h$ /csrc/ doxygen-doc/.* obj_dir/.* TAGS .*~ verilator-3.916/.gitignore0000664000177100017500000000043313205574202015510 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* gmon.out internals.txt verilator.txt verilator_bin* verilator_coverage_bin* verilator.pc **/obj_dir/* verilator-3.916/examples/0000775000177100017500000000000013206353162015337 5ustar wsnyderwsnyderverilator-3.916/examples/tracing_sc/0000775000177100017500000000000013206353162017453 5ustar wsnyderwsnyderverilator-3.916/examples/tracing_sc/sub.v0000664000177100017500000000300113205574202020424 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 sub ( input clk, input fastclk, input reset_l ); // Example counter/flop reg [31:0] count_f; always_ff @ (posedge fastclk) begin if (!reset_l) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops count_f <= 32'h0; // End of automatics end else begin count_f <= count_f + 1; end end // Another example flop reg [31:0] count_c; always_ff @ (posedge clk) begin if (!reset_l) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops count_c <= 32'h0; // End of automatics end else begin count_c <= count_c + 1; if (count_c >= 3) begin $display("[%0t] fastclk is %0d times faster than clk\n", $time, count_f/count_c); // This write is a magic value the Makefile uses to make sure the // test completes successfully. $write("*-* All Finished *-*\n"); $finish; end end end // An example assertion always_ff @ (posedge clk) begin AssertionExample: assert (!reset_l || count_c<100); end // And example coverage analysis cover property (@(posedge clk) count_c==3); endmodule verilator-3.916/examples/tracing_sc/.gitignore0000664000177100017500000000004413205574202021440 0ustar wsnyderwsnyder*.dmp *.log *.csrc *.vcd obj_* logs verilator-3.916/examples/tracing_sc/Makefile_obj0000664000177100017500000000420113205574202021741 0ustar wsnyderwsnyder# -*- Makefile -*- ####################################################################### # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/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: Vtop # Include the rules made by Verilator include Vtop.mk ####################################################################### # Compile flags # Override some default compile flags CPPFLAGS += -MMD -MP CPPFLAGS += -DVL_DEBUG=1 # SystemC isn't too clean CPPFLAGS += -Wno-deprecated # Turn on some more flags (when configured appropriately) # For testing inside Verilator, "configure --enable-ccwarn" will do this # automatically; otherwise you may want this unconditionally enabled ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users USER_CPPFLAGS_WALL += -W -Werror -Wall endif # If you build your own rules from scratch, note you need to include # SystemC as follows (Vtop.mk file includes verilated.mk with these # already). # CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE) # LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR) # See the benchmarking section of bin/verilator. # Support class optimizations. This includes the tracing and symbol table. # SystemC takes minutes to optimize, thus it is off by default. OPT_SLOW = # Fast path optimizations. Most time is spent in these classes. OPT_FAST = -O2 -fstrict-aliasing #OPT_FAST = -O #OPT_FAST = ####################################################################### # Linking final exe -- presumes have a sim_main.cpp # Special compile rule sim_main.o: sim_main.cpp $(VM_PREFIX).h ###################################################################### ###################################################################### # Automatically understand dependencies DEPS := $(wildcard *.d) ifneq ($(DEPS),) include $(DEPS) endif verilator-3.916/examples/tracing_sc/sc_main.cpp0000664000177100017500000000753713205574202021603 0ustar wsnyderwsnyder// -*- SystemC -*- // DESCRIPTION: Verilator Example: Top level main for invoking SystemC model // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. //====================================================================== // SystemC global header #include // Include common routines #include #if VM_TRACE #include #endif #include // mkdir // Include model header, generated from Verilating "top.v" #include "Vtop.h" int sc_main(int argc, char* argv[]) { // This is a more complicated example, please also see the simpler examples/hello_world_c. // Prevent unused variable warnings if (0 && argc && argv) {} // Pass arguments so Verilated code can see them, e.g. $value$plusargs Verilated::commandArgs(argc, argv); // Set debug level, 0 is off, 9 is highest presently used Verilated::debug(0); // Randomization reset policy Verilated::randReset(2); // General logfile ios::sync_with_stdio(); // Defaults time #if (SYSTEMC_VERSION>20011000) #else sc_time dut(1.0, sc_ns); sc_set_default_time_unit(dut); #endif // Define clocks #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 // Define interconnect sc_signal reset_l; sc_signal in_small; sc_signal in_quad; sc_signal > in_wide; sc_signal out_small; sc_signal out_quad; sc_signal > out_wide; // Construct the Verilated model, from inside Vtop.h Vtop* top = new Vtop("top"); // Attach signals to the model top->clk (clk); top->fastclk (fastclk); top->reset_l (reset_l); 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); #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. #if (SYSTEMC_VERSION>=20070314) sc_start(1,SC_NS); #else sc_start(1); #endif #if VM_TRACE // If verilator was invoked with --trace argument, // and if at run time passed the +trace argument, turn on tracing VerilatedVcdSc* tfp = NULL; const char* flag = Verilated::commandArgsPlusMatch("trace"); if (flag && 0==strcmp(flag, "+trace")) { cout << "Enabling waves into logs/vlt_dump.vcd...\n"; VerilatedVcdSc* tfp = new VerilatedVcdSc; top->trace (tfp, 99); mkdir("logs", 0777); tfp->open ("logs/vlt_dump.vcd"); } #endif // Simulate until $finish while (!Verilated::gotFinish()) { #if VM_TRACE // Flush the wave files each cycle so we can immediately see the output // Don't do this in "real" programs, do it in an abort() handler instead if (tfp) tfp->flush(); // Apply inputs if (VL_TIME_Q() > 1 && VL_TIME_Q() < 10) { reset_l = !1; // Assert reset } else if (VL_TIME_Q() > 1) { reset_l = !0; // Deassert reset } #endif // Simulate 1ns #if (SYSTEMC_VERSION>=20070314) sc_start(1,SC_NS); #else sc_start(1); #endif } // Close Waves #if VM_TRACE if (tfp) tfp->close(); #endif // Final model cleanup top->final(); // Coverage analysis (since test passed) #if VM_COVERAGE mkdir("logs", 0777); VerilatedCov::write("logs/coverage.dat"); #endif // Fin return 0; } verilator-3.916/examples/tracing_sc/input.vc0000664000177100017500000000020113205574202021134 0ustar wsnyderwsnyder// This file typically lists flags required by a large project, e.g. include directories +librescan +libext+.v+.sv+.vh+.svh -y . verilator-3.916/examples/tracing_sc/top.v0000664000177100017500000000243013205574202020442 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog example module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. // ====================================================================== // This is intended to be a complex example of several features, please also // see the simpler examples/hello_world_c. module top ( // Declare some signals so we can see how I/O works 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 ); // Connect up the outputs, using some trivial logic wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1); wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1); wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1); // And an example sub module. The submodule will print stuff. sub sub (/*AUTOINST*/ // Inputs .clk (clk), .fastclk (fastclk), .reset_l (reset_l)); // Print some stuff as an example initial begin $display("[%0t] Model running...\n", $time); end endmodule verilator-3.916/examples/tracing_sc/Makefile0000664000177100017500000000632513206347325021125 0ustar wsnyderwsnyder###################################################################### # # DESCRIPTION: Verilator Example: Small Makefile # # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # ###################################################################### # Check for sanity to avoid later confusion ifneq ($(words $(CURDIR)),1) $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') endif ###################################################################### # Set up variables # If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a # package inatall, and verilator is in your path. Otherwise find the # binary relative to $VERILATOR_ROOT (such as when inside the git sources). ifeq ($(VERILATOR_ROOT),) VERILATOR = verilator VERILATOR_COVERAGE = verilator_coverage else export VERILATOR_ROOT VERILATOR = $(VERILATOR_ROOT)/bin/verilator VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage endif VERILATOR_FLAGS = # Generate SystemC in executable form VERILATOR_FLAGS += -sc --exe # Generate makefile dependencies (not shown as complicates the Makefile) #VERILATOR_FLAGS += -MMD # Optimize VERILATOR_FLAGS += -O2 -x-assign 0 # Warn abount lint issues; may not want this on less solid designs VERILATOR_FLAGS += -Wall # Make waveforms VERILATOR_FLAGS += --trace # Check SystemVerilog assertions VERILATOR_FLAGS += --assert # Generate coverage analysis VERILATOR_FLAGS += --coverage # Run Verilator in debug mode #VERILATOR_FLAGS += --debug # Add this trace to get a backtrace in gdb #VERILATOR_FLAGS += --gdbbt # Check if SC exists via a verilator call (empty if not) SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) ###################################################################### ifneq ($(SYSTEMC_EXISTS),) default: run else default: nosc endif run: @echo @echo "-- Verilator tracing example" @echo @echo "-- VERILATE ----------------" $(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sc_main.cpp @echo @echo "-- COMPILE ----------------=" # To compile, we can either just do what Verilator asks, # or call a submakefile where we can override the rules ourselves # $(MAKE) -j 4 -C obj_dir -f Vtop.mk $(MAKE) -j 4 -C obj_dir -f ../Makefile_obj @echo @echo "-- RUN ---------------------" @mkdir -p logs obj_dir/Vtop +trace @echo @echo "-- COVERAGE ----------------" $(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat @echo @echo "-- DONE --------------------" @echo "To see waveforms, open vlt_dump.vcd in a waveform viewer" @echo ###################################################################### # Other targets nosc: @echo @echo "%Skip: SYSTEMC_INCLUDE not in environment" @echo "(If you have SystemC see the README, and rebuild Verilator)" @echo show-config: $(VERILATOR) -V maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core verilator-3.916/examples/tracing_c/0000775000177100017500000000000013206353162017270 5ustar wsnyderwsnyderverilator-3.916/examples/tracing_c/sub.v0000664000177100017500000000300113205574202020241 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 sub ( input clk, input fastclk, input reset_l ); // Example counter/flop reg [31:0] count_f; always_ff @ (posedge fastclk) begin if (!reset_l) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops count_f <= 32'h0; // End of automatics end else begin count_f <= count_f + 1; end end // Another example flop reg [31:0] count_c; always_ff @ (posedge clk) begin if (!reset_l) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops count_c <= 32'h0; // End of automatics end else begin count_c <= count_c + 1; if (count_c >= 3) begin $display("[%0t] fastclk is %0d times faster than clk\n", $time, count_f/count_c); // This write is a magic value the Makefile uses to make sure the // test completes successfully. $write("*-* All Finished *-*\n"); $finish; end end end // An example assertion always_ff @ (posedge clk) begin AssertionExample: assert (!reset_l || count_c<100); end // And example coverage analysis cover property (@(posedge clk) count_c==3); endmodule verilator-3.916/examples/tracing_c/.gitignore0000664000177100017500000000004413205574202021255 0ustar wsnyderwsnyder*.dmp *.log *.csrc *.vcd obj_* logs verilator-3.916/examples/tracing_c/Makefile_obj0000664000177100017500000000350613205574202021565 0ustar wsnyderwsnyder# -*- Makefile -*- ####################################################################### # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/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: Vtop # Include the rules made by Verilator include Vtop.mk ####################################################################### # Compile flags # Override some default compile flags CPPFLAGS += -MMD -MP CPPFLAGS += -DVL_DEBUG=1 # Turn on some more flags (when configured appropriately) # For testing inside Verilator, "configure --enable-ccwarn" will do this # automatically; otherwise you may want this unconditionally enabled ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users USER_CPPFLAGS_WALL += -W -Werror -Wall endif # See the benchmarking section of bin/verilator. # Support class optimizations. This includes the tracing and symbol table. # SystemC takes minutes to optimize, thus it is off by default. OPT_SLOW = # Fast path optimizations. Most time is spent in these classes. OPT_FAST = -O2 -fstrict-aliasing #OPT_FAST = -O #OPT_FAST = ####################################################################### # Linking final exe -- presumes have a sim_main.cpp # Special compile rule sim_main.o: sim_main.cpp $(VM_PREFIX).h ###################################################################### ###################################################################### # Automatically understand dependencies DEPS := $(wildcard *.d) ifneq ($(DEPS),) include $(DEPS) endif verilator-3.916/examples/tracing_c/input.vc0000664000177100017500000000020113205574202020751 0ustar wsnyderwsnyder// This file typically lists flags required by a large project, e.g. include directories +librescan +libext+.v+.sv+.vh+.svh -y . verilator-3.916/examples/tracing_c/top.v0000664000177100017500000000243013205574202020257 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog example module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. // ====================================================================== // This is intended to be a complex example of several features, please also // see the simpler examples/hello_world_c. module top ( // Declare some signals so we can see how I/O works 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 ); // Connect up the outputs, using some trivial logic wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1); wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1); wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1); // And an example sub module. The submodule will print stuff. sub sub (/*AUTOINST*/ // Inputs .clk (clk), .fastclk (fastclk), .reset_l (reset_l)); // Print some stuff as an example initial begin $display("[%0t] Model running...\n", $time); end endmodule verilator-3.916/examples/tracing_c/sim_main.cpp0000664000177100017500000000667213206347370021607 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog example module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. //====================================================================== // Include common routines #include #include // mkdir // Include model header, generated from Verilating "top.v" #include "Vtop.h" // If "verilator --trace" is used, include the tracing class #if VM_TRACE # include #endif // Current simulation time (64-bit unsigned) vluint64_t main_time = 0; // Called by $time in Verilog double sc_time_stamp () { return main_time; // Note does conversion to real, to match SystemC } int main(int argc, char** argv, char** env) { // This is a more complicated example, please also see the simpler examples/hello_world_c. // Prevent unused variable warnings if (0 && argc && argv && env) {} // Pass arguments so Verilated code can see them, e.g. $value$plusargs Verilated::commandArgs(argc, argv); // Set debug level, 0 is off, 9 is highest presently used Verilated::debug(0); // Randomization reset policy Verilated::randReset(2); // Construct the Verilated model, from Vtop.h generated from Verilating "top.v" Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper #if VM_TRACE // If verilator was invoked with --trace argument, // and if at run time passed the +trace argument, turn on tracing VerilatedVcdC* tfp = NULL; const char* flag = Verilated::commandArgsPlusMatch("trace"); if (flag && 0==strcmp(flag, "+trace")) { Verilated::traceEverOn(true); // Verilator must compute traced signals VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n"); tfp = new VerilatedVcdC; top->trace(tfp, 99); // Trace 99 levels of hierarchy mkdir("logs", 0777); tfp->open("logs/vlt_dump.vcd"); // Open the dump file } #endif // Set some inputs top->reset_l = !0; top->fastclk = 0; top->clk = 0; top->in_small = 1; top->in_quad = 0x1234; top->in_wide[0] = 0x11111111; top->in_wide[1] = 0x22222222; top->in_wide[2] = 0x3; // Simulate until $finish while (!Verilated::gotFinish()) { main_time++; // Time passes... // Toggle clocks and such top->fastclk = !top->fastclk; if ((main_time % 10) == 3) { top->clk = 1; } if ((main_time % 10) == 8) { top->clk = 0; } if (main_time > 1 && main_time < 10) { top->reset_l = !1; // Assert reset } else { top->reset_l = !0; // Deassert reset } // Assign some other inputs top->in_quad += 0x12; // Evaluate model top->eval(); // Read outputs VL_PRINTF ("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x" " -> oquad=%" VL_PRI64"x owide=%x_%08x_%08x\n", main_time, top->clk, top->reset_l, top->in_quad, top->out_quad, top->out_wide[2], top->out_wide[1], top->out_wide[0]); } // Final model cleanup top->final(); // Close trace if opened #if VM_TRACE if (tfp) { tfp->close(); } #endif // Coverage analysis (since test passed) #if VM_COVERAGE mkdir("logs", 0777); VerilatedCov::write("logs/coverage.dat"); #endif // Destroy model delete top; top = NULL; // Fin exit(0); } verilator-3.916/examples/tracing_c/Makefile0000664000177100017500000000562613206347312020741 0ustar wsnyderwsnyder###################################################################### # # DESCRIPTION: Verilator Example: Small Makefile # # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # ###################################################################### # Check for sanity to avoid later confusion ifneq ($(words $(CURDIR)),1) $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') endif ###################################################################### # Set up variables # If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a # package inatall, and verilator is in your path. Otherwise find the # binary relative to $VERILATOR_ROOT (such as when inside the git sources). ifeq ($(VERILATOR_ROOT),) VERILATOR = verilator VERILATOR_COVERAGE = verilator_coverage else export VERILATOR_ROOT VERILATOR = $(VERILATOR_ROOT)/bin/verilator VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage endif VERILATOR_FLAGS = # Generate C++ in executable form VERILATOR_FLAGS += -cc --exe # Generate makefile dependencies (not shown as complicates the Makefile) #VERILATOR_FLAGS += -MMD # Optimize VERILATOR_FLAGS += -O2 -x-assign 0 # Warn abount lint issues; may not want this on less solid designs VERILATOR_FLAGS += -Wall # Make waveforms VERILATOR_FLAGS += --trace # Check SystemVerilog assertions VERILATOR_FLAGS += --assert # Generate coverage analysis VERILATOR_FLAGS += --coverage # Run Verilator in debug mode #VERILATOR_FLAGS += --debug # Add this trace to get a backtrace in gdb #VERILATOR_FLAGS += --gdbbt ###################################################################### default: run run: @echo @echo "-- Verilator tracing example" @echo @echo "-- VERILATE ----------------" $(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sim_main.cpp @echo @echo "-- COMPILE -----------------" # To compile, we can either just do what Verilator asks, # or call a submakefile where we can override the rules ourselves # $(MAKE) -j 4 -C obj_dir -f Vtop.mk $(MAKE) -j 4 -C obj_dir -f ../Makefile_obj @echo @echo "-- RUN ---------------------" @mkdir -p logs obj_dir/Vtop +trace @echo @echo "-- COVERAGE ----------------" $(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat @echo @echo "-- DONE --------------------" @echo "To see waveforms, open vlt_dump.vcd in a waveform viewer" @echo ###################################################################### # Other targets show-config: $(VERILATOR) -V maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core verilator-3.916/examples/hello_world_sc/0000775000177100017500000000000013206353162020336 5ustar wsnyderwsnyderverilator-3.916/examples/hello_world_sc/.gitignore0000664000177100017500000000004413205574202022323 0ustar wsnyderwsnyder*.dmp *.log *.csrc *.vcd obj_* logs verilator-3.916/examples/hello_world_sc/sc_main.cpp0000664000177100017500000000241613205574202022455 0ustar wsnyderwsnyder// -*- SystemC -*- // DESCRIPTION: Verilator Example: Top level main for invoking SystemC model // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. //====================================================================== // SystemC global header #include // Include common routines #include // Include model header, generated from Verilating "top.v" #include "Vtop.h" int sc_main(int argc, char* argv[]) { // See a similar example walkthrough in the verilator manpage. // This is intended to be a minimal example. Before copying this to start a // real project, it is better to start with a more complete example, // e.g. examples/c_tracing. // Prevent unused variable warnings if (0 && argc && argv) {} // Construct the Verilated model, from Vtop.h generated from Verilating "top.v" Vtop* top = new Vtop("top"); // Initialize SC model #if (SYSTEMC_VERSION>=20070314) sc_start(1,SC_NS); #else sc_start(1); #endif // Simulate until $finish while (!Verilated::gotFinish()) { #if (SYSTEMC_VERSION>=20070314) sc_start(1,SC_NS); #else sc_start(1); #endif } // Final model cleanup top->final(); // Fin return 0; } verilator-3.916/examples/hello_world_sc/top.v0000664000177100017500000000050313205574202021324 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog example module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. // See also the EXAMPLE section in the verilator manpage/document. module top; initial begin $display("Hello World!"); $finish; end endmodule verilator-3.916/examples/hello_world_sc/Makefile0000664000177100017500000000440713205574202022002 0ustar wsnyderwsnyder###################################################################### # # DESCRIPTION: Verilator Example: Small Makefile # # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # ###################################################################### # Check for sanity to avoid later confusion ifneq ($(words $(CURDIR)),1) $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') endif ###################################################################### # This is intended to be a minimal example. Before copying this to start a # real project, it is better to start with a more complete example, # e.g. examples/tracing_sc. # If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a # package inatall, and verilator is in your path. Otherwise find the # binary relative to $VERILATOR_ROOT (such as when inside the git sources). ifeq ($(VERILATOR_ROOT),) VERILATOR = verilator else export VERILATOR_ROOT VERILATOR = $(VERILATOR_ROOT)/bin/verilator endif # Check if SC exists via a verilator call (empty if not) SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE) ifneq ($(SYSTEMC_EXISTS),) default: run else default: nosc endif run: @echo "-- Verilator hello-world simple example" @echo "-- VERILATE ----------------" $(VERILATOR) -sc --exe top.v sc_main.cpp @echo "-- COMPILE -----------------" $(MAKE) -j 4 -C obj_dir -f Vtop.mk @echo "-- RUN ---------------------" obj_dir/Vtop @echo "-- DONE --------------------" @echo "Note: Once this example is understood, see examples/tracing_sc." @echo "Note: Also see the EXAMPLE section in the verilator manpage/document." ###################################################################### nosc: @echo @echo "%Skip: SYSTEMC_INCLUDE not in environment" @echo "(If you have SystemC see the README, and rebuild Verilator)" @echo maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir *.log *.dmp *.vpd core verilator-3.916/examples/hello_world_c/0000775000177100017500000000000013206353162020153 5ustar wsnyderwsnyderverilator-3.916/examples/hello_world_c/.gitignore0000664000177100017500000000004413205574202022140 0ustar wsnyderwsnyder*.dmp *.log *.csrc *.vcd obj_* logs verilator-3.916/examples/hello_world_c/top.v0000664000177100017500000000050313205574202021141 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog example module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. // See also the EXAMPLE section in the verilator manpage/document. module top; initial begin $display("Hello World!"); $finish; end endmodule verilator-3.916/examples/hello_world_c/sim_main.cpp0000664000177100017500000000210013205574202022443 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog example module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. //====================================================================== // Include common routines #include // Include model header, generated from Verilating "top.v" #include "Vtop.h" int main(int argc, char** argv, char** env) { // See a similar example walkthrough in the verilator manpage. // This is intended to be a minimal example. Before copying this to start a // real project, it is better to start with a more complete example, // e.g. examples/c_tracing. // Prevent unused variable warnings if (0 && argc && argv && env) {} // Construct the Verilated model, from Vtop.h generated from Verilating "top.v" Vtop* top = new Vtop; // Simulate until $finish while (!Verilated::gotFinish()) { // Evaluate model top->eval(); } // Final model cleanup top->final(); // Destroy model delete top; // Fin exit(0); } verilator-3.916/examples/hello_world_c/Makefile0000664000177100017500000000370013205574202021612 0ustar wsnyderwsnyder###################################################################### # # DESCRIPTION: Verilator Example: Small Makefile # # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # ###################################################################### # Check for sanity to avoid later confusion ifneq ($(words $(CURDIR)),1) $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') endif ###################################################################### # This is intended to be a minimal example. Before copying this to start a # real project, it is better to start with a more complete example, # e.g. examples/tracing_c. # If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a # package inatall, and verilator is in your path. Otherwise find the # binary relative to $VERILATOR_ROOT (such as when inside the git sources). ifeq ($(VERILATOR_ROOT),) VERILATOR = verilator else export VERILATOR_ROOT VERILATOR = $(VERILATOR_ROOT)/bin/verilator endif default: @echo "-- Verilator hello-world simple example" @echo "-- VERILATE ----------------" $(VERILATOR) -cc --exe top.v sim_main.cpp @echo "-- COMPILE -----------------" $(MAKE) -j 4 -C obj_dir -f Vtop.mk @echo "-- RUN ---------------------" obj_dir/Vtop @echo "-- DONE --------------------" @echo "Note: Once this example is understood, see examples/tracing_c." @echo "Note: Also see the EXAMPLE section in the verilator manpage/document." ###################################################################### maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir *.log *.dmp *.vpd core verilator-3.916/COPYING.LESSER0000664000177100017500000001672512111011551015546 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.916/internals.html0000664000177100017500000010764413206353160016420 0ustar wsnyderwsnyder

NAME

Verilator Internals

INTRODUCTION

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

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

CODE FLOWS

Verilator Flow

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

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

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

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

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

Parameters are resolved and the design is elaborated.

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

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

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

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

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

Verilator finally writes the C++ modules.

Key Classes Used in the Verilator Flow

AstNode

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

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

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

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

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

AstNVisitor

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

V3Graph

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

V3GraphVertex

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

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

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

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

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

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

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

V3GraphAlg

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

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

Verilated Flow

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

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

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

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

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

CODING CONVENTIONS

Indentation style

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

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

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

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

The astgen script

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

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

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

Visitor Functions

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

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

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

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

  void visit (AstIf* nodep)
  void visit (AstNodeIf* nodep)
  void visit (AstNodeStmt* nodep)
  void visit (AstNode* nodep)

There are three ways data is passed between visitor functions.

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

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

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

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

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

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

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

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

Iterators

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

iterate()

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

iterateAndNextIgnoreEdit

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

iterateAndNext

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

iterateListBackwards

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

iterateChildren

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

iterateChildrenBackwards

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

Caution on Using Iterators When Child Changes

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

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

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

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

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

    lp = lp->acceptSubtreeReturnEdits()

Identifying derived classes

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

  void visit (AstNodeIf* nodep, AstNUser* vup)

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

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

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

TESTING

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

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

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

Preparing to Run Tests

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

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

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

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

Controlling the Test Driver

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

  test_regress/t/driver.pl --help

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

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

  top_filename("t/t_myothertest.v");

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

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

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

verilator_flags2

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

fails

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

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

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

Regression Testing for Developers

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

--enable-ccwarn

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

--enable-longtests

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

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

    cpan install Unix::Processors

There are some traps to avoid when running regression tests

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

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

        cpan install Pod::Perldoc

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

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

DEBUGGING

--debug

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

.dot output

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

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

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

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

.tree output

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

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

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

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

    "VAR" is the AstNodeType.

    "0x91a780" is the address of this node.

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

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

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

    "w32" indicates the width is 32 bits.

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

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

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

Tree Hierarchy

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

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

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

Address of the node

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

Last edit number

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

Source file and line

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

User pointers

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

Data type

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

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

s if the node is signed.

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

w always present, indicating this is the width field.

u if the node is unsized.

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

Name of the entity represented by the node if it exists

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

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

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

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

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

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

Debugging with GDB

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

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

  t/t_alw_dly.pl --debug

shows it invokes the command:

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

Start GDB, then start with the remaining arguments.

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

You can then continue execution with breakpoints as required.

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

   watch AstNode::s_editCntGbl==####

To print a node:

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

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

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

ADDING A NEW FEATURE

Generally what would you do to add a new feature?

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

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

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

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

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

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

Adding a new pass

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

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

DISTRIBUTION

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

Copyright 2008-2017 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.916/README.html0000664000177100017500000002044613206353157015356 0ustar wsnyderwsnyder

NAME

This is the Verilator package README file.

DISTRIBUTION

http://www.veripool.org/verilator

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

Verilator is free software; you can redistribute it and/or modify it under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. (See the documentation for more details.)

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

DESCRIPTION

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

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

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

The resulting executable will perform the actual simulation.

SUPPORTED SYSTEMS

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

INSTALLATION

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

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

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

    Download the latest package from that site, and decompress.

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

  • You will need the flex and bison packages installed.

  • cd to the Verilator directory containing this README.

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

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

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

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

          unset VERILATOR_ROOT      # if your shell is bash
          unsetenv VERILATOR_ROOT   # if your shell is csh
          # For the tarball, use the version number instead of git describe
          ./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"`
      
          After installing you'll want a module file like the following:
      
          set install_root /CAD_DISK/verilator/{version-number-used-above}
          unsetenv VERILATOR_ROOT
          prepend-path PATH $install_root/bin
          prepend-path MANPATH $install_root/man
          prepend-path PKG_CONFIG_PATH $install_root/share/pkgconfig
    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.

    You may now wish to consult the examples directory. Type make inside any example directory to run the example.

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
    examples/hello_world_c      => Example simple Verilog->C++ conversion
    examples/hello_world_sc     => Example simple Verilog->SystemC conversion
    examples/tracing_c          => Example Verilog->C++ with tracing
    examples/tracing_sc         => Example Verilog->SystemC with tracing
    test_regress                => Internal tests

LIMITATIONS

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

verilator-3.916/README.pod0000664000177100017500000001527413205574202015172 0ustar wsnyderwsnyder# DESCRIPTION: DOCUMENT source run through perl to produce README file # Use 'make README' to produce the output file =pod =head1 NAME This is the Verilator package README file. =head1 DISTRIBUTION http://www.veripool.org/verilator This package is Copyright 2003-2017 by Wilson Snyder. (Report bugs to L.) Verilator is free software; you can redistribute it and/or modify it under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. (See the documentation for more details.) This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. =head1 DESCRIPTION Verilator converts synthesizable (generally not behavioral) Verilog code into C++ or SystemC code. It is not a complete simulator, just a translator. Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage code. For C++ format, it outputs .cpp and .h files. For SystemC format, it outputs .cpp and .h files using the standard SystemC headers. The resulting files are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module. This is compiled in C++, and linked with the Verilated files. The resulting executable will perform the actual simulation. =head1 SUPPORTED SYSTEMS Verilator is developed and has primary testing on Ubuntu. Versions have also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It should run with minor porting on any Linix-ish platform. Verilator also works on Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated output (not Verilator itself) compiles under MSVC++ 2008 and newer. =head1 INSTALLATION For more details see L. If you will be modifying Verilator, you should use the "git" method as it will let you track changes. =over 4 =item The latest version is available at L. Download the latest package from that site, and decompress. tar xvzf verilator_version.tgz =item If you will be using SystemC (vs straight C++ output), download SystemC from L. Follow their installation instructions. You will need to set SYSTEMC_INCLUDE to point to the include directory with systemc.h in it, and SYSTEMC_LIBDIR to points to the directory with libsystemc.a in it. (Older installations may set SYSTEMC and SYSTEMC_ARCH instead.) =item You will need the C and C packages installed. =item C to the Verilator directory containing this README. =item You now have to decide how you're going to eventually install the kit. Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE, and SYSTEMC_LIBDIR as defaults into the executable, so try to have them correct before configuring. =over 4 =item 1. Our personal favorite is to always run Verilator from the kit directory. This allows the easiest experimentation and upgrading. It's also how most EDA tools operate; to run you point to the tarball, no install is needed. export VERILATOR_ROOT=`pwd` # if your shell is bash setenv VERILATOR_ROOT `pwd` # if your shell is csh ./configure =item 2. To install globally onto a "cad" disk with multiple versions of every tool, and add it to path using Modules/modulecmd: unset VERILATOR_ROOT # if your shell is bash unsetenv VERILATOR_ROOT # if your shell is csh # For the tarball, use the version number instead of git describe ./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"` After installing you'll want a module file like the following: set install_root /CAD_DISK/verilator/{version-number-used-above} unsetenv VERILATOR_ROOT prepend-path PATH $install_root/bin prepend-path MANPATH $install_root/man prepend-path PKG_CONFIG_PATH $install_root/share/pkgconfig =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. You may now wish to consult the examples directory. Type C inside any example directory to run the example. =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 examples/hello_world_c => Example simple Verilog->C++ conversion examples/hello_world_sc => Example simple Verilog->SystemC conversion examples/tracing_c => Example Verilog->C++ with tracing examples/tracing_sc => Example Verilog->SystemC with tracing test_regress => Internal tests =head1 LIMITATIONS See verilator.txt (or execute C) for limitations. verilator-3.916/internals.pod0000664000177100017500000007021613205574202016231 0ustar wsnyderwsnyder# DESCRIPTION: DOCUMENT source run through perl to produce internals.txt file # Use 'make internals.txt' to produce the output file =pod =head1 NAME Verilator Internals =head1 INTRODUCTION This file discusses internal and programming details for Verilator. It's the first for reference for developers and debugging problems. See also the Verilator internals presentation at http://www.veripool.org. =head1 CODE FLOWS =head2 Verilator Flow The main flow of Verilator can be followed by reading the Verilator.cpp process() function: First, the files specified on the command line are read. Reading involves preprocessing, then lexical analysis with Flex and parsing with Bison. This produces an abstract syntax tree (AST) representation of the design, which is what is visible in the .tree files described below. Verilator then makes a series of passes over the AST, progressively refining and optimizing it. Cells in the AST first linked, which will read and parse additional files as above. Functions, variable and other references are linked to their definitions. Parameters are resolved and the design is elaborated. Verilator then performs many additional edits and optimizations on the hierarchical design. This includes coverage, assertions, X elimination, inlining, constant propagation, and dead code elimination. References in the design are then pseudo-flattened. Each module's variables and functions get "Scope" references. A scope reference is an occurrence of that un-flattened variable in the flattened hierarchy. A module that occurs only once in the hierarchy will have a single scope and single VarScope for each variable. A module that occurs twice will have a scope for each occurrence, and two VarScopes for each variable. This allows optimizations to proceed across the flattened design, while still preserving the hierarchy. Additional edits and optimizations proceed on the pseudo-flat design. These include module references, function inlining, loop unrolling, variable lifetime analysis, lookup table creation, always splitting, and logic gate simplifications (pushing inverters, etc). Verilator orders the code. Best case, this results in a single "eval" function which has all always statements flowing from top to bottom with no loops. Verilator mostly removes the flattening, so that code may be shared between multiple invocations of the same module. It localizes variables, combines identical functions, expands macros to C primitives, adds branch prediction hints, and performs additional constant propagation. Verilator finally writes the C++ modules. =head2 Key Classes Used in the Verilator Flow =over 4 =item C The AST is represented at the top level by the class C. This abstract class has derived classes for the individual components (e.g. C for a generate block) or groups of components (e.g. C for functions and tasks, which in turn has C and C as derived classes). Each C has pointers to up to four children, accessed by the C through C methods. These methods are then abstracted in a specific Ast* node class to a more specific name. For example with the C node (for C statements), C calls C to give the pointer to the AST for the "then" block, while C calls C to give the pointer to the AST for the "else" block, or NULL if there is not one. C has the concept of a next and previous AST - for example the next and previous statements in a block. Pointers to the AST for these statements (if they exist) can be obtained using the C and C methods. It is useful to remember that the derived class C is at the top of the tree, so checking for this class is the standard way to see if you are at the top of the tree. By convention, each function/method uses the variable C as a pointer to the C currently being processed. =item C The passes are implemented by AST visitor classes (see L). These are implemented by subclasses of the abstract class, C. Each pass creates an instance of the visitor class, which in turn implements a method to perform the pass. =item C A number of passes use graph algorithms, and the class C is provided to represent those graphs. Graphs are directed, and algorithms are provided to manipulate the graphs and to output them in I dot format (see L). C provides documentation of this class. =item C This is the base class for vertices in a graph. Vertices have an associated C, C and C, which may be used in algorithms for ordering the graph. A generic C/C member variable is also provided. Virtual methods are provided to specify the name, color, shape and style to be used in dot output. Typically users provide derived classes from C which will reimplement these methods. Iterators are provided to access in and out edges. Typically these are used in the form: for (V3GraphEdge *edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { =item C This is the base class for directed edges between pairs of vertices. Edges have an associated C and may also be made C. A generic C/C member variable is also provided. Accessors, C and C return the "from" and "to" vertices respectively. Virtual methods are provided to specify the label, color and style to be used in dot output. Typically users provided derived classes from C which will reimplement these methods. =item C This is the base class for graph algorithms. It implements a C method, C which algorithms can use to decide whether an edge is followed. This method returns true if the graph edge has weight greater than one and a user function, C (supplied in the constructor) returns C. A number of predefined derived algorithm classes and access methods are provided and documented in C. =back =head2 Verilated Flow The evaluation loop outputted by Verilator is designed to allow a single function to perform evaluation under most situations. On the first evaluation, the Verilated code calls initial blocks, and then "settles" the modules, by evaluating functions (from always statements) until all signals are stable. On other evaluations, the Verilated code detects what input signals have changes. If any are clocks, it calls the appropriate sequential functions (from always @ posedge statements). Interspersed with sequential functions it calls combo functions (from always @*). After this is complete, it detects any changes due to combo loops or internally generated clocks, and if one is found must reevaluate the model again. For SystemC code, the eval() function is wrapped in a SystemC SC_METHOD, sensitive to all inputs. (Ideally it would only be sensitive to clocks and combo inputs, but tracing requires all signals to cause evaluation, and the performance difference is small.) If tracing is enabled, a callback examines all variables in the design for changes, and writes the trace for each change. To accelerate this process the evaluation process records a bitmask of variables that might have changed; if clear, checking those signals for changes may be skipped. =head1 CODING CONVENTIONS =head2 Indentation style To match the indentation of Verilator C++ sources, use 4 spaces per level, and leave tabs at 8 columns, so every other indent level is a tab stop. All files should contain the magic header to insure standard indentation: // -*- mode: C++; c-file-style: "cc-mode" -*- This sets indentation to the cc-mode defaults. (Verilator predates a CC-mode change of several years ago which overrides the defaults with GNU style indentation; the c-set-style undoes that.) =head2 The C script Some of the code implementing passes is extremely repetitive, and must be implemented for each sub-class of C. However, while repetitive, there is more variability than can be handled in C++ macros. In Verilator this is implemented by using a Perl script, C to pre-process the C++ code. For example in C this is used to implement the C functions for each binary operation using the TREEOP macro. The original C++ source code is transformed into C++ code in the C and C sub-directories (the former for the optimized version of Verilator, the latter for the debug version). So for example C into C. =head2 Visitor Functions Verilator uses the I design pattern to implement its refinement and optimization passes. This allows separation of the pass algorithm from the AST on which it operates. Wikipedia provides an introduction to the concept at L. As noted above, all visitors are derived classes of C. All derived classes of C implement the C method, which takes as argument a reference to an instance or a C derived class and applies the visit method of the C to the invoking AstNode instance (i.e. C). One possible difficulty is that a call to C may perform an edit which destroys the node it receives as argument. The C method of C is provided to apply C and return the resulting node, even if the original node is destroyed (if it is not destroyed it will just return the original node). The behavior of the visitor classes is achieved by overloading the C function for the different C derived classes. If a specific implementation is not found, the system will look in turn for overloaded implementations up the inheritance hierarchy. For example calling C on C will look in turn for: void visit (AstIf* nodep) void visit (AstNodeIf* nodep) void visit (AstNodeStmt* nodep) void visit (AstNode* nodep) There are three ways data is passed between visitor functions. =over 4 =item 1. A visitor-class member variable. This is generally for passing "parent" information down to children. C is a common example. It's set to NULL in the constructor, where that node (C visitor) sets it, then the children are iterated, then it's cleared. Children under an C will see it set, while nodes elsewhere will see it clear. If there can be nested items (for example an C under an C) the variable needs to be save-set-restored in the C visitor, otherwise exiting the lower for will lose the upper for's setting. =item 2. User attributes. Each C (B The AST node, not the visitor) has five user attributes, which may be accessed as an integer using the C through C methods, or as a pointer (of type C) using the C through C methods (a common technique lifted from graph traversal packages). A visitor first clears the one it wants to use by calling C, then it can mark any node's user() with whatever data it wants. Readers just call C<< nodep->user() >>, but may need to cast appropriately, so you'll often see C<< nodep->userp()->castSOMETYPE() >>. At the top of each visitor are comments describing how the C stuff applies to that visitor class. For example: // NODE STATE // Cleared entire netlist // AstModule::user1p() // bool. True to inline this module This says that at the C C is called. Each C's C is used to indicate if we're going to inline it. These comments are important to make sure a C on a given C type is never being used for two different purposes. Note that calling C is fast, it doesn't walk the tree, so it's ok to call fairly often. For example, it's commonly called on every module. =item 3. Parameters can be passed between the visitors in close to the "normal" function caller to callee way. This is the second C parameter of type C that is ignored on most of the visitor functions. V3Width does this, but it proved more messy than the above and is deprecated. (V3Width was nearly the first module written. Someday this scheme may be removed, as it slows the program down to have to pass vup everywhere.) =back =head2 Iterators C provides a set of iterators to facilitate walking over the tree. Each takes two arguments, a visitor, C, of type C and an optional pointer user data, C, of type C. The second is one of the ways to pass parameters to visitors described in L, but its use is now deprecated and should I be used for new visitor classes. =over 4 =item C This just applies the C method of the C to the visitor function. =item C Applies the C method of each C in a list (i.e. connected by C and C pointers). =item C Applies the C method of each C in a list. If a node is edited by the call to C, apply C again, until the node does not change. =item C Applies the C method of each C in a list, starting with the last one. =item C Apply the C method on each child C through C in turn. =item C Apply the C method on each child C through C in turn. =back =head3 Caution on Using Iterators When Child Changes Visitors often replace one node with another node; V3Width and V3Const are major examples. A visitor which is the parent of such a replacement needs to be aware that calling iteration may cause the children to change. For example: // nodep->lhsp() is 0x1234000 nodep->lhsp()->iterateAndNext(...); // and under covers nodep->lhsp() changes // nodep->lhsp() is 0x5678400 nodep->lhsp()->iterateAndNext(...); Will work fine, as even if the first iterate causes a new node to take the place of the lhsp(), that edit will update nodep->lhsp() and the second call will correctly see the change. Alternatively: lp = nodep->lhsp(); // nodep->lhsp() is 0x1234000, lp is 0x1234000 lp->iterateAndNext(...); **lhsp=NULL;** // and under covers nodep->lhsp() changes // nodep->lhsp() is 0x5678400, lp is 0x1234000 lp->iterateAndNext(...); This will cause bugs or a core dump, as lp is a dangling pointer. Thus it is advisable to set lhsp=NULL shown in the *'s above to make sure these dangles are avoided. Another alternative used in special cases mostly in V3Width is to use acceptSubtreeReturnEdits, which operates on a single node and returns the new pointer if any. Note acceptSubtreeReturnEdits does not follow nextp() links. lp = lp->acceptSubtreeReturnEdits() =head2 Identifying derived classes A common requirement is to identify the specific C class we are dealing with. For example a visitor might not implement separate C methods for C and C, but just a single method for the base class: void visit (AstNodeIf* nodep, AstNUser* vup) However that method might want to specify additional code if it is called for C. Verilator does this by providing a C method for each possible node type, using C++ C. This either returns a pointer to the object cast to that type (if it is of class C, or a derived class of C) or else NULL. So our C method could use: if (nodep->castAstGenIf()) { } A common test is for C, which is the node at the root of the AST. =head1 TESTING For an overview of how to write a test see the BUGS section of the Verilator primary manual. It is important to add tests for failures as well as success (for example to check that an error message is correctly triggered). Tests that fail should by convention have the suffix C<_bad> in their name, and include C 1> in either their C or C step as appropriate. =head2 Preparing to Run Tests For all tests to pass you must install the following packages: * SystemC to compile the SystemC outputs, see http://systemc.org * Parallel::Forker from CPAN to run tests in parallel, you can install this with e.g. "sudo cpan install Parallel::Forker". * vcddiff to find differences in VCD outputs. See the readme at https://github.com/veripool/vcddiff =head2 Controlling the Test Driver Test drivers are written in PERL. All invoke the main test driver script, which can provide detailed help on all the features available when writing a test driver. test_regress/t/driver.pl --help For convenience, a summary of the most commonly used features is provided here. All drivers require a call to C subroutine to compile the test. For run-time tests, this is followed by a call to the C subroutine. Both of these functions can optionally be provided with a hash table as argument specifying additional options. The test driver assumes by default that the source Verilog file name matches the PERL driver name. So a test whose driver is C will expect a Verilog source file C. This can be changed using the C subroutine, for example top_filename("t/t_myothertest.v"); By default all tests will run with major simulators (Icarus Verilog, NC, VCS, ModelSim) as well as Verilator, to allow results to be compared. However if you wish a test only to be used with Verilator, you can use the following: $Self->{vlt} or $Self->skip("Verilator only test"); Of the many options that can be set through arguments to C and C, the following are particularly useful: =over 4 =item C A list of flags to be passed to verilator when compiling. =item C Set to 1 to indicate that the compilation or execution is intended to fail. =back For example the following would specify that compilation requires two defines and is expected to fail. compile ( verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"], fails => 1, ); =head2 Regression Testing for Developers Developers will also want to call ./configure with two extra flags: =over 4 =item --enable-ccwarn Causes the build to stop on warnings as well as errors. A good way to ensure no sloppy code gets added, however it can be painful when it comes to testing, since third party code used in the tests (e.g. SystemC) may not be warning free. =item --enable-longtests In addition to the standard C, SystemC examples, also run the tests in the C directory when using I. This is disabled by default as SystemC installation problems would otherwise falsely indicate a Verilator problem. =back When enabling the long tests, some additional PERL modules are needed, which you can install using cpan. cpan install Unix::Processors There are some traps to avoid when running regression tests =over 4 =item * When checking the MANIFEST, the test will barf on unexpected code in the Verilator tree. So make sure to keep any such code outside the tree. =item * Not all Linux systems install Perldoc by default. This is needed for the I<--help> option to Verilator, and also for regression testing. This can be installed using cpan: cpan install Pod::Perldoc Many Linux systems also offer a standard package for this. Red Hat/Fedora/Centos offer I, while Debian/Ubuntu/Linux Mint offer I. =item * Running regression may exhaust resources on some Linux systems, particularly file handles and user processes. Increase these to respectively 16,384 and 4,096. The method of doing this is system dependent, but on Fedora Linux it would require editing the C file as root. =back =head1 DEBUGGING =head2 --debug When you run with --debug there are two primary output file types placed into the obj_dir, .tree and .dot files. =head2 .dot output Dot files are dumps of internal graphs in Graphviz L dot format. When a dot file is dumped, Verilator will also print a line on stdout that can be used to format the output, for example: dot -Tps -o ~/a.ps obj_dir/Vtop_foo.dot You can then print a.ps. You may prefer gif format, which doesn't get scaled so can be more useful with large graphs. For dynamic graph viewing consider ZGRViewer L. If you know of better viewers let us know; ZGRViewer isn't great for large graphs. =head2 .tree output Tree files are dumps of the AST Tree and are produced between every major algorithmic stage. An example: NETLIST 0x90fb00 {a0} 1: MODULE 0x912b20 {a8} top L2 [P] *1:2: VAR 0x91a780 {a22} @dt=0xa2e640(w32) out_wide [O] WIRE 1:2:1: BASICDTYPE 0xa2e640 {e24} @dt=this(sw32) integer kwd=integer range=[31:0] =over 4 The following summarizes the above example dump, with more detail on each field in the section below. "1:2:" indicates the hierarchy of the C is the C pointer under the C, which in turn is the C pointer under the C "VAR" is the AstNodeType. "0x91a780" is the address of this node. "" means the 74th edit to the netlist was the last modification to this node. "{a22}" indicates this node is related to line 22 in the source filename "a", where "a" is the first file read, "z" the 26th, and "aa" the 27th. "@dt=0x..." indicates the address of the data type this node contains. "w32" indicates the width is 32 bits. "out_wide" is the name of the node, in this case the name of the variable. "[O]" are flags which vary with the type of node, in this case it means the variable is an output. =back In more detail the following fields are dumped common to all nodes. They are produced by the C method: =over 4 =item Tree Hierarchy The dump lines begin with numbers and colons to indicate the child node hierarchy. As noted above in L, C has lists of items at the same level in the AST, connected by the C and C pointers. These appear as nodes at the same level. For example after inlining: NETLIST 0x929c1c8 {a0} w0 1: MODULE 0x92bac80 {e14} w0 TOP_t L1 [P] 1:1: CELLINLINE 0x92bab18 {e14} w0 v -> t 1:1: CELLINLINE 0x92bc1d8 {e24} w0 v__DOT__i_test_gen -> test_gen ... 1: MODULE 0x92b9bb0 {e47} w0 test_gen L3 ... =item AstNode type The textual name of this node AST type (always in capitals). Many of these correspond directly to Verilog entities (for example C and C), but others are internal to Verialtor (for example C and C). =item Address of the node A hexadecimal address of the node in memory. Useful for examining with the debugger. =item Last edit number Of the form C<< >> or C<< >> , where C is the number of the last edit to modify this node. The trailing C<#> indicates the node has been edited since the last tree dump (which typically means in the last refinement or optimization pass). GDB can watch for this, see L. =item Source file and line Of the form C<< {xxnnnn} >>, where C{xx} is the filename letter (or letters) and C is the line number within that file. The first file is C, the 26th is C, the 27th is C and so on. =item User pointers Shows the value of the node's user1p...user5p, if non-NULL. =item Data type Many nodes have an explicit data type. "@dt=0x..." indicates the address of the data type (AstNodeDType) this node uses. If a data type is present and is numeric, it then prints the width of the item. This field is a sequence of flag characters and width data as follows: C if the node is signed. C if the node is a double (i.e a floating point entity). C always present, indicating this is the width field. C if the node is unsized. C if the node is unsized, where C is the minimum width. =item Name of the entity represented by the node if it exists For example for a C it is the name of the variable. =back Many nodes follow these fields with additional node specific information. Thus the C node will print either C<[LV]> or C<[RV]> to indicate a left value or right value, followed by the node of the variable being referred to. For example: 1:2:1:1: VARREF 0x92c2598 {e24} w0 clk [RV] <- VAR 0x92a2e90 {e18} w0 clk [I] INPUT In general, examine the C method in C of the node type in question to determine additional fields that may be printed. The C has a list of C nodes referred to by its C pointer, connected by C and C pointers. Similarly the C has a list of modules referred to by its C pointer. =head2 Debugging with GDB The test_regress/driver.pl script accepts --debug --gdb to start Verilator under gdb and break when an error is hit or the program is about to exit. You can also use --debug --gdbbt to just backtrace and then exit gdb. To debug the Verilated executable, use --gdbsim. If you wish to start Verilator under GDB (or another debugger), then you can use --debug and look at the underlying invocation of verilator_dgb. For example t/t_alw_dly.pl --debug shows it invokes the command: ../verilator_bin_dbg --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v Start GDB, then C with the remaining arguments. gdb ../verilator_bin_dbg ... (gdb) start --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v > obj_dir/t_alw_dly/vlt_compile.log ... Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc) at ../Verilator.cpp:615 615 ios::sync_with_stdio(); (gdb) You can then continue execution with breakpoints as required. To break at a specific edit number which changed a node (presumably to find what made a line in the tree dumps): watch AstNode::s_editCntGbl==#### To print a node: pn nodep # or: call nodep->dumpGdb() # aliased to "pn" in src/.gdbinit pnt nodep # or: call nodep->dumpTreeGdb() # aliased to "pnt" in src/.gdbinit When GDB halts, it is useful to understand that the backtrace will commonly show the iterator functions between each invocation of C in the backtrace. You will typically see a frame sequence something like ... visit() iterateChildren() iterateAndNext() accept() visit() ... =head1 ADDING A NEW FEATURE Generally what would you do to add a new feature? =over 4 =item 1. File a bug (if there isn't already) so others know what you're working on. =item 2. Make a testcase in the test_regress/t/t_EXAMPLE format, see L. =item 3. If grammar changes are needed, look at the git version of VerilogPerl's src/VParseGrammar.y, as this grammar supports the full SystemVerilog language and has a lot of back-and-forth with Verilator's grammar. Copy the appropriate rules to src/verilog.y and modify the productions. =item 4. If a new Ast type is needed, add it to V3AstNodes.h. =back Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree file which you can examine to see if the parsing worked. See also the sections above on debugging. Modify the later visitor functions to process the new feature as needed. =head2 Adding a new pass For more substantial changes you may need to add a new pass. The simplest way to do this is to copy the C<.cpp> and C<.h> files from an existing pass. You'll need to add a call into your pass from the C function in C. To get your pass to build you'll need to add its binary filename to the list in C and reconfigure. =head1 DISTRIBUTION The latest version is available from L. Copyright 2008-2017 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.916/test_regress/0000775000177100017500000000000013206353162016232 5ustar wsnyderwsnyderverilator-3.916/test_regress/.gitignore0000664000177100017500000000016012473477707020240 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.916/test_regress/driver.pl0000775000177100017500000016170313205574202020074 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### require 5.006_001; use Cwd; 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}; } if (!$ENV{VERILATOR_ROOT} && -x "../bin/verilator") { $ENV{VERILATOR_ROOT} = Cwd::getcwd()."/.."; } } 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); use lib "."; $::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"; }; #====================================================================== #====================================================================== # main autoflush STDOUT 1; autoflush STDERR 1; our @Orig_ARGV = @ARGV; our @Orig_ARGV_Sw; foreach (@Orig_ARGV) { push @Orig_ARGV_Sw, $_ if /^-/ && !/^-j/; } our $Start = time(); $Debug = 0; my $opt_atsim; my $opt_benchmark; my @opt_tests; my $opt_gdb; my $opt_gdbbt; my $opt_gdbsim; my $opt_ghdl; my $opt_iv; my $opt_jobs = 1; my $opt_ms; my $opt_nc; my $opt_optimize; my $opt_site; my $opt_stop; my $opt_trace; my $opt_vlt; my $opt_vcs; my $opt_verbose; my $Opt_Verilated_Debug; our $Opt_Unsupported; our $Opt_Verilation = 1; our @Opt_Driver_Verilator_Flags; Getopt::Long::config ("pass_through"); if (! GetOptions ( "benchmark:i" => sub { $opt_benchmark = $_[1] ? $_[1] : 1; }, "debug" => \&debug, #debugi see parameter() "atsim|athdl!"=> \$opt_atsim, "gdb!" => \$opt_gdb, "gdbbt!" => \$opt_gdbbt, "gdbsim!" => \$opt_gdbsim, "ghdl!" => \$opt_ghdl, "golden!" => sub { $ENV{HARNESS_UPDATE_GOLDEN} = 1; }, "help" => \&usage, "iverilog!" => \$opt_iv, "j=i" => \$opt_jobs, "ms!" => \$opt_ms, "nc!" => \$opt_nc, "optimize:s" => \$opt_optimize, "site!" => \$opt_site, "stop!" => \$opt_stop, "trace!" => \$opt_trace, "unsupported!"=> \$Opt_Unsupported, "v3!" => \$opt_vlt, # Old "vl!" => \$opt_vlt, # Old "vlt!" => \$opt_vlt, "vcs!" => \$opt_vcs, "verbose!" => \$opt_verbose, "verilation!" => \$Opt_Verilation, # Undocumented debugging "verilated_debug!" => \$Opt_Verilated_Debug, #W see parameter() "<>" => \¶meter, )) { die "%Error: Bad usage, try '$0 --help'\n"; } $opt_jobs = calc_jobs() if defined $opt_jobs && $opt_jobs==0; $Fork->max_proc($opt_jobs); if (!$opt_atsim && !$opt_ghdl && !$opt_iv && !$opt_vcs && !$opt_ms && !$opt_nc && !$opt_vlt) { $opt_vlt = 1; } our @Test_Dirs = "t"; push @Test_Dirs, split(/:/,$ENV{VERILATOR_TESTS_SITE}) if (($#opt_tests<0 ? $opt_site : 1) && $ENV{VERILATOR_TESTS_SITE}); if ($#opt_tests<0) { my %uniq; foreach my $dir (@Test_Dirs) { my @stats = stat($dir); # Uniquify by inode, so different paths to same place get combined next if !$stats[1] || $uniq{$stats[1]}++; push @opt_tests, sort(glob ("${dir}/t_*.pl")); } } if ($#opt_tests>=2 && $opt_jobs>=2) { # Without this tests such as t_debug_sigsegv_bt_bad.pl will occasionally # block on input and cause a SIGSTOP, then a "fg" was needed to resume testing. print STDERR "== Many jobs; redirecting STDIN\n"; open(STDIN, "+>/dev/null"); } mkdir "obj_dir"; our $Log_Filename = "obj_dir/driver_".strftime("%Y%m%d_%H%M%S.log", localtime); my $LeftCnt=0; my $OkCnt=0; my $FailCnt=0; my $SkipCnt=0; my $UnsupCnt=0; my @fails; foreach my $testpl (@opt_tests) { one_test(pl_filename => $testpl, atsim=>1) if $opt_atsim; one_test(pl_filename => $testpl, ghdl=>1) if $opt_ghdl; one_test(pl_filename => $testpl, iv=>1) if $opt_iv; one_test(pl_filename => $testpl, ms=>1) if $opt_ms; one_test(pl_filename => $testpl, nc=>1) if $opt_nc; one_test(pl_filename => $testpl, vcs=>1) if $opt_vcs; one_test(pl_filename => $testpl, vlt=>1, 'v3'=>1) if $opt_vlt; } $Fork->wait_all(); # Wait for all children to finish sub one_test { my @params = @_; my %params = (@params); $LeftCnt++; $Fork->schedule ( test_pl_filename => $params{pl_filename}, run_on_start => sub { # Running in context of child, so can't pass data to parent directly print ("="x70,"\n"); my $test = VTest->new(@params); $test->oprint("="x50,"\n"); unlink $test->{status_filename}; $test->prep; $test->read; if ($test->ok) { $test->oprint("Test PASSED\n"); } elsif ($test->skips && !$test->errors) { $test->oprint("%Skip: $test->{skips}\n"); } elsif ($test->unsupporteds && !$test->errors) { $test->oprint("%Unsupported: $test->{unsupporteds}\n"); } else { $test->error("Missing ok\n") if !$test->errors; $test->oprint("%Error: $test->{errors}\n"); } $test->write_status; }, run_on_finish => sub { my $test = VTest->new(@params); $test->read_status; if ($test->ok) { $OkCnt++; } elsif ($test->skips && !$test->errors) { $SkipCnt++; } elsif ($test->unsupporteds && !$test->errors) { $UnsupCnt++; } else { $test->oprint("FAILED: ","*"x60,"\n"); my $j = ($opt_jobs>1?" -j":""); push @fails, ("\t#".$test->soprint("%Error: $test->{errors}\n") ."\t\tmake$j && test_regress/" .$test->{pl_filename}." ".join(' ',@Orig_ARGV_Sw)."\n"); $FailCnt++; report(\@fails, $Log_Filename); my $other = ""; foreach my $proc ($Fork->running) { $other .= " ".$proc->{test_pl_filename}; } $test->oprint("Simultaneous running tests:",$other,"\n") if $other; if ($opt_stop) { die "%Error: --stop and errors found\n"; } } $LeftCnt--; my $LeftMsg = $::Have_Forker ? $LeftCnt : "NO-FORKER"; print STDERR "==SUMMARY: Left $LeftMsg Passed $OkCnt Unsup $UnsupCnt Skipped $SkipCnt Failed $FailCnt\n"; }, )->ready(); } report(\@fails, undef); report(\@fails, $Log_Filename); exit(10) if $FailCnt; #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } sub debug { $Debug = 1; push @Opt_Driver_Verilator_Flags, "--debug --no-skip-identical"; } our $_Parameter_Next_Level; sub parameter { my $param = shift; if ($_Parameter_Next_Level) { ($param =~ /^(\d+)$/) or die "%Error: Expected number following $_Parameter_Next_Level: $param\n"; push @Opt_Driver_Verilator_Flags, $param; $_Parameter_Next_Level = undef; } elsif ($param =~ /\.pl/) { push @opt_tests, $param; } elsif ($param =~ /^-?(-debugi|-dump-treei)/) { push @Opt_Driver_Verilator_Flags, $param; $_Parameter_Next_Level = $param; } elsif ($param =~ /^-?(-W||-debug-check)/) { push @Opt_Driver_Verilator_Flags, $param; } else { die "%Error: Unknown parameter: $param\n"; } } sub calc_jobs { my $ok = eval " use Unix::Processors; return Unix::Processors->new->max_online; "; $ok && !$@ or die "%Error: Can't use -j: $@\n"; print "driver.pl: Found $ok cores, using -j ",$ok+1,"\n"; return $ok + 1; } sub report { my $fails = shift; my $filename = shift; my $fh = \*STDOUT; if ($filename) { $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename,"; } my $delta = time() - $Start; $fh->print("\n"); $fh->print("="x70,"\n"); $fh->printf("TESTS Passed $OkCnt Unsup $UnsupCnt Skipped $SkipCnt Failed $FailCnt Time %d:%02d\n", int($delta/60),$delta%60); foreach my $f (sort @$fails) { chomp $f; $fh->print("$f\n"); } $fh->printf("TESTS Passed $OkCnt Unsup $UnsupCnt Skipped $SkipCnt Failed $FailCnt Time %d:%02d\n", int($delta/60),$delta%60); } ####################################################################### ####################################################################### ####################################################################### ####################################################################### # Test class package VTest; use Carp; use Cwd; use Data::Dumper; use File::Spec; use vars qw ($Self $Self); use strict; sub new { my $class = shift; my $self = {@_}; $self->{name} ||= $2 if $self->{pl_filename} =~ m!^(.*/)?([^/]*)\.pl$!; $self->{mode} = ""; $self->{mode} ||= "atsim" if $self->{atsim}; $self->{mode} ||= "ghdl" if $self->{ghdl}; $self->{mode} ||= "vcs" if $self->{vcs}; $self->{mode} ||= "vlt" if $self->{vlt}; $self->{mode} ||= "nc" if $self->{nc}; $self->{mode} ||= "ms" if $self->{ms}; $self->{mode} ||= "iv" if $self->{iv}; # For backward compatibility, the verilator tests have no prefix $self->{obj_dir} ||= ("obj_dir/".($self->{mode} eq 'vlt' ? "" : $self->{mode}."_") ."$self->{name}"); foreach my $dir (@::Test_Dirs) { # t_dir used both absolutely and under obj_dir if (-e "$dir/$self->{name}.pl") { # Note most tests require error messages of the form t/x.v # Therefore pl_filename must be t/ for local tests $self->{pl_filename} = File::Spec->abs2rel("$dir/$self->{name}.pl"); # t_dir must be absolute - used under t or under obj_dir $self->{t_dir} ||= File::Spec->rel2abs($dir); last; } } $self->{t_dir} or die "%Error: Can't locate dir for $self->{name},"; $self = { name => undef, # Set below, name of this test pl_filename => undef, # Name of .pl file to get setup from make_top_shell => 1, # Make a default __top.v file make_main => 1, # Make __main.cpp make_pli => 0, # need to compile pli sim_time => 1100, benchmark => $opt_benchmark, verbose => $opt_verbose, run_env => '', # All compilers v_flags => [split(/\s+/,(" -f input.vc " .($self->{t_dir} !~ m!/test_regress! # Don't include standard dir, only site's ? " +incdir+$self->{t_dir} -y $self->{t_dir}" : "") .($opt_verbose ? " +define+TEST_VERBOSE=1":"") .($opt_benchmark ? " +define+TEST_BENCHMARK=$opt_benchmark":"") .($opt_trace ? " +define+WAVES=1":"") ))], v_flags2 => [], # Overridden in some sim files v_other_filenames => [], # After the filename so we can spec multiple files all_run_flags => [], pli_flags => ["-I$ENV{VERILATOR_ROOT}/include/vltstd -fPIC -shared" .(($^O eq "darwin" ) ? " -Wl,-undefined,dynamic_lookup" : " -export-dynamic") ." -o $self->{obj_dir}/libvpi.so"], # ATSIM atsim => 0, atsim_flags => [split(/\s+/,"-c +sv +define+ATSIM"), "+sv_dir+$self->{obj_dir}/.athdl_compile"], atsim_flags2 => [], # Overridden in some sim files atsim_run_flags => [], # GHDL ghdl => 0, ghdl_work_dir => "$self->{obj_dir}/ghdl_compile", ghdl_flags => [($::Debug?"-v":""), "--workdir=$self->{obj_dir}/ghdl_compile", ], ghdl_flags2 => [], # Overridden in some sim files ghdl_run_flags => [], # IV iv => 0, iv_flags => [split(/\s+/,"+define+iverilog -o $self->{obj_dir}/simiv")], iv_flags2 => [], # Overridden in some sim files iv_pli => 0, # need to use pli iv_run_flags => [], # VCS vcs => 0, vcs_flags => [split(/\s+/,"+vcs+lic+wait +cli -debug_access +define+VCS+1 -q -sverilog -CFLAGS '-DVCS' ")], vcs_flags2 => [], # Overridden in some sim files vcs_run_flags => [split(/\s+/,"+vcs+lic_wait")], # NC nc => 0, nc_flags => [split(/\s+/,("+licqueue +nowarn+LIBNOU +define+NC=1 -q +assert +sv -c " .($opt_trace ? " +access+r":"")))], nc_flags2 => [], # Overridden in some sim files nc_run_flags => [split(/\s+/,"+licqueue -q +assert +sv -R")], # ModelSim ms => 0, ms_flags => [split(/\s+/,("-sv -work $self->{obj_dir}/work"))], ms_flags2 => [], # Overridden in some sim files ms_run_flags => [split(/\s+/,"-lib $self->{obj_dir}/work -c -do 'run -all;quit' ")], # Verilator vlt => 0, 'v3' => 0, verilator_flags => ["-cc", "-Mdir $self->{obj_dir}", "-OD", # As currently disabled unless -O3 "--debug-check"], verilator_flags2 => [], verilator_flags3 => ["--clk clk"], verilator_make_gcc => 1, verilated_debug => $Opt_Verilated_Debug, stdout_filename => undef, # Redirect stdout %$self}; bless $self, $class; $self->{VM_PREFIX} ||= "V".$self->{name}; $self->{stats} ||= "$self->{obj_dir}/V".$self->{name}."__stats.txt"; $self->{status_filename} ||= "$self->{obj_dir}/V".$self->{name}.".status"; $self->{run_log_filename} ||= "$self->{obj_dir}/vlt_sim.log"; $self->{coverage_filename} ||= "$self->{obj_dir}/coverage.dat"; $self->{vcd_filename} ||= "$self->{obj_dir}/sim.vcd"; $self->{main_filename} ||= "$self->{obj_dir}/$self->{VM_PREFIX}__main.cpp"; ($self->{top_filename} = $self->{pl_filename}) =~ s/\.pl$//; if (-e ($self->{top_filename}.".vhd")) { # If VHDL file exists $self->{vhdl} = 1; $self->{top_filename} .= ".vhd"; } else { $self->{top_filename} .= ".v"; } if (!$self->{make_top_shell}) { $self->{top_shell_filename} = $self->{top_filename}; } else { $self->{top_shell_filename} = "$self->{obj_dir}/$self->{VM_PREFIX}__top.v"; } return $self; } sub soprint { my $self = shift; my $str = "$self->{mode}/$self->{name}: ".join('',@_); $str =~ s/\n\n+$/\n/s; return $str; } sub oprint { my $self = shift; print $self->soprint(@_); } sub error { my $self = shift; my $msg = join('',@_); warn "%Warning: $self->{mode}/$self->{name}: ".$msg."\n"; $self->{errors} ||= $msg; } sub skip { my $self = shift; my $msg = join('',@_); warn "%Skip: $self->{mode}/$self->{name}: ".$msg."\n"; $self->{skips} ||= "Skip: ".$msg; } sub unsupported { my $self = shift; my $msg = join('',@_); warn "%Unsupported: $self->{mode}/$self->{name}: ".$msg."\n"; if (!$::Opt_Unsupported) { $self->{unsupporteds} ||= "Unsupported: ".$msg; } } sub prep { my $self = shift; mkdir $self->{obj_dir}; # Ok if already exists } sub read { my $self = shift; # Read the control file (-r $self->{pl_filename}) or return $self->error("Can't open $self->{pl_filename}\n"); $Self = $self; delete $INC{$self->{pl_filename}}; require $self->{pl_filename}; } sub write_status { my $self = shift; my $filename = $self->{status_filename}; my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,"; print $fh Dumper($self); print $fh "1;"; $fh->close(); } sub read_status { my $self = shift; my $filename = $self->{status_filename}; use vars qw($VAR1); local $VAR1; require $filename or die "%Error: $! $filename,"; if ($VAR1) { %{$self} = %{$VAR1}; } } #---------------------------------------------------------------------- # Methods invoked by tests sub compile_vlt_flags { my $self = (ref $_[0]? shift : $Self); my %param = (%{$self}, @_); # Default arguments are from $self return 1 if $self->errors || $self->skips || $self->unsupporteds; my $checkflags = join(' ',@{$param{v_flags}}, @{$param{v_flags2}}, @{$param{verilator_flags}}, @{$param{verilator_flags2}}, @{$param{verilator_flags3}}); $self->{sc} = 1 if ($checkflags =~ /-sc\b/); $self->{trace} = 1 if ($opt_trace || $checkflags =~ /-trace\b/); $self->{savable} = 1 if ($checkflags =~ /-savable\b/); $self->{coverage} = 1 if ($checkflags =~ /-coverage\b/); my @verilator_flags = @{$param{verilator_flags}}; unshift @verilator_flags, "--gdb" if $opt_gdb; unshift @verilator_flags, "--gdbbt" if $opt_gdbbt; unshift @verilator_flags, @Opt_Driver_Verilator_Flags; unshift @verilator_flags, "--x-assign unique"; # More likely to be buggy unshift @verilator_flags, "--trace" if $opt_trace; if (defined $opt_optimize) { my $letters = ""; if ($opt_optimize =~ /[a-zA-Z]/) { $letters = $opt_optimize; } else { # Randomly turn on/off different optimizations foreach my $l ('a'..'z') { $letters .= ((rand() > 0.5) ? $l : uc $l); } unshift @verilator_flags, "--trace" if rand() > 0.5; unshift @verilator_flags, "--coverage" if rand() > 0.5; } unshift @verilator_flags, "--O".$letters; } my @cmdargs = ("perl","../bin/verilator", "--prefix ".$param{VM_PREFIX}, @verilator_flags, @{$param{verilator_flags2}}, @{$param{verilator_flags3}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, @{$param{v_other_filenames}}, ($param{stdout_filename}?"> ".$param{stdout_filename}:""), ); return @cmdargs; } sub compile { my $self = (ref $_[0]? shift : $Self); my %param = (%{$self}, @_); # Default arguments are from $self return 1 if $self->errors || $self->skips || $self->unsupporteds; $self->oprint("Compile\n"); compile_vlt_flags(%param); if (!$self->{make_top_shell}) { $param{top_shell_filename} = $self->{top_shell_filename} = $self->{top_filename}; } else { $param{top_shell_filename} = $self->{top_shell_filename} = "$self->{obj_dir}/$self->{VM_PREFIX}__top.".$self->v_suffix; } if ($param{atsim}) { $self->_make_top(); $self->_run(logfile=>"$self->{obj_dir}/atsim_compile.log", fails=>$param{fails}, cmd=>[($ENV{VERILATOR_ATSIM}||"atsim"), @{$param{atsim_flags}}, @{$param{atsim_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}, ]); } elsif ($param{ghdl}) { mkdir $self->{ghdl_work_dir}; $self->_make_top(); $self->_run(logfile=>"$self->{obj_dir}/ghdl_compile.log", fails=>$param{fails}, cmd=>[($ENV{VERILATOR_GHDL}||"ghdl"), # Add -c here, as having -c twice freaks it out ((($ENV{VERILATOR_GHDL}||' ') =~ / -c\b/) ? "" : "-c"), @{$param{ghdl_flags}}, @{$param{ghdl_flags2}}, #@{$param{v_flags}}, # Not supported #@{$param{v_flags2}}, # Not supported $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}, "-e t", ]); } elsif ($param{vcs}) { $self->_make_top(); $self->_run(logfile=>"$self->{obj_dir}/vcs_compile.log", fails=>$param{fails}, cmd=>[($ENV{VERILATOR_VCS}||"vcs"), @{$param{vcs_flags}}, @{$param{vcs_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}, ]); } elsif ($param{nc}) { $self->_make_top(); my @more_args; if ($self->vhdl) { ((my $ts = $param{top_shell_filename}) =~ s!\.v!!); $ts =~ s!.*/!!;; push @more_args, "-vhdltop", $ts; } $self->_run(logfile=>"$self->{obj_dir}/nc_compile.log", fails=>$param{fails}, cmd=>[($ENV{VERILATOR_NCVERILOG}||"ncverilog"), @{$param{nc_flags}}, @{$param{nc_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}, @more_args ]); } elsif ($param{ms}) { $self->_make_top(); $self->_run(logfile=>"$self->{obj_dir}/ms_compile.log", fails=>$param{fails}, cmd=>[("vlib $self->{obj_dir}/work && "), ($ENV{VERILATOR_MODELSIM}||"vlog"), @{$param{ms_flags}}, @{$param{ms_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}} ]); } elsif ($param{iv}) { $self->_make_top(); my @cmd = (($ENV{VERILATOR_IVERILOG}||"iverilog"), @{$param{iv_flags}}, @{$param{iv_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}); @cmd = grep { s/\+define\+/-D /g; $_; } @cmd; $self->_run(logfile=>"$self->{obj_dir}/iv_compile.log", fails=>$param{fails}, cmd=>\@cmd); } elsif ($param{vlt}) { my @cmdargs = $self->compile_vlt_flags(%param); if ($self->sc && !defined $ENV{SYSTEMC} && !defined $ENV{SYSTEMC_INCLUDE}) { $self->skip("Test requires SystemC; ignore error since not installed\n"); return 1; } if (!$param{fails} && $param{verilator_make_gcc} && $param{make_main}) { $self->_make_main(); } $self->_run(logfile=>"$self->{obj_dir}/vlt_compile.log", fails=>$param{fails}, expect=>$param{expect}, cmd=>\@cmdargs) if $::Opt_Verilation; return 1 if $self->errors || $self->skips || $self->unsupporteds; if (!$param{fails} && $param{verilator_make_gcc}) { $self->oprint("GCC\n"); $self->_run(logfile=>"$self->{obj_dir}/vlt_gcc.log", cmd=>["make", "-C ".$self->{obj_dir}, "-f ".getcwd()."/Makefile_obj", "VM_PREFIX=$self->{VM_PREFIX}", "CPPFLAGS_DRIVER=-D".uc($self->{name}), ($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""), ($param{make_main}?"":"MAKE_MAIN=0"), ($param{benchmark}?"OPT_FAST=-O2":""), "$self->{VM_PREFIX}", # bypass default rule, as we don't need archive ($param{make_flags}||""), ]); } } else { $self->error("No compile step for this simulator"); } if ($param{make_pli}) { $self->oprint("Compile vpi\n"); my @cmd = ('c++', @{$param{pli_flags}}, "-DIS_VPI", "$self->{t_dir}/$self->{name}.cpp"); $self->_run(logfile=>"$self->{obj_dir}/pli_compile.log", fails=>$param{fails}, cmd=>\@cmd); } return 1; } sub execute { my $self = (ref $_[0]? shift : $Self); return 1 if $self->errors || $self->skips || $self->unsupporteds; my %param = (%{$self}, @_); # Default arguments are from $self # params may be expect or {tool}_expect $self->oprint("Run\n"); my $run_env = $param{run_env}; $run_env .= ' ' if $run_env; if ($param{atsim}) { $self->_run(logfile=>"$self->{obj_dir}/atsim_sim.log", fails=>$param{fails}, cmd=>["echo q | ".$run_env."$self->{obj_dir}/athdl_sv", @{$param{atsim_run_flags}}, @{$param{all_run_flags}}, ], %param, expect=>$param{atsim_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{ghdl}) { $self->_run(logfile=>"$self->{obj_dir}/ghdl_sim.log", fails=>$param{fails}, cmd=>[$run_env."$self->{obj_dir}/simghdl", @{$param{ghdl_run_flags}}, @{$param{all_run_flags}}, ], %param, expect=>$param{ghdl_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{iv}) { my @cmd = ($run_env."$self->{obj_dir}/simiv", @{$param{iv_run_flags}}, @{$param{all_run_flags}}, ); if ($param{iv_pli}) { unshift @cmd, "vvp -n -m $self->{obj_dir}/libvpi.so"; # don't enter command line on $stop, include vpi } $self->_run(logfile=>"$self->{obj_dir}/iv_sim.log", fails=>$param{fails}, cmd=> \@cmd, %param, expect=>$param{iv_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{ms}) { $self->_run(logfile=>"$self->{obj_dir}/ms_sim.log", fails=>$param{fails}, cmd=>["echo q | ".$run_env.($ENV{VERILATOR_MODELSIM}||"vsim"), @{$param{ms_run_flags}}, @{$param{all_run_flags}}, (" top") ], %param, expect=>$param{ms_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{nc}) { $self->_run(logfile=>"$self->{obj_dir}/nc_sim.log", fails=>$param{fails}, cmd=>["echo q | ".$run_env.($ENV{VERILATOR_NCVERILOG}||"ncverilog"), @{$param{nc_run_flags}}, @{$param{all_run_flags}}, ], %param, expect=>$param{nc_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{vcs}) { #my $fh = IO::File->new(">simv.key") or die "%Error: $! simv.key,"; #$fh->print("quit\n"); $fh->close; $self->_run(logfile=>"$self->{obj_dir}/vcs_sim.log", cmd=>["echo q | ".$run_env."./simv", @{$param{vcs_run_flags}}, @{$param{all_run_flags}}, ], %param, expect=>$param{vcs_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{vlt} #&& (!$param{needs_v4} || -r "$ENV{VERILATOR_ROOT}/src/V3Gate.cpp") ) { $param{executable} ||= "$self->{obj_dir}/$param{VM_PREFIX}"; $self->_run(logfile=>"$self->{obj_dir}/vlt_sim.log", cmd=>[($run_env .($opt_gdbsim ? ("gdb"||$ENV{VERILATOR_GDB})." " : "") .$param{executable} .($opt_gdbsim ? " -ex 'run " : "")), @{$param{all_run_flags}}, ($opt_gdbsim ? "'" : ""), ], %param, expect=>$param{expect}, # backward compatible name ); } else { $self->error("No execute step for this simulator"); } } sub inline_checks { my $self = (ref $_[0]? shift : $Self); return 1 if $self->errors || $self->skips || $self->unsupporteds; return 1 if !$self->{vlt}; my %param = (%{$self}, @_); # Default arguments are from $self my $covfn = $Self->{coverage_filename}; my $contents = $self->file_contents($covfn); $self->oprint("Extract checks\n"); my $fh = IO::File->new("<$self->{top_filename}"); while (defined(my $line = $fh->getline)) { if ($line =~ /CHECK/) { if ($line =~ /CHECK_COVER *\( *([---0-9]+) *, *"([^"]+)" *, *("([^"]+)" *,|) *(\d+) *\)/) { my $lineno=($. + $1); my $hier=$2; my $comment=$4; my $count=$5; my $regexp = "\001l\002".$lineno; $regexp .= ".*\001o\002".quotemeta($comment) if $comment; $regexp .= ".*\001h\002".quotemeta($hier); $regexp .= ".*' ".$count; if ($contents !~ /$regexp/) { $self->error("CHECK_COVER: $covfn: Regexp not found: $regexp\n". "From $self->{top_filename}:$.: $line"); } } elsif ($line =~ /CHECK_COVER_MISSING *\( *([---0-9]+) *\)/) { my $lineno=($. + $1); my $regexp = "\001l\002".$lineno; if ($contents =~ /$regexp/) { $self->error("CHECK_COVER_MISSING: $covfn: Regexp found: $regexp\n". "From $self->{top_filename}:$.: $line"); } } else { $self->error("$self->{top_filename}:$.: Unknown CHECK request: $line"); } } } $fh->close; } #---------------------------------------------------------------------- # Accessors sub ok { my $self = (ref $_[0]? shift : $Self); $self->{ok} = $_[0] if defined $_[0]; $self->{ok} = 0 if $self->{errors} || $self->{skips} || $self->unsupporteds; return $self->{ok}; } sub continuing { my $self = (ref $_[0]? shift : $Self); return !($self->errors || $self->skips || $self->unsupporteds); } sub errors { my $self = (ref $_[0]? shift : $Self); return $self->{errors}; } sub skips { my $self = (ref $_[0]? shift : $Self); return $self->{skips}; } sub unsupporteds { my $self = (ref $_[0]? shift : $Self); return $self->{unsupporteds}; } sub top_filename { my $self = (ref $_[0]? shift : $Self); $self->{top_filename} = shift if defined $_[0]; return $self->{top_filename}; } sub vhdl { my $self = (ref $_[0]? shift : $Self); $self->{vhdl} = shift if defined $_[0]; if ($self->{vhdl}) { $self->{top_filename} =~ s/\.v$/\.vhdl/; } return $self->{vhdl}; } sub v_suffix { my $self = (ref $_[0]? shift : $Self); # Suffix for file type, e.g. .vhdl or .v return $self->{vhdl} ? "vhdl" : "v"; } sub sc { my $self = (ref $_[0]? shift : $Self); return $self->{sc}; } #---------------------------------------------------------------------- sub run { my $self = (ref $_[0]? shift : $Self); $self->_run(@_); } sub _run { my $self = (ref $_[0]? shift : $Self); my %param = (tee=>1, @_); my $command = join(' ',@{$param{cmd}}); $command = "time $command" if $opt_benchmark && $command !~ /^cd /; 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 $ok = ($wholefile eq $param{expect} || _try_regex($wholefile, $param{expect}) == 1 || $wholefile =~ /$quoted/ms); if (!$ok) { #print "**BAD $self->{name} $param{logfile} MT $moretry $try\n"; next if $moretry; $self->error("Mismatch in output from $param{cmd}[0]\n"); $self->error("Might be error in regexp format\n") if $ok<1; print "GOT:\n"; print $wholefile; print "ENDGOT\n"; print "EXPECT:\n"; print $param{expect}; print "ENDEXPECT\n"; } } last; } } } ####################################################################### # Little utilities sub _try_regex { # Try to eval a regexp # Returns: # 1 if $text ~= /$regex/ms # 0 if no match # -1 if $regex is invalid, doesn't compile my ($text, $regex) = @_; my $result; { local $@; eval { $result = ($text =~ /$regex/ms); }; $result = -1 if $@; } return $result; } 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 \"verilated_vcd_c.h\"\n" if $self->{trace}; print $fh "#include \"verilated_save.h\"\n" if $self->{savable}; print $fh "$VM_PREFIX * topp;\n"; if (!$self->sc) { 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) { 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->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"); $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) { $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(" unsigned int save_time = !save_time_strp[0] ? 0 : atoi(save_time_strp+strlen(\"+save_time=\"));\n"); $fh->print(" const char* save_restore_strp = Verilated::commandArgsPlusMatch(\"save_restore=\");\n"); $fh->print(" unsigned int save_restore = !save_restore_strp[0] ? 0 : 1;\n"); } if ($self->{savable}) { $fh->print(" if (save_restore) {\n"); $fh->print(" restore_model(\"$self->{obj_dir}/saved.vltsv\");\n"); $fh->print(" } else {\n"); } else { $fh->print(" {\n"); } print $fh " ${set}fastclk = false;\n" if $self->{inputs}{fastclk}; print $fh " ${set}clk = false;\n" if $self->{inputs}{clk}; _print_advance_time($self, $fh, 10); print $fh " }\n"; print $fh " while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {\n"; for (my $i=0; $i<5; $i++) { my $action = 0; if ($self->{inputs}{fastclk}) { print $fh " ${set}fastclk=!${set}fastclk;\n"; $action = 1; } if ($i==0 && $self->{inputs}{clk}) { print $fh " ${set}clk=!${set}clk;\n"; $action = 1; } if ($self->{savable}) { $fh->print(" if (sc_time_stamp() == save_time && save_time) {\n"); $fh->print(" save_model(\"$self->{obj_dir}/saved.vltsv\");\n"); $fh->print(" printf(\"Exiting after save_model\\n\");\n"); $fh->print(" exit(0);\n"); $fh->print(" }\n"); } _print_advance_time($self, $fh, 1, $action); } print $fh " }\n"; print $fh " if (!Verilated::gotFinish()) {\n"; print $fh ' vl_fatal(__FILE__,__LINE__,"main", "%Error: Timeout; never got a $finish");',"\n"; print $fh " }\n"; print $fh " topp->final();\n"; if ($self->{coverage}) { $fh->print("#if VM_COVERAGE\n"); $fh->print(" VerilatedCov::write(\"",$self->{coverage_filename},"\");\n"); $fh->print("#endif //VM_COVERAGE\n"); } if ($self->{trace}) { $fh->print("#if VM_TRACE\n"); $fh->print(" if (tfp) tfp->close();\n"); $fh->print("#endif //VM_TRACE\n"); } $fh->print("\n"); print $fh " delete topp; topp=NULL;\n"; print $fh " exit(0L);\n"; print $fh "}\n"; $fh->close(); } sub _print_advance_time { my $self = shift; my $fh = shift; my $time = shift; my $action = shift; my $set; if ($self->sc) { $set = ""; } else { $set = "topp->"; } if ($self->sc) { 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) { $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 " ${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 " ${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 " signal ${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 _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 $cmd = qq{vcddiff --help}; print "\t$cmd\n" if $::Debug; my $out = `$cmd`; if ($out !~ /Usage:/) { $self->skip("No vcddiff installed\n"); return 0; } $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; } our $_Cxx_Version; sub cxx_version { $_Cxx_Version ||= `make -f Makefile print-cxx-version`; return $_Cxx_Version; } our $_Cfg_With_Threaded; sub cfg_with_threaded { my $out = `make -f ../Makefile print-cfg-with-threaded`; return ($out =~ /yes/i) ? 1:0; } sub file_grep_not { my $self = (ref $_[0]? shift : $Self); my $filename = shift; my $regexp = shift; my $expvalue = shift; return if $self->errors || $self->skips || $self->unsupporteds; !defined $expvalue or $self->error("file_grep_not: Unexpected 3rd argument: $expvalue"); my $contents = $self->file_contents($filename); return if ($contents eq "_Already_Errored_"); if ($contents =~ /$regexp/) { $self->error("File_grep_not: $filename: Regexp found: $regexp\n"); } } sub file_grep { my $self = (ref $_[0]? shift : $Self); my $filename = shift; my $regexp = shift; my $expvalue = shift; return if $self->errors || $self->skips || $self->unsupporteds; my $contents = $self->file_contents($filename); return if ($contents eq "_Already_Errored_"); if ($contents !~ /$regexp/) { $self->error("File_grep: $filename: Regexp not found: $regexp\n"); } elsif ($expvalue && $expvalue ne $1) { $self->error("File_grep: $filename: Got='$1' Expected='$expvalue' in regexp: $regexp\n"); } } my %_File_Contents_Cache; sub file_contents { my $self = (ref $_[0]? shift : $Self); my $filename = shift; if (!$_File_Contents_Cache{$filename}) { my $fh = IO::File->new("<$filename"); if (!$fh) { $_File_Contents_Cache{$filename} = "_Already_Errored_"; $self->error("File_grep file not found: ".$filename."\n"); return $_File_Contents_Cache{$filename}; } local $/; undef $/; my $wholefile = <$fh>; $fh->close(); $_File_Contents_Cache{$filename} = $wholefile; } return $_File_Contents_Cache{$filename}; } sub write_wholefile { my $self = (ref $_[0]? shift : $Self); my $filename = shift; my $contents = shift; my $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename,"; print $fh $contents; $fh->close; } ####################################################################### ####################################################################### ####################################################################### ####################################################################### # Forker class package Forker; use strict; # This is a shell that matches Parallel::Forker. # If that package is not installed, this runs the tests in *series* sub new { my $class = shift; my $self = {@_}; bless $self, $class; return $self; } sub schedule { my $self = shift; my %params = (@_); &{$params{run_on_start}}(); &{$params{run_on_finish}}(); return $self; } sub max_proc {} sub sig_child {} sub kill_tree_all {} sub wait_all {} sub ready {} sub running {} ####################################################################### 1; package main; __END__ =pod =head1 NAME driver.pl - Run regression tests =head1 SYNOPSIS driver.pl =head1 DESCRIPTION driver.pl invokes Verilator or another simulator on each test file. The driver reports the number of tests which pass, fail, skipped (some resource required by the test is not available, such as SystemC), or are unsupported (buggy or require a feature change before will pass.) There are hundreds of tests, and for faster completion you may want to run the regression tests with CCACHE enabled and in parallel on a machine with many cores. See the -j option. =head1 TEST CONFIGURATION The Perl script (e.g. C) controls how the test will run by driver.pl. In general it includes a call to the C subroutine to compile the test with Verilator (or an alternative simulator), followed by a call to the C subroutine to run the test. Compile-only tests omit the call to C. If those complete, the script calls C to increment the count of successful tests and then returns 1 as its result. Both C and C take an optional argument hash table to control their behavior. For example: compile ( verilator_flags2 => ["--lint-only"], fails => 1, ); indicates that when compiling this test, the C<--lint-only> flag should be passed and that the test is expected to fail. The full list of arguments can be found by looking at the C source code. Some commonly used arguments are: =over 4 =item all_run_flags A list of flags to be passed when running the simulator (Verilated model or one of the other simulators). =item check_finished Set to 1 to indicate successful completion of the test is indicated by the string C<*-* All Finished *-*> being printed on standard output. This is the normal way for successful tests to finish. =item expect A quoted list of strings or regular expression to be matched in the output. See for more detail on how this argument should be used. =item fails Set to 1 to indicate this step (C or C) is expected to fail. Tests that are expected to fail generally have _bad in their filename. =item make_main Set to 0 to disable the automatic creation of a C++ test wrapper (for example when a hand-written test wrapper is provided using C<--exe>). =item make_top_shell Set to 0 to disable the automatic creation of a top level shell to run the executable (for example when a hand-written test wrapper is provided using C<--exe>). =item ms_flags =item ms_flags2 =item ms_run_flags The equivalent of C, C and C, but only for use with the ModelSim simulator. =item nc_flags =item nc_flags2 =item nc_run_flags The equivalent of C, C and C, but only for use with the Cadence NC simulator. =item iv_flags =item iv_flags2 =item iv_run_flags The equivalent of C, C and C, but only for use with the Icarus Verilog simulator. =item v_flags A list of standard Verilog simulator flags to be passed to the simulator compiler (Verilator or one of the other simulators). This list is create by the driver and rarely changed, use v_flags2 instead. =item v_flags2 A list of standard Verilog simulator flags to be passed to the simulator compiler (Verilator or one of the other simulators). Unlike v_flags, these options may be overridden in some simulation files. Similar sets of flags exist for atsim, GHDL, Cadence NC, Modelsim and Synopsys VCS. =item vcs_flags =item vcs_flags2 =item vcs_run_flags The equivalent of C, C and C, but only for use with the Synopsys VCS simulator. =item verilator_flags =item verilator_flags2 The equivalent of C and C, but only for use with Verilator. If a flag is a standard flag (+incdir for example) v_flags2 should be used instead. =back =head2 HINTS ON WRITING TESTS There is generally no need for the test to create its own main program or top level shell as the driver creates one automatically, however some tests require their own C++ or SystemC test harness. This is commonly given the same name as the test, but with .cpp as suffix (C). This can be specified as follows: compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], ); Tests should be self-checking, rather than producing lots of output. If a test succeeds it should print C<*-* All Finished *-*> to standard output and terminate (in Verilog C<$finish>), if not it should just stop (in Verilog C<$stop>) as that signals an error. If termination should be triggered from the C++ wrapper, the following code can be used: vl_fatal (__FILE__, __LINE__, "dut", ""); exit (1); This can be particularly useful if checking that the Verilator model has not unexpectedly terminated. if (Verilated::gotFinish ()) { vl_fatal (__FILE__, __LINE__, "dut", ""); exit (1); } Where it might be useful for a test to produce output, it should qualify this with C. For example in Verilog: `ifdef TEST_VERBOSE $write ("Conditional generate if MASK [%1d] = %d\n", g, MASK[g]); `endif Or in a hand-written C++ wrapper: #ifdef TEST_VERBOSE cout << "Read a = " << a << endl; #endif The C argument should not generally be used to decide if a test has succeeded. However, in the case of tests that are designed to fail at compile time, it is the only option. For example: compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Error: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Error: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Error: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Error: Exiting due to .*}, ); The strings to match should be made general - for example the line numbers in the Verilog should not be critical and the total number of errors should not matter. This makes it easier to extend or modify the test in future. =head1 DRIVER ARGUMENTS =over 4 =item --atsim Run using ATSIM simulator. =item --benchmark [] Show execution times of each step. If an optional number is given, specifies the number of simulation cycles (for tests that support it). =item --debug Same as C: Use the debug version of Verilator which enables additional assertions, debugging messages, and structure dump files. =item --debugi(-) Same as C: Set Verilator internal debugging level globally to the specified debug level (1-10) or set the specified source file to the specified level. Higher levels produce more detailed messages (plain C<--debug> is equivalent to C<--debugi 4>). =item --dump-tree Same as C: Enable Verilator writing .tree debug files with dumping level 3, which dumps the standard critical stages. For details on the format see the Verilator Internals manual. =item --gdb Same as C: Run Verilator under the debugger. =item --gdbbt Same as C: Run Verilator under the debugger, only to print backtrace information. Requires --debug. =item --gdbsim Run Verilator generated executable under the debugger. =item --ghdl Run using GHDL simulator. =item --golden Update golden files, equivalent to setting HARNESS_UPDATE_GOLDEN=1. =item --help Displays this message and program version and exits. =item --iverilog Run using Icarus Verilog simulator. =item --j # Run number of parallel tests, or 0 to determine the count based on the number of cores installed. Requires Perl's Parallel::Forker package. =item --ms Run using ModelSim simulator. =item --nc Run using Cadence NC-Verilog simulator. =item --optimize Randomly turn on/off different optimizations. With specific flags, use those optimization settings =item --site Run site specific tests also. =item --stop Stop on the first error. =item --trace Set the simulator specific flags to request waveform tracing. =item --unsupported Run tests even if marked as unsupported. =item --vcs Run using Synopsys VCS simulator. =item --verbose Compile and run the test in verbose mode. This means C will be defined for the test (Verilog and any C++/SystemC wrapper). =item --vlt Run using Verilator. Defaults set unless another simulator is requested. =back =head1 ENVIRONMENT =over 4 =item SYSTEMC Root directory name of SystemC kit. Only used if SYSTEMC_INCLUDE not set. =item SYSTEMC_INCLUDE Directory name with systemc.h in it. =item VERILATOR_GHDL Command to use to invoke GHDL. =item VERILATOR_IVERILOG Command to use to invoke Icarus Verilog. =item VERILATOR_MODELSIM Command to use to invoke ModelSim. =item VERILATOR_NCVERILOG Command to use to invoke ncverilog. =item VERILATOR_TESTS_SITE With --site, directory of tests to be added to testlist. =item VERILATOR_VCS Command to use to invoke VCS. =back =head1 DISTRIBUTION The latest version is available from L. Copyright 2003-2017 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.916/test_regress/Makefile_obj0000664000177100017500000000427613205574202020534 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/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 SC_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 += -DVM_PREFIX_INCLUDE="<$(VM_PREFIX).h>" CPPFLAGS += $(CPPFLAGS_DRIVER) CPPFLAGS += $(CPPFLAGS_DRIVER2) CPPFLAGS += $(CPPFLAGS_ADD) ifeq ($(CFG_WITH_LONGTESTS),yes) ifeq ($(DRIVER_STD),newest) CPPFLAGS += $(CFG_CXXFLAGS_STD_NEWEST) else ifeq ($(DRIVER_STD),oldest) CPPFLAGS += $(CFG_CXXFLAGS_STD_OLDEST) endif endif ####################################################################### # Linking final exe ifeq ($(VM_SC),1) LIBS += $(SC_LIBS) endif .SUFFIXES: #Default compile, pick up OBJCACHE %.o: %.cpp $(OBJCACHE) $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< #Default link, using normal make rules #$(VM_PREFIX): $(VK_GLOBAL_OBJS) $(VK_OBJS) # $(LINK) $(LDFLAGS) -g $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) 2>&1 | c++filt #Our own compile rules; Faster compile, all in one file $(VM_PREFIX)__ALLboth.cpp: $(VK_CLASSES_CPP) $(VK_SUPPORT_CPP) $(VERILATOR_INCLUDER) -DVL_INLINE_OPT=inline $^ > $@ $(VM_PREFIX)__ALLboth.o: $(VM_PREFIX)__ALLboth.cpp $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $< ifneq ($(MAKE_MAIN),0) $(VM_PREFIX): $(VM_PREFIX)__ALLboth.o $(LINK) $(LDFLAGS) -g $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) 2>&1 | c++filt endif verilator-3.916/test_regress/vgen.pl0000775000177100017500000011465113205574202017540 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); $Rerun_Args =~ s/\s+$//; 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 # Unspecified behavior with == (a-signed / b) -- see t_math_signed5.v test 'VDIV'=> {weight=>1&&8, width=>0, signed=>0, sc=>1, terminal=>0, v=>'((%2)==%xw\'h0 ? %xw\'%xsh0:(%1 / %2))', }, 'VMODDIV'=> {weight=>1&&8, width=>0, signed=>0, sc=>1, terminal=>0, v=>'((%2)==%xw\'h0 ? %xw\'%xsh0:(%1 %% %2))', }, #'VPOW'=> {weight=>2&&0,width=>-64, sc=>0, terminal=>0, v=>'(%1 ** %2)', }, 'VSHIFTL'=> {weight=>1&&8, width=>0, signed=>0, sc=>0, terminal=>0, v=>'(%1 << %2)', }, 'VSHIFTLS'=> {weight=>1&&8, width=>0, signed=>1, sc=>0, terminal=>0, v=>'(%1 <<< %2)', }, 'VSHIFTR'=> {weight=>1&&8, width=>0, signed=>0, sc=>0, terminal=>0, v=>'(%1 >> %2)', }, 'VSHIFTRS'=> {weight=>1&&15,width=>0, signed=>1, sc=>0, terminal=>0, v=>'(%1 >>> %2)', }, # ShiftR seems to sign extend differently for <=32 and >32 bits 'VCONCAT'=> {weight=>1&&4, width=>-2,signed=>0, sc=>0, terminal=>0, v=>'{%1,%2}', }, 'VREPLIC'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'{%1{%2}}', }, 'VREPLIC1W'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'{%1{%2}}', }, 'VSIGNED'=> {weight=>1&&2, width=>0, signed=>1, sc=>0, terminal=>0, v=>'\$signed(%1)', }, 'VUNSIGNED'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'\$unsigned(%1)', }, # Triops 'VCOND'=> {weight=>1&&4, width=>0, sc=>0, terminal=>0, v=>'(%1 ? %2 : %3)', }, # Control flow #VIF #VFOR #VCASE #VCASEX #VCASEZ ); my %ops2 = ( 'VCONST'=> {pl=>'', rnd=>'rnd_const(%tr);'}, 'VIDNEW'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=next_id(%tw);' .' $Vars{%i}=gen_leaf(width=>%tw,trunc=>1,signed=>%tg);' .' $VarAttrs{%i}{lsb} = rnd_lsb();' .' id_commit(%tr,"%i");1;',}, 'VIDOLD'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=id_old(%tr);', ok_id_width=>1,}, 'VIDSAME'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=id_same(%tr);', ok_id_width=>1,}, # These create IDs they then extract from 'VRANGE'=> {pl=>'VRANGE(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});', rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();' .' my $lsb=rnd(128-%tw); my $msb=$lsb+%tw-1;' .' %2r=val_leaf($msb); %3r=val_leaf($lsb);' .' $Vars{%i}=gen_leaf(width=>($msb+1));'}, 'VBITSEL'=> {pl=>'VRANGE(%tr,$Vars{%i}{val},%2v,%2v,$VarAttrs{%i}{lsb});', rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();' .' my $wid=min(128,rnd_width()|3);' .' %2r=gen_leaf(width=>(log2($wid)-1),signed=>0);' .' $Vars{%i}=gen_leaf(width=>$wid);'}, 'VBITSELP'=> {pl=>'VBITSELP(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});', rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();' .' my $wid=min(128,(%tw+rnd_width()|3)); %3r=val_leaf(%tw); my $maxval = $wid-%tw; %2r=(($maxval<4)?val_leaf($maxval):gen_leaf(width=>(log2($maxval)-1),signed=>0));' .' $Vars{%i}=gen_leaf(width=>$wid);'}, 'VBITSELM'=> {pl=>'VBITSELM(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});', rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();' .' my $wid=min(128,(%tw+rnd_width()|3)); %3r=val_leaf(%tw); my $maxval = $wid-1; my $minval=%tw-1; %2r=val_leaf(rnd($maxval-$minval)+$minval);' .' $Vars{%i}=gen_leaf(width=>$wid);'}, # No easy way to make expr with specified minimum # Unary 'VEXTEND'=> {pl=>'VRESIZE (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>rnd_width(%tw-1));'}, 'VLOGNOT'=> {pl=>'VLOGNOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDAND'=> {pl=>'VREDAND (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDOR'=> {pl=>'VREDOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDNAND'=> {pl=>'VREDNAND (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDNOR'=> {pl=>'VREDNOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDXOR'=> {pl=>'VREDXOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDXNOR'=> {pl=>'VREDXNOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VNOT'=> {pl=>'VNOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VNEGATE'=> {pl=>'VNEGATE (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VCOUNTONES'=> {pl=>'VCOUNTONES(%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VONEHOT'=> {pl=>'VONEHOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VONEHOT0'=> {pl=>'VONEHOT0 (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, # Binary 'VAND'=> {pl=>'VAND (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VOR'=> {pl=>'VOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VNAND'=> {pl=>'VNAND (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VNOR'=> {pl=>'VNOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VXOR'=> {pl=>'VXOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VXNOR'=> {pl=>'VXNOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VEQ'=> {pl=>'VEQ (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VNEQ'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VGT'=> {pl=>'VGT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VGTE'=> {pl=>'VGE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VLT'=> {pl=>'VLT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VLTE'=> {pl=>'VLE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VEQCASE'=> {pl=>'VEQ (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VNEQCASE'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VLOGOR'=> {pl=>'VLOGOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>0);'}, 'VLOGAND'=> {pl=>'VLOGAND(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>0);'}, 'VADD'=> {pl=>'VADD (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,}, 'VSUB'=> {pl=>'VSUB (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,}, 'VMUL'=> {pl=>'VMUL (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,}, # Multiply generates larger width, so need truncate for safety 'VDIV'=> {pl=>'VDIV (%tr,%1r,%2r,0);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VMODDIV'=> {pl=>'VDIV (%tr,%1r,%2r,1);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, #'VPOW'=> {pl=>'VPOW (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>min(%tw,6),signed=>%tg); %2r=gen_leaf(width=>min(%tw,8),signed=>%tg);', trunc=>1,}, # Generates larger width, so need truncate for safety 'VSHIFTL'=> {pl=>'VSHIFTL(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'}, 'VSHIFTLS'=> {pl=>'VSHIFTL(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'}, 'VSHIFTR'=> {pl=>'VSHIFTR(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'}, 'VSHIFTRS'=> {pl=>'VSHIFTRS(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'}, 'VCONCAT'=> {pl=>'VCONCAT(%tr,%1v,%2v);', rnd=>'my $d=(rnd(%tw-2)+1); %1r=gen_leaf(width=>$d,signed=>0); %2r=gen_leaf(width=>(%tw-$d),signed=>0);'}, 'VREPLIC'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'my $d=rnd_rep_width(%tw); %1r=val_leaf($d); %2r=gen_leaf(width=>(%tw/$d),signed=>0);'}, 'VREPLIC1W'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'%1r=val_leaf(%tw); %2r=gen_leaf(width=>1,signed=>0);'}, 'VSIGNED'=> {pl=>'VCLONE (%tr,%1v,0);', rnd=>'%1r=gen_leaf(width=>%tw);'}, 'VUNSIGNED'=> {pl=>'VCLONE (%tr,%1v,0);', rnd=>'%1r=gen_leaf(width=>%tw);'}, # Triops 'VCOND'=> {pl=>'VCOND(%tr,%1v,%2v,%3v);', rnd=>'%1r=gen_leaf(width=>1); %2r=gen_leaf(width=>%tw,signed=>%tg); %3r=gen_leaf(width=>%tw,signed=>%tg);'}, ); foreach my $op (keys %ops2) { while ((my $key,my $val) = each %{$ops2{$op}}) { $Ops{$op}{$key} = $val; } } #====================================================================== # main #Bit::Vector->Configuration("ops=arithmetic"); my $opt_seed=5; our $Opt_NumOps = 30; our $Opt_Depth = 4; our $Opt_Output; our $Opt_Signed = 1; our $Opt_Raise; 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, "o=s" => \$Opt_Output, "raise=i" => \$Opt_Raise, "seed=i" => \$opt_seed, "signed!" => \$Opt_Signed, "<>" => \¶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(); $Opt_Output or die "%Error: Need -o option,"; write_output_v($Opt_Output); #---------------------------------------------------------------------- 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); } 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 ($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 for (my $w=0; $w<$val->Word_Size; ++$w) { $val->Word_Store(0,~0); } } elsif ($v<60) { # one $val->Word_Store(0,1); } else { #random for (my $w=0; $w<$val->Word_Size; ++$w) { $val->Word_Store($w,rnd_int()); } } $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);\n"; print $fh " input clk;\n"; print $fh " reg check; initial check = '0;\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 " parameter [31:0] CYCLES /*verilator public*/ = $cycles;\n"; print $fh "\n"; print $fh " integer cyc; initial cyc = 0;\n"; print $fh " always @(posedge clk) begin\n"; print $fh "`ifdef TEST_VERBOSE\n"; print $fh ' $write("[%0t] cyc=%0d check=%d\n", $time, cyc, check);',"\n"; print $fh "`endif\n"; print $fh " cyc <= cyc + 1;\n"; print $fh " if (cyc < CYCLES) begin\n"; print $fh " check <= 1'b0;\n"; print $fh " end\n"; print $fh " else if (cyc >= CYCLES) begin\n"; print $fh " check <= 1'b1;\n"; print $fh " if (cyc >= (CYCLES+10)) begin\n"; print $fh ' $write("*-* All Finished *-*\n");',"\n"; print $fh ' $finish;',"\n"; print $fh " end\n"; print $fh " end\n"; print $fh " end\n"; print $fh "endmodule\n"; $fh->close(); } ###################################################################### sub callers { for (my $i=0; ; $i++) { my @c = caller($i); last if !$c[0]; print "Caller $i: ",join(' ',@c[0..3]),"\n"; } } ####################################################################### ####################################################################### ####################################################################### ####################################################################### # Code generation/emitting Functions sub do_a_test { local $Depth = 0; @Commit = (); %VarsBlock = (); my $block = { name=>"Block".($#Blocks+2), body=>[], preass=>[], inputs=>[], outputs=>[], }; for (my $i=0; $i<$Opt_BlockStmts; $i++) { my $treeref = gen_leaf(width=>0); push @{$block->{body}}, "\tif ($treeref->{text} != ".$treeref->val_to_text().") if (check) ".stop_text().";\n"; } foreach my $var (keys %VarsBlock) { push @{$block->{inputs}}, $var if $VarsBlock{$var}{used} && !$VarsBlock{$var}{set}; } foreach my $var (reverse (sort (keys %Vars))) { my $varref = $Vars{$var}; next if $varref->{printedit}; $varref->{printedit} = 1; push @{$block->{outputs}}, $var; push @{$block->{preass}}, sprintf ("\t$var = %s;\n" ,$varref->{text}); } foreach my $com (@Commit) { &{$com} or die "%Error: Can't eval:\n$com\n $@ "; } push @Blocks, $block; } sub gen_leaf { my $inforef = {width=>0, # Anything need_terminal=>0, #trunc=>undef, # Allow multiply op @_}; $inforef->{width} ||= rnd_width(); $inforef->{signed} = ($Opt_Signed && $inforef->{width}>1 && (rnd(100)<$Signed_Pct))?1:0 if !defined $inforef->{signed}; print +((" "x$Depth)."Leaf of width $inforef->{width}\n") if $Debug; my $op = rnd_op($inforef); my $treeref = new Vg::Base; while ((my $key,my $val) = each %{$op}) { $treeref->{$key} = $val; } while ((my $key,my $val) = each %{$inforef}) { $treeref->{$key} = $val; } local $Depth = $Depth+1; print "RndSub $treeref->{rnd_sub_text}\n" if $Debug; $treeref->{rnd_sub}($treeref); $treeref->tree_dump() if $Debug; print "RndPl\n" if $Debug; $treeref->{pl_sub}($treeref); print "RndV\n" if $Debug; $treeref->{text} = $treeref->{v_sub}($treeref); print "Done\n" if $Debug; print " Value ",$treeref->{val}," = ",$treeref->val_to_text(),"\n" if $Debug; #$treeref->tree_dump() if $Debug; $treeref->{val_size} = $treeref->{val}->Size; #Debugging $treeref->{val_text} = $treeref->{val}->to_Hex; #Debugging ($treeref->{val}->Size == $treeref->{width}) or die "%Error: Size mismatch ",$treeref->{val}->Size,"!=",$treeref->{width},"\n",Dumper($treeref); return $treeref; } sub gen_v { my $opref = shift; my $fmt = $opref->{v}; $fmt =~ s/%1/%s/g; $fmt =~ s/%2/%s/g; $fmt =~ s/%3/%s/g; $fmt =~ s/%v/%s/g; $fmt =~ s/%i/%s/g; $fmt =~ s/%x[wds]/%s/g; my $argl = $opref->{v}; my @args; while ($argl =~ s/(%x.|%.)//) { my $arg = $1; push @args, '$treeref->{op1}{text}' if $arg =~ /%1/; push @args, '$treeref->{op2}{text}' if $arg =~ /%2/; push @args, '$treeref->{op3}{text}' if $arg =~ /%3/; push @args, '$treeref->val_to_text' if $arg =~ /%v/; push @args, '$treeref->{id}' if $arg =~ /%i/; push @args, '$treeref->{signed}?"s":""' if $arg =~ /%xs/; push @args, '$treeref->{width}' if $arg =~ /%xw/; push @args, '$treeref->{width}-$treeref->{op1}{width}' if $arg =~ /%xd/; } my $func = ("sub { " ." my \$treeref = shift;" ." sprintf(\"$fmt\",".join(',',@args).");" ."}"); my $set = ("\$opref->{v_sub} = $func; 1;"); $opref->{v_sub_text} = $func; # For seeing it in debugging dumps #print "Op V $opref->{name} $set\n"; eval($set) or die "%Error: Can't eval:\n$set\n $@ "; } sub escapes { my $str = shift; my $cmt = shift; $str =~ s/%tr/\$treeref/g; $str =~ s/%tg/\$treeref->{signed}/g; $str =~ s/%tv/\$treeref->{val}/g; $str =~ s/%tw/\$treeref->{width}/g; # $str =~ s/%1r/\$treeref->{op1}/g; $str =~ s/%1g/\$treeref->{op1}{signed}/g; $str =~ s/%1n/(\$treeref->{op1}{val}->Word_Read(0))/g; $str =~ s/%1v/\$treeref->{op1}{val}/g; $str =~ s/%1w/\$treeref->{op1}{width}/g; # $str =~ s/%2r/\$treeref->{op2}/g; $str =~ s/%2g/\$treeref->{op2}{signed}/g; $str =~ s/%2n/(\$treeref->{op2}{val}->Word_Read(0))/g; $str =~ s/%2v/\$treeref->{op2}{val}/g; $str =~ s/%2w/\$treeref->{op2}{width}/g; # $str =~ s/%3r/\$treeref->{op3}/g; $str =~ s/%3g/\$treeref->{op3}{signed}/g; $str =~ s/%3n/(\$treeref->{op3}{val}->Word_Read(0))/g; $str =~ s/%3v/\$treeref->{op3}{val}/g; $str =~ s/%3w/\$treeref->{op3}{width}/g; # $str =~ s/%i/\$treeref->{id}/g; ($str !~ /%/) or die "%Error: $cmt: Unknown %% escape in $str,"; return $str; } sub gen_pl { my $opref = shift; my $str = escapes($opref->{pl}, $opref->{name}); my $func = ("sub { " ." my \$treeref = shift;" ." $str;" ."}"); my $set = ("\$opref->{pl_sub} = $func; 1;"); $opref->{pl_sub_text} = $func; # For seeing it in debugging dumps #print "Op PL $opref->{name} $set\n"; eval($set) or die "%Error: Can't eval:\n$set\n $@ "; } sub gen_rnd { my $opref = shift; my $str = escapes($opref->{rnd}, $opref->{name}); my $func = ("sub { " ." my \$treeref = shift;" ." $str;" ."}"); my $set = ("\$opref->{rnd_sub} = $func; 1;"); $opref->{rnd_sub_text} = $func; # For seeing it in debugging dumps #print "Op RND $opref->{name} $set\n"; eval($set) or die "%Error: Can't eval:\n$set\n $@ "; } sub stop_text { return '$stop'; } sub decl_text { my $var = shift; my $decl_with = shift; my $varref = $Vars{$var}; 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; 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 -o vgen.v =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 -o I Specify output filename. =item --raise Pick the specified number of random opcodes, and raise their frequency. =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-2017 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 --depth=10 --blockstmts=10 -o obj_dir/vgen.v" ### compile-command: "v4make test_regress/t/t_vgen.pl " ### End: verilator-3.916/test_regress/input.vc0000664000177100017500000000013413170167153017724 0ustar wsnyderwsnyder +librescan +libext+.v -y t -y obj_dir/ +incdir+t +incdir+../include +incdir+obj_dir/ verilator-3.916/test_regress/Makefile0000664000177100017500000000457113205574202017700 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-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/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 .SUFFIXES: ###################################################################### .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 ####################################################################### # Informational - used by some tests print-cxx-version: $(CXX) --version ###################################################################### 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.916/test_regress/t/0000775000177100017500000000000013206353165016500 5ustar wsnyderwsnyderverilator-3.916/test_regress/t/t_func_twocall.pl0000775000177100017500000000071712473477707022066 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_zx_bad.pl0000775000177100017500000000117013151152521021614 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_unopt_array.pl0000775000177100017500000000077312671044616021740 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_flag_topmodule_bad.pl0000775000177100017500000000145612473477707023216 0ustar 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.916/test_regress/t/t_verilated_all.v0000664000177100017500000000117713205574202022023 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc!=0) begin if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end cyc_eq_5: cover property (@(posedge clk) cyc==5) $display("*COVER: Cyc==5"); export "DPI-C" function dpix_f_int; function int dpix_f_int (); return cyc; endfunction endmodule verilator-3.916/test_regress/t/t_unopt_combo.pl0000775000177100017500000000076612473477707021736 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_preproc_ttempty.v0000664000177100017500000000034313205574202022446 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. //`define TARGET_PACKAGE `define TARGET_PACKAGE_```TARGET_PACKAGE verilator-3.916/test_regress/t/t_program.v0000664000177100017500000000040512473477707020676 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.916/test_regress/t/t_bitsel_struct2.v0000664000177100017500000000274712671044616022177 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.916/test_regress/t/t_var_pins_sc32.pl0000775000177100017500000000405113205574202022032 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -no-pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.916/test_regress/t/t_mem_multi_io2.cpp0000664000177100017500000000333613205574202022271 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 VM_PREFIX_INCLUDE 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.916/test_regress/t/t_inst_first_a.v0000664000177100017500000000142112671044616021677 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_inst_first_a (/*AUTOARG*/ // Outputs o_w5, o_w5_d1r, o_w40, o_w104, // Inputs clk, i_w5, i_w40, i_w104 ); input clk; input [4:0] i_w5; output [4:0] o_w5; output [4:0] o_w5_d1r; input [39:0] i_w40; output [39:0] o_w40; input [104:0] i_w104; output [104:0] o_w104; wire [4:0] o_w5 = i_w5; wire [39:0] o_w40 = i_w40; wire [104:0] o_w104 = i_w104; /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [4:0] o_w5_d1r; // End of automatics always @ (posedge clk) begin o_w5_d1r <= i_w5; end endmodule verilator-3.916/test_regress/t/t_vlcov_data_a.dat0000664000177100017500000000026713205574202022140 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint0ffile1.sphl159' 0 C 'CoverPoint1ffile1.sphl159' 1 C 'CoverPoint2ffile1.sphl159' 10 C 'CoverPoint3ffile1.sphl159' 0 verilator-3.916/test_regress/t/t_case_dupitems.v0000664000177100017500000000344613205574202022042 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.916/test_regress/t/t_clk_concat2.v0000664000177100017500000000334213205574202021372 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // module some_module ( input wrclk ); logic [ 1 : 0 ] some_state; logic [1:0] some_other_state; always @(posedge wrclk) begin case (some_state) 2'b11: if (some_other_state == 0) some_state <= 2'b00; default: $display ("This is a display statement"); endcase if (wrclk) some_other_state <= 0; end endmodule `define BROKEN module t1( input [3:0] i_clks, input i_clk0, input i_clk1 ); some_module some_module ( `ifdef BROKEN .wrclk (i_clks[3]) `else .wrclk (i_clk1) `endif ); endmodule module t2( input [2:0] i_clks, input i_clk0, input i_clk1, input i_clk2, input i_data ); logic [3:0] the_clks; logic data_q; assign the_clks[3] = i_clk1; assign the_clks[2] = i_clk2; assign the_clks[1] = i_clk1; assign the_clks[0] = i_clk0; always @(posedge i_clk0) begin data_q <= i_data; end t1 t1 ( .i_clks (the_clks), .i_clk0 (i_clk0), .i_clk1 (i_clk1) ); endmodule module t( /*AUTOARG*/ // Inputs clk /*verilator clocker*/, input clk0 /*verilator clocker*/, input clk1 /*verilator clocker*/, input clk2 /*verilator clocker*/, input data_in ); input clk; logic [2:0] clks; assign clks = {1'b0, clk1, clk0}; t2 t2 ( .i_clks (clks), .i_clk0 (clk0), .i_clk1 (clk), .i_clk2 (clk2), .i_data (data_in) ); always @(posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_func_plog.pl0000775000177100017500000000071712473477707021362 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_alw.pl0000775000177100017500000000071712473477707021022 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_file_scan.pl0000775000177100017500000000112312473477707022217 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_tri_eqcase.pl0000775000177100017500000000071712671044616021512 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_rand.pl0000775000177100017500000000116113151152521021311 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_blocking.pl0000775000177100017500000000071712473477707021176 0ustar 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.916/test_regress/t/t_struct_pat_width.v0000664000177100017500000000157013205574202022600 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder. module t (clk); input clk; typedef struct packed { logic [2:0] _foo; logic [2:0] _bar; } struct_t; logic [2:0] meh; struct_t param; localparam integer twentyone = 21; // verilator lint_off WIDTH assign param = '{ _foo: twentyone % 8 + 1, _bar: (twentyone / 8) + 1 }; assign meh = twentyone % 8 + 1; // verilator lint_on WIDTH always @ (posedge clk) begin `ifdef TEST_VERBOSE $display("param: %d, %d, %b, %d", param._foo, param._bar, param, meh); `endif if (param._foo != 6) $stop; if (param._bar != 3) $stop; if (param != 6'b110011) $stop; if (meh != 6) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_func_graphcirc.v0000664000177100017500000000177312473477707022215 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.916/test_regress/t/t_dpi_imp_gen.v0000664000177100017500000000136213205574202021462 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 (/*AUTOARG*/ // Inputs clk ); input clk; parameter integer BLKS = 3; generate for (genvar blkIdx=0; blkIdx < BLKS; blkIdx=blkIdx+1 ) begin : slice import "DPI-C" context function void dpi_genvarTest (); initial begin dpi_genvarTest(); $display("slice = %0d : %m", blkIdx); end end endgenerate always @ (posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_interface_down_gen.v0000664000177100017500000000321012671044616023031 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.916/test_regress/t/t_preproc_ifdef.pl0000775000177100017500000000071712473477707022215 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_v2k.v0000664000177100017500000000271312671044616020757 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.916/test_regress/t/t_chg_first.v0000664000177100017500000000330612671044616021167 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk, fastclk ); input clk; input fastclk; // surefire lint_off_line UDDIXN integer _mode; initial _mode=0; reg [31:0] ord1; initial ord1 = 32'h1111; wire [31:0] ord2; reg [31:0] ord3; wire [31:0] ord4; wire [31:0] ord5; wire [31:0] ord6; wire [31:0] ord7; // verilator lint_off UNOPT t_chg_a a ( .a(ord1), .a_p1(ord2), .b(ord4), .b_p1(ord5), .c(ord3), .c_p1(ord4), .d(ord6), .d_p1(ord7) ); // surefire lint_off ASWEMB assign ord6 = ord5 + 1; // verilator lint_on UNOPT always @ (/*AS*/ord2) ord3 = ord2 + 1; always @ (fastclk) begin // surefire lint_off_line ALWLTR ALWMTR if (_mode==1) begin //$write("[%0t] t_chg: %d: Values: %x %x %x %x %x %x %x\n",$time,fastclk,ord1,ord2,ord3,ord4,ord5,ord6,ord7); //if (ord2 == 2 && ord7 != 7) $stop; end end always @ (posedge clk) begin if (_mode==0) begin $write("[%0t] t_chg: Running\n", $time); _mode<=1; ord1 <= 1; end else if (_mode==1) begin _mode<=2; if (ord7 !== 7) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module t_chg_a (/*AUTOARG*/ // Outputs a_p1, b_p1, c_p1, d_p1, // Inputs a, b, c, d ); input [31:0] a; output [31:0] a_p1; wire [31:0] a_p1 = a + 1; input [31:0] b; output [31:0] b_p1; wire [31:0] b_p1 = b + 1; input [31:0] c; output [31:0] c_p1; wire [31:0] c_p1 = c + 1; input [31:0] d; output [31:0] d_p1; wire [31:0] d_p1 = d + 1; endmodule verilator-3.916/test_regress/t/t_param_concat.v0000664000177100017500000000105512473477707021660 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.916/test_regress/t/t_preproc_persist_inc.v0000664000177100017500000000034713205574202023266 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. `ifndef COMMON_GUARD `define COMMON_GUARD 1 Inside `__FILE__. `endif verilator-3.916/test_regress/t/t_math_signed3.v0000664000177100017500000000610112671044616021560 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) module t (/*AUTOARG*/); // verilator lint_off WIDTH wire [1:0] bug729_au = ~0; wire signed [1:0] bug729_as = ~0; wire [2:0] bug729_b = ~0; // the $signed output is unsigned because the input is unsigned; the signedness does not change. wire [0:0] bug729_yuu = $signed(2'b11) == 3'b111; //1'b0 wire [0:0] bug729_ysu = $signed(2'sb11) == 3'b111; //1'b0 wire [0:0] bug729_yus = $signed(2'b11) == 3'sb111; //1'b1 wire [0:0] bug729_yss = $signed(2'sb11) == 3'sb111; //1'b1 wire [0:0] bug729_zuu = 2'sb11 == 3'b111; //1'b0 wire [0:0] bug729_zsu = 2'sb11 == 3'b111; //1'b0 wire [0:0] bug729_zus = 2'sb11 == 3'sb111; //1'b1 wire [0:0] bug729_zss = 2'sb11 == 3'sb111; //1'b1 wire [3:0] bug733_a = 4'b0010; wire [3:0] bug733_yu = $signed(|bug733_a); // 4'b1111 note | is always unsigned wire signed [3:0] bug733_ys = $signed(|bug733_a); // 4'b1111 wire [3:0] bug733_zu = $signed(2'b11); // 4'b1111 wire signed [3:0] bug733_zs = $signed(2'sb11); // 4'b1111 // When RHS of assignment is fewer bits than lhs, RHS sign or zero extends based on RHS's sign wire [3:0] bug733_qu = 2'sb11; // 4'b1111 wire signed [3:0] bug733_qs = 2'sb11; // 4'b1111 reg signed [32:0] bug349_s; reg signed [32:0] bug349_u; wire signed [1:0] sb11 = 2'sb11; wire [3:0] subout_u; sub sub (.a(2'sb11), .z(subout_u)); initial `checkh(subout_u, 4'b1111); wire [5:0] cond_a = 1'b1 ? 3'sb111 : 5'sb11111; initial `checkh(cond_a, 6'b111111); wire [5:0] cond_b = 1'b0 ? 3'sb111 : 5'sb11111; initial `checkh(cond_b, 6'b111111); initial begin // verilator lint_on WIDTH `checkh(bug729_yuu, 1'b0); `checkh(bug729_ysu, 1'b0); `checkh(bug729_yus, 1'b1); `checkh(bug729_yss, 1'b1); `checkh(bug729_zuu, 1'b0); `checkh(bug729_zsu, 1'b0); `checkh(bug729_zus, 1'b1); `checkh(bug729_zss, 1'b1); `checkh(bug733_yu, 4'b1111); `checkh(bug733_ys, 4'b1111); `checkh(bug733_zu, 4'b1111); `checkh(bug733_zs, 4'b1111); `checkh(bug733_qu, 4'b1111); `checkh(bug733_qs, 4'b1111); // verilator lint_off WIDTH bug349_s = 4'sb1111; `checkh(bug349_s, 33'h1ffffffff); bug349_u = 4'sb1111; `checkh(bug349_u, 33'h1ffffffff); bug349_s = 4'sb1111 - 1'b1; `checkh(bug349_s,33'he); bug349_s = 4'sb1111 - 5'b00001; `checkh(bug349_s,33'he); case (2'sb11) 4'b1111: ; default: $stop; endcase case (sb11) 4'b1111: ; default: $stop; endcase $write("*-* All Finished *-*\n"); $finish; end endmodule module sub (input [3:0] a, output [3:0] z); assign z = a; endmodule verilator-3.916/test_regress/t/t_debug_fatalsrc_bt_bad.pl0000775000177100017500000000144012671044616023625 0ustar 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.916/test_regress/t/t_chg_first.pl0000775000177100017500000000072212671044616021337 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_cat_reopen.out0000664000177100017500000001745013205574202023054 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 t $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.916/test_regress/t/t_dist_fixme.pl0000775000177100017500000000201212671044616021514 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. use IO::File; my $root = ".."; my $Debug; if (!-r "$root/.git") { $Self->skip("Not in a git repository"); } else { ### Must trim output before and after our file list my $files = `cd $root && git ls-files --exclude-standard`; print "ST $files\n" if $Debug; $files =~ s/\s+/ /g; my $cmd = "cd $root && fgrep -n FIX"."ME $files | sort | grep -v t_dist_fixme"; my $grep = `$cmd`; print "$grep\n"; if ($grep ne "") { my %names; foreach my $line (split /\n/, $grep) { $names{$1} = 1 if $line =~ /^([^:]+)/; } $Self->error("Files with FIX"."MEs: ",join(' ',sort keys %names)); } } ok(1); 1; verilator-3.916/test_regress/t/t_param_real.v0000664000177100017500000000112413205574202021307 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Johan Bjork module mod #( parameter real HZ = 0 ); //verilator no_inline_module initial begin if ((HZ-$floor(HZ)) - 0.45 > 0.01) $stop; if ((HZ-$floor(HZ)) - 0.45 < -0.01) $stop; end endmodule module t(); mod #(.HZ(123.45)) mod1(); mod #(.HZ(24.45)) mod2(); initial begin if (mod1.HZ != 123.45) $stop; if (mod2.HZ != 24.45) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_select_bad_msb.v0000664000177100017500000000060412473477707022156 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.916/test_regress/t/t_order_doubleloop.v0000664000177100017500000000456212473477707022576 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.916/test_regress/t/t_lint_input_eq_bad.v0000664000177100017500000000035612671044616022701 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.916/test_regress/t/t_flag_names.pl0000775000177100017500000000104613205574202021454 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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 => ["--mod-prefix modPrefix --top-module t --l2-name l2Name"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_restore_bad.v0000664000177100017500000000057612473477707022557 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.916/test_regress/t/t_interface_top_bad.v0000664000177100017500000000065512671044616022653 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.916/test_regress/t/t_vlcov_data_d.dat0000664000177100017500000000007713205574202022142 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint6ffile1.sphl159' 12 verilator-3.916/test_regress/t/t_clk_first.pl0000775000177100017500000000072212671044616021347 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_shift_sel.pl0000775000177100017500000000072213205574202022351 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_nest.v0000664000177100017500000000201312671044616021566 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.916/test_regress/t/t_flag_wfatal.pl0000775000177100017500000000155512473477707021656 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_param_array.v0000664000177100017500000000416413205574202021511 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jeremy Bennett. module t (/*AUTOARG*/); typedef enum int { PADTYPE_DEFAULT = 32'd0, PADTYPE_GPIO, PADTYPE_VDD, PADTYPE_GND } t_padtype; localparam int STR_PINID [0:15] = '{ "DEF", "ERR", "ERR", "ERR", "ERR", "ERR", "ERR", "ERR", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7" }; typedef struct packed { t_padtype padtype; int aux; } t_pin_descriptor; localparam t_pin_descriptor PINOUT[ 1: 6] = '{ '{default:0, padtype:PADTYPE_GPIO, aux:1}, '{default:0, padtype:PADTYPE_GPIO}, '{default:0, padtype:PADTYPE_GPIO}, '{default:0, padtype:PADTYPE_GPIO}, '{default:0, padtype:PADTYPE_VDD}, '{default:0, padtype:PADTYPE_GND} }; localparam int PINOUT_SIZE = 6; localparam int PINOUT_WA[1:PINOUT_SIZE][3] = '{ '{0, PADTYPE_GPIO, 0}, '{1, PADTYPE_GPIO, 0}, '{2, PADTYPE_GPIO, 0}, '{5, PADTYPE_GPIO, 0}, '{6, PADTYPE_VDD, 0}, '{8, PADTYPE_GND , 0} }; const int pinout_static_const[1:PINOUT_SIZE][3] = '{ '{0, PADTYPE_GPIO, 0}, '{1, PADTYPE_GPIO, 0}, '{2, PADTYPE_GPIO, 0}, '{5, PADTYPE_GPIO, 0}, '{6, PADTYPE_VDD, 0}, '{8, PADTYPE_GND , 0} }; // Make sure consants propagate checkstr #(.PINID(STR_PINID[1]), .EXP("ERR")) substr1 (); checkstr #(.PINID(STR_PINID[8]), .EXP("PA0")) substr8 (); initial begin $display("PINID1 %s", STR_PINID[1]); $display("PINID8 %s", STR_PINID[8]); if (STR_PINID[1] != "ERR") $stop; if (STR_PINID[8] != "PA0") $stop; if (pinout_static_const[1][0] != 0) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module checkstr; parameter int PINID = " "; parameter int EXP = " "; initial begin $display("PID %s EXP %s", PINID, EXP); if (EXP != "ERR" && EXP != "PA0") $stop; if (PINID != EXP) $stop; end endmodule verilator-3.916/test_regress/t/t_math_synmul.v0000664000177100017500000000532512473477707021575 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.916/test_regress/t/t_clk_latchgate.pl0000775000177100017500000000071712473477707022173 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_dpi_imp_gen.pl0000775000177100017500000000077513205574202021642 0ustar 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_imp_gen_c.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_select_bound1.pl0000775000177100017500000000072213205574202022107 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_only.v0000664000177100017500000000033412473477707021237 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.916/test_regress/t/t_lint_realcvt_bad.pl0000775000177100017500000000141713151152521022652 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_langext_3_bad.pl0000775000177100017500000000103612671044616022060 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_clk_concat.pl0000775000177100017500000000072713205574202021465 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_mem_multidim_trace.pl0000775000177100017500000000103613205574202023217 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_mem_multidim.v"); compile ( verilator_flags2 => ['--cc --trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_grey.pl0000775000177100017500000000071712473477707021367 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_assert_synth.pl0000775000177100017500000000102513151152521022077 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_interface_missing_bad.pl0000775000177100017500000000103713205574202023657 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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=> qr{%Error: t/t_interface_missing_bad.v:\d+: Cannot find file containing interface: foo_intf .*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_defparam.v0000664000177100017500000000040712473477707022036 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.916/test_regress/t/t_func_bad_width.pl0000775000177100017500000000151512473477707022343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_tri_gate_nmos.pl0000775000177100017500000000133713161445457022227 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_bitsel_enum.v0000664000177100017500000000123213205574202021512 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Jonathon Donaldson. module t_bitsel_enum ( output out0, output out1 ); localparam [6:0] CNST_VAL = 7'h22; enum logic [6:0] { ENUM_VAL = 7'h33 } MyEnum; assign out0 = CNST_VAL[0]; // Not supported by NC-verilog nor VCS, but other simulators do assign out1 = ENUM_VAL[0]; // named values of an enumeration should act like constants so this should work just like the line above works initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_tri_dangle.v0000664000177100017500000000103712473477707021341 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.916/test_regress/t/t_package_abs.v0000664000177100017500000000135412671044616021440 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.916/test_regress/t/t_param_type.v0000664000177100017500000000301113205574202021342 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, output int siz ); initial cnt = 0; always @ (posedge clk) cnt <= cnt + 1; assign siz = $bits (cnt); endmodule verilator-3.916/test_regress/t/t_flag_topmodule.v0000664000177100017500000000075012473477707022233 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.916/test_regress/t/t_array_compare.v0000664000177100017500000000275013205574202022036 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Andrew Bardsley. // bug1071 module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [3:0] array_1 [2:0]; reg [3:0] array_2 [2:0]; reg [3:0] array_3 [3:1]; reg [3:0] elem; reg array_1_ne_array_2; reg array_1_eq_array_2; reg array_1_ne_array_3; reg array_1_eq_array_3; initial begin array_1[0] = 4'b1000; array_1[1] = 4'b1000; array_1[2] = 4'b1000; array_2[0] = 4'b1000; array_2[1] = 4'b1000; array_2[2] = 4'b1000; array_3[1] = 4'b1000; array_3[2] = 4'b0100; array_3[3] = 4'b0100; array_1_ne_array_2 = array_1 != array_2; // 0 array_1_eq_array_2 = array_1 == array_2; // 0 array_1_ne_array_3 = array_1 != array_3; // 1 array_1_eq_array_3 = array_1 == array_3; // 1 //Not legal: array_rxor = ^ array_1; //Not legal: array_rxnor = ^~ array_1; //Not legal: array_ror = | array_1; //Not legal: array_rand = & array_1; `ifdef TEST_VERBOSE $write("array_1_ne_array2==%0d\n", array_1_ne_array_2); $write("array_1_ne_array3==%0d\n", array_1_ne_array_3); `endif if (array_1_ne_array_2 !== 0) $stop; if (array_1_eq_array_2 !== 1) $stop; if (array_1_ne_array_3 !== 1) $stop; if (array_1_eq_array_3 !== 0) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_dpi_context.v0000664000177100017500000000327213205574202021532 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. module t (); sub a (.inst(1)); sub b (.inst(2)); initial begin a.test1; b.test1; a.test2; b.test2; $write("*-* All Finished *-*\n"); $finish; end endmodule module sub (input integer inst); import "DPI-C" context function int dpic_line(); import "DPI-C" context function int dpic_save(int value); import "DPI-C" context function int dpic_restore(); import "DPI-C" context function int unsigned dpic_getcontext(); int result; task test1; // Check line numbering `ifndef verilator // Not all sims support SV2009 `__LINE__, and some that do fail the specific-line test result = dpic_line(); if (!result) $stop; `else result = dpic_line(); if (result !== `__LINE__) $stop; // result = dpic_line(); if (result !== `__LINE__) $stop; `endif // Check save-restore result = dpic_save(23+inst); if (result==0) $stop; endtask task test2; if (dpic_restore() != 23+inst) $stop; endtask int unsigned cntxt1; int unsigned cntxt2; initial begin cntxt1 = dpic_getcontext(); begin : caller_context // call from a different scope - should still get the context of the function declaration cntxt2 = dpic_getcontext(); end // svContext should be the context of the function declaration, not the context of the function call if (cntxt1 != cntxt2) $stop; end endmodule verilator-3.916/test_regress/t/t_threads_counter_0.pl0000775000177100017500000000105613205574202022771 0ustar wsnyderwsnyder#!/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_threads_counter.v"); compile ( verilator_flags2 => ['--cc --no-threads'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_assign_landr.pl0000775000177100017500000000072213205574202022674 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_sel_range_bad.pl0000775000177100017500000000140213205574202023301 0ustar 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_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.916/test_regress/t/t_inst_signed.v0000664000177100017500000000312113205574202021511 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; wire signed [7:0] sgn_wide; wire [7:0] unsgn_wide; // The instantiation will Z extend, not sign extend // verilator lint_off WIDTH sub sub (.clk, .sgn(sgn_wide), .unsgn(unsgn_wide), .iss(3'sh7), .isu(3'h7), .ius(3'sh7), .iuu(3'h7)); // verilator lint_on WIDTH always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("out: 'b%b 'b%b\n", sgn_wide, unsgn_wide); `endif if (sgn_wide[2:0] != 3'sh7) $stop; if (unsgn_wide[2:0] != 3'h7) $stop; // Simulators differ here. if (sgn_wide !== 8'sbzzzzz111 // z-extension - NC && sgn_wide !== 8'sb11111111) $stop; // sign extension - VCS if (unsgn_wide !== 8'sbzzzzz111 && unsgn_wide!== 8'sb00000111) $stop; cyc <= cyc + 1; if (cyc==3) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub ( input clk, output wire signed [2:0] sgn, output wire [2:0] unsgn, input signed [7:0] iss, input signed [7:0] isu, input [7:0] ius, input [7:0] iuu); assign sgn = 3'sh7; assign unsgn = 3'h7; always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("in: %x %x %x %x\n", iss, isu, ius, iuu); if (iss != 8'hff) $stop; if (isu != 8'h07) $stop; if (ius != 8'hff) $stop; if (iuu != 8'h07) $stop; `endif end endmodule verilator-3.916/test_regress/t/t_stream2.pl0000775000177100017500000000072212671044616020744 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_first.pl0000775000177100017500000000071712473477707021373 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface.pl0000775000177100017500000000072212671044616021327 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_types_bad.v0000664000177100017500000000260612671044616022043 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.916/test_regress/t/t_alw_dly.v0000664000177100017500000000266412473477707020673 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.916/test_regress/t/t_mem_packed.pl0000775000177100017500000000071712473477707021473 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_readmem_bad_end.pl0000775000177100017500000000107412473477707023347 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify 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.916/test_regress/t/t_func_task_bad.v0000664000177100017500000000046412473477707022017 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.916/test_regress/t/t_math_repl.pl0000775000177100017500000000071712473477707021361 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_pp_pragmas.v0000664000177100017500000000241312671044616021346 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.916/test_regress/t/t_math_signed5.v0000664000177100017500000001340213205574202021555 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0) `define checkf(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0) `ifdef VERILATOR `define c(v,vs) ($c(vs)) // Don't constify a value `else `define c(v,vs) (v) `endif module t (/*AUTOARG*/ // Outputs ow4_u ); bit fail; reg signed [3:0] w4_s; reg signed [4:0] w5_s; reg [2:0] w3_u; reg [3:0] w4_u; reg [4:0] w5_u; reg [5:0] w6_u; reg [15:0] w16a_u; reg [15:0] w16_u; reg [31:0] w32_u; real r; reg signed [4:0] bug754_a; integer i; //verilator lint_off WIDTH wire a = (5'b0 == (5'sb11111 >>> 3'd7)); wire b = (5'sb11111 == (5'sb11111 >>> 3'd7)); wire c = (1'b0+(5'sb11111 >>> 3'd7)); wire d = (1'sb0+(5'sb11111 >>> 3'd7)); wire e = (5'b0 == (5'sb11111 / 5'sd3)); wire f = (5'sb0 == (5'sb11111 / 5'sd3)); wire g = (5'b01010 == (5'b11111 / 5'sd3)); initial begin // verilator lint_off STMTDLY #1; `ifdef VCS // I-2014.03 `checkh({a, b, c, d, e, f, g}, 7'b1101111); `else `checkh({a, b, c, d, e, f, g}, 7'b1101011); `endif //====================================================================== if ((-1 >>> 3) != -1) $stop; // Decimals are signed i = 3'sb111 >>> 3; `checkh(i, -1); i = -1 >>> 3; `checkh(i, -1); bug754_a = -1; w4_u = |0 != (bug754_a >>> 3'd7); `checkh(w4_u, 4'b0); // Sanity check: -1>>7 == -1 w5_u = (5'sb11111 >>> 3'd7); `checkh(w5_u, 5'b11111); // bug756 w4_u = (5'b0 == (5'sb11111 >>> 3'd7)); `checkh(w4_u, 4'b0001); w4_u = ((5'b0 == (5'sb11111 >>> 3'd7))); // Exp 0 Vlt 0 `checkh(w4_u, 4'b0001); w4_u = ((5'b01111 == (5'sb11111 / 5'sd2))); // Strength-reduces to >>> `ifdef VCS // I-2014.03 `checkh(w4_u, 4'b0000); // Wrong, gets 5'b0==..., unsigned does not propagate `else `checkh(w4_u, 4'b0001); // NC-Verilog, Modelsim, XSim, ... `endif // Does == sign propagate from lhs to rhs? Yes, but not in VCS w4_u = ((5'b01010 == (5'sb11111 / 5'sd3))); // Exp 0 Vlt 0 // Must be signed result (-1/3) to make this result zero `ifdef VCS // I-2014.03 `checkh(w4_u, 4'b0000); // Wrong, gets 5'b0==..., unsigned does not propagate // Somewhat questionable, as spec says division signed depends on only LHS and RHS, however differs from others `else `checkh(w4_u, 4'b0001); // NC-Verilog, Modelsim, XSim, ... `endif w4_u = (1'b0+(5'sb11111 >>> 3'd7)); // Exp 00000 Vlt 000000 Actually the signedness of result does NOT matter `checkh(w4_u, 4'b0000); w4_u = (5'sb0 == (5'sb11111 / 5'sd3)); // Must be signed result (-1/3) to make this result zero `checkh(w4_u, 4'b0001); // Does == width propagate from lhs to rhs? Yes w4_u = (3'b100==(3'b111 << 2)); `checkh(w4_u, 4'b0001); w4_u = (4'b100==(3'b111 << 2)); `checkh(w4_u, 4'b0000); w4_u = (4'b1100==(3'b111 << 2)); `checkh(w4_u, 4'b0001); // Does >>> sign propagate from input same as for +? Yes w4_u = (1'b0+(5'sb11111 >>> 3'd7)); `checkh(w4_u, 4'b0000); w4_u = (1'sb0+(5'sb11111 >>> 3'd7)); `checkh(w4_u, 4'b1111); // Does << width propagate from input same as for +? Yes w4_u = (3'b0+(3'b111 << 2)); `checkh(w4_u, 4'b1100); // width 4 =='s LHS w4_u = (4'b0+(3'b111 << 2)); `checkh(w4_u, 4'b1100); w4_u = (5'sb11111 == (5'sb11111 >>> 3'd7)); // WHAT? Signedness does propagate across ==????? `checkh(w4_u, 4'b0001); w4_u = ((5'b0 == (5'sb11111 >>> 3'd7))); `checkh(w4_u, 4'b0001); // bug756 w5_s = -1; w3_u = 7; w4_u = |0 != (w5_s >>> w3_u); `checkh(w4_u, 4'b0000); // bug763 w3_u = 2; w4_u = (w3_u >> 2'b11) >> 1; `checkh(w4_u, 4'b0000); // bug766 w16a_u = 16'h1234; w16_u = (w16a_u >> 16) >>> 32'h7ffffff1; `checkh(w16_u, 16'h0000); // bug768 w4_s = 4'sd4; w4_u = $signed(5'd1 > w4_s-w4_s); `checkh(w4_u, 4'b1111); w4_s = `c(4,"4"); // Eval at runtime w4_u = $signed(5'd1 > w4_s-w4_s); `checkh(w4_u, 4'b1111); // bug772 w4_s = w4_u << 1 <<< 0/0; `ifndef VERILATOR // In v4 can't check value as not 4-state `checkh(w4_s, 4'bxxxx); `endif // bug773 w5_u = `c(31, 31); w5_s = w5_u >> ((w5_u ? 1 : 2) << w5_u); `checkh(w5_s, 5'b0); // bug774 w4_u = `c(4, 5); w6_u = `c(6, 35); w4_u = 64'd0 | (w4_u << w6_u); `checkh(w4_u, 0); // bug776 w4_u = `c(4, 1); w4_u = (w4_u >> w4_u) ^~ (w4_u >> w4_u); `checkh(w4_u, 4'b1111); // bug828 // verilator lint_off WIDTH w32_u = 32'(signed'({4'b0001,5'b10000}) << 3); `checkh(w32_u, 32'h0000_0180); w32_u = 32'(signed'({4'b0011,5'b10000}) << 3); `checkh(w32_u, 32'h0000_0380); w32_u = signed'(32'({4'b0001,5'b10000}) << 3); `checkh(w32_u, 32'h0000_0180); w32_u = signed'(32'({4'b0011,5'b10000}) << 3); `checkh(w32_u, 32'h0000_0380); // verilator lint_on WIDTH w32_u = 32'(signed'({4'b0011,5'b10000})) << 3; // Check no width warning `checkh(w32_u, 32'h0000_0380); if (fail) $stop; $write("*-* All Finished *-*\n"); $finish; end // bug775 output [3:0] ow4_u; // Must be consumed assign ow4_u = ((0/0) ? 1 : 2) % 0; endmodule verilator-3.916/test_regress/t/t_gen_for2.pl0000775000177100017500000000072213205574202021061 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_werror_bad1.pl0000775000177100017500000000146012473477707022602 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_param_public.pl0000775000177100017500000000115413205574202022016 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. if ($Self->{vlt}) { compile ( verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], make_top_shell => 0, make_main => 0, ); } else { compile ( ); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_pp_underline_bad.v0000664000177100017500000000037512473477707022527 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.916/test_regress/t/t_flag_topmodule_inline.pl0000775000177100017500000000104312473477707023736 0ustar 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.916/test_regress/t/t_trace_decoration.pl0000775000177100017500000000113113205574202022660 0ustar wsnyderwsnyder#!/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 --no-decoration'], ); execute ( check_finished=>1, ); file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr!// Body!x); ok(1); 1; verilator-3.916/test_regress/t/t_mod_recurse1.pl0000775000177100017500000000072213205574202021750 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_initial_dlyass.v0000664000177100017500000000103212671044616022221 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.916/test_regress/t/t_lint_always_comb_bad.v0000664000177100017500000000146212671044616023354 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.916/test_regress/t/t_select_lhs_oob2.pl0000775000177100017500000000071712473477707022454 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gate_basic.pl0000775000177100017500000000071712473477707021467 0ustar 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.916/test_regress/t/t_tri_array_bufif.v0000664000177100017500000000600012473477707022373 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.916/test_regress/t/t_flag_topmodule.pl0000775000177100017500000000104412473477707022401 0ustar 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.916/test_regress/t/t_dpi_accessors.cpp0000664000177100017500000005675713205574202022370 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.t")); // 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.916/test_regress/t/t_order_comboloop.pl0000775000177100017500000000071712473477707022572 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mod_interface_array.pl0000775000177100017500000000072213205574202023355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_topmodule_bad2.pl0000775000177100017500000000134012473477707023270 0ustar 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.916/test_regress/t/t_inst_dtree.v0000664000177100017500000000260713205574202021353 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.916/test_regress/t/t_inst_array_bad.v0000664000177100017500000000112112473477707022204 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.916/test_regress/t/t_dpi_accessors_inc.vh0000664000177100017500000000316312671044616023042 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.916/test_regress/t/t_param_mem_attr.v0000664000177100017500000000211213205574202022172 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.916/test_regress/t/t_package_ddecl.pl0000775000177100017500000000071713205574202022112 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_unused_iface_bad.v0000664000177100017500000000067613205574202023505 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. interface dummy_if (); logic sig_udrv; logic sig_uusd; endinterface: dummy_if module sub ( dummy_if dummy ); assign dummy.sig_uusd = 1'b0 | dummy.sig_udrv; endmodule module t (/*AUTOARG*/); dummy_if dummy (); sub sub (.dummy(dummy) ); endmodule verilator-3.916/test_regress/t/t_preproc_inc_bad.v0000664000177100017500000000034712473477707022345 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.916/test_regress/t/t_func_outp.pl0000775000177100017500000000071712473477707021410 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_endian.v0000664000177100017500000000534312473477707021506 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.916/test_regress/t/t_math_concat.v0000664000177100017500000000546512473477707021522 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.916/test_regress/t/t_enum_int.v0000664000177100017500000000461212473477707021051 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.916/test_regress/t/t_lint_blksync_loop.v0000664000177100017500000000453113205574202022735 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; x1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_param.pl0000775000177100017500000000105113205574202021632 0ustar wsnyderwsnyder#!/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 ( v_flags2 => ["--trace"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_display_bad.pl0000775000177100017500000000121313205574202021627 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_display_bad.v:\d+: Missing arguments for \$display-like format %Error: t/t_display_bad.v:\d+: Unknown \$display-like format code: %q %Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_sformat.pl0000775000177100017500000000071712473477707021757 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_local.v0000664000177100017500000000170712473477707021177 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.916/test_regress/t/t_math_mul.pl0000775000177100017500000000071712473477707021214 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_unopt_converge_unopt_bad.pl0000775000177100017500000000125012473477707024467 0ustar 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.916/test_regress/t/t_inst_dff.pl0000775000177100017500000000072212671044616021163 0ustar 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.916/test_regress/t/t_dpi_exp_bad.pl0000775000177100017500000000121613205574202021615 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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_exp_bad.v:\d+: DPI functions cannot return > 32 bits; use a two-state type or task instead: dpix_f_bit48__Vfuncrtn %Error: Exiting due to .*' ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_slice.v0000664000177100017500000000547013205574202021151 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic use_AnB; logic [1:0] active_command [8:0]; logic [1:0] command_A [8:0]; logic [1:0] command_B [8:0]; logic [1:0] active_command2 [8:0]; logic [1:0] command_A2 [8:0]; logic [1:0] command_B2 [8:0]; logic [1:0] active_command3 [1:0][2:0][3:0]; logic [1:0] command_A3 [1:0][2:0][3:0]; logic [1:0] command_B3 [1:0][2:0][3:0]; logic [2:0] use_A4nB4; logic [8:0][1:0] active_command4; logic [8:0][1:0] command_A4; logic [8:0][1:0] command_B4; logic [8:0] pipe1 [7:0]; logic [8:0] pipe1_input; integer cyc; assign active_command[8:0] = (use_AnB) ? command_A[8:0] : command_B[8:0]; assign active_command2 = (use_AnB) ? command_A2 : command_B2; // Illegal to have [1:0][x:y] here - IEEE only allows single dimension slicing assign active_command3[1:0] = (use_AnB) ? command_A3[1:0] : command_B3[1:0]; // Check we can cope with things other than packed arrays assign active_command4 = (use_A4nB4[0]) ? command_A4 : command_B4; always @ (posedge clk) begin pipe1_input <= pipe1_input + 1; pipe1[0] <= pipe1_input; pipe1[7:1] <= pipe1[6:0]; end logic [3:0][13:0] iq_read_data [15:0]; logic [3:0][13:0] iq_data; logic [3:0] sel; assign iq_data = iq_read_data[sel]; always @ (posedge clk) begin sel = sel + 1; end initial begin cyc = 0; use_AnB = 0; for (int i = 0; i < 7; ++i) begin command_A[i] = 2'b00; command_B[i] = 2'b11; command_A2[i] = 2'b00; command_B2[i] = 2'b11; pipe1_input = 9'b0; end for (int i = 0; i < 2; ++i) begin for (int j = 0; j < 3; ++j) begin for (int k = 0; k < 4; ++k) begin command_A3[i][j][k] = 2'b00; command_B3[i][j][k] = 2'b11; end end end end always @ (posedge clk) begin use_AnB <= ~use_AnB; cyc <= cyc + 1; if (use_AnB) begin if (active_command[3] != 2'b00) begin $stop; end if (active_command2[3] != 2'b00) begin $stop; end if (active_command3[0][1][2] != 2'b00) begin $stop; end end if (!use_AnB) begin if (active_command[3] != 2'b11) begin $stop; end if (active_command2[3] != 2'b11) begin $stop; end end end logic [8:0] last_pipe; always @(posedge clk) begin if (cyc < 3) begin last_pipe <= pipe1[0]; end else begin if (last_pipe + 1 != pipe1[0]) begin $stop; end else begin last_pipe <= pipe1[0]; end end if (cyc > 10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule : t verilator-3.916/test_regress/t/t_var_bad_hide.pl0000775000177100017500000000132012473477707021764 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_order_comboclkloop.v0000664000177100017500000000321512473477707023107 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.916/test_regress/t/t_inst_tree_inl0_pub1.pl0000775000177100017500000000341513205574202023227 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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'], ); sub checkRelativeRefs { my ($mod, $expect_relative) = @_; my $found_relative = 0; my $file = "$Self->{obj_dir}/V$Self->{name}_${mod}.cpp"; my $text = file_contents($file); # Remove "this->__VlSymsp" which is noise $text =~ s/this->__VlSymsp//g; if ($text =~ m/this->/) { $found_relative = 1; } if ($found_relative != $expect_relative) { $Self->error("$file " . ($found_relative ? "has" : "does not have") . " relative variable references."); } } if ($Self->{vlt}) { # We expect to combine sequent functions across multiple instances of # l2, l3, l4, l5. If this number drops, please confirm this has not broken. file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 52); # Expect absolute refs in CFuncs for t (top module) and l1 (because it # has only one instance) checkRelativeRefs("t", 0); checkRelativeRefs("l1", 0); # Others should get relative references checkRelativeRefs("l2", 1); checkRelativeRefs("l3", 1); checkRelativeRefs("l4", 1); checkRelativeRefs("l5__P1", 1); checkRelativeRefs("l5__P2", 1); } execute ( check_finished=>1, expect=> '\] (%m|.*t\.ps): Clocked ', ); ok(1); 1; verilator-3.916/test_regress/t/t_enum_name3.v0000664000177100017500000000066413205574202021243 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jonathon Donaldson. // bug855 module our; typedef enum logic {n,N} T_Flg_N; typedef struct packed { T_Flg_N N; } T_PS_Reg; T_PS_Reg PS = 1'b1; initial begin $write ("P:%s\n", PS.N.name); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_gen_defparam.pl0000775000177100017500000000071712671044616022003 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_public.v0000664000177100017500000000253212473477707021666 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.916/test_regress/t/t_math_clog2.pl0000775000177100017500000000071712473477707021425 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_pull01.pl0000775000177100017500000000071712671044616021366 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_pins_sc_uint_biguint.pl0000775000177100017500000000475113205574202024454 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc --pins-sc-uint --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.916/test_regress/t/t_gen_mislevel.v0000664000177100017500000000121212473477707021675 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.916/test_regress/t/t_func_under2.v0000664000177100017500000000201712671044616021427 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.916/test_regress/t/t_func_begin2.v0000664000177100017500000000147713205574202021400 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.916/test_regress/t/t_math_divw.v0000664000177100017500000001363312473477707021220 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.916/test_regress/t/t_mod_dup_bad.v0000664000177100017500000000041012473477707021460 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.916/test_regress/t/t_param_value.v0000664000177100017500000000332113205574202021501 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.916/test_regress/t/t_math_vgen.pl0000775000177100017500000000071712473477707021356 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_lsb.v0000664000177100017500000000404212671044616020626 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.916/test_regress/t/t_select_plus.pl0000775000177100017500000000071712473477707021730 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_mlog2.v0000664000177100017500000000234512473477707021267 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.916/test_regress/t/t_dpi_string_c.cpp0000664000177100017500000000237413151152521022171 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.916/test_regress/t/t_a_first_cc.v0000664000177100017500000000053113205574202021301 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // Test loop always @ (posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_inside.v0000664000177100017500000000404112671044616020467 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.916/test_regress/t/t_lint_unused_bad.v0000664000177100017500000000160313205574202022345 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.916/test_regress/t/t_vlcov_data_c.dat0000664000177100017500000000007713205574202022141 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint6ffile1.sphl159' 10 verilator-3.916/test_regress/t/t_struct_notfound_bad.v0000664000177100017500000000052212671044616023262 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.916/test_regress/t/t_udp_bad.pl0000775000177100017500000000120412671044616020761 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_param_repl.v0000664000177100017500000000230212671044616021334 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.916/test_regress/t/t_func_first.pl0000775000177100017500000000071712473477707021550 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_concat.pl0000775000177100017500000000077412473477707022040 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_math_vgen.v0000664000177100017500000002422213164174554021172 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg check; initial check = 1'b0; // verilator lint_off WIDTH //============================================================ reg [ 1:0] W0095; //=3 reg [ 58:0] W0101; //=0000000FFFFFFFF always @(posedge clk) begin if (cyc==1) begin W0095 = ((2'h3)); W0101 = ({27'h0,({16{(W0095)}})}); end end always @(posedge clk) begin if (cyc==2) begin if ((W0101) != (59'h0FFFFFFFF)) if (check) $stop; end end //============================================================ reg [ 0:0] W1243; //=1 always @(posedge clk) begin if (cyc==1) begin W1243 = ((1'h1)); end end always @(posedge clk) begin if (cyc==2) begin // Width violation, but still... if (((-W1243) < 32'h01) != (1'h0)) if (check) $stop; if (({32{W1243}} < 32'h01) != (1'h0)) if (check) $stop; end end //============================================================ reg [ 0:0] W0344; //=0 always @(posedge clk) begin if (cyc==1) begin W0344 = 1'b0; end end always @(posedge clk) begin if (cyc==2) begin if ((W0344) != (1'h0)) if (check) $stop; if (({116{(((- 95'h7FFFFFFFFFFFFFFFFFFFFFFF) ^ 95'h7FFFFFFFFFFFFFFFFFFFFFFF ) == ({94'h0,W0344}))}})) if (check) $stop; end end //============================================================ reg [ 63:0] W0372; //=FFFFFFFFFFFFFFFF reg [118:0] W0420; //=7FFFFFFFFFFFFFFFFFFFFFFFFFFFFF reg [115:0] W0421; //=00000000000000000000000000000 always @(posedge clk) begin if (cyc==1) begin W0372 = ({64{((1'h1))}}); W0421 = 116'h0; W0420 = ({119{((W0372) <= (W0372))}}); end end always @(posedge clk) begin if (cyc==2) begin if ((W0420[(- (W0421[115:110]))]) != (1'h1)) if (check) $stop; end end //============================================================ // gcc_2_96_bug reg [ 31:0] W0161; //=FFFFFFFF reg [ 62:0] W0217; //=0000000000000000 reg [ 53:0] W0219; //=00000000000000 always @(posedge clk) begin if (cyc==1) begin W0161 = 32'hFFFFFFFF; W0217 = 63'h0; W0219 = 54'h0; end end always @(posedge clk) begin if (cyc==2) begin if ((W0161) != (32'hFFFFFFFF)) if (check) $stop; if (((- (W0161)) & ((W0217[62:31]) & ({25'h0,(W0219[53:47])}))) != (32'h00000000)) if (check) $stop; end end //============================================================ reg [119:0] W0592; //=000000000000000000000000000000 reg [ 7:0] W0593; //=70 always @(posedge clk) begin if (cyc==1) begin W0593 = (((8'h90)) * ((8'hFF))); W0592 = 120'h000000000000000000000000000000; end end always @(posedge clk) begin if (cyc==2) begin if (((W0592[119:9]) >> ((W0593))) != (111'h0000000000000000000000000000)) if (check) $stop; end end //============================================================ reg [127:0] WA1063 ; //=00000000000000000000000000000001 reg [ 34:0] WA1064 /*verilator public*/; //=7FFFFFFFF reg [ 62:0] WA1065 ; //=0000000000000000 reg [ 89:0] WA1066 /*verilator public*/; //=00000000000000000000001 reg [ 34:0] WA1067 ; //=7FFFFFFFF reg [111:0] WA1068; always @(check) begin WA1067 = (~ (35'h0)); WA1066 = (90'h00000000000000000000001); WA1065 = (WA1066[89:27]); WA1064 = (WA1067); WA1063 = (~ ((~ (128'hffffffffffffffffffffffffffffffff)) ^ (~ (128'h00000000000000000000000000000001)))); end always @(posedge clk) begin if (cyc==2) begin if ((WA1063[(WA1064[(WA1065[((5'h04) | (5'h0))+:4])+:3])+:112]) != 112'h0) if (check) $stop; end end //============================================================ reg [127:0] WB1063 ; //=00000000000000000000000000000001 reg [ 34:0] WB1064 /*verilator public*/; //=7FFFFFFFF reg [ 62:0] WB1065 ; //=0000000000000000 reg [ 89:0] WB1066 /*verilator public*/; //=00000000000000000000001 reg [ 34:0] WB1067 ; //=7FFFFFFFF reg [111:0] WB1068; always @(posedge clk) begin if (cyc==1) begin WB1067 = (~ (35'h0)); WB1066 = (90'h00000000000000000000001); end if (cyc==2) WB1065 <= (WB1066[89:27]); if (cyc==3) WB1064 <= (WB1067); if (cyc==4) WB1063 <= (~ ((~ (128'hffffffffffffffffffffffffffffffff)) ^ (~ (128'h00000000000000000000000000000001)))); if (cyc==5) WB1068 <= (WB1063[(WB1064[(WB1065[((5'h04) | (5'h0))+:4])+:3])+:112]); end always @(posedge clk) begin if (cyc==9) begin if (WB1068 != 112'h0) if (check) $stop; if ((WB1063[(WB1064[(WB1065[((5'h04) | (5'h0))+:4])+:3])+:112]) != 112'h0) if (check) $stop; end end //============================================================ reg signed [ 60:0] WC0064 ; //=1FFFFFFFFFFFFFFF reg signed [ 6:0] WC0065 ; //=00 reg signed [ 62:0] WC0067 /*verilator public*/; //=33250A3BFFFFFFFF always @(check) begin WC0064 = 61'sh1FFFFFFFFFFFFFFF; WC0065 = 7'sh0; if (((WC0064) >>> (WC0065)) != 61'sh1fffffffffffffff) if (check) $stop; end //============================================================ reg signed [ 76:0] W0234 ; //=00000000000000000000 reg signed [ 7:0] W0235 /*verilator public*/; //=B6 always @(check) begin W0235 = 8'shb6; W0234 = ((77'sh0001ffffffffffffffff) >>> (W0235)); if ((W0234) != 77'sh0) if (check) $stop; end //============================================================ reg signed [ 30:0] W0146 ; //=00000001 always @(check) begin : Block71 W0146 = (31'sh00000001); if ((W0146 >>> 6'sh3f) != 31'sh0) if (check) $stop; end //============================================================ reg signed [ 54:0] W0857 /*verilator public*/; //=7FFFFFFFFFFFFF always @(check) begin : Block405 W0857 = 55'sh7fffffffffffff; if ((63'sh7fffffffffffffff >>> (W0857[54:54] ? 7'sh56 : 7'sh7f)) != 63'sh7fffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((((122'sh3ffffffffffffffd3e48e0900000001 >>> 8'shff) >>> 8'b1) ) != 122'sh3ffffffffffffffffffffffffffffff) if (check) $stop; if (((95'sh7fff_ffff_ffffffff_ffffffff < 95'sh4a76_3d8b_0f4e3995_1146e342) != 1'h0)) if (check) $stop; end //============================================================ reg signed [ 82:0] W0226 ; //=47A4301EE3FB4133EE3DA always @* begin : Block144 W0226 = 83'sh47A4301EE3FB4133EE3DA; if ((W0226 >>> 8'sh1a) != 83'sh7ffffff1e90c07b8fed04) if (check) $stop; end //============================================================ reg signed [ 68:0] W0792 /*verilator public*/; //=169351569551247E0C reg signed [ 68:0] W0793 ; //=1FFFFFFFFF4EB1A91A always @(posedge clk) begin W0793 <= 69'sh1f_ffffffff_4eb1a91a; W0792 <= (W0793 * 69'sh1F_0E989F3E_F15F509E); if (W0792 != 69'sh16_93515695_51247E0C) if (check) $stop; end //============================================================ reg signed [ 2:0] DW0515 /*verilator public*/; //=7 always @(posedge clk) begin DW0515 <= 3'sh7; if ($signed({62'h0,DW0515[1'h1]}) != 63'sh0000000000000001) if (check) $stop; end //============================================================ reg signed [ 62:0] W0753 ; //=004E20004ED93E26 reg [ 2:0] W0772 /*verilator public*/; //=7 always @(posedge clk) begin W0753 <= 63'sh004E20004ED93E26; //(63'sh7fffffffffffffff + (63'sh464eac8c4ed93e27 & (63'sh08cf6243ffffffff))); W0772 <= 3'h7; if ((W0772[(W0753 < 63'sh0876c66a7e29fabf)]) != 1'h1) if (check) $stop; if ((W0772[(63'sh004E20004ED93E26 < 63'sh0876c66a7e29fabf)]) != 1'h1) if (check) $stop; end //============================================================ reg [ 98:0] W1027 ; //=7FFFFFFFFFFFFFFFFFFFFFFFF always @(posedge clk) begin W1027 <= ~99'h0; // verilator lint_off CMPCONST if (((1'sb1 < (95'sh7fffffffffffffffffffffff >= 95'sh09deb904ffffffffe062d44c))) != 1'h0) if (check) $stop; // verilator lint_on CMPCONST end //============================================================ reg signed [ 5:0] W123_is_3f ; //=3F always @(posedge clk) begin W123_is_3f <= 6'sh3f; end always @(posedge clk) begin if (((~ ((32'sh088d1bcb) <<< W123_is_3f)) >>> 6'sh3f) != 32'shffffffff) if (check) $stop; end //============================================================ reg signed [105: 0] W0032 /*verilator public*/; //=106'h3ff0000000100000000bd597bb1 always @(check) begin : Block237 W0032 = 106'sh3ff0000000100000000bd597bb1; if ((106'sh1ca0000000000000000b96b8dc2 / 106'sh3ff0000000100000000bd597bb1) != 106'sh3fffffffffffffffffffffffe36) if (check) $stop; if ((106'sh1ca0000000000000000b96b8dc2 / W0032) != 106'sh3fffffffffffffffffffffffe36) if (check) $stop; end //============================================================ reg signed [ 83: 0] W0024 ; //=84'h0000000000000e1fe9094 reg signed [ 83: 0] W0025 ; //=84'h0f66afffffffe308b3d7c always @(posedge clk) begin W0024 <= 84'h0000000000000e1fe9094; W0025 <= 84'h0f66afffffffe308b3d7c; if ((W0024 % W0025) != 84'sh0000000000000e1fe9094) if (check) $stop; end //============================================================ always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==18) begin check <= 1'b1; end if (cyc==20) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_math_divw.pl0000775000177100017500000000071712473477707021370 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_pow5.v0000664000177100017500000000321613205574202021113 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 [67:0] q; reg signed [67:0] qs; initial begin q = 68'he_12345678_9abcdef0 ** 68'h3; if (q != 68'hcee3cb96ce96cf000) $stop; // q = 68'he_12345678_9abcdef0 ** 68'h5_6789abcd_ef012345; if (q != 68'h0) $stop; // qs = 68'she_12345678_9abcdef0 ** 68'sh3; if (qs != 68'shcee3cb96ce96cf000) $stop; // qs = 68'she_12345678_9abcdef0 ** 68'sh5_6789abcd_ef012345; if (qs != 68'h0) $stop; end reg [67:0] left; reg [67:0] right; wire [67:0] outu = left ** right; wire signed [67:0] outs = $signed(left) ** $signed(right); 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, outu, outs); `endif if (cyc==1) begin left <= 68'h1; right <= '0; end if (cyc==2) begin if (outu != 68'h1) $stop; if (outs != 68'h1) $stop; end if (cyc==3) begin left <= 68'he_12345678_9abcdef0; right <= 68'h3; end if (cyc==4) begin if (outu != 68'hcee3cb96ce96cf000) $stop; if (outs != 68'hcee3cb96ce96cf000) $stop; end if (cyc==5) begin left <= 68'he_12345678_9abcdef0; right <= 68'h5_6789abcd_ef012345; end if (cyc==6) begin if (outu != 68'h0) $stop; if (outs != 68'h0) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_dist_tabs.pl0000775000177100017500000000425513205574202021341 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 { ### Must trim output before and after our file list my %warns; my $prefix; my $summary; { my $diff = `cd $root && git diff HEAD`; #print "DS $diff\n" if $Debug; my $file; my $atab; my $btab; foreach my $line ((split /\n/, $diff), "+++ b/_the_end") { if ($line =~ m!^\+\+\+ b/(.*)!) { if ($file && !$atab && $btab) { $summary = "File modifications adds new tabs (please untabify the patch):"; $warns{$file} = "File modification adds new tabs (please untabify the patch): $file"; } # Next $file = $1; $atab = 0; $btab = 0; print " File $file\n" if $Self->{verbose}; } elsif ($line =~ m!^[- ].*\t!) { print " Had tabs\n" if $Self->{verbose} && !$atab; $atab = 1; } elsif ($line =~ m!^\+.*\t!) { print " Inserts tabs\n" if $Self->{verbose} && !$btab; $btab = 1; } } } if (keys %warns) { # First warning lists everything as that's shown in the driver summary $Self->error($summary." ",join(' ',sort keys %warns)); foreach my $file (sort keys %warns) { $Self->error($warns{$file}); } } } sub _has_tabs { my $filename = shift; my $contents = file_contents($filename); if ($filename =~ /\.out$/) { # Ignore golden files } elsif ($contents =~ /[\001\002\003\004\005\006]/) { # Ignore binrary files } elsif ($contents =~ /\t/) { return 1; } return 0; } ok(1); 1; verilator-3.916/test_regress/t/t_interface_array.v0000664000177100017500000000332113205574202022343 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Functionally demonstrate an array of interfaces // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. interface foo_intf; logic a; modport source ( output a ); modport sink ( input a ); endinterface function integer identity (input integer val); return val; endfunction module t (/*AUTOARG*/ // Inputs clk ); input clk; localparam N = 5; logic [N-1:0] a_in; logic [N-1:0] a_out; logic [N-1:0] ack_out; foo_intf foos [N-1:0] (); // Deferred link dotting with genvars generate genvar i; for (i = 0; i < N-4; i++) begin : someLoop assign ack_out[i] = a_in[i]; assign foos[i].a = a_in[i]; assign a_out[i] = foos[i].a; end endgenerate // Defferred link dotting with localparam localparam THE_LP = N-3; assign ack_out[THE_LP] = a_in[THE_LP]; assign foos[THE_LP].a = a_in[THE_LP]; assign a_out[THE_LP] = foos[THE_LP].a; // Defferred link dotting with arithmetic expression assign ack_out[N-2] = a_in[N-2]; assign foos[N-2].a = a_in[N-2]; assign a_out[N-2] = foos[N-2].a; // Defferred link dotting with funcrefs assign ack_out[identity(N-1)] = a_in[identity(N-1)]; assign foos[identity(N-1)].a = a_in[identity(N-1)]; assign a_out[identity(N-1)] = foos[identity(N-1)].a; initial a_in = '0; always @(posedge clk) begin a_in <= a_in + { {N-1 {1'b0}}, 1'b1 }; if (ack_out != a_out) begin $display("%%Error: Interface and non-interface paths do not match: 0b%b 0b%b", ack_out, a_out); $stop; end if (& a_in) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_mem_packed_assign.v0000664000177100017500000000147312671044616022653 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.916/test_regress/t/t_param_default.pl0000664000177100017500000000072513205574202022164 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vlcov_rank.pl0000775000177100017500000000153513205574202021527 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); $Self->run(cmd=>["../bin/verilator_coverage", "--rank", "t/t_vlcov_data_a.dat", "t/t_vlcov_data_b.dat", "t/t_vlcov_data_c.dat", "t/t_vlcov_data_d.dat", ], logfile=>"$Self->{obj_dir}/vlcov.log", tee => 0, ); ok(files_identical("$Self->{obj_dir}/vlcov.log", "t/$Self->{name}.out")); 1; verilator-3.916/test_regress/t/t_lint_bsspace_bad.v0000664000177100017500000000046613205574202022470 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. // Fake binary character here '', so is treated as binary and // don't get whitespace violation. `define FOO blak \ blak module t; endmodule verilator-3.916/test_regress/t/t_package_param.pl0000775000177100017500000000072212671044616022142 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gate_array.pl0000775000177100017500000000072212671044616021505 0ustar 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.916/test_regress/t/t_lint_bsspace_bad.pl0000775000177100017500000000140313205574202022631 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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, fails => 1, expect=> '%Warning-BSSPACE: t/t_lint_bsspace_bad.v:\d+: Backslash followed by whitespace, perhaps the whitespace is accidental\? .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_graph.pl0000775000177100017500000000067512671044616021355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_interface_gen3_noinl.pl0000775000177100017500000000102613205574202023431 0ustar wsnyderwsnyder#!/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_gen3.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_inside.v0000664000177100017500000000313312671044616021463 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.916/test_regress/t/t_hierarchy_identifier_bad.pl0000775000177100017500000000220512671044616024353 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_trace_ena_cc.pl0000775000177100017500000000155413205574202021752 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_trace_ena.v"); compile ( verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/V$Self->{name}__Trace__Slow.cpp", qr/c_trace_on\"/x); file_grep_not ("$Self->{obj_dir}/V$Self->{name}__Trace__Slow.cpp", qr/_trace_off\"/x); file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x); file_grep_not ("$Self->{obj_dir}/simx.vcd", qr/inside_sub/x); } ok(1); 1; verilator-3.916/test_regress/t/t_select_index.pl0000775000177100017500000000072012473477707022046 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_mp_func.v0000664000177100017500000000145413205574202022661 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. interface pads_if(); modport mp_dig( import fIn, import fOut ); integer exists[8]; function automatic integer fIn (integer i); fIn = exists[i]; endfunction task automatic fOut (integer i); exists[i] = 33; endtask endinterface module t(); pads_if padsif[1:0](); pads_if padsif_arr[1:0](); initial begin padsif[0].fOut(3); if (padsif[0].fIn(3) != 33) $stop; padsif_arr[0].fOut(3); if (padsif_arr[0].fIn(3) != 33) $stop; padsif_arr[1].fOut(3); if (padsif_arr[1].fIn(3) != 33) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_unpacked_array_order.pl0000775000177100017500000000071213205574202023542 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_gen8.v0000664000177100017500000000216713205574202022075 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // bug998 interface intf #(parameter PARAM = 0) (); logic val; function integer func (); return 5; endfunction endinterface module t1(intf mod_intf); initial begin $display("%m %d", mod_intf.val); end endmodule module t(); //intf #(.PARAM(1)) my_intf [1:0] (); intf #(.PARAM(1)) my_intf (); generate genvar the_genvar; for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf //assign my_intf[the_genvar].val = '1; //t1 t (.mod_intf(my_intf[the_genvar])); t1 t (.mod_intf(my_intf)); end endgenerate // t1 t (.mod_intf(my_intf[1])); // generate // begin : TestIf // assign my_intf[1].val = '1; // t1 t (.mod_intf(my_intf[1])); // end // endgenerate // generate // begin // assign my_intf[0].val = '1; // t1 t (.mod_intf(my_intf[0])); // end // endgenerate initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_trace_complex_params.pl0000775000177100017500000000127713151152521023552 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t_trace_complex.v"); compile ( verilator_flags2 => ['--cc --trace --no-trace-structs --trace-params'], ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ PARAM /); vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out"); ok(1); 1; verilator-3.916/test_regress/t/t_package.v0000664000177100017500000000255413205574202020607 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.916/test_regress/t/t_inst_darray.v0000664000177100017500000000301413205574202021523 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by John Stevenson. typedef logic [63:0] uid_t; typedef logic [31:0] value_t; interface the_intf #(parameter M = 5); logic valid; uid_t uid; value_t [M-1:0] values; modport i( output valid, output uid, output values ); modport t( input valid, input uid, input values ); endinterface module Contemplator #( parameter IMPL = 0, parameter M = 5, parameter N = 1 ) ( input logic clk, the_intf.i out [N-1:0] ); the_intf #(.M(M)) inp[N-1:0] (); DeepThought #( .N ( N )) ultimateAnswerer( .src ( inp ), .dst ( out )); endmodule module DeepThought #( parameter N = 1 ) ( the_intf.t src[N-1:0], the_intf.i dst[N-1:0] ); endmodule module t (/*AUTOARG*/ // Inputs clk ); input clk; localparam M = 5; localparam N = 1; the_intf #(.M(M)) out0 [N-1:0] (); the_intf #(.M(M)) out1 [N-1:0] (); Contemplator #( .IMPL ( 0 ), .M ( M ), .N ( N )) contemplatorOfTheZerothKind( .clk ( clk ), .out ( out0 )); Contemplator #( .IMPL ( 1 ), .M ( M ), .N ( N )) contemplatorOfTheFirstKind( .clk ( clk ), .out ( out1 )); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_sys_sformat.v0000664000177100017500000000404013205574202021555 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. `include "verilated.v" module t; // Note $sscanf already tested elsewhere reg [3:0] n; reg [63:0] q; reg [16*8:1] wide; reg [8:1] ochar; reg [48*8:1] str; reg [48*8:1] str2; string str3; 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; str3 = $sformatf("n=%b q=%d w=%s", n, q, wide); `ifdef TEST_VERBOSE $display("str3=%0s",str3); `endif if (str3 !== "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 if (str2 !== "mod=top.t") $stop; $swrite(str2, "lib=%l"); `ifdef TEST_VERBOSE $display("chkl %0s",str2); `endif if (str2 !== "lib=t") $stop; str3 = $sformatf("u=%u", {"a","b","c","d"}); // Value selected so is printable `ifdef TEST_VERBOSE $display("chku %s %s",str3,str3); `endif if (str3 !== "u=dcba") $stop; str3 = $sformatf("v=%v", {"a","b","c","d"}); // Value selected so is printable `ifdef TEST_VERBOSE $display("chkv %s %s",str3,str3); `endif $sformat(ochar,"%s","c"); if (ochar != "c") $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_param_while.v0000664000177100017500000000126012671044616021504 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.916/test_regress/t/t_interface_arraymux.pl0000775000177100017500000000105213205574202023245 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_mp_func.pl0000775000177100017500000000072212671044616023036 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_const_struct_bad.pl0000775000177100017500000000215513205574202023735 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2017 by Todd Strader. This program is free software; you can # redistribute it and/or 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-USERFATAL: f_add = 15 %Warning-USERFATAL: Use "/* verilator lint_off USERFATAL */" and lint_on around source to disable this message. %Error: t/t_func_const_struct_bad.v:16: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_add2' %Error: t/t_func_const_struct_bad.v:27: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing Called from: t/t_func_const_struct_bad.v:37: f_add() with parameters: params = '{a: 32'h7, b: 32'h8} Called from: t/t_func_const_struct_bad.v:16: f_add2() with parameters: a = ?32?sh7 b = ?32?sh8 c = ?32?sh9 }, ); ok(1); 1; verilator-3.916/test_regress/t/t_dedupe_seq_logic.pl0000775000177100017500000000106712671044616022665 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_select_bad_tri.v0000664000177100017500000000044712473477707022200 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.916/test_regress/t/t_cover_line_sc.pl0000775000177100017500000000115713151152521022171 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_pp_lib_inc.vh0000664000177100017500000000026112473477707021475 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.916/test_regress/t/t_array_interface.v0000664000177100017500000000254613205574202022353 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Johan Bjork. interface intf; logic logic_in_intf; modport source(output logic_in_intf); modport sink(input logic_in_intf); endinterface module modify_interface ( input logic value, intf.source intf_inst ); assign intf_inst.logic_in_intf = value; endmodule function integer return_3(); return 3; endfunction module t #( parameter N = 6 )(); intf ifs[N-1:0] (); logic [N-1:0] data; assign data = {1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 1'b1}; generate genvar i; for (i = 0;i < 3; i++) begin assign ifs[i].logic_in_intf = data[i]; end endgenerate modify_interface m3 ( .value(data[return_3()]), .intf_inst(ifs[return_3()])); modify_interface m4 ( .value(data[4]), .intf_inst(ifs[4])); modify_interface m5 ( .value(~ifs[4].logic_in_intf), .intf_inst(ifs[5])); generate genvar j; for (j = 0;j < N-1; j++) begin initial begin if (ifs[j].logic_in_intf != data[j]) $stop; end end endgenerate initial begin if (ifs[5].logic_in_intf != ~ifs[4].logic_in_intf) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_inst_implicit.v0000664000177100017500000000201413205574202022052 0ustar wsnyderwsnyder// DESCRIPTION:tor:ilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [31:0] o; wire [31:0] oe; Test test (/*AUTOINST*/ // Outputs .o (o[31:0]), .oe (oe[31:0])); // Test loop always @ (posedge clk) begin if (o !== 32'h00000001) $stop; if (oe !== 32'h00000001) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module subimp(o,oe); output [31:0] o; assign o = 32'h12345679; output [31:0] oe; assign oe = 32'hab345679; endmodule module Test(o,oe); output [31:0] o; output [31:0] oe; wire [31:0] xe; assign xe[31:1] = 0; // verilator lint_off IMPLICIT // verilator lint_off WIDTH subimp subimp(x, // x is implicit and one bit xe[0]); // xe explicit one bit assign o = x; assign oe = xe; // verilator lint_on WIDTH // verilator lint_on IMPLICIT endmodule verilator-3.916/test_regress/t/t_enum_large_methods.pl0000775000177100017500000000072213205574202023221 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_port_array.pl0000775000177100017500000000072212671044616022606 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vpi_unimpl.cpp0000664000177100017500000001304613205574202021711 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_vcd_c.h" // No verilated_vpi.h, make sure can link without it #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)) { \ std::cout<", (exp)?(exp):""); \ return __LINE__; \ } #define CHECK_RESULT_CSTR_STRIP(got, exp) \ CHECK_RESULT_CSTR(got+strspn(got, " "), exp) int _mon_check_unimpl(p_cb_data cb_data) { static TestVpiHandle cb, clk_h; if (cb_data) { // this is the callback s_vpi_error_info info; vpi_chk_error(&info); callback_count++; printf("%%Info: got pli message %s\n", info.message); } else { // setup and install static t_cb_data cb_data; clk_h = vpi_handle_by_name((PLI_BYTE8*)"t.clk", NULL); cb_data.reason = cbPLIError; cb_data.cb_rtn = _mon_check_unimpl; // this function cb = vpi_register_cb(&cb_data); CHECK_RESULT_NZ(cb); // now exercise unimplemented fns vpi_get_cb_info(cb, NULL); CHECK_RESULT(callback_count, 1); vpi_register_systf(NULL); CHECK_RESULT(callback_count, 2); vpi_get_systf_info(NULL, NULL); CHECK_RESULT(callback_count, 3); vpi_handle_multi(0, NULL, NULL); CHECK_RESULT(callback_count, 4); vpi_get64(0, NULL); CHECK_RESULT(callback_count, 5); vpi_get_delays(NULL, NULL); CHECK_RESULT(callback_count, 6); vpi_put_delays(NULL, NULL); CHECK_RESULT(callback_count, 7); vpi_get_value_array(NULL, NULL, NULL, 0); CHECK_RESULT(callback_count, 8); vpi_put_value_array(NULL, NULL, NULL, 0); CHECK_RESULT(callback_count, 9); vpi_get_time(NULL, NULL); CHECK_RESULT(callback_count, 10); vpi_mcd_name(0); CHECK_RESULT(callback_count, 11); vpi_compare_objects(NULL, NULL); CHECK_RESULT(callback_count, 12); vpi_get_data(0, NULL, 0); CHECK_RESULT(callback_count, 13); vpi_put_data(0, NULL, 0); CHECK_RESULT(callback_count, 14); vpi_get_userdata(NULL); CHECK_RESULT(callback_count, 15); vpi_put_userdata(NULL, NULL); CHECK_RESULT(callback_count, 16); vpi_handle_by_multi_index(NULL, 0, NULL); CHECK_RESULT(callback_count, 17); } return 0; // Ok } int mon_check() { // Callback from initial block in monitor if (int status = _mon_check_unimpl(NULL)) return status; return 0; // Ok } //====================================================================== double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { double sim_time = 1100; Verilated::commandArgs(argc, argv); Verilated::debug(0); Verilated::fatalOnVpiError(0); // we're going to be checking for these errors do don't crash out VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out #ifdef VERILATOR # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif #endif #if VM_TRACE Verilated::traceEverOn(true); VL_PRINTF("Enabling waves...\n"); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_vpi_var/simx.vcd"); #endif topp->eval(); topp->clk = 0; main_time += 10; while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += 1; topp->eval(); //VerilatedVpi::callValueCbs(); // Make sure can link without verilated_vpi.h included 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.916/test_regress/t/t_math_equal.v0000664000177100017500000000272712473477707021360 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.916/test_regress/t/t_func_wide.pl0000775000177100017500000000071712473477707021351 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_gen10.v0000664000177100017500000000115213205574202022137 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // bug998 interface intf #(parameter PARAM = 0) (); logic val; function integer func (); return 5; endfunction endinterface module t1(intf mod_intf); initial begin $display("%m %d", mod_intf.val); end endmodule module t(); generate begin : TestIf intf #(.PARAM(1)) my_intf [0:0] (); t1 t (.mod_intf(my_intf[0])); end endgenerate initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_dpi_context_noopt.pl0000775000177100017500000000111212473477707023133 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_sys_readmem_bad_digit.pl0000775000177100017500000000107412473477707023701 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify 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.916/test_regress/t/t_var_overcmp.v0000664000177100017500000000520513205574202021533 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs dout, // Inputs clk, rstn, dval0, dval1, dbgsel_w ); input clk; input rstn; input [7:0] dval0; input [7:0] dval1; input [7:0] dbgsel_w; output [7:0] dout; wire [7:0] dout = dout0 | dout1; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [7:0] dout0; // From sub0 of sub0.v wire [7:0] dout1; // From sub1 of sub1.v // End of automatics initial begin $write("*-* All Finished *-*\n"); $finish; end reg [7:0] dbgsel_msk; always_comb begin reg [7:0] mask; mask = 8'hff; dbgsel_msk = (dbgsel_w & mask); end reg [7:0] dbgsel; always @(posedge clk) begin if ((rstn == 0)) begin dbgsel <= 0; end else begin dbgsel <= dbgsel_msk; end end sub0 sub0 (/*AUTOINST*/ // Outputs .dout0 (dout0[7:0]), // Inputs .rstn (rstn), .clk (clk), .dval1 (dval1[7:0]), .dbgsel (dbgsel[7:0])); sub1 sub1 (/*AUTOINST*/ // Outputs .dout1 (dout1[7:0]), // Inputs .rstn (rstn), .clk (clk), .dval1 (dval1[7:0]), .dbgsel (dbgsel[7:0])); endmodule module sub0 ( /*AUTOARG*/ // Outputs dout0, // Inputs rstn, clk, dval1, dbgsel ); input rstn; input clk; input [7:0] dval1; input [7:0] dbgsel; output reg [7:0] dout0; reg [7:0] dbgsel_d1r; always_comb begin // verilator lint_off WIDTH if (((dbgsel_d1r >= 34) && (dbgsel_d1r < 65))) begin // verilator lint_on WIDTH dout0 = dval1; end else begin dout0 = 0; end end always @(posedge clk) begin if ((rstn == 0)) begin dbgsel_d1r <= 0; end else begin dbgsel_d1r <= dbgsel; end end endmodule module sub1 ( /*AUTOARG*/ // Outputs dout1, // Inputs rstn, clk, dval1, dbgsel ); input rstn; input clk; input [7:0] dval1; input [7:0] dbgsel; output reg [7:0] dout1; reg [7:0] dbgsel_d1r; always_comb begin // verilator lint_off WIDTH if (((dbgsel_d1r >= 334) && (dbgsel_d1r < 365))) begin // verilator lint_on WIDTH dout1 = dval1; end else begin dout1 = 0; end end always @(posedge clk) begin if ((rstn == 0)) begin dbgsel_d1r <= 0; end else begin dbgsel_d1r <= dbgsel; end end endmodule verilator-3.916/test_regress/t/t_trace_complex_params.out0000664000177100017500000000612513205574202023744 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Tue Apr 15 19:42:37 2014 $end $timescale 1ns $end $scope module top $end $var wire 1 9 clk $end $scope module $unit $end $var wire 1 # global_bit $end $upscope $end $scope module t $end $var wire 1 9 clk $end $var wire 32 $ cyc [31:0] $end $var real 64 3 v_arr_real(0) $end $var real 64 5 v_arr_real(1) $end $var wire 2 * v_arrp [2:1] $end $var wire 4 + v_arrp_arrp [3:0] $end $var wire 4 , v_arrp_strp [3:0] $end $var wire 1 : v_arru(1) $end $var wire 1 ; v_arru(2) $end $var wire 2 - v_arru_arrp(3) [2:1] $end $var wire 2 . v_arru_arrp(4) [2:1] $end $var wire 1 < v_arru_arru(3)(1) $end $var wire 1 = v_arru_arru(3)(2) $end $var wire 1 > v_arru_arru(4)(1) $end $var wire 1 ? v_arru_arru(4)(2) $end $var wire 2 / v_arru_strp(3) [1:0] $end $var wire 2 0 v_arru_strp(4) [1:0] $end $var real 64 1 v_real $end $var wire 64 % v_str32x2 [63:0] $end $var wire 2 ' v_strp [1:0] $end $var wire 4 ( v_strp_strp [3:0] $end $var wire 2 ) v_unip_strp [1:0] $end $scope module p2 $end $var wire 32 @ PARAM [31:0] $end $upscope $end $scope module p3 $end $var wire 32 A PARAM [31:0] $end $upscope $end $scope module unnamedblk1 $end $var wire 32 7 b [31:0] $end $scope module unnamedblk2 $end $var wire 32 8 a [31:0] $end $upscope $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 1# b00000000000000000000000000000000 $ b0000000000000000000000000000000000000000000000000000000011111111 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0 1 r0 3 r0 5 b00000000000000000000000000000000 7 b00000000000000000000000000000000 8 09 0: 0; 0< 0= 0> 0? b00000000000000000000000000000010 @ b00000000000000000000000000000011 A #10 b00000000000000000000000000000001 $ b0000000000000000000000000000000100000000000000000000000011111110 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.1 1 r0.2 3 r0.3 5 b00000000000000000000000000000101 7 b00000000000000000000000000000101 8 19 #15 09 #20 b00000000000000000000000000000010 $ b0000000000000000000000000000001000000000000000000000000011111101 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.2 1 r0.4 3 r0.6 5 19 #25 09 #30 b00000000000000000000000000000011 $ b0000000000000000000000000000001100000000000000000000000011111100 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.3 1 r0.6000000000000001 3 r0.8999999999999999 5 19 #35 09 #40 b00000000000000000000000000000100 $ b0000000000000000000000000000010000000000000000000000000011111011 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.4 1 r0.8 3 r1.2 5 19 #45 09 #50 b00000000000000000000000000000101 $ b0000000000000000000000000000010100000000000000000000000011111010 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.5 1 r1 3 r1.5 5 19 #55 09 #60 b00000000000000000000000000000110 $ b0000000000000000000000000000011000000000000000000000000011111001 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.6 1 r1.2 3 r1.8 5 19 verilator-3.916/test_regress/t/t_interface_gen4.v0000664000177100017500000000210013205574202022054 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // bug789 generates module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc #(1) itopa(); ifc #(2) itopb(); sub #(1) ca (.isub(itopa), .i_value(4)); sub #(2) cb (.isub(itopb), .i_value(5)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==1) begin if (itopa.MODE != 1) $stop; if (itopb.MODE != 2) $stop; end if (cyc==20) begin if (itopa.i != 4) $stop; if (itopb.i != 5) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub #(parameter MODE = 0) ( ifc isub, input integer i_value ); // Commercial unsupported Xmrs into scopes within interfaces generate always_comb isub.i = i_value; endgenerate endmodule interface ifc; parameter MODE = 0; // Commercial unsupported Xmrs into scopes within interfaces generate integer i; endgenerate endinterface verilator-3.916/test_regress/t/t_param_sel.pl0000775000177100017500000000071712473477707021351 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_unroll_complexcond.pl0000775000177100017500000000072213205574202023266 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_array_partial.v0000664000177100017500000000422313205574202023076 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.916/test_regress/t/t_lint_implicit.v0000664000177100017500000000052712473477707022074 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.916/test_regress/t/t_flag_f.v0000664000177100017500000000123612473477707020450 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.916/test_regress/t/t_mem_multiwire.v0000664000177100017500000000344212671044616022077 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.916/test_regress/t/t_interface_modport_noinl.pl0000775000177100017500000000103113205574202024255 0ustar wsnyderwsnyder#!/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 ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_public.pl0000775000177100017500000000103012473477707021664 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_package_dot.pl0000775000177100017500000000072213205574202021621 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_array2.v0000664000177100017500000000076013205574202021571 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t; localparam int c[4] = '{5, 6, 7, 8}; a #(.p(c)) i_a (); endmodule module a #( parameter int p[4] = '{1, 2, 3, 4} ); initial begin if (p[0] != 5) $stop; if (p[1] != 6) $stop; if (p[2] != 7) $stop; if (p[3] != 8) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_interface_mismodport_bad.pl0000775000177100017500000000130012671044616024403 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_assert_question.v0000664000177100017500000000137413205574202022443 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder module t (/*AUTOARG*/ // Outputs dout, // Inputs clk, sel, a, c ); input clk; input bit [3:0] sel; input bit [3:0] a; input bit c; output bit dout; localparam logic DC = 1'b?; always_ff @(posedge clk) begin unique casez(sel) 4'b0000: dout <= a[0]; 4'b001?: dout <= a[1]; {1'b0, 1'b1, 1'b?, 1'b?}: dout <= a[2]; {1'b1, 1'b?, 1'b?, DC}: dout <= a[3]; default: dout <= '0; endcase $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_gen_for1.v0000664000177100017500000000276512473477707020742 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.916/test_regress/t/t_bitsel_wire_array_bad.v0000664000177100017500000000076112671044616023535 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.916/test_regress/t/t_func.pl0000775000177100017500000000071712473477707020341 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_outfirst.v0000664000177100017500000000532712473477707022131 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.916/test_regress/t/t_parse_delay.pl0000775000177100017500000000072212671044616021657 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_shift.v0000664000177100017500000000666513205574202021351 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs ign, ign2, ign3, // Inputs clk ); input clk; output [31:0] ign; output [3:0] ign2; output [11:0] ign3; parameter [95:0] P6 = 6; localparam P64 = (1 << P6); // verilator lint_off WIDTH localparam [4:0] PBIG23 = 1'b1 << ~73'b0; localparam [3:0] PBIG29 = 4'b1 << 33'h100000000; // verilator lint_on WIDTH reg [31:0] right; reg [31:0] left; reg [P64-1:0] qright; reg [P64-1:0] qleft; reg [31:0] amt; assign ign = {31'h0, clk} >>> 4'bx; // bug760 assign ign2 = {amt[1:0] >> {22{amt[5:2]}}, amt[1:0] << (0 <<< amt[5:2])}; // bug1174 assign ign3 = {amt[1:0] >> {22{amt[5:2]}}, amt[1:0] >> {11{amt[5:2]}}, $signed(amt[1:0]) >>> {22{amt[5:2]}}, $signed(amt[1:0]) >>> {11{amt[5:2]}}, amt[1:0] << {22{amt[5:2]}}, amt[1:0] << {11{amt[5:2]}}}; 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 (P64 != 64) $stop; 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.916/test_regress/t/t_var_xref_gen.v0000664000177100017500000000156713205574202021664 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This is to test the handling of VarXRef when the referenced VAR is // under a generate construction. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Jie Xu and Roland Kruse. module t (/*AUTOARG*/ // Inputs clk, addr, res ); input clk; input [31:0] addr; output [15:0] res; memory i_mem(.addr(addr),.dout(res)); assign i_mem.cxrow_inst[0].cmem_xrow[0] = 16'h0; endmodule module memory(addr, dout); parameter CM_XROWSIZE = 256; parameter CM_NUMXROWS = 2; input [31:0] addr; output [15:0] dout; generate genvar g_cx; for (g_cx = 0; g_cx < CM_NUMXROWS; g_cx++) begin: cxrow_inst reg [15:0] cmem_xrow[0:CM_XROWSIZE - 1]; end endgenerate assign dout = cxrow_inst[0].cmem_xrow[addr]; endmodule verilator-3.916/test_regress/t/t_stream3.v0000664000177100017500000000441012671044616020572 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; /*AUTOWIRE*/ generate for (genvar width=1; width<=16; width++) begin for (genvar amt=1; amt<=width; amt++) begin Test #(.WIDTH(width), .AMT(amt)) test (.ins(crc[width-1:0])); end end endgenerate // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x\n", $time, cyc, crc); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h0 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Inputs ins ); parameter WIDTH = 1; parameter AMT = 1; input [WIDTH-1:0] ins; reg [WIDTH-1:0] got; reg [WIDTH-1:0] expec; int istart; int bitn; int ostart; always @* begin got = { << AMT {ins}}; // Note always starts with right-most bit expec = 0; for (istart=0; istart= 0 && (ostart+bitn) < WIDTH && (ostart+bitn) >= 0) begin expec[ostart+bitn] = ins[istart+bitn]; end end end `ifdef TEST_VERBOSE $write("[%0t] exp %0d'b%b got %0d'b%b = { << %0d { %0d'b%b }}\n", $time, WIDTH, expec, WIDTH, got, AMT, WIDTH, ins); `endif `checkh(got, expec); end endmodule verilator-3.916/test_regress/t/t_var_overzero.v0000664000177100017500000000625613205574202021742 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs dout, // Inputs clk, rstn, dval0, dval1 ); input clk; input rstn; output wire [7:0] dout; input [7:0] dval0; input [7:0] dval1; wire [7:0] dbgsel_w = '0; tsub tsub (/*AUTOINST*/ // Outputs .dout (dout[7:0]), // Inputs .clk (clk), .rstn (rstn), .dval0 (dval0[7:0]), .dval1 (dval1[7:0]), .dbgsel_w (dbgsel_w[7:0])); endmodule module tsub (/*AUTOARG*/ // Outputs dout, // Inputs clk, rstn, dval0, dval1, dbgsel_w ); input clk; input rstn; input [7:0] dval0; input [7:0] dval1; input [7:0] dbgsel_w; output [7:0] dout; wire [7:0] dout = dout0 | dout1; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [7:0] dout0; // From sub0 of sub0.v wire [7:0] dout1; // From sub1 of sub1.v // End of automatics initial begin $write("*-* All Finished *-*\n"); $finish; end reg [7:0] dbgsel_msk; always_comb begin reg [7:0] mask; mask = 8'hff; dbgsel_msk = (dbgsel_w & mask); end // TODO this should optimize away, but presently does not because // V3Gate constifies then doesn't see all other input edges have disappeared reg [7:0] dbgsel; always @(posedge clk) begin if ((rstn == 0)) begin dbgsel <= 0; end else begin dbgsel <= dbgsel_msk; end end sub0 sub0 (/*AUTOINST*/ // Outputs .dout0 (dout0[7:0]), // Inputs .rstn (rstn), .clk (clk), .dval0 (dval0[7:0]), .dbgsel (dbgsel[7:0])); sub1 sub1 (/*AUTOINST*/ // Outputs .dout1 (dout1[7:0]), // Inputs .rstn (rstn), .clk (clk), .dval1 (dval1[7:0]), .dbgsel (dbgsel[7:0])); endmodule module sub0 ( /*AUTOARG*/ // Outputs dout0, // Inputs rstn, clk, dval0, dbgsel ); input rstn; input clk; input [7:0] dval0; input [7:0] dbgsel; output reg [7:0] dout0; reg [7:0] dbgsel_d1r; always_comb begin // verilator lint_off WIDTH if (((dbgsel_d1r >= 34) && (dbgsel_d1r < 65))) begin // verilator lint_on WIDTH dout0 = dval0; end else begin dout0 = 0; end end always @(posedge clk) begin if ((rstn == 0)) begin dbgsel_d1r <= 0; end else begin dbgsel_d1r <= dbgsel; end end endmodule module sub1 ( /*AUTOARG*/ // Outputs dout1, // Inputs rstn, clk, dval1, dbgsel ); input rstn; input clk; input [7:0] dval1; input [7:0] dbgsel; output reg [7:0] dout1; reg [7:0] dbgsel_d1r; always_comb begin if (((dbgsel_d1r >= 84) && (dbgsel_d1r < 95))) begin dout1 = dval1; end else begin dout1 = 0; end end always @(posedge clk) begin if ((rstn == 0)) begin dbgsel_d1r <= 0; end else begin dbgsel_d1r <= dbgsel; end end endmodule verilator-3.916/test_regress/t/t_interface1.pl0000775000177100017500000000072713151152521021402 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_mem_multi_io3_cc.pl0000775000177100017500000000122413205574202022565 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_mem_multi_io3.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io3.cpp -Oi"], verilator_flags3 => [], ); ok(1); 1; verilator-3.916/test_regress/t/t_math_signed7.pl0000775000177100017500000000072213205574202021731 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_enum.v0000664000177100017500000000334213205574202020154 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, e12, 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 (e12 !== 12) $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.916/test_regress/t/t_mod_longname.v0000664000177100017500000000342013205574202021644 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // The code as shown makes a really big file name with Verilator. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. `define LONG_NAME_MOD modlongnameiuqyrewewriqyewroiquyweriuqyewriuyewrioryqoiewyriuewyrqrqioeyriuqyewriuqyeworqiurewyqoiuewyrqiuewoyewriuoeyqiuewryqiuewyroiqyewiuryqeiuwryuqiyreoiqyewiuryqewiruyqiuewyroiuqyewroiuyqewoiryqiewuyrqiuewyroqiyewriuqyewrewqroiuyqiuewyriuqyewroiqyewroiquewyriuqyewroiqewyriuqewyroiqyewroiyewoiuryqoiewyriuqyewiuryqoierwyqoiuewyrewoiuyqroiewuryewurqyoiweyrqiuewyreqwroiyweroiuyqweoiuryqiuewyroiuqyroie `define LONG_NAME_SUB sublongnameiuqyrewewriqyewroiquyweriuqyewriuyewrioryqoiewyriuewyrqrqioeyriuqyewriuqyeworqiurewyqoiuewyrqiuewoyewriuoeyqiuewryqiuewyroiqyewiuryqeiuwryuqiyreoiqyewiuryqewiruyqiuewyroiuqyewroiuyqewoiryqiewuyrqiuewyroqiyewriuqyewrewqroiuyqiuewyriuqyewroiqyewroiquewyriuqyewroiqewyriuqewyroiqyewroiyewoiuryqoiewyriuqyewiuryqoierwyqoiuewyrewoiuyqroiewuryewurqyoiweyrqiuewyreqwroiyweroiuyqweoiuryqiuewyroiuqyroie `define LONG_NAME_VAR varlongnameiuqyrewewriqyewroiquyweriuqyewriuyewrioryqoiewyriuewyrqrqioeyriuqyewriuqyeworqiurewyqoiuewyrqiuewoyewriuoeyqiuewryqiuewyroiqyewiuryqeiuwryuqiyreoiqyewiuryqewiruyqiuewyroiuqyewroiuyqewoiryqiewuyrqiuewyroqiyewriuqyewrewqroiuyqiuewyriuqyewroiqyewroiquewyriuqyewroiqewyriuqewyroiqyewroiyewoiuryqoiewyriuqyewiuryqoierwyqoiuewyrewoiuyqroiewuryewurqyoiweyrqiuewyreqwroiyweroiuyqweoiuryqiuewyroiuqyroie module t (); initial begin $write("*-* All Finished *-*\n"); $finish; end logic `LONG_NAME_VAR; `LONG_NAME_MOD `LONG_NAME_SUB (); endmodule module `LONG_NAME_MOD (); // Force Verilator to make a new class logic a1 /* verilator public */; endmodule verilator-3.916/test_regress/t/t_flag_wfatal.v0000664000177100017500000000036712473477707021505 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.916/test_regress/t/t_inst_misarray_bad.pl0000775000177100017500000000131013205574202023044 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> q{%Error: t/t_inst_misarray_bad.v:16: VARREF 't.foo' is not an unpacked array, but is in an unpacked array context %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_alw.v0000664000177100017500000000330612473477707020646 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.916/test_regress/t/t_interface_gen2_noinl.pl0000775000177100017500000000102613205574202023430 0ustar wsnyderwsnyder#!/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_gen2.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_unroll_forfor.pl0000775000177100017500000000072213205574202022250 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vpi_var.v0000664000177100017500000000647713205574202020672 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.916/test_regress/t/t_case_write1_tasks.v0000664000177100017500000030173612473477707022655 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.916/test_regress/t/t_select_plus.v0000664000177100017500000000625413205574202021537 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [83:4] from; reg [83:4] to; reg [6:0] bitn; reg [3:0] nibblep; reg [3:0] nibblem; reg [7:0] cyc; initial cyc=0; always @* begin nibblep = from[bitn +: 4]; nibblem = from[bitn -: 4]; to = from; to[bitn +: 4] = cyc[3:0]; to[bitn -: 4] = cyc[3:0]; end always @ (posedge clk) begin //$write("[%0t] cyc==%d nibblep==%b nibblem==%b to^from==%x\n",$time, cyc, nibblep, nibblem, from^to); cyc <= cyc + 8'd1; case (cyc) 8'd00: begin from<=80'h7bea9d779b67e48f67da; bitn<=7'd7; end 8'd01: begin from<=80'hefddce326b11ca5dc448; bitn<=7'd8; end 8'd02: begin from<=80'h3f99c5f34168401e210d; bitn<=7'd4; end // truncate -: 8'd03: begin from<=80'hc90635f0a7757614ce3f; bitn<=7'd79; end 8'd04: begin from<=80'hc761feca3820331370ec; bitn<=7'd83; end // truncate +: 8'd05: begin from<=80'hd6e36077bf28244f84b5; bitn<=7'd6; end // half trunc 8'd06: begin from<=80'h90118c5d3d285a1f3252; bitn<=7'd81; end // half trunc 8'd07: begin from<=80'h38305da3d46b5859fe16; bitn<=7'd67; end 8'd08: begin from<=80'h4b9ade23a8f5cc5b3111; bitn<=7'd127; end // truncate 8'd09: begin $write("*-* All Finished *-*\n"); $finish; end default: ; endcase case (cyc) 8'd00: ; 8'd01: begin if ((nibblep & 4'b1111)!==4'b1011) $stop; if ((nibblem & 4'b1111)!==4'b1010) $stop; end 8'd02: begin if ((nibblep & 4'b1111)!==4'b0100) $stop; if ((nibblem & 4'b1111)!==4'b0100) $stop; end 8'd03: begin if ((nibblep & 4'b1111)!==4'b1101) $stop; if ((nibblem & 4'b0000)!==4'b0000) $stop; end 8'd04: begin if ((nibblep & 4'b1111)!==4'b1001) $stop; if ((nibblem & 4'b1111)!==4'b1001) $stop; end 8'd05: begin if ((nibblep & 4'b0000)!==4'b0000) $stop; if ((nibblem & 4'b1111)!==4'b1100) $stop; end 8'd06: begin if ((nibblep & 4'b1111)!==4'b1101) $stop; if ((nibblem & 4'b0000)!==4'b0000) $stop; end 8'd07: begin if ((nibblep & 4'b0000)!==4'b0000) $stop; if ((nibblem & 4'b1111)!==4'b0100) $stop; end 8'd08: begin if ((nibblep & 4'b1111)!==4'b0000) $stop; if ((nibblem & 4'b1111)!==4'b0101) $stop; end 8'd09: begin if ((nibblep & 4'b0000)!==4'b0000) $stop; if ((nibblem & 4'b0000)!==4'b0000) $stop; end default: $stop; endcase case (cyc) 8'd00: ; 8'd01: begin if ((to^from)!==80'h0000000000000000005b) $stop; end 8'd02: begin if ((to^from)!==80'h0000000000000000006c) $stop; end 8'd03: begin if ((to^from)!==80'h0000000000000000000e) $stop; end 8'd04: begin if ((to^from)!==80'h6d000000000000000000) $stop; end 8'd05: begin if (((to^from)&~80'hf)!==80'h90000000000000000000) $stop; end // Exceed bounds, verilator may write index 0 8'd06: begin if (((to^from)&~80'hf)!==80'h00000000000000000020) $stop; end // Exceed bounds, verilator may write index 0 8'd07: begin if (((to^from)&~80'hf)!==80'h4c000000000000000000) $stop; end 8'd08: begin if ((to^from)!==80'h0004d000000000000000) $stop; end 8'd09: begin if (((to^from)&~80'hf)!==80'h00000000000000000000) $stop; end default: $stop; endcase end endmodule verilator-3.916/test_regress/t/t_pp_lib.pl0000775000177100017500000000077612473477707020660 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_bind2.pl0000775000177100017500000000072212671044616020365 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_shift.pl0000775000177100017500000000077013205574202021511 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ["-Wno-CLKDATA"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_genfor_hier.v0000664000177100017500000000112713205574202021476 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Demonstrate deferred linking across module // bondaries // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. module m1(); logic v1; endmodule module t (/*AUTOARG*/); for (genvar the_genvar = 0; the_genvar < 4; the_genvar++) begin : m1_b m1 m1_inst(); end for (genvar the_other_genvar = 0; the_other_genvar < 4; the_other_genvar++) begin always_comb m1_b[the_other_genvar].m1_inst.v1 = 1'b0; end initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_interface_gen6.pl0000775000177100017500000000072713205574202022244 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_interface_gen8.pl0000775000177100017500000000072713205574202022246 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_flag_skipidentical.v0000664000177100017500000000030312473477707023040 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.916/test_regress/t/t_case_66bits.pl0000775000177100017500000000025012473477707021506 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.916/test_regress/t/t_clk_2in.v0000664000177100017500000000703212671044616020540 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.916/test_regress/t/t_enum_name2.v0000664000177100017500000000115313205574202021234 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jonathon Donaldson. package our_pkg; typedef enum logic [8-1:0] { ADC_IN2IN = 8'h99, ADC_IMMED = 8'h88, ADC_INDIR = 8'h86, ADC_INIDX = 8'h97 } T_Opcode; endpackage : our_pkg module t (); our our (); endmodule module our import our_pkg::*; (); T_Opcode IR = ADC_IN2IN; initial begin $write ("%s (%t)\n", IR.name, $realtime); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_math_svl.v0000664000177100017500000000677112473477707021060 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.916/test_regress/t/t_interface_param_another_bad.v0000664000177100017500000000063613205574202024661 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Johan Bjork. module t (); simple_bus sb_intf(); simple_bus #(.PARAMETER($bits(sb_intf.dummy))) simple(); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule interface simple_bus #(PARAMETER = 0); logic dummy; endinterface verilator-3.916/test_regress/t/t_func_begin2.pl0000775000177100017500000000104212671044616021544 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_first.pl0000775000177100017500000000072212671044616021676 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_typedef_array.pl0000775000177100017500000000072213205574202022216 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_gen9.pl0000775000177100017500000000072713205574202022247 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_sys_readmem.v0000664000177100017500000000433213205574202021520 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_string [2:15]; 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 begin string fns = "t/t_sys_readmem_b.mem"; $readmemb(fns, binary_string); `ifdef TEST_VERBOSE for (i=0; i<16; i=i+1) $write(" @%x = %x\n", i, binary_string[i]); `endif if (binary_string['h2] != 6'h02) $stop; end $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_flag_libinc.v0000664000177100017500000000077012473477707021465 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.916/test_regress/t/t_case_x_bad.pl0000775000177100017500000000133013151152521021420 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_sys_file_scan.v0000664000177100017500000000173212671044616022041 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.916/test_regress/t/t_order_quad.cpp0000664000177100017500000000202312671044616021654 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. #include #include "Vt_order_quad.h" //====================================================================== unsigned int main_time = 0; double sc_time_stamp () { return main_time; } VM_PREFIX* topp = NULL; bool fail = false; void check (QData got, QData exp) { if (got != exp) { VL_PRINTF("%%Error: got=0x%" VL_PRI64 "x exp=0x%" VL_PRI64 "x\n", got, exp); fail = true; } } int main (int argc, char *argv[]) { topp = new VM_PREFIX; Verilated::debug(0); topp->a0 = 0; topp->eval(); check (topp->y, VL_ULL(0x0)); topp->a0 = 15; topp->eval(); check (topp->y, VL_ULL(0x3c00000000)); topp->final(); if (!fail) { VL_PRINTF("*-* All Finished *-*\n"); topp->final(); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results\n"); } return 0; } verilator-3.916/test_regress/t/t_tri_ifbegin.v0000664000177100017500000000172013205574202021467 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.916/test_regress/t/t_math_equal.pl0000775000177100017500000000071712473477707021526 0ustar 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.916/test_regress/t/t_vlcov_merge.pl0000775000177100017500000000147313205574202021674 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); $Self->run(cmd=>["../bin/verilator_coverage", "--write", "$Self->{obj_dir}/coverage.dat", "t/t_vlcov_data_a.dat", "t/t_vlcov_data_b.dat", "t/t_vlcov_data_c.dat", "t/t_vlcov_data_d.dat", ], ); ok(files_identical("$Self->{obj_dir}/coverage.dat", "t/$Self->{name}.out")); 1; verilator-3.916/test_regress/t/t_string.v0000664000177100017500000000456313205574202020524 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); `define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=\"%s\" exp=\"%s\"\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [4*8:1] vstr; const string s = "a"; // Check static assignment string s2; string s3; reg eq; // Operators == != < <= > >= {a,b} {a{b}} a[b] // a.len, a.putc, a.getc, a.toupper, a.tolower, a.compare, a.icompare, a.substr // a.atoi, a.atohex, a.atooct, a.atobin, a.atoreal, // a.itoa, a.hextoa, a.octoa, a.bintoa, a.realtoa initial begin $sformat(vstr, "s=%s", s); `checks(vstr, "s=a"); `checks(s, "a"); `checks({s,s,s}, "aaa"); `checks({4{s}}, "aaaa"); // Constification `checkh(s == "a", 1'b1); `checkh(s == "b", 1'b0); `checkh(s != "a", 1'b0); `checkh(s != "b", 1'b1); `checkh(s > " ", 1'b1); `checkh(s > "a", 1'b0); `checkh(s >= "a", 1'b1); `checkh(s >= "b", 1'b0); `checkh(s < "a", 1'b0); `checkh(s < "b", 1'b1); `checkh(s <= " ", 1'b0); `checkh(s <= "a", 1'b1); end // Test loop always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin // Setup s2 = "c0"; end else if (cyc==1) begin $sformat(vstr, "s2%s", s2); `checks(vstr, "s2c0"); end else if (cyc==2) begin s3 = s2; $sformat(vstr, "s2%s", s3); `checks(vstr, "s2c0"); end else if (cyc==3) begin s2 = "a"; s3 = "b"; end else if (cyc==4) begin `checks({s2,s3}, "ab"); `checks({3{s3}}, "bbb"); `checkh(s == "a", 1'b1); `checkh(s == "b", 1'b0); `checkh(s != "a", 1'b0); `checkh(s != "b", 1'b1); `checkh(s > " ", 1'b1); `checkh(s > "a", 1'b0); `checkh(s >= "a", 1'b1); `checkh(s >= "b", 1'b0); `checkh(s < "a", 1'b0); `checkh(s < "b", 1'b1); `checkh(s <= " ", 1'b0); `checkh(s <= "a", 1'b1); end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_func_const_bad.v0000664000177100017500000000303613205574202022157 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 // Verify $fatal works with sformatf as argument localparam BFATAL = f_bad_fatal(3); function integer f_bad_fatal(input [31:0] a); for (integer i=0;i<3;i++) begin $display("Printing in loop: %s", $sformatf("%d", i)); end $fatal(2, "%s", $sformatf("Fatal Error")); endfunction endmodule verilator-3.916/test_regress/t/t_arraysel_wide.pl0000775000177100017500000000065113205574202022213 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_case_write2.pl0000775000177100017500000000121413151152521021560 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_func_const.v0000664000177100017500000000615513205574202021356 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 testpackage; localparam PARAM = 1024 >> 3; endpackage import testpackage::*; 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; localparam P128 = f_package(); typedef struct packed { logic [7:0] data; } type_t; typedef type_t [1:0] flist; localparam flist PLIST = {8'd4,8'd8}; localparam flist PARR = f_list_swap_2(PLIST); typedef struct packed { logic first; logic second; logic [31:0] data; } bigstruct_t; localparam bigstruct_t bigparam = f_return_struct(1'b1, 1'b0, 32'hfff12fff); 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; if (PARR[0] != PLIST[1]) $stop; if (PARR[1] != PLIST[0]) $stop; if (bigparam.first != 1'b1) $stop; if (bigparam.second != 1'b0) $stop; if (bigparam.data != 32'hfff12fff) $stop; if (P128 != 128) $stop; $write("*-* All Finished *-*\n"); $finish; end function integer f_package(); return PARAM; endfunction 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 function flist f_list_swap_2(input flist in_list); f_list_swap_2[0].data = in_list[1].data; f_list_swap_2[1].data = in_list[0].data; endfunction function bigstruct_t f_return_struct(input first, input second, input [31:0] data); bigstruct_t result; result.data = data; result.first = first; result.second = second; return result; endfunction endmodule verilator-3.916/test_regress/t/t_var_xref_gen.pl0000775000177100017500000000072513205574202022030 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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 => ["--debug-check"], ); ok(1); 1; verilator-3.916/test_regress/t/t_select_bad_range2.v0000664000177100017500000000207212473477707022554 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.916/test_regress/t/t_mem_slice.pl0000775000177100017500000000071712671044616021330 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_program.pl0000775000177100017500000000071712473477707021055 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_if.pl0000775000177100017500000000073412473477707020634 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_math_pow2.pl0000775000177100017500000000072212671044616021267 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_twod.pl0000775000177100017500000000072713151152521022356 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_func_const2_bad.pl0000775000177100017500000000211613205574202022410 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2017 by Todd Strader. This program is free software; you can # redistribute it and/or 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-USERFATAL: f_add = 15 %Warning-USERFATAL: Use "/* verilator lint_off USERFATAL */" and lint_on around source to disable this message. %Error: t/t_func_const2_bad.v:10: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_add2' %Error: t/t_func_const2_bad.v:21: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing Called from: t/t_func_const2_bad.v:26: f_add() with parameters: a = 32'h7 b = 32'h8 Called from: t/t_func_const2_bad.v:10: f_add2() with parameters: a = ?32?sh7 b = ?32?sh8 c = ?32?sh9 }, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_declfilename.pl0000775000177100017500000000111212473477707023032 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_func_bad.pl0000775000177100017500000000222512671044616021130 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_lint_colonplus_bad.v0000664000177100017500000000042413205574202023060 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs z ); reg [3:0] r = 4'b1010; output [2:1] z = r[2 :+ 1]; endmodule verilator-3.916/test_regress/t/t_cast.v0000664000177100017500000000374413205574202020150 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; typedef struct packed { logic [15:0] data; } packed_t; packed_t pdata; assign pdata.data = 16'h1234; logic [7:0] logic8bit; assign logic8bit = $bits(logic8bit)'(pdata >> 8); mc_t o; logic [15:0] allones = 16'hffff; parameter FOUR = 4; // bug925 localparam [6:0] RESULT = 7'((6*9+92)%96); logic signed [14:0] samp0 = 15'h0000; logic signed [14:0] samp1 = 15'h0000; logic signed [14:0] samp2 = 15'h6000; logic signed [11:0] coeff0 = 12'h009; logic signed [11:0] coeff1 = 12'h280; logic signed [11:0] coeff2 = 12'h4C5; logic signed [26:0] mida = ((27'(coeff2 * samp2) >>> 11)); // verilator lint_off WIDTH logic signed [26:0] midb = 15'((27'(coeff2 * samp2) >>> 11)); // verilator lint_on WIDTH logic signed [14:0] outa = 15'((27'(coeff0 * samp0) >>> 11) + // 27' size casting in order for intermediate result to not be truncated to the width of LHS vector (27'(coeff1 * samp1) >>> 11) + (27'(coeff2 * samp2) >>> 11)); // 15' size casting to avoid synthesis/simulator warnings initial begin if (logic8bit != 8'h12) $stop; if (4'shf > 4'sh0) $stop; if (signed'(4'hf) > 4'sh0) $stop; if (4'hf < 4'h0) $stop; if (unsigned'(4'shf) < 4'h0) $stop; if (4'(allones) !== 4'hf) $stop; if (6'(allones) !== 6'h3f) $stop; if ((4)'(allones) !== 4'hf) $stop; if ((4+2)'(allones) !== 6'h3f) $stop; if ((4-2)'(allones) !== 2'h3) $stop; if ((FOUR+2)'(allones) !== 6'h3f) $stop; if (50 !== RESULT) $stop; o = tocast_t'(4'b1); if (o != 4'b1) $stop; if (15'h6cec != outa) $stop; if (27'h7ffecec != mida) $stop; if (27'h7ffecec != midb) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_sv_bus_mux_demux/0000775000177100017500000000000013206353162022414 5ustar wsnyderwsnyderverilator-3.916/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_wrap.sv0000664000177100017500000000646412671044616027433 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.916/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_demux.sv0000664000177100017500000000435612671044616027602 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.916/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_mux.sv0000664000177100017500000000444212671044616027265 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.916/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_def.sv0000664000177100017500000000200212671044616027200 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.916/test_regress/t/t_clk_concat4.pl0000775000177100017500000000072713205574202021551 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_param_wide_io.pl0000775000177100017500000000066713205574202022167 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify 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.916/test_regress/t/t_inst_comma.v0000664000177100017500000000307113205574202021340 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; parameter ONE = 1; wire [17:10] bitout; reg [7:0] allbits; reg [15:0] onebit; sub #(1) sub0 (allbits, onebit[1:0], bitout[10]), sub1 (allbits, onebit[3:2], bitout[11]), sub2 (allbits, onebit[5:4], bitout[12]), sub3 (allbits, onebit[7:6], bitout[13]), sub4 (allbits, onebit[9:8], bitout[14]), sub5 (allbits, onebit[11:10], bitout[15]), sub6 (allbits, onebit[13:12], bitout[16]), sub7 (allbits, onebit[15:14], bitout[17]); integer x; always @ (posedge clk) begin //$write("%x\n", bitout); if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin allbits <= 8'hac; onebit <= 16'hc01a; end if (cyc==2) begin if (bitout !== 8'h07) $stop; allbits <= 8'hca; onebit <= 16'h1f01; end if (cyc==3) begin if (bitout !== 8'h41) $stop; if (sub0.bitout !== 1'b1) $stop; if (sub1.bitout !== 1'b0) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule `ifdef USE_INLINE `define INLINE_MODULE /*verilator inline_module*/ `else `define INLINE_MODULE /*verilator public_module*/ `endif module sub (input [7:0] allbits, input [1:0] onebit, output bitout); `INLINE_MODULE parameter integer P = 0; initial if (P != 1) $stop; wire bitout = (^ onebit) ^ (^ allbits); endmodule verilator-3.916/test_regress/t/t_var_bad_hide2.v0000664000177100017500000000067512473477707021711 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.916/test_regress/t/t_EXAMPLE.v0000664000177100017500000000454413205602276020313 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, 2017 by ____YOUR_NAME_HERE____. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[31:0]), // Inputs .clk (clk), .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h4afe43fb79d7b71e if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); // Replace this module with the device under test. // // Change the code in the t module to apply values to the inputs and // merge the output values into the result vector. input clk; input [31:0] in; output reg [31:0] out; always @(posedge clk) begin out <= in; end endmodule verilator-3.916/test_regress/t/t_gen_for0.pl0000775000177100017500000000071712473477707021105 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_array_bad.pl0000775000177100017500000000125513205574202023326 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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_interface_array_bad.v:\d+: Expecting expression to be constant, but variable isn\'t const: bar %Error: t/t_interface_array_bad.v:\d+: Could not expand constant selection inside dotted reference: bar %Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_unsized_bad.v0000664000177100017500000000035013205574202022521 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t; bit [256:0] num = 'd123456789123456789123456789; endmodule verilator-3.916/test_regress/t/t_param_no_parentheses.v0000664000177100017500000000266112473477707023432 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.916/test_regress/t/t_math_reverse.v0000664000177100017500000000411712473477707021717 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.916/test_regress/t/t_tri_various.v0000664000177100017500000001076612671044616021575 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.916/test_regress/t/t_sys_readmem_bad_addr.v0000664000177100017500000000052512671044616023327 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.916/test_regress/t/t_slice_init.v0000664000177100017500000000355413205574202021337 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk, d0, d1 ); input clk; input [7:0] d0, d1; logic [7:0] inia [1:0][3:0] = '{ '{ '0, '1, 8'hfe, 8'hed }, '{ '1, '1, 8'h11, 8'h22 }}; logic [7:0] inil [0:1][0:3] = '{ '{ '0, '1, 8'hfe, 8'hed }, '{ '1, '1, 8'h11, 8'h22 }}; logic [7:0] data [1:0][3:0]; logic [7:0] datl [0:1][0:3]; initial begin data = '{ '{ d0, d1, 8'hfe, 8'hed }, '{ d1, d1, 8'h11, 8'h22 }}; data[0] = '{ d0, d1, 8'h19, 8'h39 }; datl = '{ '{ d0, d1, 8'hfe, 8'hed }, '{ d1, d1, 8'h11, 8'h22 }}; datl[0] = '{ d0, d1, 8'h19, 8'h39 }; `ifdef TEST_VERBOSE $display("D=%x %x %x %x -> 39 19 x x", data[0][0], data[0][1], data[0][2], data[0][3]); $display("D=%x %x %x %x -> ed fe x x", data[1][0], data[1][1], data[1][2], data[1][3]); $display("L=%x %x %x %x -> x x 19 39", datl[0][0], datl[0][1], datl[0][2], datl[0][3]); $display("L=%x %x %x %x -> x x 11 12", datl[1][0], datl[1][1], datl[1][2], datl[1][3]); `endif if (inia[0][0] !== 8'h22) $stop; if (inia[0][1] !== 8'h11) $stop; if (inia[1][0] !== 8'hed) $stop; if (inia[1][1] !== 8'hfe) $stop; if (inil[0][2] !== 8'hfe) $stop; if (inil[0][3] !== 8'hed) $stop; if (inil[1][2] !== 8'h11) $stop; if (inil[1][3] !== 8'h22) $stop; if (data[0][0] !== 8'h39) $stop; if (data[0][1] !== 8'h19) $stop; if (data[1][0] !== 8'hed) $stop; if (data[1][1] !== 8'hfe) $stop; if (datl[0][2] !== 8'h19) $stop; if (datl[0][3] !== 8'h39) $stop; if (datl[1][2] !== 8'h11) $stop; if (datl[1][3] !== 8'h22) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_lint_syncasyncnet_bad.pl0000775000177100017500000000200412671044616023737 0ustar 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.916/test_regress/t/t_param_ddeep_width.pl0000775000177100017500000000103412671044616023024 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_func_crc.v0000664000177100017500000002117312473477707021016 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.916/test_regress/t/t_dpi_var.cpp0000664000177100017500000001134013205574202021146 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__,"", (std::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__,"", (std::string("Unexp scope name ")+namep).c_str()); if (strcmp(modp,"t.sub")) vl_fatal(__FILE__,__LINE__,"", (std::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.916/test_regress/t/t_func_defaults.v0000664000177100017500000000117513205574202022034 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test for warning (not error) on improperly width'ed // default function argument // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. parameter logic Bar = 1'b1; function automatic logic calc_y; return 1'b1; endfunction function automatic logic [1:0] foo ( input logic x = Bar, input logic y = calc_y() ); return x + y; endfunction module t (/*AUTOARG*/); logic [1:0] foo_val; initial begin foo_val = foo(); if (foo_val != 2'b10) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_langext_3.v0000664000177100017500000000075412671044616021107 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.916/test_regress/t/t_math_tri.pl0000775000177100017500000000071712473477707021215 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_attr_parenstar.pl0000775000177100017500000000071712473477707022437 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_notfound_bad.pl0000775000177100017500000000105412671044616023434 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_shift.pl0000775000177100017500000000072213205574202021655 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_gen4_noinl.pl0000775000177100017500000000102613205574202023432 0ustar wsnyderwsnyder#!/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_gen4.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_for_local.pl0000775000177100017500000000071712473477707021346 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_notunsized.v0000664000177100017500000000460012473477707022467 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.916/test_regress/t/t_mem_slice_bad.pl0000775000177100017500000000165513205622711022130 0ustar 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=> q{%Error: t/t_mem_slice_bad.v:\d+: Slice selection index '\[2:0\]' outside data type's '\[1:0\]' %Error: t/t_mem_slice_bad.v:\d+: Slice selection index '\[3:0\]' outside data type's '\[2:0\]' %Error: t/t_mem_slice_bad.v:\d+: Slice selection index '\[3:0\]' outside data type's '\[1:0\]' %Error: t/t_mem_slice_bad.v:\d+: Slice selection index '\[8:0\]' outside data type's '\[7:0\]' %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_const_packed_array_bad.v0000664000177100017500000000155713205574202024672 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Todd Strader. module t; localparam [ 1 : 0 ] [ 31 : 0 ] P = {32'd5, 32'd1}; localparam P6 = f_add(P); localparam P14 = f_add2(2, 3, f_add(P)); localparam P24 = f_add2(7, 8, 9); initial begin // Should never get here $write("*-* All Finished *-*\n"); $finish; end function integer f_add(input [ 1 : 0 ] [ 31 : 0 ] params); f_add = params[0]+params[1]; if (f_add == 15) $fatal(2, "f_add = 15"); endfunction // Speced ok: function called from function function integer f_add2(input [31:0] a, input [31:0] b, input [31:0] c); logic [ 1 : 0 ] [ 31 : 0 ] params; params[0] = a; params[1] = b; f_add2 = f_add(params)+c; endfunction endmodule verilator-3.916/test_regress/t/t_order_first.pl0000775000177100017500000000072212671044616021711 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_const2_bad.v0000664000177100017500000000132513205574202022240 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Todd Strader. module t; localparam P6 = f_add(5, 1); localparam P14 = f_add2(2, 3, f_add(4, 5)); localparam P24 = f_add2(7, 8, 9); initial begin // Should never get here $write("*-* All Finished *-*\n"); $finish; end function integer f_add(input [31:0] a, input [31:0] b); f_add = a+b; if (f_add == 15) $fatal(2, "f_add = 15"); 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 endmodule verilator-3.916/test_regress/t/t_gen_for.v0000664000177100017500000000712612473477707020655 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [7:0] crc; genvar g; wire [7:0] out_p1; wire [15:0] out_p2; wire [7:0] out_p3; wire [7:0] out_p4; paramed #(.WIDTH(8), .MODE(0)) p1 (.in(crc), .out(out_p1)); paramed #(.WIDTH(16), .MODE(1)) p2 (.in({crc,crc}), .out(out_p2)); paramed #(.WIDTH(8), .MODE(2)) p3 (.in(crc), .out(out_p3)); gencase #(.MODE(3)) p4 (.in(crc), .out(out_p4)); wire [7:0] out_ef; enflop #(.WIDTH(8)) enf (.a(crc), .q(out_ef), .oe_e1(1'b1), .clk(clk)); always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%b %x %x %x %x %x\n",$time, cyc, crc, out_p1, out_p2, out_p3, out_p4, out_ef); cyc <= cyc + 1; crc <= {crc[6:0], ~^ {crc[7],crc[5],crc[4],crc[3]}}; if (cyc==0) begin // Setup crc <= 8'hed; end else if (cyc==1) begin end else if (cyc==3) begin if (out_p1 !== 8'h2d) $stop; if (out_p2 !== 16'h2d2d) $stop; if (out_p3 !== 8'h78) $stop; if (out_p4 !== 8'h44) $stop; if (out_ef !== 8'hda) $stop; end else if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module gencase (/*AUTOARG*/ // Outputs out, // Inputs in ); parameter MODE = 0; input [7:0] in; output [7:0] out; generate // : genblk1 begin case (MODE) 2: mbuf mc [7:0] (.q(out[7:0]), .a({in[5:0],in[7:6]})); default: mbuf mc [7:0] (.q(out[7:0]), .a({in[3:0],in[3:0]})); endcase end endgenerate endmodule module paramed (/*AUTOARG*/ // Outputs out, // Inputs in ); parameter WIDTH = 1; parameter MODE = 0; input [WIDTH-1:0] in; output [WIDTH-1:0] out; generate if (MODE==0) initial $write("Mode=0\n"); // No else endgenerate `ifndef NC // for(genvar) unsupported `ifndef ATSIM // for(genvar) unsupported generate // Empty loop body, local genvar for (genvar j=0; j<3; j=j+1) begin end // Ditto to make sure j has new scope for (genvar j=0; j<5; j=j+1) begin end endgenerate `endif `endif generate endgenerate genvar i; generate if (MODE==0) begin // Flip bitorder, direct assign method for (i=0; i1, ); ok(1); 1; verilator-3.916/test_regress/t/t_display_time.pl0000775000177100017500000000157612473477707022075 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_tri_gen.v0000664000177100017500000000133113205574202020633 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.916/test_regress/t/t_interface_down_inlac.pl0000775000177100017500000000112412671044616023521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_select_set.pl0000775000177100017500000000072012473477707021532 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_index.v0000664000177100017500000000262312671044616021160 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.916/test_regress/t/t_interface_gen7.pl0000775000177100017500000000072713205574202022245 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_flag_csplit.pl0000775000177100017500000000271312671044616021660 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_array_rev.v0000664000177100017500000000224713205574202021205 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Geoff Barrett. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; // verilator lint_off LITENDIAN logic arrd [0:1] = '{ 1'b1, 1'b0 }; // verilator lint_on LITENDIAN logic y0, y1; logic localbkw [1:0]; arr_rev arr_rev_u ( .arrbkw (arrd), .y0(y0), .y1(y1) ); always @ (posedge clk) begin if (arrd[0] != 1'b1) $stop; if (arrd[1] != 1'b0) $stop; localbkw = arrd; `ifdef TEST_VERBOSE $write("localbkw[0]=%b\n", localbkw[0]); $write("localbkw[1]=%b\n", localbkw[1]); `endif if (localbkw[0] != 1'b0) $stop; if (localbkw[1] != 1'b1) $stop; `ifdef TEST_VERBOSE $write("y0=%b\n", y0); $write("y1=%b\n", y1); `endif if (y0 != 1'b0) $stop; if (y1 != 1'b1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module arr_rev ( input var logic arrbkw [1:0], output var logic y0, output var logic y1 ); always_comb y0 = arrbkw[0]; always_comb y1 = arrbkw[1]; endmodule verilator-3.916/test_regress/t/t_sv_bus_mux_demux.pl0000775000177100017500000000102612671044616022761 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_var_in_assign.pl0000775000177100017500000000071712473477707022230 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_real.pl0000775000177100017500000000071712473477707021342 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_x.pl0000775000177100017500000000077413151152521020625 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_param_circ_bad.v0000664000177100017500000000042612473477707022140 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.916/test_regress/t/t_interface_gen5.v0000664000177100017500000000237413205601572022073 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // bug998 interface intf #(parameter PARAM = 0) (); logic val; function integer func (); return 5; endfunction endinterface module t1(intf mod_intf); initial begin $display("%m %d", mod_intf.val); end endmodule module t(); generate begin : TestIf intf #(.PARAM(1)) my_intf (); assign my_intf.val = '0; t1 t (.mod_intf(my_intf)); // initial $display("%0d", my_intf.func()); end endgenerate generate begin intf #(.PARAM(1)) my_intf (); assign my_intf.val = '1; t1 t (.mod_intf(my_intf)); // initial $display("%0d", my_intf.func()); end endgenerate localparam LP = 1; logic val; generate begin if (LP) begin intf #(.PARAM(2)) my_intf (); assign my_intf.val = '1; assign val = my_intf.val; end else begin intf #(.PARAM(3)) my_intf (); assign my_intf.val = '1; assign val = my_intf.val; end end endgenerate initial begin $display("%0d", val); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_func_named.pl0000775000177100017500000000072212671044616021466 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_assert_synth.v0000664000177100017500000000370313020617245021737 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.916/test_regress/t/t_langext_1.pl0000775000177100017500000000075712671044616021261 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_param_type2.pl0000775000177100017500000000072513205574202021606 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); #execute ( # check_finished=>1, # ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_for_overlap.v0000664000177100017500000000203612671044616022365 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. // bug749 module t (/*AUTOARG*/ // Inputs clk ); input clk; genvar g; for (g=1; g<3; ++g) begin : gblk sub2 #(.IN(g)) u (); //sub #(.IN(g)) u2 (); end sub1 #(.IN(0)) u (); always @ (posedge clk) begin if (t.u.IN != 0) $stop; if (t.u.FLAVOR != 1) $stop; //if (t.u2.IN != 0) $stop; // This should be not found if (t.gblk[1].u.IN != 1) $stop; if (t.gblk[2].u.IN != 2) $stop; if (t.gblk[1].u.FLAVOR != 2) $stop; if (t.gblk[2].u.FLAVOR != 2) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module sub1 (/*AUTOARG*/); parameter [31:0] IN = 99; parameter FLAVOR = 1; `ifdef TEST_VERBOSE initial $display("%m"); `endif endmodule module sub2 (/*AUTOARG*/); parameter [31:0] IN = 99; parameter FLAVOR = 2; `ifdef TEST_VERBOSE initial $display("%m"); `endif endmodule verilator-3.916/test_regress/t/t_case_huge_sub4.v0000664000177100017500000000333412473477707022113 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.916/test_regress/t/t_array_packed_write_read.pl0000775000177100017500000000102612671044616024217 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_func_graphcirc.pl0000775000177100017500000000071712473477707022363 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_order_multidriven.v0000664000177100017500000001101413205574202022740 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.916/test_regress/t/t_lint_declfilename_bad.pl0000775000177100017500000000153112473477707023645 0ustar 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.916/test_regress/t/t_gate_unsup.pl0000775000177100017500000000110712473477707021552 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_select_bad_range.v0000664000177100017500000000063212473477707022472 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.916/test_regress/t/t_pp_lib.v0000664000177100017500000000040012473477707020467 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.916/test_regress/t/t_flag_woff.pl0000775000177100017500000000112412671044616021316 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only -Wno-WIDTH"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.916/test_regress/t/t_vpi_var.cpp0000664000177100017500000004445213205574202021202 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_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, 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; } 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 VerilatedVpi::selfTest(); #endif return 0; // Ok } //====================================================================== #ifdef IS_VPI static int mon_check_vpi() { vpiHandle href = vpi_handle(vpiSysTfCall, 0); s_vpi_value vpi_value; vpi_value.format = vpiIntVal; vpi_value.value.integer = mon_check(); vpi_put_value(href, &vpi_value, NULL, vpiNoDelay); return 0; } static s_vpi_systf_data vpi_systf_data[] = { {vpiSysFunc, vpiIntFunc, (PLI_BYTE8*)"$mon_check", (PLI_INT32(*)(PLI_BYTE8*))mon_check_vpi, 0, 0, 0}, 0 }; // cver entry void vpi_compat_bootstrap(void) { p_vpi_systf_data systf_data_p; systf_data_p = &(vpi_systf_data[0]); while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++); } // icarus entry void (*vlog_startup_routines[])() = { vpi_compat_bootstrap, 0 }; #else double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { double sim_time = 1100; Verilated::commandArgs(argc, argv); Verilated::debug(0); VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out #ifdef VERILATOR # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif #endif #if VM_TRACE Verilated::traceEverOn(true); VL_PRINTF("Enabling waves...\n"); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_vpi_var/simx.vcd"); #endif topp->eval(); topp->clk = 0; main_time += 10; while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += 1; topp->eval(); VerilatedVpi::callValueCbs(); topp->clk = !topp->clk; //mon_do(); #if VM_TRACE if (tfp) tfp->dump (main_time); #endif } CHECK_RESULT(callback_count, 501); CHECK_RESULT(callback_count_half, 250); CHECK_RESULT(callback_count_quad, 2); CHECK_RESULT(callback_count_strs, callback_count_strs_max); if (!Verilated::gotFinish()) { vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish"); } topp->final(); #if VM_TRACE if (tfp) tfp->close(); #endif delete topp; topp=NULL; exit(0L); } #endif verilator-3.916/test_regress/t/t_unroll_forfor.v0000664000177100017500000000155113205574202022100 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This files is used to generated the following error: // %Error: Internal Error: t/t_unroll_forfor.v:27: ../V3Simulate.h:177: No value found for node. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Jan Egil Ruud. module t (/*AUTOARG*/ // Inputs clk, in ); input clk; input [71:0] in; reg [71:0] in_tmp; localparam [71:0] TEST_PARAM = {72{1'b0}}; // Test loop always @* begin: testmap byte i, j; // bug1044 for ( i = 0; i < 9; i = i + 1 ) for ( j=0; j<(TEST_PARAM[i*8+:8]); j=j+1 ) begin // verilator lint_off WIDTH in_tmp[TEST_PARAM[i*8+:8]+j] = in[TEST_PARAM[i*8+:8]+j]; // verilator lint_on WIDTH end $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_struct_init.pl0000775000177100017500000000072312671044616021737 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_select_bad_msb.pl0000775000177100017500000000117012473477707022326 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_lint_comb_use.v0000664000177100017500000000112413205574202022026 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 hval, // Inputs sel ); input logic [2:0] sel; output logic [3:0] hval; /*AUTOINPUT*/ /*AUTOOUTPUT*/ always_comb begin unique case (sel) 3'h0: hval = 4'hd; 3'h1: hval = 4'hc; 3'h7: hval = 4'hf; default: begin $ignore ("ERROR : %s [%m]", $sformatf ("Illegal sel = %x", sel)); hval = 4'bx; end endcase end endmodule verilator-3.916/test_regress/t/t_gen_cond_bitrange.v0000664000177100017500000000557512671044616022660 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.916/test_regress/t/t_embed1_child.v0000664000177100017500000000167413205574202021516 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.916/test_regress/t/t_gen_assign.v0000664000177100017500000000234112473477707021345 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.916/test_regress/t/t_interface_array.pl0000775000177100017500000000072213205574202022516 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_readmem_b_8.mem0000664000177100017500000000066512473477707022610 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.916/test_regress/t/t_vpi_var.pl0000775000177100017500000000146113205574202021027 0ustar 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 --vpi --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.916/test_regress/t/t_package_param.v0000664000177100017500000000141112671044616021765 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.916/test_regress/t/t_preproc_inc_inc_bad.vh0000664000177100017500000000032312473477707023340 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.916/test_regress/t/t_mod_recurse.v0000664000177100017500000000521413205574202021517 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 = {60'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.916/test_regress/t/t_cover_line.v0000664000177100017500000000607713205574202021345 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.t.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.t.b*",0) // Make sure that we don't optimize away zero buckets end if (toggle) begin // CHECK_COVER(-1,"top.t.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.t.t1",1) end if (external) begin // CHECK_COVER(-1,"top.t.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.t.o1",1) // because under coverage_module_off end end endmodule verilator-3.916/test_regress/t/t_math_arith.pl0000775000177100017500000000071712473477707021526 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_gen6_noinl.pl0000775000177100017500000000102613205574202023434 0ustar wsnyderwsnyder#!/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_gen6.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_gate_notif1.pl0000775000177100017500000000134313151152521022432 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_var_tieout.v0000664000177100017500000000204713205574202021372 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.916/test_regress/t/t_display.pl0000775000177100017500000001151113205574202021023 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the 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=>dequote( q{[0] In top.t: Hi [0] In top.t.sub (sub) [0] In top.t.sub.subblock (sub) [0] In top.t.sub2 (sub2) [0] In top.t.sub2.subblock2 (sub2) [0] Back \ Quote " [0] %b=000001100 %0b=1100 %b=00000101010111011101110111100110011001100 %0b=101010111011101110111100110011001100 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0b=1010101111000001001000110100010101100111100000010010001101000101011001111000 [0] %B=000001100 %0B=1100 %B=00000101010111011101110111100110011001100 %0B=101010111011101110111100110011001100 %B=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0B=1010101111000001001000110100010101100111100000010010001101000101011001111000 [0] %d= 12 %0d=12 %d= 46099320012 %0d=46099320012 [0] %D= 12 %0D=12 %D= 46099320012 %0D=46099320012 [0] %h=00c %0h=c %h=00abbbbcccc %0h=abbbbcccc %h=00abc1234567812345678 %0h=abc1234567812345678 [0] %H=00c %0H=c %H=00abbbbcccc %0H=abbbbcccc %H=00abc1234567812345678 %0H=abc1234567812345678 [0] %o=014 %0o=14 %o=00527356746314 %0o=527356746314 %o=012570110642547402215053170 %0o=12570110642547402215053170 [0] %O=014 %0O=14 %O=00527356746314 %0O=527356746314 %O=012570110642547402215053170 %0O=12570110642547402215053170 [0] %x=00c %0x=c %x=00abbbbcccc %0x=abbbbcccc %x=00abc1234567812345678 %0x=abc1234567812345678 [0] %X=00c %0X=c %X=00abbbbcccc %0X=abbbbcccc %X=00abc1234567812345678 %0X=abc1234567812345678 [0] %C=m %0C=m [0] %c=m %0c=m [0] %v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 < [0] %V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 < [0] %p='hc %0p='hc %p='habbbbcccc %0p='habbbbcccc %p='habc1234567812345678 %0p='habc1234567812345678 [0] %P='hc %0P='hc %P='habbbbcccc %0P='habbbbcccc %P='habc1234567812345678 %0P='habc1234567812345678 [0] %P="sv-str" [0] %u=dcba %0u=dcba [0] %U=dcba %0U=dcba [0] %D= 12 %d= 12 %01d=12 %06d=000012 %6d= 12 [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. hello, from a concatenated string. hello, from a concatenated format string [0]. extra argument: 0000000000000000 0000000000000000: pre argument [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.916/test_regress/t/t_lint_only.pl0000775000177100017500000000155013151152521021363 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_flag_ldflags_c.cpp0000664000177100017500000000226113151152521022427 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.916/test_regress/t/t_sys_readmem_bad_digit.v0000664000177100017500000000052712671044616023517 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.916/test_regress/t/t_mem_func.pl0000775000177100017500000000071712473477707021177 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_order_comboclkloop.pl0000775000177100017500000000072313151152521023233 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_tri_inout.cpp0000664000177100017500000000222112671044616021543 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.916/test_regress/t/t_assert_comp_bad.pl0000775000177100017500000000137413205574202022511 0ustar wsnyderwsnyder#!/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=>0, fails => 1, expect => '.*%Warning: t_assert_comp_bad.v:\d+: Assertion failed in top.t.genblk1: User compile-time warning .*%Error: t_assert_comp_bad.v:\d+: Assertion failed in top.t.genblk1: User compile-time error' ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_readmem_b.mem0000664000177100017500000000055012473477707022352 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.916/test_regress/t/t_var_const_bad.v0000664000177100017500000000063712473477707022042 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.916/test_regress/t/t_order.v0000664000177100017500000000565612473477707020357 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.916/test_regress/t/t_tri_pull_bad.v0000664000177100017500000000030713205574202021646 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.916/test_regress/t/t_mem_multi_io3.cpp0000664000177100017500000000102213205574202022260 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // This file ONLY is placed into the Public Domain, for any use, // without warranty. #include VM_PREFIX_INCLUDE 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.916/test_regress/t/t_trace_off_sc.pl0000775000177100017500000000120213151152521021763 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_cover_line.out0000664000177100017500000000652113205574202021701 0ustar wsnyderwsnyder // verilator_coverage annotation // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg toggle; initial toggle=0; integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; alpha a1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); alpha a2 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); beta b1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); beta b2 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); tsk t1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); off o1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); always @ (posedge clk) begin 000010 if (cyc!=0) begin cyc <= cyc + 1; toggle <= '0; %000001 if (cyc==3) begin toggle <= '1; end %000001 else if (cyc==5) begin `ifdef VERILATOR $c("call_task();"); `else call_task(); `endif end %000001 else if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end task call_task; /* verilator public */ t1.center_task(1'b1); endtask endmodule module alpha (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; always @ (posedge clk) begin %000002 if (toggle) begin // CHECK_COVER(-1,"top.t.a*",2) // t.a1 and t.a2 collapse to a count of 2 end if (toggle) begin // CHECK_COVER_MISSING(-1) // This doesn't even get added // verilator coverage_block_off $write(""); end end endmodule module beta (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; /* verilator public_module */ always @ (posedge clk) begin %000000 if (0) begin // CHECK_COVER(-1,"top.t.b*",0) // Make sure that we don't optimize away zero buckets end %000002 if (toggle) begin // CHECK_COVER(-1,"top.t.b*",2) // t.b1 and t.b2 collapse to a count of 2 end if (toggle) begin // CHECK_COVER_MISSING(-1) // This doesn't // verilator coverage_block_off $write(""); end end endmodule module tsk (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; /* verilator public_module */ always @ (posedge clk) begin center_task(1'b0); end task center_task; input external; begin %000001 if (toggle) begin // CHECK_COVER(-1,"top.t.t1",1) end %000001 if (external) begin // CHECK_COVER(-1,"top.t.t1",1) $write("[%0t] Got external pulse\n", $time); end end endtask endmodule module off (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; // verilator coverage_off always @ (posedge clk) begin if (toggle) begin // CHECK_COVER_MISSING(-1) // because under coverage_module_off end end // verilator coverage_on always @ (posedge clk) begin %000001 if (toggle) begin // CHECK_COVER(-1,"top.t.o1",1) // because under coverage_module_off end end endmodule verilator-3.916/test_regress/t/t_flag_bboxsys.v0000664000177100017500000000065712473477707021722 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.916/test_regress/t/t_inst_signed.pl0000775000177100017500000000072212671044616021675 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_alw_dly.pl0000775000177100017500000000077113205574202021017 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ["-Wno-CLKDATA"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_port_array.v0000664000177100017500000000205712671044616022440 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.916/test_regress/t/t_dpi_accessors.pl0000775000177100017500000000130312671044616022204 0ustar 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.916/test_regress/t/t_array_packed_sysfunct.v0000664000177100017500000001444413205574202023600 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.916/test_regress/t/t_detectarray_1.pl0000775000177100017500000000077313205574202022115 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ["-Wno-CLKDATA"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_f.vc0000664000177100017500000000036312473477707020613 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.916/test_regress/t/t_clk_concat3.v0000664000177100017500000000325713205574202021400 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // /* verilator lint_off LITENDIAN */ module some_module ( input wrclk ); logic [ 1 : 0 ] some_state; logic [1:0] some_other_state; always @(posedge wrclk) begin case (some_state) 2'b11: if (some_other_state == 0) some_state <= 2'b00; default: $display ("This is a display statement"); endcase if (wrclk) some_other_state <= 0; end endmodule `define BROKEN module t1( input [-12:-9] i_clks, input i_clk0, input i_clk1 ); some_module some_module ( `ifdef BROKEN .wrclk (i_clks[-12]) `else .wrclk (i_clk1) `endif ); endmodule module t2( input [2:0] i_clks, input i_clk0, input i_clk1, input i_clk2, input i_data ); logic [-12:-9] the_clks; logic data_q; assign the_clks[-12] = i_clk1; assign the_clks[-11] = i_clk2; assign the_clks[-10] = i_clk1; assign the_clks[-9] = i_clk0; always @(posedge i_clk0) begin data_q <= i_data; end t1 t1 ( .i_clks (the_clks), .i_clk0 (i_clk0), .i_clk1 (i_clk1) ); endmodule module t( input clk0 /*verilator clocker*/, input clk1 /*verilator clocker*/, input clk2 /*verilator clocker*/, input data_in ); logic [2:0] clks; assign clks = {1'b0, clk1, clk0}; t2 t2 ( .i_clks (clks), .i_clk0 (clk0), .i_clk1 (clk1), .i_clk2 (clk2), .i_data (data_in) ); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_vpi_unimpl.v0000664000177100017500000000154512671044616021404 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.916/test_regress/t/t_array_pattern_unpacked.v0000664000177100017500000000354412671044616023750 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Iztok Jeras. module t (/*AUTOARG*/); logic [3:0] array_simp [1:0] [3:0]; // big endian array initial begin array_simp[0] = '{ 4'd3, 4'd2, 4'd1, 4'd0}; if ({array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 16'h3210) $stop; // verilator lint_off WIDTH array_simp[0] = '{ 3 ,2 ,1, 0 }; // verilator lint_on WIDTH if ({array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 16'h3210) $stop; // Doesn't seem to work for unpacked arrays in other simulators //array_simp[0] = '{ 1:4'd3, default:13 }; //if ({array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 16'hDD3D) $stop; array_simp = '{ '{ 4'd3, 4'd2, 4'd1, 4'd0 }, '{ 4'd1, 4'd2, 4'd3, 4'd4 }}; if ({array_simp[1][3],array_simp[1][2],array_simp[1][1],array_simp[1][0], array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 32'h3210_1234) $stop; // Doesn't seem to work for unpacked arrays in other simulators array_simp = '{2{ '{4'd3, 4'd2, 4'd1, 4'd0 } }}; if ({array_simp[1][3],array_simp[1][2],array_simp[1][1],array_simp[1][0], array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 32'h3210_3210) $stop; array_simp = '{2{ '{4{ 4'd3 }} }}; if ({array_simp[1][3],array_simp[1][2],array_simp[1][1],array_simp[1][0], array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 32'h3333_3333) $stop; // Not legal in other simulators - replication doesn't match // However IEEE suggests this is legal. //array_simp = '{2{ '{2{ 4'd3, 4'd2 }} }}; // Note it's not '{3,2} $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_interface_gen_noinl.pl0000775000177100017500000000102513205574202023345 0ustar wsnyderwsnyder#!/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_gen.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_pow6.pl0000775000177100017500000000072213205574202021264 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_order_quad.pl0000775000177100017500000000110512671044616021510 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe","$Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_cover_toggle.pl0000775000177100017500000000127013205574202022036 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ['--cc --coverage-toggle --stats'], ); execute ( check_finished=>1, ); # Read the input .v file and do any CHECK_COVER requests inline_checks(); file_grep ($Self->{stats}, qr/Coverage, Toggle points joined\s+(\d+)/i, 25) if $Self->{vlt}; ok(1); 1; verilator-3.916/test_regress/t/t_foreach.v0000664000177100017500000000360713205574202020623 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t (/*AUTOARG*/); // verilator lint_off LITENDIAN // verilator lint_off WIDTH reg [63:0] sum; reg [2:1] [4:3] array [5:6] [7:8]; reg [1:2] [3:4] larray [6:5] [8:7]; function [63:0] crc (input [63:0] sum, input [31:0] a, input [31:0] b, input [31:0] c, input [31:0] d); crc = {sum[62:0],sum[63]} ^ {4'b0,a[7:0], 4'h0,b[7:0], 4'h0,c[7:0], 4'h0,d[7:0]}; endfunction initial begin sum = 0; foreach (array[a]) begin sum = crc(sum, a, 0, 0, 0); end `checkh(sum, 64'h000000c000000000); sum = 0; foreach (array[a,b]) begin sum = crc(sum, a, b, 0, 0); end `checkh(sum, 64'h000003601e000000); sum = 0; foreach (array[a,b,c]) begin sum = crc(sum, a, b, c, 0); end `checkh(sum, 64'h00003123fc101000); sum = 0; foreach (array[a,b,c,d]) begin sum = crc(sum, a, b, c, d); end `checkh(sum, 64'h0030128ab2a8e557); // sum = 0; foreach (larray[a]) begin sum = crc(sum, a, 0, 0, 0); end `checkh(sum, 64'h0000009000000000); sum = 0; foreach (larray[a,b]) begin sum = crc(sum, a, b, 0, 0); sum = sum + {4'b0,a[7:0], 4'h0,b[7:0]}; end `checkh(sum, 64'h000002704b057073); sum = 0; foreach (larray[a,b,c]) begin sum = crc(sum, a, b, c, 0); end `checkh(sum, 64'h00002136f9000000); sum = 0; foreach (larray[a,b,c,d]) begin sum = crc(sum, a, b, c, d); end `checkh(sum, 64'h0020179aa7aa0aaa); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_clk_vecgen3.pl0000775000177100017500000000103312473477707021561 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_param_chain.v0000664000177100017500000000142212671044616021456 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.916/test_regress/t/t_case_group.v0000664000177100017500000000076413205574202021344 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jonathon Donaldson. module t ( input i_clk, input [6:0] i_input, output logic o_output ); always_ff @(posedge i_clk) // verilator lint_off CASEINCOMPLETE case (i_input) 7'(92+2), 7'(92+3): o_output <= 1'b1; endcase initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_math_cmp.pl0000775000177100017500000000071713161610121021144 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_array_bad.pl0000775000177100017500000000125713151152521022341 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_inst_array_bad.v:\d+: Input port connection 'onebit' as part of a module instance array requires 1 or 8 bits, but connection's VARREF 'onebitbad' generates 9 bits. %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_concat_large_bad.v0000664000177100017500000000041713205574202022437 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/); wire [32767:0] a = {32768{1'b1}}; initial begin $stop; end endmodule verilator-3.916/test_regress/t/t_repeat.v0000664000177100017500000000133212473477707020507 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.916/test_regress/t/t_trace_timescale.v0000664000177100017500000000046213205574202022334 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.916/test_regress/t/t_interface_modport.v0000664000177100017500000000613012671044616022721 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.916/test_regress/t/t_enum_public.cpp0000664000177100017500000000122213205574202022022 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. #include #include "Vt_enum_public.h" #include "Vt_enum_public_p3.h" #include "Vt_enum_public_p62.h" int main (int argc, char *argv[]) { Vt_enum_public *topp = new Vt_enum_public; Verilated::debug(0); // Make sure public tag worked if (Vt_enum_public_p3::ZERO == Vt_enum_public_p3::ONE) {} if (Vt_enum_public_p62::ZERO == Vt_enum_public_p62::ALLONE) {} for (int i = 0; i < 10; i++) { topp->eval(); } } verilator-3.916/test_regress/t/t_inst_dtree_inlab.pl0000775000177100017500000000112012671044616022665 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_interface1_modport_nansi.pl0000775000177100017500000000104513205574202024334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_interface1_modport.v"); compile ( v_flags2 => ['+define+NANSI'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gated_clk_1.pl0000775000177100017500000000072212671044616021524 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_packed.v0000664000177100017500000001124412671044616021304 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.916/test_regress/t/t_select_negative.pl0000775000177100017500000000071712473477707022547 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_gate_pmos.pl0000775000177100017500000000133713151152521022213 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_lint_pindup_bad.v0000664000177100017500000000063712473477707022371 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.916/test_regress/t/t_tri_gate_cond.pl0000775000177100017500000000133713151152521022160 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_case_itemwidth.v0000664000177100017500000000457712473477707022236 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.916/test_regress/t/t_lint_unused_bad.pl0000775000177100017500000000236612671044616022534 0ustar 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.916/test_regress/t/t_extend_class_c.h0000664000177100017500000000073412671044616022161 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.916/test_regress/t/t_struct_packed_write_read.v0000664000177100017500000001237412671044616024264 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.916/test_regress/t/t_verilated_debug.out0000664000177100017500000000144013205574202022674 0ustar wsnyderwsnyder-V{t0,1}- Verilated::debug is on. Message prefix indicates {,}. -V{t0,2}+ Vt_verilated_debug::_ctor_var_reset -V{t0,3}+ Vt_verilated_debug::_eval_initial -V{t0,4}+ Vt_verilated_debug::_eval_settle -V{t0,5}+ Vt_verilated_debug::_eval -V{t0,6}+ Vt_verilated_debug::_change_request -V{t0,7}+++++TOP Evaluate Vt_verilated_debug::eval -V{t0,8}+ Clock loop -V{t0,9}+ Vt_verilated_debug::_eval -V{t0,10}+ Vt_verilated_debug::_change_request -V{t0,11}+++++TOP Evaluate Vt_verilated_debug::eval -V{t0,12}+ Clock loop -V{t0,13}+ Vt_verilated_debug::_eval -V{t0,14}+ Vt_verilated_debug::_sequent__TOP__1 *-* All Finished *-* - t/t_verilated_debug.v:16: Verilog $finish -V{t0,15}+ Vt_verilated_debug::_change_request -V{t0,16}+ Vt_verilated_debug::final verilator-3.916/test_regress/t/t_dpi_shortcircuit.pl0000775000177100017500000000130412671044616022742 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_initarray_nonarray.v0000664000177100017500000000113713205574202023123 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // The code here is used to trigger Verilator internal error // "InitArray on non-array" // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Jie Xu. typedef logic [7:0] mask_t [7:0]; // parameter logic [7:0] IMP_MASK[7:0] = '{8'hE1, 8'h03, 8'h07, 8'h3F, 8'h33, 8'hC3, 8'hC3, 8'h37}; parameter mask_t IMP_MASK = '{8'hE1, 8'h03, 8'h07, 8'h3F, 8'h33, 8'hC3, 8'hC3, 8'h37}; module t (/*AUTOARG*/ // Inputs clk ); input clk; mask_t a; //logic [7:0] a[7:0]; assign a = IMP_MASK; endmodule verilator-3.916/test_regress/t/t_trace_packed_struct.v0000664000177100017500000000132713205574202023222 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Andrew Bardsley. module t (/*AUTOARG*/ // Inputs clk ); input clk; // This won't compile with tracing as an incorrect declaration is made for // the temp variables used to represent the elements of localparam v typedef struct packed { logic [2:0][31:0] a; } t; localparam t v[2:0] = '{ '{'{32'h10000002, 32'h10000001, 32'h10000000}}, '{'{32'h20000002, 32'h20000001, 32'h20000000}}, '{'{32'h30000002, 32'h30000001, 32'h30000000}} }; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_struct_packed_value_list.v0000664000177100017500000001174112671044616024303 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.916/test_regress/t/t_lint_literal_bad.pl0000775000177100017500000000110713205574202022646 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2017 by Todd Strader. This program is free software; you can # redistribute it and/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=> '%Warning-WIDTH: t/t_lint_literal_bad.v:9: Value too large for 8 bit number: 256 ', ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_dtree_inld.pl0000775000177100017500000000107712671044616022541 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_flag_ldflags_a.cpp0000664000177100017500000000133713151152521022430 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.916/test_regress/t/t_var_outoforder.pl0000775000177100017500000000071712473477707022446 0ustar 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.916/test_regress/t/t_mem.v0000664000177100017500000000274213205574202017771 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // [16] is SV syntax for [0:15] reg [7:0] memory8_16 [16]; reg m_we; reg [3:1] m_addr; reg [15:0] m_data; always @ (posedge clk) begin // Load instructions from cache memory8_16[{m_addr,1'd0}] <= 8'hfe; if (m_we) begin {memory8_16[{m_addr,1'd1}], memory8_16[{m_addr,1'd0}]} <= m_data; end end reg [7:0] memory8_16_4; reg [7:0] memory8_16_5; // Test complicated sensitivity lists always @ (memory8_16[4][7:1] or memory8_16[5]) begin memory8_16_4 = memory8_16[4]; memory8_16_5 = memory8_16[5]; end always @ (posedge clk) begin m_we <= 0; if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin m_we <= 1'b1; m_addr <= 3'd2; m_data <= 16'h55_44; end if (cyc==2) begin m_we <= 1'b1; m_addr <= 3'd3; m_data <= 16'h77_66; end if (cyc==3) begin m_we <= 0; // Check we really don't write this m_addr <= 3'd3; m_data <= 16'h0bad; end if (cyc==5) begin if (memory8_16_4 != 8'h44) $stop; if (memory8_16_5 != 8'h55) $stop; if (memory8_16[6] != 8'hfe) $stop; if (memory8_16[7] != 8'h77) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_mod_interface_array.v0000664000177100017500000000247013205574202023206 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Johan Bjork. parameter N = 4; interface a_if #(parameter PARAM = 0) (); logic long_name; modport source (output long_name); modport sink (input long_name); endinterface module intf_source ( input logic [N-1:0] intf_input, a_if.source i_intf_source[N-1:0] ); generate for (genvar i=0; i < N;i++) begin assign i_intf_source[i].long_name = intf_input[i]; end endgenerate endmodule module intf_sink ( output [N-1:0] a_out, a_if.sink i_intf_sink[N-1:0] ); generate for (genvar i=0; i < N;i++) begin assign a_out[i] = i_intf_sink[i].long_name; end endgenerate endmodule module t ( clk ); input clk; logic [N-1:0] a_in; logic [N-1:0] a_out; logic [N-1:0] ack_out; a_if #(.PARAM(1)) tl_intf [N-1:0] (); intf_source source(a_in, tl_intf); intf_sink sink(a_out, tl_intf); initial a_in = '0; always @(posedge clk) begin a_in <= a_in + { {N-1 {1'b0}}, 1'b1 }; ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 }; if (ack_out != a_out) begin $stop; end if (& a_in) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_var_init.pl0000775000177100017500000000071712473477707021221 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_bitsel_struct.v0000664000177100017500000000125012671044616022101 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.916/test_regress/t/t_flag_fi_h.h0000664000177100017500000000131413205574202021065 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 void myfunction(); verilator-3.916/test_regress/t/t_gen_var_bad.v0000664000177100017500000000044312473477707021460 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.916/test_regress/t/t_var_overzero.pl0000775000177100017500000000100013205574202022071 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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 fast"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_assert_basic.pl0000775000177100017500000000102113151152521022007 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_xml_first.out0000664000177100017500000000524013205574202021560 0ustar wsnyderwsnyder verilator-3.916/test_regress/t/t_var_vec_sel.pl0000775000177100017500000000104212671044616021653 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_math_swap.pl0000775000177100017500000000071712473477707021371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_repl.pl0000775000177100017500000000071712473477707021530 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_select_unsized.v0000664000177100017500000000141512671044616023114 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.916/test_regress/t/t_interface_down_noinl.pl0000775000177100017500000000102613205574202023544 0ustar wsnyderwsnyder#!/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_down.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_bitsel_struct.pl0000775000177100017500000000072212671044616022255 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_ccall.v0000664000177100017500000000241712473477707021347 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.916/test_regress/t/t_math_concat0.v0000664000177100017500000000411312473477707021567 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.916/test_regress/t/t_param.v0000664000177100017500000000275113205574202020313 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); parameter PAR = 3; m1 #(PAR) m1(); m3 #(PAR) m3(); mnooverride #(10) mno(); input clk; integer cyc=1; reg [4:0] bitsel; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin bitsel = 0; if (PAR[bitsel]!==1'b1) $stop; bitsel = 1; if (PAR[bitsel]!==1'b1) $stop; bitsel = 2; if (PAR[bitsel]!==1'b0) $stop; end if (cyc==1) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module m1; localparam PAR1MINUS1 = PAR1DUP-2-1; localparam PAR1DUP = PAR1+2; // Check we propagate parameters properly parameter PAR1 = 0; m2 #(PAR1MINUS1) m2 (); // Packed arrays localparam [1:0][3:0] PACKED_PARAM = { 4'h3, 4'h6 }; initial if (PACKED_PARAM != 8'h36) $stop; endmodule // bug 810 module m2 #(/*parameter*/ integer PAR2 = 10); initial begin $display("%x",PAR2); if (PAR2 !== 2) $stop; end endmodule module m3; localparam LOC = 13; parameter PAR = 10; initial begin $display("%x %x",LOC,PAR); if (LOC !== 13) $stop; if (PAR !== 3) $stop; end endmodule module mnooverride; localparam LOC = 13; parameter PAR = 10; initial begin $display("%x %x",LOC,PAR); if (LOC !== 13) $stop; if (PAR !== 10) $stop; end endmodule verilator-3.916/test_regress/t/t_sv_bus_mux_demux.v0000664000177100017500000001635112671044616022617 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.916/test_regress/t/t_scope_map.v0000664000177100017500000000251313205574202021155 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test symbol table scope map and general public // signal reflection // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. module t ( input wire CLK ); foo #(.WIDTH (1)) foo1 (.*); foo #(.WIDTH (7)) foo7 (.*); foo #(.WIDTH (8)) foo8 (.*); foo #(.WIDTH (32)) foo32 (.*); foo #(.WIDTH (33)) foo33 (.*); foo #(.WIDTH (40)) foo40 (.*); foo #(.WIDTH (41)) foo41 (.*); foo #(.WIDTH (64)) foo64 (.*); foo #(.WIDTH (65)) foo65 (.*); foo #(.WIDTH (96)) foo96 (.*); foo #(.WIDTH (97)) foo97 (.*); foo #(.WIDTH (128)) foo128 (.*); foo #(.WIDTH (256)) foo256 (.*); foo #(.WIDTH (1024)) foo1024 (.*); bar #(.WIDTH (1024)) bar1024 (.*); endmodule module foo #( parameter WIDTH = 32 ) ( input CLK ); logic [ ( ( WIDTH + 7 ) / 8 ) * 8 - 1 : 0 ] initial_value; logic [ WIDTH - 1 : 0 ] value_q /* verilator public */; integer i; initial begin initial_value = '1; for (i = 0; i < WIDTH / 8; i++) initial_value[ i * 8 +: 8 ] = i[ 7 : 0 ]; value_q = initial_value[ WIDTH - 1 : 0 ]; end always @(posedge CLK) value_q <= ~value_q; endmodule module bar #( parameter WIDTH = 32 ) ( input CLK ); foo #(.WIDTH (WIDTH)) foo (.*); endmodule verilator-3.916/test_regress/t/t_assert_basic_fail.pl0000775000177100017500000000120213151152521023003 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_math_width.v0000664000177100017500000000241712671044616021351 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (); // See also t_lint_width parameter A_ONE = '1; // verilator lint_off WIDTH parameter [3:0] A_W4 = A_ONE; // verilator lint_on WIDTH initial begin if ($bits(A_ONE) != 1 || A_ONE !== 1'b1) $stop; if ($bits(A_W4) != 4) $stop; if (A_W4 != 4'b0001) $stop; end b #(.B_WIDTH(48)) b (); reg [4:0] c; integer c_i; initial begin c_i = 3; c = 1'b1 << c_i; // No width warning when not embedded in expression, as is common syntax if (c != 5'b1000) $stop; end localparam D_TT = 32'd23; localparam D_SIX = 6; // verilator lint_off WIDTH localparam [5:0] D_SUB = D_TT - D_SIX; // verilator lint_on WIDTH initial begin if (D_SUB != 17) $stop; end initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule module b; parameter B_WIDTH = 1; localparam B_VALUE0 = {B_WIDTH{1'b0}}; localparam B_VALUE1 = {B_WIDTH{1'b1}}; reg [47:0] b_val; initial begin b_val = B_VALUE0; if (b_val != 48'b0) $stop; b_val = B_VALUE1; if (b_val != ~48'b0) $stop; end endmodule verilator-3.916/test_regress/t/t_gen_intdot2.v0000664000177100017500000001032712473477707021447 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.916/test_regress/t/t_langext_2_bad.pl0000775000177100017500000000103612671044616022057 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_math_svl.pl0000775000177100017500000000110612473477707021214 0ustar 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.916/test_regress/t/t_interface_gen3.v0000664000177100017500000000315612671044616022076 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.916/test_regress/t/t_unroll_signed.pl0000775000177100017500000000071712473477707022252 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_array_type_methods.pl0000775000177100017500000000072213205574202023262 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_cond_const.v0000664000177100017500000000245212671044616022202 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.916/test_regress/t/t_case_huge_prof.pl0000775000177100017500000000265713205574202022342 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); top_filename("t/t_case_huge.v"); compile ( verilator_flags2 => ["--stats --profile-cfuncs -CFLAGS '-pg' -LDFLAGS '-pg'"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10); file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10); } unlink $_ foreach (glob "$Self->{obj_dir}/gmon.out.*"); $ENV{GMON_OUT_PREFIX} = "$Self->{obj_dir}/gmon.out"; execute ( check_finished=>1, ); my $gmon_path; $gmon_path = $_ foreach (glob "$Self->{obj_dir}/gmon.out.*"); $gmon_path or $Self->error("Profiler did not create a gmon.out"); (my $gmon_base = $gmon_path) =~ s!.*[/\\]!!; $Self->run(cmd=>["cd $Self->{obj_dir} && gprof $Self->{VM_PREFIX} $gmon_base > gprof.out"], check_finished=>0); $Self->run(cmd=>["cd $Self->{obj_dir} && $ENV{VERILATOR_ROOT}/bin/verilator_profcfunc gprof.out > cfuncs.out"], check_finished=>0); file_grep ("$Self->{obj_dir}/cfuncs.out", qr/Overall summary by/); ok(1); 1; verilator-3.916/test_regress/t/t_savable.v0000664000177100017500000000366513205574202020635 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); /*verilator no_inline_module*/ // So we'll get hiearachy we can test input clk; sub sub (/*AUTOINST*/ // Inputs .clk (clk)); endmodule module sub (/*AUTOARG*/ // Inputs clk ); input clk; /*verilator no_inline_module*/ // So we'll get hiearachy we can test integer cyc=0; reg [127:0] save128; reg [47:0] save48; reg [1:0] save2; reg [255:0] cycdone; // Make sure each cycle executes exactly once reg [31:0] vec[2:1][2:1]; real r; string s,s2; string si; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d\n",$time, cyc); `endif si = "siimmed"; cyc <= cyc + 1; if (cycdone[cyc[7:0]]) $stop; cycdone[cyc[7:0]] <= '1; if (cyc==0) begin // Setup save128 <= 128'hc77bb9b3784ea0914afe43fb79d7b71e; save48 <= 48'h4afe43fb79d7; save2 <= 2'b10; vec[1][1] <= 32'h0101; vec[1][2] <= 32'h0102; vec[2][1] <= 32'h0201; vec[2][2] <= 32'h0202; r <= 1.234; s <= "hello"; end if (cyc==1) begin if ($test$plusargs("save_restore")!=0) begin // Don't allow the restored model to run from time 0, it must run from a restore $write("%%Error: didn't really restore\n"); $stop; end end else if (cyc==99) begin if (save128 !== 128'hc77bb9b3784ea0914afe43fb79d7b71e) $stop; if (save48 !== 48'h4afe43fb79d7) $stop; if (save2 !== 2'b10) $stop; if (cycdone !== {{(256-99){1'b0}}, {99{1'b1}}}) $stop; if (vec[1][1] !== 32'h0101) $stop; if (vec[1][2] !== 32'h0102) $stop; if (vec[2][1] !== 32'h0201) $stop; if (vec[2][2] !== 32'h0202) $stop; if (r != 1.234) $stop; $display("%s",s); $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_var_rsvd_port.pl0000775000177100017500000000073512473477707022300 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_package_dot.v0000664000177100017500000000101613205574202021445 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. package pkg; typedef struct packed { logic [3:0] msk; logic [3:0] dat; } STR_t; endpackage; package csr_pkg; typedef pkg::STR_t reg_t; localparam reg_t REG_RST = 8'h34; endpackage module t (/*AUTOARG*/); initial begin if (csr_pkg::REG_RST.msk != 4'h3) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_func_const_bad.pl0000775000177100017500000000541613205574202022334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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:11: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_output' %Error: t/t_func_const_bad.v:12: ... Location of non-constant VAR 'o': Language violation: Outputs not allowed in constant functions %Error: t/t_func_const_bad.v:20: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_dotted' %Error: t/t_func_const_bad.v:22: ... Location of non-constant VARXREF 'EIGHT': Language violation: Dotted hierarchical references not allowed in constant functions Called from: t/t_func_const_bad.v:20: f_bad_dotted() with parameters: a = ?32?sh2 %Error: t/t_func_const_bad.v:27: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_nonparam' %Error: t/t_func_const_bad.v:29: ... Location of non-constant VARREF 'modvar': Language violation: reference to non-function-local variable Called from: t/t_func_const_bad.v:27: f_bad_nonparam() with parameters: a = ?32?sh3 %Error: t/t_func_const_bad.v:35: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_infinite' %Error: t/t_func_const_bad.v:37: ... Location of non-constant WHILE: Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above 1024 Called from: t/t_func_const_bad.v:35: f_bad_infinite() with parameters: a = ?32?sh3 %Error: t/t_func_const_bad.v:43: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_stop' %Error: t/t_func_const_bad.v:45: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing Called from: t/t_func_const_bad.v:43: f_bad_stop() with parameters: a = ?32?sh3 -Info: Printing in loop: 0 -Info: Printing in loop: 1 -Info: Printing in loop: 2 %Warning-USERFATAL: Fatal Error %Warning-USERFATAL: Use "/* verilator lint_off USERFATAL */" and lint_on around source to disable this message. %Error: t/t_func_const_bad.v:49: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_fatal' %Error: t/t_func_const_bad.v:54: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing Called from: t/t_func_const_bad.v:49: f_bad_fatal() with parameters: a = ?32?sh3 }, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_unsup_deassign.v0000664000177100017500000000046013205574202023263 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder. module t ( input wire rst ); integer q; always @(*) if (rst) assign q = 0; else deassign q; endmodule verilator-3.916/test_regress/t/t_enum_public.v0000664000177100017500000000114513205574202021511 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. package p3; typedef enum logic [2:0] { ZERO = 3'b0, ONE = 3'b1 } e3_t /*verilator public*/; endpackage package p62; typedef enum logic [62:0] { ZERO = '0, ALLONE = '1 } e62_t /*verilator public*/; endpackage module t (/*AUTOARG*/); enum integer { EI_A, EI_B, EI_C } m_state; initial begin m_state = EI_A; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_for_init_bug.pl0000775000177100017500000000066412473477707022055 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify 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.916/test_regress/t/t_gen_mislevel.pl0000775000177100017500000000071712473477707022057 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_select_loop.pl0000775000177100017500000000071712473477707021716 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_modport_import_noinl.pl0000775000177100017500000000103313205574202025651 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_import.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_rand.v0000664000177100017500000000131012473477707021162 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.916/test_regress/t/t_udp_noname.pl0000775000177100017500000000103112671044616021506 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_clk_gater.pl0000775000177100017500000000117412671044616021324 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_pp_dupdef.v0000664000177100017500000000050213155551312021152 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.916/test_regress/t/t_bitsel_const_bad.pl0000775000177100017500000000117412671044616022667 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_flag_parameter.vc0000664000177100017500000000036313205574202022324 0ustar wsnyderwsnyder-Greal11=0.2 -pvalue+real12=0.2 -Greal21=4e2 -pvalue+real22=4e2 -Greal31=0.2e2 -pvalue+real32=0.2e2 -Gint11=0x10 -pvalue+int12=0x10 -Gint21=020 -pvalue+int22=020 -Gint31=123 -pvalue+int32=123 -Gint41=32'hdead_beef -pvalue+int42=32'hdead_beef verilator-3.916/test_regress/t/t_enum.pl0000775000177100017500000000071712473477707020352 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_cat_renew.pl0000775000177100017500000000151613151152521022503 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_gen_var_bad.pl0000775000177100017500000000107512473477707021633 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_if_blk.v0000664000177100017500000000564312671044616021633 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.916/test_regress/t/t_bench_mux4k.pl0000775000177100017500000000075713205574202021577 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( v_flags2 => ["--stats"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_display.v0000664000177100017500000001060713205574202020657 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; initial nine = 12; string svs = "sv-str"; 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 $display("[%0t] %%b=%b %%0b=%0b %%b=%b %%0b=%0b %%b=%b %%0b=%0b", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%B=%B %%0B=%0B %%B=%B %%0B=%0B %%B=%B %%0B=%0B", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%d=%d %%0d=%0d %%d=%d %%0d=%0d", $time, nine, nine, quad, quad); $display("[%0t] %%D=%D %%0D=%0D %%D=%D %%0D=%0D", $time, nine, nine, quad, quad); $display("[%0t] %%h=%h %%0h=%0h %%h=%h %%0h=%0h %%h=%h %%0h=%0h", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%H=%H %%0H=%0H %%H=%H %%0H=%0H %%H=%H %%0H=%0H", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%o=%o %%0o=%0o %%o=%o %%0o=%0o %%o=%o %%0o=%0o", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%O=%O %%0O=%0O %%O=%O %%0O=%0O %%O=%O %%0O=%0o", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%x=%x %%0x=%0x %%x=%x %%0x=%0x %%x=%x %%0x=%0x", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%X=%X %%0X=%0X %%X=%X %%0X=%0X %%X=%X %%0X=%0X", $time, nine, nine, quad, quad, wide, wide); // // verilator lint_off WIDTH $display("[%0t] %%C=%C %%0C=%0C", $time, "a"+nine, "a"+nine); $display("[%0t] %%c=%c %%0c=%0c", $time, "a"+nine, "a"+nine); // verilator lint_on WIDTH $display("[%0t] %%v=%v %%0v=%0v %%v=%v %%0v=%0v %%v=%v %%0v=%0v <", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%V=%V %%0V=%0V %%V=%V %%0V=%0V %%V=%V %%0V=%0V <", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%p=%p %%0p=%0p %%p=%p %%0p=%0p %%p=%p %%0p=%0p", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%P=%P %%0P=%0P %%P=%P %%0P=%0P %%P=%P %%0P=%0P", $time, nine, nine, quad, quad, wide, wide); $display("[%0t] %%P=%P", $time, svs); $display("[%0t] %%u=%u %%0u=%0u", $time, {"a","b","c","d"}, {"a","b","c","d"}); // Avoid binary output $display("[%0t] %%U=%U %%0U=%0U", $time, {"a","b","c","d"}, {"a","b","c","d"}); // Avoid binary output // %z is tested in t_sys_sformat.v $display("[%0t] %%D=%D %%d=%d %%01d=%01d %%06d=%06d %%6d=%6d", $time, nine, nine, nine, nine, nine); $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."); $display("hel", "lo, fr", "om a concatenated string."); $write("hel", "lo, fr", "om a concatenated format string [%0t].\n", $time); $display("extra argument: ", $time); $display($time, ": pre argument"); $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 (%l)\n", $time); begin : subblock $write("[%0t] In %M (%L)\n", $time); // Uppercase %M test end end endtask endmodule module sub2; // verilator no_inline_module task write_m; begin $write("[%0t] In %m (%l)\n", $time); begin : subblock2 $write("[%0t] In %m (%L)\n", $time); end end endtask endmodule verilator-3.916/test_regress/t/t_verilated_all.pl0000775000177100017500000000242213205574202022166 0ustar wsnyderwsnyder#!/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 $root = ".."; compile ( # Can't use --coverage and --savable together, so cheat and compile inline verilator_flags2 => ['--cc --coverage-toggle --coverage-line --coverage-user --trace --vpi $root/include/verilated_save.cpp'], ); execute ( check_finished=>1, ); my %hit; foreach my $file (glob("$root/include/*.cpp $root/include/*.h")) { $file =~ s!.*/!!; print "NEED: $file\n" if $Self->{verbose}; $hit{$file} = 0; } foreach my $dfile (glob("$Self->{obj_dir}/*.d")) { my $wholefile = file_contents($dfile); foreach my $file (split /\s+/, $wholefile) { $file =~ s!.*/!!; print "USED: $file\n" if $Self->{verbose}; $hit{$file} = 1; } } foreach my $file (sort keys %hit) { if (!$hit{$file} && $file !~ /_sc/) { $Self->error("Include file not covered by t_verilated_all test: ",$file); } } ok(1); 1; verilator-3.916/test_regress/t/t_tri_inout.pl0000775000177100017500000000116513151152521021372 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_trace_param.v0000664000177100017500000000134413205574202021466 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jonathon Donaldson. package my_funcs; function automatic int simple_func (input int value); begin simple_func = value; end endfunction endpackage package my_module_types; import my_funcs::*; localparam MY_PARAM = 3; localparam MY_PARAM2 /*verilator public*/ = simple_func(12); endpackage module t import my_module_types::*; ( input i_clk, input [MY_PARAM-1:0] i_d, output logic [MY_PARAM-1:0] o_q ); always_ff @(posedge i_clk) o_q <= i_d; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_preproc_ifdef.v0000664000177100017500000000145412473477707022043 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.916/test_regress/t/t_func_const.pl0000775000177100017500000000071712473477707021547 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_clk_2in.cpp0000664000177100017500000000177213205574202021053 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. #include #include VM_PREFIX_INCLUDE 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.916/test_regress/t/t_extend_class.pl0000775000177100017500000000107713151152521022034 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_dpi_shortcircuit_c.cpp0000664000177100017500000000375113205574202023411 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) # if defined(T_DPI_SHORTCIRCUIT) # include "Vt_dpi_shortcircuit__Dpi.h" # elif defined(T_DPI_SHORTCIRCUIT2) # include "Vt_dpi_shortcircuit2__Dpi.h" # else # error "Unknown test" # endif #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["--stats"], ); execute ( check_finished=>1, expect=> (quotemeta( 'Merge: This should merge f a=top.t b=top.t pre t=0 t2=0 post t3=0 t4=0 t5=00000000000000000 m t=0 t2=0 t3=0 t4=0 t5=0 t=0 t2=0 t3=0 t4=0 t5=0 mm f a=top.t b=top.t pre t=0 t2=0 post t3=0 t4=0 t5=00000000000000000m t=0 t2=0 t3=0 t4=0 t5=0 t=0 t2=0 t3=0 t4=0 t5=0mm *-* All Finished *-*') .'.*') ); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}__stats.txt", qr/Node count, DISPLAY \s+ 32 \s+ 25 \s+ 25 \s+ 25/); ok(1); 1; verilator-3.916/test_regress/t/t_typedef_array.v0000664000177100017500000000114113205574202022041 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by James Pallister. typedef logic logic_alias_t; module t; logic_alias_t [6:1] signal; // verilator lint_off LITENDIAN logic_alias_t [1:6] signal2; // verilator lint_on LITENDIAN initial begin signal[6:1] = 'b100001; signal[3] = 'b1; signal2[1:6] = 'b100001; signal2[4] = 'b1; if (signal != 'b100101) $stop; if (signal2 != 'b100101) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_func_flip.v0000664000177100017500000000244512473477707021202 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 INT_RANGE 31:0 `define INT_RANGE 31:0 // Duplicate identical defs are OK `define INT_RANGE_MAX 31 `define VECTOR_RANGE 511:0 module t (clk); // verilator lint_off WIDTH parameter WIDTH = 16; // Must be a power of 2 parameter WIDTH_LOG2 = 4; // set to log2(WIDTH) parameter USE_BS = 1; // set to 1 for enable input clk; function [`VECTOR_RANGE] func_tree_left; input [`VECTOR_RANGE] x; // x[width-1:0] is the input vector reg [`VECTOR_RANGE] flip; begin flip = 'd0; func_tree_left = flip; end endfunction reg [WIDTH-1:0] a; // value to be shifted reg [WIDTH-1:0] tree_left; always @(a) begin : barrel_shift tree_left = func_tree_left (a); end // barrel_shift integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin a = 5; end if (cyc==2) begin $display ("%x\n",tree_left); //if (tree_left != 'd15) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_inst_dtree_inlb.pl0000775000177100017500000000107712671044616022537 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_concat.pl0000775000177100017500000000071712473477707021666 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_assert_question.pl0000775000177100017500000000077513205574202022620 0ustar wsnyderwsnyder#!/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'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_for_funcbound.pl0000775000177100017500000000076412473477707022241 0ustar 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.916/test_regress/t/t_gate_implicit.pl0000775000177100017500000000071712473477707022220 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_clocker.v0000664000177100017500000000264013205574202020632 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Simple test of CLkDATA // // Trigger the CLKDATA detection // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Jie Xu. localparam ID_MSB = 1; module t (/*AUTOARG*/ // Inputs clk, res, res8, res16 ); input clk; output res; output [7:0] res8; output [15:0] res16; wire [7:0] clkSet; wire clk_1; wire [2:0] clk_3; wire [3:0] clk_4; wire clk_final; reg [7:0] count; assign clkSet = {8{clk}}; assign clk_4 = clkSet[7:4]; assign clk_1 = clk_4[0];; // arraysel assign clk_3 = {3{clk_1}}; assign clk_final = clk_3[0]; // the following two assignment triggers the CLKDATA warning // because on LHS there are a mix of signals both CLOCK and // DATA /* verilator lint_off CLKDATA */ assign res8 = {clk_3, 1'b0, clk_4}; assign res16 = {count, clk_3, clk_1, clk_4}; /* verilator lint_on CLKDATA */ initial count = 0; always @(posedge clk_final or negedge clk_final) begin count = count + 1; // the following assignment should trigger the CLKDATA warning // because CLOCK signal is used as DATA in sequential block /* verilator lint_off CLKDATA */ res <= clk_final; /* verilator lint_on CLKDATA */ if ( count == 8'hf) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_var_notfound_bad.v0000664000177100017500000000107212671044616022527 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.916/test_regress/t/t_bitsel_slice.v0000664000177100017500000000344412671044616021663 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.916/test_regress/t/t_assert_cover.pl0000775000177100017500000000275713205574202022071 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_assert_cover.v"); compile ( verilator_flags2 => ['--assert --cc --coverage-user'], nc_flags2 => ["+nccovoverwrite +nccoverage+all +nccovtest+$Self->{name}"] ); execute ( check_finished=>1, ); if ($Self->{nc}) { my $name = $Self->{name}; my $cf = "$Self->{obj_dir}/${name}__nccover.cf"; { my $fh = IO::File->new(">$cf") or die "%Error: $! writing $cf,"; $fh->printf("report_summary -module *\n"); $fh->printf("report_detail -both -instance *\n"); $fh->printf("report_html -both -instance * > $Self->{obj_dir}/${name}__nccover.html\n"); $fh->close; } $Self->run(logfile=>"$Self->{obj_dir}/${name}__nccover.log", tee=>0, cmd=>[($ENV{VERILATOR_ICCR}||'iccr'), "-test ${name} ${cf}"]); } file_grep ($Self->{run_log_filename}, qr/COVER: Cyc==4/); file_grep ($Self->{run_log_filename}, qr/COVER: Cyc==5/); file_grep ($Self->{run_log_filename}, qr/COVER: Cyc==6/); # Allow old Perl format dump, or new binary dump file_grep ($Self->{coverage_filename}, qr/(cyc_eq_5.*,c=>[^0]|cyc_eq_5.* [1-9][0-9]*\n)/); ok(1); 1; verilator-3.916/test_regress/t/t_array_backw_index_bad.v0000664000177100017500000000103313205622627023472 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/); logic [31:0] array_assign [3:0]; logic [31:0] larray_assign [0:3]; initial begin array_assign[1:3] = '{32'd4, 32'd3, 32'd2}; larray_assign[3:1] = '{32'd4, 32'd3, 32'd2}; array_assign[4:3] = '{32'd4, 32'd3}; array_assign[1:-1] = '{32'd4, 32'd3}; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_lint_literal_bad.v0000664000177100017500000000034113205574202022474 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Todd Strader. module t ( ); localparam the_localparam = 8'd256; endmodule verilator-3.916/test_regress/t/t_math_signed6.pl0000775000177100017500000000072213205574202021730 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_escape.out0000664000177100017500000000412213205574202021657 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 t $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.916/test_regress/t/t_case_group.pl0000775000177100017500000000072213205574202021507 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_leak.v0000664000177100017500000000074212473477707020147 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.916/test_regress/t/t_struct_packed_sysfunct.v0000664000177100017500000000302312671044616024004 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.916/test_regress/t/t_table_fsm.v0000664000177100017500000000767212473477707021200 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.916/test_regress/t/t_display_real.v0000664000177100017500000000343212473477707021702 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.916/test_regress/t/t_param_up_bad.v0000664000177100017500000000112613205574202021620 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Ian Thompson. //bug1099 typedef struct packed { logic foo; } some_struct_t; module child (); logic a_bad; // bar is in the parent module, but illegal to reference without module name assign a_bad = bar.foo; endmodule module parent #( parameter PARAM = 0 ) ( ); some_struct_t bar; child c (); endmodule module t (); // The parameter must be anything other than the default parent #( 1 ) p (); endmodule verilator-3.916/test_regress/t/t_flag_xinitial_0.v0000664000177100017500000000074113205574202022241 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs value ); output reg [63:0] value; initial begin `ifdef VERILATOR // Default is all ones, so we assume that here if (value != '0) $stop; `else if (value != {64{1'bx}}) $stop; `endif $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_dos.pl0000775000177100017500000000071712473477707020173 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_pow4.v0000664000177100017500000000254612671044616021126 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Clifford Wolf. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; wire [31:0] y; reg a; test004 sub (/*AUTOINST*/ // Outputs .y (y[31:0]), // Inputs .a (a)); // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d a=%x y=%x\n",$time, cyc, a, y); `endif cyc <= cyc + 1; if (cyc==0) begin a <= 0; end else if (cyc==1) begin a <= 1; if (y != 32'h0) $stop; end else if (cyc==2) begin if (y != 32'h010000ff) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module test004(a, y); input a; output [31:0] y; wire [7:0] y0; wire [7:0] y1; wire [7:0] y2; wire [7:0] y3; assign y = {y0,y1,y2,y3}; localparam [7:0] v0 = +8'sd1 ** -8'sd2; //'h01 localparam [7:0] v1 = +8'sd2 ** -8'sd2; //'h00 localparam [7:0] v2 = -8'sd2 ** -8'sd3; //'h00 localparam [7:0] v3 = -8'sd1 ** -8'sd3; //'hff localparam [7:0] zero = 0; initial $display("v0=%x v1=%x v2=%x v3=%x", v0,v1,v2,v3); assign y0 = a ? v0 : zero; assign y1 = a ? v1 : zero; assign y2 = a ? v2 : zero; assign y3 = a ? v3 : zero; endmodule verilator-3.916/test_regress/t/t_enum_overlap_bad.pl0000775000177100017500000000130612473477707022703 0ustar 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.916/test_regress/t/t_dpi_shortcircuit2.v0000664000177100017500000000307113205574202022647 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 ctr); import "DPI-C" function bit dpii_inc0 (input int ctr); import "DPI-C" function bit dpii_inc1 (input int ctr); import "DPI-C" function bit dpii_incx (input int ctr, input bit value); integer i; integer j; integer k; bit b; 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 // bug963 dpii_clear(); j = 0; for (i=0; i<64; i++) begin if (i[0]) j = 0; else j = {31'b0, dpii_inc1(0)}; k = k + j; end $write("%x\n",k); check (`__LINE__, dpii_count(0), 32); if (|errors) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_enum_type_pins.v0000664000177100017500000000614113205574202022246 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.916/test_regress/t/t_func_under2.pl0000775000177100017500000000072212671044616021601 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_array_pattern_unpacked.pl0000775000177100017500000000072212671044616024114 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_width_bad.v0000664000177100017500000000213613100174640022157 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (); // See also t_math_width // This shows the uglyness in width warnings across param modules // TODO: Would be nice to also show relevant parameter settings p #(.WIDTH(4)) p4 (.in(4'd0)); p #(.WIDTH(5)) p5 (.in(5'd0)); //==== localparam [3:0] XS = 'hx; // User presumably intended to use 'x //==== wire [4:0] c = 1'b1 << 2; // No width warning, as is common syntax wire [4:0] d = (1'b1 << 2) + 5'b1; // Has warning as not obvious what expression width is //==== localparam WIDTH = 6; wire one_bit; wire [2:0] shifter = 1; wire [WIDTH-1:0] masked = (({{(WIDTH){1'b0}}, one_bit}) << shifter); //==== // We presently warn here, in theory we could detect if the number of one bit additions could overflow the LHS wire one = 1; wire [2:0] cnt = (one + one + one + one); endmodule module p #(parameter WIDTH=64) (input [WIDTH-1:0] in); wire [4:0] out = in; endmodule verilator-3.916/test_regress/t/t_const_dec_mixed_bad.v0000664000177100017500000000035712473477707023172 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.916/test_regress/t/t_select_index2.v0000664000177100017500000000151213205574202021735 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.916/test_regress/t/t_var_set_link.v0000664000177100017500000000100012473477707021677 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.916/test_regress/t/t_param_mem_attr.pl0000775000177100017500000000067412671044616022365 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_interface_array_nocolon_bad.v0000664000177100017500000000116513205574202024704 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Functionally demonstrate an array of interfaces // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Mike Popoloski. interface foo_intf ( input x ); endinterface module foo_subm ( input x ); endmodule module t (); localparam N = 3; wire [2:0] X = 3'b110; // Will cause LITENDIAN warning? foo_intf foos [N] (.x(X)); // bad foo_intf fool [1:3] (.x(X)); // bad foo_intf foom [3:1] (.x(X)); // ok foo_subm subs [N] (.x(X)); // bad foo_subm subl [1:3] (.x(X)); // bad foo_subm subm [3:1] (.x(X)); // ok endmodule verilator-3.916/test_regress/t/t_math_precedence.pl0000775000177100017500000000103212671044616022470 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. #!$Self->{vcs} or $Self->unsupported("VCS does ** wrong, fixed in 2014"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_implicit.pl0000775000177100017500000000101212473477707022233 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_pp_misdef_bad.v0000664000177100017500000000046012473477707022004 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.916/test_regress/t/t_pipe_filter.pf0000664000177100017500000000316212473477707021674 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.916/test_regress/t/t_trace_off_cc.pl0000775000177100017500000000117613151152521021755 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_interface_param_another_bad.pl0000775000177100017500000000111513205574202025023 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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=> q{%Error: t/t_interface_param_another_bad.v:\d+: Parameter-resolved constants must not use dotted references: dummy %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_preproc.v0000664000177100017500000004241013205574202020661 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2000-2011 by Wilson Snyder. //=========================================================================== // Includes `include "t_preproc_inc2.vh" //=========================================================================== // Comments /* verilator pass_thru comment */ // verilator pass_thru_comment2 //=========================================================================== // Defines `define DEF_A3 `define DEF_A1 // DEF_A0 set by command line wire [3:0] q = { `ifdef DEF_A3 1'b1 `else 1'b0 `endif , `ifdef DEF_A2 1'b1 `else 1'b0 `endif , `ifdef DEF_A1 1'b1 `else 1'b0 `endif , `ifdef DEF_A0 1'b1 `else 1'b0 `endif }; text. `define FOOBAR foo /*this */ bar /* this too */ `define FOOBAR2 foobar2 // but not `FOOBAR `FOOBAR2 `define MULTILINE first part \ second part \ third part `define MOREMULTILINE {\ a,\ b,\ c} /*******COMMENT*****/ `MULTILINE `MOREMULTILINE Line_Preproc_Check `__LINE__ //=========================================================================== `define syn_negedge_reset_l or negedge reset_l `define DEEP deep `define DEEPER `DEEP `DEEP `DEEPER `define nosubst NOT_SUBSTITUTED `define WITHTICK "`nosubst" "Inside: `nosubst" `WITHTICK `define withparam(a, b) a b LLZZ a b `withparam(x,y) `withparam(`withparam(p,q),`withparam ( r , s )) `withparam(firstline , comma","line) `define withquote(a, bar) a bar LLZZ "a" bar `withquote( x , y) // Simulators disagree here; some substitute "a" others do not `define noparam (a,b) `noparam(a,b) `define msg(x,y) `"x: `\`"y`\`"`" $display(`msg(left side, right side)) `define foo(f) f``_suffix `foo(bar) more `define zap(which) \ $c("Zap(\"",which,"\");"); `zap(bug1); `zap("bug2"); /* Define inside comment: `DEEPER and `WITHTICK */ // More commentary: `zap(bug1); `zap("bug2"); //====================================================================== // display passthru `define ls left_side `define rs right_side `define noarg na `define thru(x) x `define thruthru `ls `rs // Doesn't expand `define msg(x,y) `"x: `\`"y`\`"`" initial begin //$display(`msg( \`, \`)); // Illegal $display(`msg(pre `thru(thrupre `thru(thrumid) thrupost) post,right side)); $display(`msg(left side,right side)); $display(`msg( left side , right side )); $display(`msg( `ls , `rs )); $display(`msg( `noarg , `rs )); $display(`msg( prep ( midp1 `ls midp2 ( outp ) ) , `rs )); $display(`msg(`noarg,`noarg`noarg)); $display(`msg( `thruthru , `thruthru )); // Results vary between simulators $display(`msg(`thru(),)); // Empty $display(`msg(`thru(left side),`thru(right side))); $display(`msg( `thru( left side ) , `thru( right side ) )); $display(`"standalone`"); // Unspecified when the stringification has multiple lines `define twoline first \ second $display(`msg(twoline, `twoline)); //$display(`msg(left side, \ right side \ )); // Not sure \{space} is legal. $write("*-* All Finished *-*\n"); $finish; end endmodule //====================================================================== // rt.cpan.org bug34429 `define ADD_UP(a,c) \ wire tmp_``a = a; \ wire tmp_``c = tmp_``a + 1; \ assign c = tmp_``c ; module add1 ( input wire d1, output wire o1); `ADD_UP(d1,o1) // expansion is OK endmodule module add2 ( input wire d2, output wire o2); `ADD_UP( d2 , o2 ) // expansion is bad endmodule `define check(mod, width, flopname, gate, path) \ generate for (i=0; i<(width); i=i+1) begin \ psl cover { path.d[i] & ~path.q[i] & !path.cond & (gate)} report `"fondNoRise: mod.flopname`"; \ psl cover { ~path.d[i] & path.q[i] & !path.cond & (gate)} report `"fondNoFall: mod.flopname`"; \ end endgenerate // parameterized macro with arguments that are macros `define MK m5k.f `define MF `MK .ctl `define CK_fr (`MF.alive & `MF.alive_m1) `check(m5kc_fcl, 3, _ctl_mvldx_m1, `CK_fr, `MF._ctl_mvldx_m1) // ignorecmt //====================================================================== // Quotes are legal in protected blocks. Grr. module prot(); `protected I!#r#e6<_Q{{E2+]I3<[3s)1@D|'E''i!O?]jD>Jo_![Cl) #nj1]p,3^1~,="E@QZB\T)eU\pC#C|7=\$J$##A[@-@{Qk] `endprotected endmodule //" //====================================================================== // macro call with define that has comma `define REG_H 6 `define REG_L 7 `define _H regs[`REG_H] `define _L regs[`REG_L] `define _HL {`_H, `_L} `define EX_WRITE(ad, da) begin addr <= (ad); wdata <= (da); wr <= 1; end `define EX_READ(ad) begin addr <= (ad); rd <= 1; end `EX_READ((`_HL + 1)) and `EX_WRITE((`_HL), rdata) `EX_READ(`_HL + 1) `EX_WRITE(`_HL, rdata) more //====================================================================== // include of parameterized file `define INCNAME "t_preproc_inc4.vh" `include `INCNAME `ifndef T_PREPROC_INC4 `error "No Inc4" `endif `undef T_PREPROC_INC4 `ifdef NOT_DEFINED_INC `include NOT_DEFINED_INC `endif //====================================================================== // macro call with , in {} `define xxerror(logfile, msg) $blah(logfile,msg) `xxerror("ab,cd","e,f"); `xxerror(this.logfile, vec); `xxerror(this.logfile, vec[1,2,3]); `xxerror(this.logfile, {blah.name(), " is not foo"}); //====================================================================== // pragma/default net type `pragma foo = 1 `default_nettype none `default_nettype uwire //====================================================================== // Ifdef `define EMPTY_TRUE `ifndef EMPTY_TRUE `error "Empty is still true" `endif Line_Preproc_Check `__LINE__ //====================================================================== // bug84 `define ARGPAR(a, // Hello, comments MIGHT not be legal /*more,,)cmts*/ b // But newlines ARE legal... who speced THAT? ) (a,b) `ARGPAR(p,q) `ARGPAR( //Here x, y //Too ) Line_Preproc_Check `__LINE__ //====================================================================== // defines split arguments `define BEGIN begin `define END end `define BEGINEND `BEGIN`END `define quoteit(x) `"x`" `BEGIN`END // 2001 spec doesn't require two tokens, so "beginend" ok `BEGINEND // 2001 spec doesn't require two tokens, so "beginend" ok `quoteit(`BEGIN`END) // No space "beginend" //====================================================================== // bug106 `define \esc`def got_escaped `ifdef \esc`def `\esc`def `endif Not a \`define //====================================================================== // misparsed comma in submacro `define sb bee `define appease_emacs_paren_matcher ( `define sa(l) x,y) `define sfoo(q,r) q--r `sfoo(`sa(el),`sb) submacro has comma paren //====================================================================== // bug191 `define bug191(bits) $display("bits %d %d", $bits(foo), bits); `bug191(10) //====================================================================== // 1800-2009 `define UDALL `ifndef PREDEF_COMMAND_LINE `error "Test setup error, PREDEF_COMMAND_LINE pre-missing" `endif `undefineall `ifdef UDALL `error "undefineall failed" `endif `ifndef PREDEF_COMMAND_LINE `error "Deleted too much, no PREDEF_COMMAND_LINE" `endif //====================================================================== // bug202 `define FC_INV3(out, in) \ `ifdef DC \ cell \inv_``out <$typeof(out)> (.a(), .o()); \ /* multi-line comment \ multi-line comment */ \ `else \ `ifdef MACRO_ATTRIBUTE \ (* macro_attribute = `"INV (out``,in``)`" *) \ `endif \ assign out = ~in ; \ `endif `FC_INV3(a3,b3) `define /* multi \ line1*/ \ bug202( i /*multi \ line2*/ \ ) \ /* multi \ line 3*/ \ def i \ `bug202(foo) //====================================================================== `define CMT1 // verilator NOT IN DEFINE `define CMT2 /* verilator PART OF DEFINE */ `define CMT3 /* verilator NOT PART OF DEFINE */ `define CMT4 /* verilator PART \ OF DEFINE */ `define CMT5 // CMT NOT \ also in // BUT TEXT IS \ also3 // CMT NOT 1 `CMT1 (nodef) 2 `CMT2 (hasdef) 3 `CMT3 (nodef) 4 `CMT4 (nodef) 5 `CMT5 (nodef) `define NL HAS a NEW \ LINE `NL //====================================================================== `define msg_fatal(log, msg) \ do \ /* synopsys translate_off */ \ `ifdef NEVER \ `error "WTF" \ `else \ if (start(`__FILE__, `__LINE__)) begin \ `endif \ message(msg); \ end \ /* synopsys translate_on */ \ while(0) `define msg_scen_(cl) cl``_scen `define MSG_MACRO_TO_STRING(x) `"x`" EXP: clxx_scen `msg_scen_(clxx) EXP: clxx_scen `MSG_MACRO_TO_STRING(`msg_scen_(clxx)) `define mf(clx) `msg_fatal(this.log, {"Blah-", `MSG_MACRO_TO_STRING(`msg_scen_(clx)), " end"}); EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", " end"}); end while(0); `mf(clx) //====================================================================== `define makedefine(name) \ `define def_``name This is name \ `define def_``name``_2 This is name``_2 \ `makedefine(fooed) `ifndef def_fooed `error "No def_fooed" `endif //`ifndef def_fooed_2 `error "No def_fooed_2" `endif EXP: This is fooed `def_fooed EXP: This is fooed_2 `def_fooed_2 //====================================================================== `define NOPARAM() np `NOPARAM() `NOPARAM( ) //====================================================================== // It's unclear if the spec allows this; is text_macro_idenitfier before or after substitution? `define NODS_DEFINED `define NODS_INDIRECT(x) x `ifndef `NODS_INDIRECT(NODS_DEFINED) `error "Indirect failed" `endif `ifdef `NODS_INDIRECT(NODS_UNDEFINED) `error "Indirect2 failed" `endif //====================================================================== // Metaprogramming `define REPEAT_0(d) `define REPEAT_1(d) d `define REPEAT_2(d) `REPEAT_1(d)d `define REPEAT_3(d) `REPEAT_2(d)d `define REPEAT_4(d) `REPEAT_3(d)d `define CONCAT(a, b) a``b `define REPEATC(n, d) `CONCAT(`REPEAT_, n)(d) `define REPEATT(n, d) `REPEAT_``n(d) `REPEATC(3, hello3 ) `REPEATT(4, hello4 ) //====================================================================== // Include from stringification `undef T_PREPROC_INC4 `define NODS_CONC_VH(m) `"m.vh`" `include `NODS_CONC_VH(t_preproc_inc4) `ifndef T_PREPROC_INC4 `error_here `endif //====================================================================== // Defines doing defines // Note the newline on the end - required to form the end of a define `define DEFINEIT(d) d \ `define _DEFIF_Z_0 1 `define DEFIF_NZ(d,n) `undef d `ifndef _DEFIF_Z_``n `DEFINEIT(`define d 1) `endif `DEFIF_NZ(TEMP,1) `ifndef TEMP `error "bad" `endif `DEFIF_NZ(TEMP,0) `ifdef TEMP `error "bad0" `endif Line_Preproc_Check `__LINE__ //====================================================================== // Quoted multiline - track line numbers, and insure \\n gets propagated `define MULQUOTE "FOO \ BAR " `define MULQUOTE2(mq) `MULQUOTE mq `MULQUOTE Line_Preproc_Check `__LINE__ `MULQUOTE2("arg_line1 \ arg_line2") Line_Preproc_Check `__LINE__ //====================================================================== // bug283 `define A a `define B b `define C c // EXP: abc `define C5 `A``b```C `C5 `undef A `undef B `undef C `define XTYPE sonet `define XJOIN(__arg1, __arg2) __arg1``__arg2 `define XACTION `XJOIN(`XTYPE, _frame) EXP: sonet_frame `XACTION // `define XFRAME frame `define XACTION2 `XJOIN(sonet_, `XFRAME) EXP: sonet_frame `XACTION2 // This result varies between simulators `define sonet_frame other_frame `define XACTION3 `XTYPE``_frame EXP: sonet_frame `XACTION3 // The existance of non-existance of a base define can make a difference `define QA_b zzz `define Q1 `QA``_b EXP: module zzz ; endmodule module `Q1 ; endmodule module `Q1 ; endmodule `define QA a EXP: module a_b ; endmodule module `Q1 ; endmodule module `Q1 ; endmodule //====================================================================== // bug311 integer/*NEED_SPACE*/foo; //====================================================================== // bug441 module t; //----- // case provided // note this does NOT escape as suggested in the mail `define LEX_CAT(lexem1, lexem2) lexem1``lexem2 `define LEX_ESC(name) \name \ initial begin : `LEX_ESC( `LEX_CAT(a[0],_assignment) ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`LEX_CAT(a[0],_assignment) "); end //----- // SHOULD(simulator-dependant): Backslash doesn't prevent arguments from // substituting and the \ staying in the expansion // Note space after name is important so when substitute it has ending whitespace `define ESC_CAT(name,name2) \name``_assignment_``name2 \ initial begin : `ESC_CAT( a[0],a[1] ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\a[0]_assignment_a[1] "); end `undef ESC_CAT //----- `define CAT(a,b) a``b `define ESC(name) \`CAT(name,suffix) // RULE: Ignoring backslash does NOT allow an additional expansion level // (Because ESC gets expanded then the \ has it's normal escape meaning) initial begin : `ESC(pp) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(pp,suffix) "); end `undef CAT `undef ESC //----- `define CAT(a,b) a``b `define ESC(name) \name \ // Similar to above; \ does not allow expansion after substitution initial begin : `ESC( `CAT(ff,bb) ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(ff,bb) "); end `undef CAT `undef ESC //----- `define ESC(name) \name \ // MUST: Unknown macro with backslash escape stays as escaped symbol name initial begin : `ESC( `zzz ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`zzz "); end `undef ESC //----- `define FOO bar `define ESC(name) \name \ // SHOULD(simulator-dependant): Known macro with backslash escape expands initial begin : `ESC( `FOO ) $write("GOT%%m='%m' OTHER_EXP='%s'\n OUR_EXP='%s'", "t.bar ","t.\\`FOO "); end // SHOULD(simulator-dependant): Prefix breaks the above initial begin : `ESC( xx`FOO ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\xx`FOO "); end `undef FOO `undef ESC //----- // MUST: Unknown macro not under call with backslash escape doesn't expand `undef UNKNOWN initial begin : \`UNKNOWN $write("GOT%%m='%m' EXP='%s'\n", "t.\\`UNKNOWN "); end //----- // MUST: Unknown macro not under call doesn't expand `define DEF_NO_EXPAND error_dont_expand initial begin : \`DEF_NO_EXPAND $write("GOT%%m='%m' EXP='%s'\n", "t.\\`DEF_NO_EXPAND "); end `undef DEF_NO_EXPAND //----- // bug441 derivative // SHOULD(simulator-dependant): Quotes doesn't prevent arguments from expanding (like backslashes above) `define STR(name) "foo name baz" initial $write("GOT='%s' EXP='%s'\n", `STR(bar), "foo bar baz"); `undef STR //----- // RULE: Because there are quotes after substituting STR, the `A does NOT expand `define STR(name) "foo name baz" `define A(name) boo name hiss initial $write("GOT='%s' EXP='%s'\n", `STR(`A(bar)), "foo `A(bar) baz"); `undef A `undef STR //---- // bug845 `define SLASHED "1//2.3" initial $write("Slashed=`%s'\n", `SLASHED); //---- // bug915 `define BUG915(a,b,c) \ $display("%s%s",a,`"b``c``\n`") initial `BUG915("a1",b2,c3); endmodule //====================================================================== //bug1225 `define X_ITEM(SUB,UNIT) `X_STRING(SUB``UNIT) `define X_STRING(A) `"A`" $display(`X_ITEM(RAM,0)); $display(`X_ITEM(CPU,)); `define EMPTY `define EMPTYP(foo) `define SOME some `define SOMEP(foo) foo `define XXE_FAMILY XXE_```EMPTY XXE_FAMILY = `XXE_FAMILY `define XXE_```EMPTY `ifdef XXE_ $display("XXE_ is defined"); `endif `define XYE_FAMILY XYE_```EMPTYP(foo) XYE_FAMILY = `XYE_FAMILY `define XYE_```EMPTYP(foo) `ifdef XYE_ $display("XYE_ is defined"); `endif `define XXS_FAMILY XXS_```SOME XXS_FAMILY = `XXS_FAMILY `define XXS_```SOME `ifdef XXS_some $display("XXS_some is defined"); `endif `define XYS_FAMILY XYS_```SOMEP(foo) XYS_FAMILY = `XYS_FAMILY `define XYS_```SOMEP(foo) `ifdef XYS_foo $display("XYS_foo is defined"); `endif //==== `ifdef NEVER `define NXE_FAMILY NXE_```EMPTY NXE_FAMILY = `NXE_FAMILY `define NXE_```EMPTY `ifdef NXE_ $display("NXE_ is defined"); `endif `define NYE_FAMILY NYE_```EMPTYP(foo) NYE_FAMILY = `NYE_FAMILY `define NYE_```EMPTYP(foo) `ifdef NYE_ $display("NYE_ is defined"); `endif `define NXS_FAMILY NXS_```SOME NXS_FAMILY = `NXS_FAMILY `define NXS_```SOME `ifdef NXS_some $display("NXS_some is defined"); `endif `define NYS_FAMILY NYS_```SOMEP(foo) NYS_FAMILY = `NYS_FAMILY `define NYS_```SOMEP(foo) `ifdef NYS_foo $display("NYS_foo is defined"); `endif `include `EMPTY `endif // NEVER //bug1227 `define INSTANCE(NAME) (.mySig (myInterface.``NAME), `INSTANCE(pa5) //====================================================================== // 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.916/test_regress/t/t_interface_gen8_noinl.pl0000775000177100017500000000102613205574202023436 0ustar wsnyderwsnyder#!/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_gen8.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_unsup_deassign.pl0000775000177100017500000000104113205574202023430 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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 --bbox-unsup"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_gate.v0000664000177100017500000000205412671044616021014 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.916/test_regress/t/t_tri_select.v0000664000177100017500000000201612671044616021351 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.916/test_regress/t/t_package_enum.v0000664000177100017500000000133612671044616021637 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.916/test_regress/t/t_func_rand.cpp0000664000177100017500000000123712671044616021474 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.916/test_regress/t/t_order_wireloop.v0000664000177100017500000000046713205574202022250 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs bar ); wire foo; output bar; // Oh dear. assign foo = bar; assign bar = foo; endmodule verilator-3.916/test_regress/t/t_delay_stmtdly_bad.pl0000775000177100017500000000176412473477707023075 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_func_wide_out_bad.pl0000775000177100017500000000122312671044616023024 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_math_pow5.pl0000775000177100017500000000072213205574202021263 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_assert_comp.pl0000775000177100017500000000103313205574202021673 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_math_signed2.v0000664000177100017500000000300612473477707021573 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.916/test_regress/t/t_func_twocall.v0000664000177100017500000000275212473477707021716 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.916/test_regress/t/t_inst_slice_noinl.pl0000775000177100017500000000102313205574202022706 0ustar wsnyderwsnyder#!/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_slice.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_bind.pl0000775000177100017500000000072212671044616020303 0ustar 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.916/test_regress/t/t_order_a.v0000664000177100017500000000311112473477707020637 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.916/test_regress/t/t_gen_cond_bitrange_bad.pl0000775000177100017500000000163512671044616023630 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_lint_always_comb_bad.pl0000775000177100017500000000127112671044616023523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_vams_wreal.pl0000775000177100017500000000071713071024263021522 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_slice_init.pl0000775000177100017500000000072213205574202021502 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_complex.out0000664000177100017500000000612513205574202022401 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Tue Apr 15 19:42:28 2014 $end $timescale 1ns $end $scope module top $end $var wire 1 9 clk $end $scope module $unit $end $var wire 1 # global_bit $end $upscope $end $scope module t $end $var wire 1 9 clk $end $var wire 32 $ cyc [31:0] $end $var real 64 3 v_arr_real(0) $end $var real 64 5 v_arr_real(1) $end $var wire 2 * v_arrp [2:1] $end $var wire 4 + v_arrp_arrp [3:0] $end $var wire 4 , v_arrp_strp [3:0] $end $var wire 1 : v_arru(1) $end $var wire 1 ; v_arru(2) $end $var wire 2 - v_arru_arrp(3) [2:1] $end $var wire 2 . v_arru_arrp(4) [2:1] $end $var wire 1 < v_arru_arru(3)(1) $end $var wire 1 = v_arru_arru(3)(2) $end $var wire 1 > v_arru_arru(4)(1) $end $var wire 1 ? v_arru_arru(4)(2) $end $var wire 2 / v_arru_strp(3) [1:0] $end $var wire 2 0 v_arru_strp(4) [1:0] $end $var real 64 1 v_real $end $var wire 64 % v_str32x2 [63:0] $end $var wire 2 ' v_strp [1:0] $end $var wire 4 ( v_strp_strp [3:0] $end $var wire 2 ) v_unip_strp [1:0] $end $scope module p2 $end $var wire 32 @ PARAM [31:0] $end $upscope $end $scope module p3 $end $var wire 32 A PARAM [31:0] $end $upscope $end $scope module unnamedblk1 $end $var wire 32 7 b [31:0] $end $scope module unnamedblk2 $end $var wire 32 8 a [31:0] $end $upscope $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 1# b00000000000000000000000000000000 $ b0000000000000000000000000000000000000000000000000000000011111111 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0 1 r0 3 r0 5 b00000000000000000000000000000000 7 b00000000000000000000000000000000 8 09 0: 0; 0< 0= 0> 0? b00000000000000000000000000000010 @ b00000000000000000000000000000011 A #10 b00000000000000000000000000000001 $ b0000000000000000000000000000000100000000000000000000000011111110 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.1 1 r0.2 3 r0.3 5 b00000000000000000000000000000101 7 b00000000000000000000000000000101 8 19 #15 09 #20 b00000000000000000000000000000010 $ b0000000000000000000000000000001000000000000000000000000011111101 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.2 1 r0.4 3 r0.6 5 19 #25 09 #30 b00000000000000000000000000000011 $ b0000000000000000000000000000001100000000000000000000000011111100 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.3 1 r0.6000000000000001 3 r0.8999999999999999 5 19 #35 09 #40 b00000000000000000000000000000100 $ b0000000000000000000000000000010000000000000000000000000011111011 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.4 1 r0.8 3 r1.2 5 19 #45 09 #50 b00000000000000000000000000000101 $ b0000000000000000000000000000010100000000000000000000000011111010 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.5 1 r1 3 r1.5 5 19 #55 09 #60 b00000000000000000000000000000110 $ b0000000000000000000000000000011000000000000000000000000011111001 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.6 1 r1.2 3 r1.8 5 19 verilator-3.916/test_regress/t/t_mod_longname.pl0000775000177100017500000000072213205574202022017 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_gate_bufif1.pl0000775000177100017500000000134313151152521022406 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_case_write2_tasks.v0000664000177100017500000025433112473477707022654 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.916/test_regress/t/t_dedupe_seq_logic.v0000664000177100017500000000525212671044616022514 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.916/test_regress/t/t_tri_select_unsized.pl0000775000177100017500000000074512671044616023272 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_var_pins_sc_biguint.pl0000775000177100017500000000467013205574202023415 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.916/test_regress/t/t_tri_select.pl0000775000177100017500000000116513151152521021513 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_inst_wideconst.v0000664000177100017500000000220412473477707022262 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.916/test_regress/t/t_gen_inc.v0000664000177100017500000001271613205574202020617 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.916/test_regress/t/t_var_pins_sc2.pl0000775000177100017500000000407113205574202021751 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -pins-bv 2 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.916/test_regress/t/t_lint_defparam_bad.pl0000775000177100017500000000154512473477707023021 0ustar 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.916/test_regress/t/t_tri_inout2.pl0000775000177100017500000000066012671044616021466 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 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.916/test_regress/t/t_flag_define.vc0000664000177100017500000000023213205574202021571 0ustar wsnyderwsnyder+define+D1A +define+D2A=VALA +define+D3A+D3B +define+D4A=VALA+D4B +define+D5A=VALA+D5B=VALB // Quotes do NOT escape the plus //+define+D5A="VALA+D5B"+D5C verilator-3.916/test_regress/t/t_pp_display.pl0000775000177100017500000000160212473477707021544 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the 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.916/test_regress/t/t_trace_complex_structs.out0000664000177100017500000000765113205574202024175 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Tue Apr 15 12:58:17 2014 $end $timescale 1ns $end $scope module top $end $var wire 1 D clk $end $scope module $unit $end $var wire 1 # global_bit $end $upscope $end $scope module t $end $var wire 1 D clk $end $var wire 32 $ cyc [31:0] $end $var real 64 > v_arr_real(0) $end $var real 64 @ v_arr_real(1) $end $var wire 2 / v_arrp [2:1] $end $var wire 2 0 v_arrp_arrp(3) [1:0] $end $var wire 2 1 v_arrp_arrp(4) [1:0] $end $var wire 1 E v_arru(1) $end $var wire 1 F v_arru(2) $end $var wire 2 6 v_arru_arrp(3) [2:1] $end $var wire 2 7 v_arru_arrp(4) [2:1] $end $var wire 1 G v_arru_arru(3)(1) $end $var wire 1 H v_arru_arru(3)(2) $end $var wire 1 I v_arru_arru(4)(1) $end $var wire 1 J v_arru_arru(4)(2) $end $var real 64 < v_real $end $scope module unnamedblk1 $end $var wire 32 B b [31:0] $end $scope module unnamedblk2 $end $var wire 32 C a [31:0] $end $upscope $end $upscope $end $scope module v_arrp_strp(3) $end $var wire 1 3 b0 $end $var wire 1 2 b1 $end $upscope $end $scope module v_arrp_strp(4) $end $var wire 1 5 b0 $end $var wire 1 4 b1 $end $upscope $end $scope module v_arru_strp(3) $end $var wire 1 9 b0 $end $var wire 1 8 b1 $end $upscope $end $scope module v_arru_strp(4) $end $var wire 1 ; b0 $end $var wire 1 : b1 $end $upscope $end $scope module v_str32x2(0) $end $var wire 32 % data [31:0] $end $upscope $end $scope module v_str32x2(1) $end $var wire 32 & data [31:0] $end $upscope $end $scope module v_strp $end $var wire 1 ( b0 $end $var wire 1 ' b1 $end $upscope $end $scope module v_strp_strp $end $scope module x0 $end $var wire 1 , b0 $end $var wire 1 + b1 $end $upscope $end $scope module x1 $end $var wire 1 * b0 $end $var wire 1 ) b1 $end $upscope $end $upscope $end $scope module v_unip_strp $end $scope module x0 $end $var wire 1 . b0 $end $var wire 1 - b1 $end $upscope $end $scope module x1 $end $var wire 1 . b0 $end $var wire 1 - b1 $end $upscope $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 1# b00000000000000000000000000000000 $ b00000000000000000000000011111111 % b00000000000000000000000000000000 & 0' 0( 0) 0* 0+ 0, 0- 0. b00 / b00 0 b00 1 02 03 04 05 b00 6 b00 7 08 09 0: 0; r0 < r0 > r0 @ b00000000000000000000000000000000 B b00000000000000000000000000000000 C 0D 0E 0F 0G 0H 0I 0J #10 b00000000000000000000000000000001 $ b00000000000000000000000011111110 % b00000000000000000000000000000001 & 1' 1( 1) 1* 1+ 1, 1- 1. b11 / b11 0 b11 1 12 13 14 15 b11 6 b11 7 18 19 1: 1; r0.1 < r0.2 > r0.3 @ b00000000000000000000000000000101 B b00000000000000000000000000000101 C 1D #15 0D #20 b00000000000000000000000000000010 $ b00000000000000000000000011111101 % b00000000000000000000000000000010 & 0' 0( 0) 0* 0+ 0, 0- 0. b00 / b00 0 b00 1 02 03 04 05 b00 6 b00 7 08 09 0: 0; r0.2 < r0.4 > r0.6 @ 1D #25 0D #30 b00000000000000000000000000000011 $ b00000000000000000000000011111100 % b00000000000000000000000000000011 & 1' 1( 1) 1* 1+ 1, 1- 1. b11 / b11 0 b11 1 12 13 14 15 b11 6 b11 7 18 19 1: 1; r0.3 < r0.6000000000000001 > r0.8999999999999999 @ 1D #35 0D #40 b00000000000000000000000000000100 $ b00000000000000000000000011111011 % b00000000000000000000000000000100 & 0' 0( 0) 0* 0+ 0, 0- 0. b00 / b00 0 b00 1 02 03 04 05 b00 6 b00 7 08 09 0: 0; r0.4 < r0.8 > r1.2 @ 1D #45 0D #50 b00000000000000000000000000000101 $ b00000000000000000000000011111010 % b00000000000000000000000000000101 & 1' 1( 1) 1* 1+ 1, 1- 1. b11 / b11 0 b11 1 12 13 14 15 b11 6 b11 7 18 19 1: 1; r0.5 < r1 > r1.5 @ 1D #55 0D #60 b00000000000000000000000000000110 $ b00000000000000000000000011111001 % b00000000000000000000000000000110 & 0' 0( 0) 0* 0+ 0, 0- 0. b00 / b00 0 b00 1 02 03 04 05 b00 6 b00 7 08 09 0: 0; r0.6 < r1.2 > r1.8 @ 1D verilator-3.916/test_regress/t/t_display_wide.pl0000775000177100017500000001053712473477707022064 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_pp_misdef_bad.pl0000775000177100017500000000117312473477707022157 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_param_named_2.v0000664000177100017500000000206312473477707021716 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.916/test_regress/t/t_display_merge.v0000664000177100017500000000246713205574202022043 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/); initial begin $display("Merge:"); $write("This "); $write("should "); $display("merge"); $display("f"); $display(" a=%m"); $display(" b=%m"); $display(" pre"); $display(" t=%0d",$time); $display(" t2=%0d",$time); $display(" post"); $display(" t3=%0d",$time); $display(" t4=%0d t5=%0d",$time,$time,$time); $display("m"); $display(" t=%0d t2=%0d t3=%0d t4=%0d t5=%0d",$time,$time,$time,$time,$time); $display(" t=%0d t2=%0d t3=%0d t4=%0d t5=%0d",$time,$time,$time,$time,$time); $display("mm"); $display(""); $write("f"); $write(" a=%m"); $write(" b=%m"); $write(" pre"); $write(" t=%0d",$time); $write(" t2=%0d",$time); $write(" post"); $write(" t3=%0d",$time); $write(" t4=%0d t5=%0d",$time,$time,$time); $write("m"); $write(" t=%0d t2=%0d t3=%0d t4=%0d t5=%0d",$time,$time,$time,$time,$time); $write(" t=%0d t2=%0d t3=%0d t4=%0d t5=%0d",$time,$time,$time,$time,$time); $display("mm"); $write("\n*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_array_compare.pl0000775000177100017500000000072213205574202022204 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_array2.pl0000775000177100017500000000072213205574202021740 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_v.pl0000775000177100017500000000072212671044616020647 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface2.v0000664000177100017500000000470312671044616021243 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.916/test_regress/t/t_package_twodeep.pl0000775000177100017500000000071712671044616022515 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_inout.v0000664000177100017500000000105312671044616021230 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.916/test_regress/t/t_lint_width.pl0000775000177100017500000000110613151152521021516 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_order_loop_bad.pl0000775000177100017500000000143213205574202022331 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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+: t.ready %Error: Example path: t/t_order_loop_bad.v:\d+: ACTIVE .*', ); ok(1); 1; verilator-3.916/test_regress/t/t_math_signed.pl0000775000177100017500000000071412473477707021665 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_scstruct.v0000664000177100017500000000071313205574202022237 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. // verilator lint_off UNUSED // verilator lint_off UNDRIVEN //bug858 typedef struct packed { logic m_1; logic m_2; } struct_t; typedef struct packed { logic [94:0] m_1; logic m_2; } struct96_t; module t ( input struct_t test_input, input struct96_t t96 ); endmodule verilator-3.916/test_regress/t/t_flag_fi.pl0000775000177100017500000000122713205574202020750 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["-FI $Self->{t_dir}/t_flag_fi_h.h", "--exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_various.pl0000775000177100017500000000025212671044616021733 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.916/test_regress/t/t_lint_unused.pl0000775000177100017500000000121012671044616021711 0ustar 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.916/test_regress/t/t_math_concat64.pl0000775000177100017500000000071712473477707022040 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_pins_cc.pl0000775000177100017500000000303313173724353021654 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_gen_intdot.pl0000775000177100017500000000071712473477707021540 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_pick.pl0000775000177100017500000000072212671044616021326 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_clk_2in.pl0000775000177100017500000000114413205574202020700 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_var_bad_sv.pl0000775000177100017500000000151712473477707021513 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_struct_param.pl0000775000177100017500000000072213205574202022064 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_dedupe_clk_gate.pl0000775000177100017500000000106712671044616022471 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_mem_multidim_Ox.pl0000775000177100017500000000102613151152521022502 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_sys_rand.pl0000775000177100017500000000071712473477707021230 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vpi_memory.cpp0000664000177100017500000001642113205574202021715 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_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, .value = {.integer = 0} }; // 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, .value = {.integer = 0} }; vpi_printf((PLI_BYTE8*)"Check memory vpi ...\n"); mem_h = vpi_handle_by_name((PLI_BYTE8*)TestSimulator::rooted("mem0"), NULL); CHECK_RESULT_NZ(mem_h); // check type int vpitype = vpi_get(vpiType, mem_h); CHECK_RESULT(vpitype, vpiMemory); if (int status = _mon_check_range(mem_h, 16, 16, 1)) return status; // iterate and store iter_h = vpi_iterate(vpiMemoryWord, mem_h); cnt = 0; while ((lcl_h = vpi_scan(iter_h))) { value.value.integer = ++cnt; vpi_put_value(lcl_h, &value, NULL, vpiNoDelay); // check size and range if (int status = _mon_check_range(lcl_h, 32, 31, 0)) return status; } CHECK_RESULT(cnt, 16); // should be 16 addresses // iterate and accumulate iter_h = vpi_iterate(vpiMemoryWord, mem_h); cnt = 0; while ((lcl_h = vpi_scan(iter_h))) { ++cnt; vpi_get_value(lcl_h, &value); CHECK_RESULT(value.value.integer, cnt); } CHECK_RESULT(cnt, 16); // should be 16 addresses // don't care for non verilator // (crashes on Icarus) if (TestSimulator::is_icarus()) { vpi_printf((PLI_BYTE8*)"Skipping property checks for simulator %s\n", TestSimulator::get_info().product); return 0; // Ok } // make sure trying to get properties that don't exist // doesn't crash int should_be_0 = vpi_get(vpiSize, iter_h); CHECK_RESULT(should_be_0, 0); should_be_0 = vpi_get(vpiIndex, iter_h); CHECK_RESULT(should_be_0, 0); vpiHandle should_be_NULL = vpi_handle(vpiLeftRange, iter_h); CHECK_RESULT(should_be_NULL, 0); should_be_NULL = vpi_handle(vpiRightRange, iter_h); CHECK_RESULT(should_be_NULL, 0); should_be_NULL = vpi_handle(vpiScope, iter_h); CHECK_RESULT(should_be_NULL, 0); return 0; // Ok } int mon_check() { // Callback from initial block in monitor if (int status = _mon_check_memory()) return status; return 0; // Ok } //====================================================================== #ifdef IS_VPI static int mon_check_vpi() { vpiHandle href = vpi_handle(vpiSysTfCall, 0); s_vpi_value vpi_value; vpi_value.format = vpiIntVal; vpi_value.value.integer = mon_check(); vpi_put_value(href, &vpi_value, NULL, vpiNoDelay); return 0; } static s_vpi_systf_data vpi_systf_data[] = { {vpiSysFunc, vpiIntFunc, (PLI_BYTE8*)"$mon_check", (PLI_INT32(*)(PLI_BYTE8*))mon_check_vpi, 0, 0, 0}, 0 }; // cver entry void vpi_compat_bootstrap(void) { p_vpi_systf_data systf_data_p; systf_data_p = &(vpi_systf_data[0]); while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++); } // icarus entry void (*vlog_startup_routines[])() = { vpi_compat_bootstrap, 0 }; #else double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { double sim_time = 1100; Verilated::commandArgs(argc, argv); Verilated::debug(0); Verilated::fatalOnVpiError(0); // we're going to be checking for these errors do don't crash out VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out #ifdef VERILATOR # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif #endif #if VM_TRACE Verilated::traceEverOn(true); VL_PRINTF("Enabling waves...\n"); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_vpi_var/simx.vcd"); #endif topp->eval(); topp->clk = 0; main_time += 10; while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += 1; topp->eval(); VerilatedVpi::callValueCbs(); topp->clk = !topp->clk; //mon_do(); #if VM_TRACE if (tfp) tfp->dump (main_time); #endif } if (!Verilated::gotFinish()) { vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish"); } topp->final(); #if VM_TRACE if (tfp) tfp->close(); #endif delete topp; topp=NULL; exit(0L); } #endif verilator-3.916/test_regress/t/t_assert_casez.v0000664000177100017500000000107313205574202021675 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder module t; reg [1:0] value; initial begin value = 2'b00; unique casez (value) 2'b00 : ; 2'b01 : ; 2'b1? : ; endcase value = 2'b11; unique casez (value) 2'b00 : ; 2'b01 : ; 2'b1? : ; endcase unique casez (1'b1) default: ; endcase $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_inst_prepost.pl0000775000177100017500000000065112671044616022121 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_interface_gen2.pl0000775000177100017500000000072713151152521022234 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_uniqueif_fail4.pl0000775000177100017500000000144013205574202022262 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_uniqueif.v"); compile ( v_flags2 => ['+define+FAILING_ASSERTION4'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], fails => $Self->{nc}, ); execute ( fails => $Self->{vlt}, expect=> '.*%Error: t_uniqueif.v:\d+: Assertion failed in top.t: \'unique if\' statement violated %Error: t/t_uniqueif.v:\d+: Verilog \$stop .*', ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_gen6.v0000664000177100017500000000206513205574202022070 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // bug1001 interface intf #(parameter PARAM = 0) (); logic val; endinterface module t(); generate if (1) begin intf #(.PARAM(2)) my_intf (); assign my_intf.val = '1; end else begin intf #(.PARAM(3)) my_intf (); assign my_intf.val = '0; end endgenerate generate begin if (1) begin intf #(.PARAM(2)) my_intf (); assign my_intf.val = '1; end else begin intf #(.PARAM(3)) my_intf (); assign my_intf.val = '0; end end endgenerate generate begin begin if (1) begin intf #(.PARAM(2)) my_intf (); assign my_intf.val = '1; end else begin intf #(.PARAM(3)) my_intf (); assign my_intf.val = '0; end end end endgenerate initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_math_signed3.pl0000775000177100017500000000072212671044616021734 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inside_wild.v0000664000177100017500000000334112671044616021510 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.916/test_regress/t/t_inst_v2k__sub.vi0000664000177100017500000000101312671044616022130 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.916/test_regress/t/t_inst_recurse_bad.v0000664000177100017500000000057512473477707022552 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.916/test_regress/t/t_mem_multi_io3.v0000664000177100017500000000305113205574202021747 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.916/test_regress/t/t_for_count.v0000664000177100017500000000457412473477707021240 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.916/test_regress/t/t_dpi_context_c.cpp0000664000177100017500000000633313205574202022352 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2009 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include "svdpi.h" //====================================================================== #if defined(VERILATOR) # ifdef T_DPI_CONTEXT_NOOPT # include "Vt_dpi_context_noopt__Dpi.h" # else # include "Vt_dpi_context__Dpi.h" # endif #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef VERILATOR # include "verilated.h" #endif #ifdef NEED_EXTERNS extern "C" { extern int dpic_line(); extern int dpic_save(int value); extern int dpic_restore(); extern unsigned dpic_getcontext(); } #endif //====================================================================== int dpic_line() { svScope scope = svGetScope(); if (!scope) { printf("%%Warning: svGetScope failed\n"); return 0; } #ifdef VERILATOR static int didDump = 0; if (didDump++ == 0) { Verilated::scopesDump(); } #endif const char* scopenamep = svGetNameFromScope(scope); if (!scopenamep) { printf("%%Warning: svGetNameFromScope failed\n"); return 0; } if (scope != svGetScopeFromName(scopenamep)) { printf("%%Warning: svGetScopeFromName repeat failed\n"); return 0; } const char* filenamep = ""; int lineno = 0; if (svGetCallerInfo(&filenamep, &lineno)) { printf("Call from %s:%d:%s\n", filenamep, lineno, scopenamep); } else { printf("%%Warning: svGetCallerInfo failed\n"); return 0; } return lineno; } extern int Dpic_Unique; int Dpic_Unique = 0; // Address used for uniqueness int dpic_save(int value) { svScope scope = svGetScope(); if (!scope) { printf("%%Warning: svGetScope failed\n"); return 0; } // Use union to avoid cast to different size pointer warnings union valpack { void* ptr; int i; } vp; vp.i = value; if (svPutUserData(scope, &Dpic_Unique, vp.ptr)) { printf("%%Warning: svPutUserData failed\n"); return 0; } return 1; } int dpic_restore() { svScope scope = svGetScope(); if (!scope) { printf("%%Warning: svGetScope failed\n"); return 0; } if (void* userp = svGetUserData(scope, (void*)&Dpic_Unique)) { // Use union to avoid cast to different size pointer warnings union valpack { void* ptr; int i; } vp; vp.ptr = userp; return vp.i; } else { printf("%%Warning: svGetUserData failed\n"); return 0; } } unsigned dpic_getcontext() { svScope scope = svGetScope(); printf("%%Info: svGetScope returned scope (%p) with name %s\n", scope, svGetNameFromScope(scope)); return (unsigned) (uintptr_t) scope; } verilator-3.916/test_regress/t/t_flag_xinitial_unique.pl0000775000177100017500000000111513205574202023555 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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 unique"], ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/VL_RAND_RESET/); ok(1); 1; verilator-3.916/test_regress/t/t_math_shift_rep.pl0000775000177100017500000000101612671044616022360 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb -O0'"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_ldflags_so.cpp0000664000177100017500000000134013151152521022623 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.916/test_regress/t/t_interface2.pl0000775000177100017500000000100313151152521021367 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_param_up_bad.pl0000775000177100017500000000132113205574202021766 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_up_bad.v:\d+: Can\'t find definition of scope/variable: bar .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_order_loop_bad.v0000664000177100017500000000153612671044616022174 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.916/test_regress/t/t_dpi_shortcircuit.v0000664000177100017500000002045613205574202022573 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 ctr); import "DPI-C" function bit dpii_inc0 (input int ctr); import "DPI-C" function bit dpii_inc1 (input int ctr); import "DPI-C" function bit dpii_incx (input int ctr, input bit value); integer i; integer j; bit b; 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.916/test_regress/t/t_attr_parenstar.v0000664000177100017500000000133412473477707022262 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.916/test_regress/t/t_flag_relinc.v0000664000177100017500000000051513205574202021454 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2017 by Wilson Snyder. This program is free software; you can // redistribute it and/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; t_flag_relinc_sub sub (); endmodule verilator-3.916/test_regress/t/t_tri_pullup.v0000664000177100017500000000106512473477707021431 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.916/test_regress/t/t_vpi_unimpl.pl0000775000177100017500000000114513205574202021542 0ustar 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 --vpi --no-l2name $Self->{t_dir}/t_vpi_unimpl.cpp"], ); execute ( check_finished=>1 ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_multi_ref_bad.v0000664000177100017500000000140412473477707022661 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.916/test_regress/t/t_typedef.pl0000775000177100017500000000071712473477707021046 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_assert_synth_off.pl0000775000177100017500000000121013151152521022725 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_func_tie_bad.v0000664000177100017500000000054012473477707021631 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.916/test_regress/t/t_gen_index.pl0000775000177100017500000000070213205574202021316 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # Compile time only test compile ( ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_slice_dtype_bad.pl0000775000177100017500000000107013205574402023327 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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_mem_slice_dtype_bad.v:\d+: ADD unexpected in assignment to unpacked array .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_emit_constw.v0000664000177100017500000001333613205574202021547 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. `define checkhw(gotv,w,expv) do if (gotv[(w)*32+:$bits(expv)] !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv[(w)*32+:32]), (expv)); $stop; end while(0); module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; bit [4*32-1:0] w4 = {32'h7c709753, 32'hbc8f6059, 32'h3b0db464, 32'h721a8fad}; bit [8*32-2:0] w8m = {31'h7146e1bf, 32'ha8549e42, 32'hca6960bd, 32'h191b7f9b, 32'h93d79866, 32'hf4489e2b, 32'h8e9a3236, 32'h1d2a2d1d}; bit [8*32-1:0] w8 = {32'hc211addc, 32'he5d4a057, 32'h5cbf88fe, 32'h42cf42e2, 32'heb584263, 32'ha585f118, 32'h231531c8, 32'hc73f7b06}; bit [8*32-0:0] w8p = {1'b1, 32'h096aa54b, 32'h48aae18e, 32'hf9502cea, 32'h518c8b61, 32'h9e8641a2, 32'h0dc0249c, 32'hd421a87a, 32'hb8ee9199}; bit [9*32-1:0] w9 = {32'hca800ac1, 32'h0de4823a, 32'ha51663ac, 32'h96351446, 32'h6b0bbcd5, 32'h4a64b530, 32'h4967d59a, 32'hfcc17292, 32'h57926621}; bit [16*32-2:0] w16m = {31'h77ad72c7, 32'h73aa9cbb, 32'h7ecf026d, 32'h985a3ed2, 32'hfe961c1d, 32'h7a01df72, 32'h79e13d71, 32'hb69e2e32, 32'h09fcbc45, 32'hcfd738c1, 32'hc197ac7c, 32'hc316d727, 32'h903034e4, 32'h92a047d1, 32'h6a5357af, 32'ha82ce9c8}; bit [16*32-1:0] w16 = {32'he49548a7, 32'ha02336a2, 32'h2bb48f0d, 32'h9974e098, 32'h34ae644f, 32'hca46dc2c, 32'h9f71a468, 32'h64ae043e, 32'h7bc94d66, 32'h57aba588, 32'h5b9bb4fe, 32'hb87ed644, 32'hd34b5b20, 32'h712928de, 32'h4bdbd28e, 32'ha0576784}; bit [16*32-0:0] w16p = {1'b1, 32'hd278a306, 32'h374ce262, 32'hb608c88e, 32'h43d3e446, 32'h42e26866, 32'h44c31148, 32'hd3db659f, 32'hb3b84b2e, 32'h1aa7a184, 32'h73b28538, 32'h6384e801, 32'h98d58e00, 32'h9c1d1429, 32'hb407730e, 32'he974c1fd, 32'he787c302}; bit [17*32-1:0] w17 = {32'hf1e322ac, 32'hbbdbd761, 32'h760fe07d, 32'h3808cb28, 32'haf313051, 32'h37dc63b9, 32'hdddb418b, 32'he65a9d64, 32'hc1b6ab23, 32'h11131ac1, 32'h0050e0bc, 32'h442e3754, 32'h0eb4556e, 32'hd153064b, 32'h41349f97, 32'hb6f4149f, 32'h34bb1fb1}; function [7:0] bytehash (input [32*32-1:0] data); integer i; bytehash = 0; for (i=0; i<32*32; ++i) begin bytehash = {bytehash[0], bytehash[7:1]} ^ data[i +: 8]; end return bytehash; endfunction // Aggregate outputs into a single result vector // verilator lint_off WIDTH wire [63:0] result = (bytehash(w4) ^ bytehash(w8m) ^ bytehash(w8) ^ bytehash(w8p) ^ bytehash(w9) ^ bytehash(w16m) ^ bytehash(w16) ^ bytehash(w16p) ^ bytehash(w17)); // verilator lint_on WIDTH `define EXPECTED_SUM 64'hb6fdb64085fc17f5 // 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; // verilator lint_off SELRANGE `checkhw(w4,3,32'h7c709753); `checkhw(w4,2,32'hbc8f6059); `checkhw(w4,1,32'h3b0db464); `checkhw(w4,0,32'h721a8fad); `checkhw(w8m,7,31'h7146e1bf); `checkhw(w8m,6,32'ha8549e42); `checkhw(w8m,5,32'hca6960bd); `checkhw(w8m,4,32'h191b7f9b); `checkhw(w8m,3,32'h93d79866); `checkhw(w8m,2,32'hf4489e2b); `checkhw(w8m,1,32'h8e9a3236); `checkhw(w8m,0,32'h1d2a2d1d); `checkhw(w8,7,32'hc211addc); `checkhw(w8,6,32'he5d4a057); `checkhw(w8,5,32'h5cbf88fe); `checkhw(w8,4,32'h42cf42e2); `checkhw(w8,3,32'heb584263); `checkhw(w8,2,32'ha585f118); `checkhw(w8,1,32'h231531c8); `checkhw(w8,0,32'hc73f7b06); `checkhw(w8p,8,1'b1); `checkhw(w8p,7,32'h096aa54b); `checkhw(w8p,6,32'h48aae18e); `checkhw(w8p,5,32'hf9502cea); `checkhw(w8p,4,32'h518c8b61); `checkhw(w8p,3,32'h9e8641a2); `checkhw(w8p,2,32'h0dc0249c); `checkhw(w8p,1,32'hd421a87a); `checkhw(w8p,0,32'hb8ee9199); `checkhw(w9,8,32'hca800ac1); `checkhw(w9,7,32'h0de4823a); `checkhw(w9,6,32'ha51663ac); `checkhw(w9,5,32'h96351446); `checkhw(w9,4,32'h6b0bbcd5); `checkhw(w9,3,32'h4a64b530); `checkhw(w9,2,32'h4967d59a); `checkhw(w9,1,32'hfcc17292); `checkhw(w9,0,32'h57926621); `checkhw(w16m,15,31'h77ad72c7); `checkhw(w16m,14,32'h73aa9cbb); `checkhw(w16m,13,32'h7ecf026d); `checkhw(w16m,12,32'h985a3ed2); `checkhw(w16m,11,32'hfe961c1d); `checkhw(w16m,10,32'h7a01df72); `checkhw(w16m,9,32'h79e13d71); `checkhw(w16m,8,32'hb69e2e32); `checkhw(w16m,7,32'h09fcbc45); `checkhw(w16m,6,32'hcfd738c1); `checkhw(w16m,5,32'hc197ac7c); `checkhw(w16m,4,32'hc316d727); `checkhw(w16m,3,32'h903034e4); `checkhw(w16m,2,32'h92a047d1); `checkhw(w16m,1,32'h6a5357af); `checkhw(w16m,0,32'ha82ce9c8); // verilator lint_on SELRANGE end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin w4 = w4 >>> 1; w8m = w8m >>> 1; w8 = w8 >>> 1; w8p = w8p >>> 1; w9 = w9 >>> 1; w16m = w16m >>> 1; w16 = w16 >>> 1; w16p = w16p >>> 1; w17 = w17 >>> 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.916/test_regress/t/t_clocker.pl0000775000177100017500000000077613205574202021013 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_sv_conditional.pl0000775000177100017500000000072212671044616022402 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_public.v0000664000177100017500000000137713205574202021654 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. //bug505 module t (/*AUTOARG*/ // Inputs clk ); input clk; a #(1) a1 (); b #(2) b2 (); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule module a; parameter ONE /*verilator public*/ = 22; initial if (ONE != 1) $stop; `ifdef VERILATOR initial if ($c32("ONE") != 1) $stop; `endif endmodule module b #( parameter TWO /*verilator public*/ = 22 ); initial if (TWO != 2) $stop; `ifdef VERILATOR initial if ($c32("TWO") != 2) $stop; `endif endmodule //bug804 package p; localparam INPACK /*verilator public*/ = 6; endpackage verilator-3.916/test_regress/t/t_preproc_def09.out0000664000177100017500000000255212473477707022237 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.916/test_regress/t/t_package_dimport.pl0000775000177100017500000000066712671044616022530 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_var_static.pl0000775000177100017500000000103113205574202021511 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} and $Self->unsupported("Verilator unsupported, bug546"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_tree_inl1_pub1.pl0000775000177100017500000000112513205574202023224 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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|.*t\.ps): Clocked ', ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_skipidentical.pl0000775000177100017500000000170712473477707023222 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_flag_fi.v0000664000177100017500000000063513205574202020601 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2017 by Wilson Snyder. This program is free software; you can // redistribute it and/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 (); initial begin $c("myfunction();"); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_alw_combdly.v0000664000177100017500000000244112671044616021512 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [31:0] a, b, c, d, e, f, g, h; always @ (*) begin // Test Verilog 2001 (*) // verilator lint_off COMBDLY c <= a | b; // verilator lint_on COMBDLY end always @ (posedge (clk)) begin // always bug 2008/4/18 d <= a | b; end always @ ((d)) begin // always bug 2008/4/18 e = d; end parameter CONSTANT = 1; always @ (e, 1'b0, CONSTANT) begin // not technically legal, see bug412 f = e; end always @ (1'b0, CONSTANT, f) begin // not technically legal, see bug412 g = f; end always @ ({CONSTANT, g}) begin // bug745 h = g; end //always @ ((posedge b) or (a or b)) begin // note both illegal always @ (posedge clk) begin if (cyc!=0) begin cyc<=cyc+1; if (cyc==1) begin a <= 32'hfeed0000; b <= 32'h0000face; end if (cyc==2) begin if (c != 32'hfeedface) $stop; end if (cyc==3) begin if (h != 32'hfeedface) $stop; end if (cyc==7) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_func_gen.pl0000775000177100017500000000071712671044616021157 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_x_bad.v0000664000177100017500000000064712473477707021307 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.916/test_regress/t/t_lint_incabspath_bad.pl0000775000177100017500000000157112473477707023355 0ustar 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.916/test_regress/t/t_math_svl2.v0000664000177100017500000000155112473477707021131 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.916/test_regress/t/t_var_in_assign.v0000664000177100017500000000252613205574202022035 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.916/test_regress/t/t_lint_once_bad.pl0000775000177100017500000000153613151152521022140 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_mod_interface_array2.v0000664000177100017500000000253013205574202023265 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Johan Bjork. parameter N = 4; // verilator lint_off LITENDIAN interface a_if #(parameter PARAM = 0) (); logic long_name; modport source (output long_name); modport sink (input long_name); endinterface module intf_source ( input logic [0:N-1] intf_input, a_if.source i_intf_source[0:N-1] ); generate for (genvar i=0; i < N;i++) begin assign i_intf_source[i].long_name = intf_input[i]; end endgenerate endmodule module intf_sink ( output [0:N-1] a_out, a_if.sink i_intf_sink[0:N-1] ); generate for (genvar i=0; i < N;i++) begin assign a_out[i] = i_intf_sink[i].long_name; end endgenerate endmodule module t ( clk ); input clk; logic [0:N-1] a_in; logic [0:N-1] a_out; logic [0:N-1] ack_out; a_if #(.PARAM(1)) tl_intf [0:N-1] (); intf_source source(a_in, tl_intf); intf_sink sink(a_out, tl_intf); initial a_in = '0; always @(posedge clk) begin a_in <= a_in + { {N-1 {1'b0}}, 1'b1 }; ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 }; if (ack_out != a_out) begin $stop; end if (& a_in) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_select_little.pl0000775000177100017500000000071712473477707022242 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_order_quad.v0000664000177100017500000000070413205574202021334 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. //bug 762 module t(a0, y); input [3:0] a0; output [44:0] y; assign y[40] = 0; assign y[30] = 0; // verilator lint_off UNOPTFLAT assign { y[44:41], y[39:31], y[29:0] } = { 6'b000000, a0, 7'b0000000, y[40], y[30], y[30], y[30], y[30], 21'b000000000000000000000 }; endmodule verilator-3.916/test_regress/t/t_pp_dupdef_bad.pl0000775000177100017500000000200313205574202022126 0ustar 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.916/test_regress/t/t_array_interface_noinl.pl0000775000177100017500000000102213205574202023707 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_array_interface.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_order_clkinst_bad.pl0000775000177100017500000000112313205574202023024 0ustar wsnyderwsnyder#!/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_order_clkinst.v"); compile ( v_flags2 => ["-Wwarn-IMPERFECTSCH"], fails=>1, expect=> q{.*%Warning-IMPERFECTSCH: .* .*%Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_cellarray.v0000664000177100017500000000423213205574202021165 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jie Xu. // // change these two parameters to see the speed differences `define DATA_WIDTH 8 `define REP_COUNT4 `DATA_WIDTH/4 `define REP_COUNT2 `DATA_WIDTH/2 module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [3:0] count4 = 0; reg [1:0] count2 = 0; reg [`DATA_WIDTH-1:0] a = {`REP_COUNT4{4'b0000}}; reg [`DATA_WIDTH-1:0] b = {`REP_COUNT4{4'b1111}}; reg [`DATA_WIDTH-1:0] c = {`REP_COUNT4{4'b1111}}; reg [`DATA_WIDTH-1:0] d = {`REP_COUNT4{4'b1111}}; reg [`DATA_WIDTH-1:0] res1; reg [`DATA_WIDTH-1:0] res2; reg [`DATA_WIDTH-1:0] res3; reg [`DATA_WIDTH-1:0] res4; drv1 t_drv1 [`DATA_WIDTH-1:0] (.colSelA(a), .datao(res1)); drv2 t_drv2 [`DATA_WIDTH-1:0] (.colSelA(a), .colSelB(b), .datao(res2)); drv3 t_drv3 [`DATA_WIDTH-1:0] (.colSelA(a), .colSelB(b), .colSelC(c), .datao(res3)); drv4 t_drv4 [`DATA_WIDTH-1:0] (.colSelA(a), .colSelB(b), .colSelC(c), .colSelD(d), .datao(res4)); always@(posedge clk) begin count2 <= count2 + 1; count4 <= count4 + 1; a <= {`REP_COUNT4{count4}}; b <= {`REP_COUNT4{count4}}; c <= {`REP_COUNT2{count2}}; d <= {`REP_COUNT2{count2}}; if (res1 != (a)) begin $stop; end if (res2 != (a&b)) begin $stop; end if (res3 != (a&b&c)) begin $stop; end if (res4 != (a&b&c&d)) begin $stop; end if (count4 > 10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module drv1 (input colSelA, output datao ); assign datao = colSelA; endmodule module drv2 (input colSelA, input colSelB, output datao ); assign datao = colSelB & colSelA; endmodule module drv3 (input colSelA, input colSelB, input colSelC, output datao ); assign datao = colSelB & colSelA & colSelC; endmodule module drv4 (input colSelA, input colSelB, input colSelC, input colSelD, output datao ); assign datao = colSelB & colSelA & colSelC & colSelD; endmodule verilator-3.916/test_regress/t/t_interface_gen5_noinl.pl0000775000177100017500000000102713205574202023434 0ustar wsnyderwsnyder#!/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_gen5.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_pull2_bad.pl0000775000177100017500000000116312671044616022111 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_math_vliw.pl0000775000177100017500000000071712473477707021400 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_hierarchy_unnamed.v0000664000177100017500000000062312671044616022703 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.916/test_regress/t/t_math_div0.pl0000775000177100017500000000074512671044616021247 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ['--x-assign 0'], ); execute ( ); ok(1); 1; verilator-3.916/test_regress/t/t_param_bit_sel.pl0000775000177100017500000000072212671044616022170 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_realcvt_bad.v0000664000177100017500000000035412473477707022526 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.916/test_regress/t/t_func_numones.v0000664000177100017500000000202012473477707021721 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.916/test_regress/t/t_mod_interface_array_noinl.pl0000775000177100017500000000102613205574202024552 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_mod_interface_array.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_dtree_inlc.pl0000775000177100017500000000107712671044616022540 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_inst_dtree_inlac.pl0000775000177100017500000000112012671044616022666 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_preproc_undefineall.pl0000775000177100017500000000111512473477707023417 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_interface1_modport.v0000664000177100017500000000176613205574202023005 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // Very simple test for interface pathclearing interface ifc; integer hidden_from_isub; integer value; modport out_modport (output value); endinterface module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc itop(); sub c1 (.isub(itop), .i_value(4)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==20) begin if (itop.value != 4) $stop; itop.hidden_from_isub = 20; if (itop.hidden_from_isub != 20) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub `ifdef NANSI // bug868 ( isub, i_value ); ifc.out_modport isub; // Note parenthesis are not legal here input integer i_value; `else ( ifc.out_modport isub, input integer i_value ); `endif always @* begin isub.value = i_value; end endmodule verilator-3.916/test_regress/t/t_enum_name3.pl0000775000177100017500000000072213205574202021407 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_public.cpp0000664000177100017500000000105513205574202022162 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. #include #include "Vt_param_public.h" #include "Vt_param_public_p.h" int main (int argc, char *argv[]) { Vt_param_public *topp = new Vt_param_public; Verilated::debug(0); // Make sure public tag worked if (static_cast(Vt_param_public_p::INPACK)) {} for (int i = 0; i < 10; i++) { topp->eval(); } } verilator-3.916/test_regress/t/t_mem_fifo.pl0000775000177100017500000000071712473477707021167 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_precedence.v0000664000177100017500000001060412671044616022324 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; wire [1:0] a = crc[1 +: 2]; wire [1:0] b = crc[3 +: 2]; wire [1:0] c = crc[5 +: 2]; wire [1:0] d = crc[7 +: 2]; wire [1:0] e = crc[9 +: 2]; wire [1:0] f = crc[11+: 2]; wire [1:0] g = crc[13+: 2]; // left () [] :: . // unary + - ! ~ & ~& | ~| ^ ~^ ^~ ++ -- (unary) // left ** // left * / % // left + - (binary) // left << >> <<< >>> // left < <= > >= inside dist // left == != === !== ==? !=? // left & (binary) // left ^ ~^ ^~ (binary) // left | (binary) // left && // left || // left ? : // right -> // none = += -= *= /= %= &= ^= |= <<= >>= <<<= >>>= := :/ <= // {} {{}} concatenation wire [1:0] bnz = (b==2'b0) ? 2'b11 : b; wire [1:0] cnz = (c==2'b0) ? 2'b11 : c; wire [1:0] dnz = (d==2'b0) ? 2'b11 : d; wire [1:0] enz = (e==2'b0) ? 2'b11 : e; // verilator lint_off WIDTH // Do a few in each group wire [1:0] o1 = ~ a; // Can't get more than one reduction to parse wire [1:0] o2 = ^ b; // Can't get more than one reduction to parse wire [1:0] o3 = a ** b ** c; // Some simulators botch this wire [1:0] o4 = a * b / cnz % dnz * enz; wire [1:0] o5 = a + b - c + d; wire [1:0] o6 = a << b >> c <<< d >>> e <<< f; wire [1:0] o7 = a < b <= c; wire [1:0] o8 = a == b != c === d == e; wire [1:0] o9 = a & b & c; wire [1:0] o10 = a ^ b ~^ c ^~ d ^ a; wire [1:0] o11 = a | b | c; wire [1:0] o12 = a && b && c; wire [1:0] o13 = a || b || c; wire [1:0] o14 = a ? b ? c : d : e; wire [1:0] o15 = a ? b : c ? d : e; // Now cross each pair of groups wire [1:0] x1 = ~ a ** ~ b ** ~c; // Some simulators botch this wire [1:0] x2 = a ** b * c ** d; // Some simulators botch this wire [1:0] x3 = a + b * c + d; wire [1:0] x4 = a + b << c + d; wire [1:0] x5 = a == b << c == d; wire [1:0] x6 = a & b << c & d; wire [1:0] x7 = a ^ b & c ^ d; wire [1:0] x8 = a | b ^ c | d; wire [1:0] x9 = a && b | c && d; wire [1:0] x10 = a || b && c || d; wire [1:0] x11 = a ? b || c : d ? e : f; // verilator lint_on WIDTH function [1:0] pow (input [1:0] x, input [1:0] y); casez ({x,y}) 4'b00_??: pow = 2'b00; 4'b01_00: pow = 2'b01; 4'b01_01: pow = 2'b01; 4'b01_10: pow = 2'b01; 4'b01_11: pow = 2'b01; 4'b10_00: pow = 2'b01; 4'b10_01: pow = 2'b10; 4'b10_10: pow = 2'b00; 4'b10_11: pow = 2'b00; 4'b11_00: pow = 2'b01; 4'b11_01: pow = 2'b11; 4'b11_10: pow = 2'b01; 4'b11_11: pow = 2'b11; endcase endfunction // Aggregate outputs into a single result vector wire [63:0] result = {12'h0, x11,x10,x9,x8,x7,x6,x5,x4,x3,x2,x1, o15,o14,o13,o12,o11,o10,o9,o8,o7,o6,o5,o4,o3,o2,o1}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x ",$time, cyc, crc, result); $write(" %b",o1); $write(" %b",o2); $write(" %b",o3); $write(" %b",o4); $write(" %b",o5); $write(" %b",o6); $write(" %b",o7); $write(" %b",o8); $write(" %b",o9); $write(" %b",o10); $write(" %b",o11); $write(" %b",o12); $write(" %b",o13); $write(" %b",o14); $write(" %b",o15); // Now cross each pair of groups $write(" %b",x1); $write(" %b",x2); $write(" %b",x3); $write(" %b",x4); $write(" %b",x5); $write(" %b",x6); $write(" %b",x7); $write(" %b",x8); $write(" %b",x9); $write(" %b",x10); $write(" %b",x11); $write("\n"); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h2756ea365ec7520e if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_math_pow6.v0000664000177100017500000000257213205574202021120 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs i65, j65, i33, j33, i30, j30, q65, r65, q33, r33, q30, r30, w65, x65, w33, x33, w30, x30, // Inputs a, a40, a70 ); input [3:0] a; input [39:0] a40; input [69:0] a70; // -- Verilator 621c515 creates code that uses the undeclared function VL_POW_WWI() // verilator lint_off WIDTH output [3:0] i65 = 65'd3 ** a; // WWI output [3:0] j65 = a ** 65'd3; // IIW output [3:0] i33 = 33'd3 ** a; // QQI output [3:0] j33 = a ** 33'd3; // IIQ output [3:0] i30 = 30'd3 ** a; // III output [3:0] j30 = a ** 30'd3; // III output [39:0] q65 = 65'd3 ** a40; // WWQ output [39:0] r65 = a40 ** 65'd3; // WWQ output [39:0] q33 = 33'd3 ** a40; // QQQ output [39:0] r33 = a40 ** 33'd3; // QQQ output [39:0] q30 = 30'd3 ** a40; // QQI output [39:0] r30 = a40 ** 30'd3; // QQI output [69:0] w65 = 65'd3 ** a70; // WWW output [69:0] x65 = a70 ** 65'd3; // WWW output [69:0] w33 = 33'd3 ** a70; // WWW output [69:0] x33 = a70 ** 33'd3; // WWW output [69:0] w30 = 30'd3 ** a70; // WWW output [69:0] x30 = a70 ** 30'd3; // WWW // verilator lint_on WIDTH initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_bitsel_struct3.pl0000775000177100017500000000072212671044616022340 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_array_packed_write_read.v0000664000177100017500000002350712671044616024056 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.916/test_regress/t/t_optm_if_array.pl0000775000177100017500000000103213205574202022206 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/rstn_r/); ok(1); 1; verilator-3.916/test_regress/t/t_array_backw_index_bad.pl0000775000177100017500000000163613205622627023654 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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=> q{%Error: t/t_array_backw_index_bad.v:\d+: Slice selection '\[1:3\]' has backward indexing versus data type's '\[3:0\]' %Error: t/t_array_backw_index_bad.v:\d+: Slice selection '\[3:1\]' has backward indexing versus data type's '\[0:3\]' %Error: t/t_array_backw_index_bad.v:\d+: Slice selection index '\[4:3\]' outside data type's '\[3:0\]' %Error: t/t_array_backw_index_bad.v:\d+: Slice selection index '\[1:-1\]' outside data type's '\[3:0\]' .*%Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_dpi_display.v0000664000177100017500000000214713205574202021513 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.916/test_regress/t/t_cover_toggle.v0000664000177100017500000000603313205574202021667 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.t.a*",4) // 2 edges * (t.a1 and t.a2) input [7:0] cyc_copy; // CHECK_COVER(-1,"top.t.a*","cyc_copy[0]",22) // CHECK_COVER(-2,"top.t.a*","cyc_copy[1]",10) // CHECK_COVER(-3,"top.t.a*","cyc_copy[2]",4) // CHECK_COVER(-4,"top.t.a*","cyc_copy[3]",2) // CHECK_COVER(-5,"top.t.a*","cyc_copy[4]",0) // CHECK_COVER(-6,"top.t.a*","cyc_copy[5]",0) // CHECK_COVER(-7,"top.t.a*","cyc_copy[6]",0) // CHECK_COVER(-8,"top.t.a*","cyc_copy[7]",0) reg toggle_internal; // CHECK_COVER(-1,"top.t.a*",4) // 2 edges * (t.a1 and t.a2) output reg toggle_up; // CHECK_COVER(-1,"top.t.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.t.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.t.o1","toggle",2) endmodule verilator-3.916/test_regress/t/t_clk_gen.pl0000775000177100017500000000071712473477707021010 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_pindup_bad.pl0000775000177100017500000000174712671044616022532 0ustar 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.916/test_regress/t/t_select_bad_range3.v0000664000177100017500000000071513205574202022535 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs outwires, // Inputs inwires ); input [7:0] inwires [12:10]; output wire [7:0] outwires [12:10]; assign outwires[10] = inwires[11]; assign outwires[11] = inwires[12]; assign outwires[12] = inwires[13]; // must be an error here endmodule verilator-3.916/test_regress/t/t_var_init.v0000664000177100017500000000124112473477707021041 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.916/test_regress/t/t_preproc_noline.out0000664000177100017500000000010712671044616022573 0ustar wsnyderwsnyderHello in t_preproc_psl.v yes Multi text multiline line Line: 20 verilator-3.916/test_regress/t/t_gate_array.v0000664000177100017500000000414612671044616021340 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [7:0] a = crc[7:0]; wire [7:0] b = crc[15:8]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [63:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[63:0]), // Inputs .clk (clk), .a (a[7:0]), .b (b[7:0])); // Aggregate outputs into a single result vector wire [63:0] result = {out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h0908a1f2194d24ee if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, a, b ); input clk; input [7:0] a; input [7:0] b; output reg [63:0] out; and u0[7:0] (out[7:0], a[7:0], b[7:0]); and u1[7:0] (out[15:8], a[0], b[7:0]); and u2[7:0] (out[23:16], a[0], b[0]); nand u3[7:0] (out[31:24], a[0], b[7:0]); or u4[7:0] (out[39:32], a[0], b[7:0]); nor u5[7:0] (out[47:40], a[0], b[7:0]); xor u6[7:0] (out[55:48], a[0], b[7:0]); xnor u7[7:0] (out[63:56], a[0], b[7:0]); endmodule verilator-3.916/test_regress/t/t_param_type.pl0000775000177100017500000000072213205574202021521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_default_bad.v0000664000177100017500000000055512473477707022462 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.916/test_regress/t/t_case_zx_bad.v0000664000177100017500000000056512473477707021500 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.916/test_regress/t/t_order_multidriven.cpp0000664000177100017500000000214312671044616023267 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.916/test_regress/t/t_flag_f__3.v0000664000177100017500000000002312473477707021022 0ustar wsnyderwsnyder`define GOT_DEF3 1 verilator-3.916/test_regress/t/t_math_clog2.v0000664000177100017500000000513712473477707021255 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.916/test_regress/t/t_clk_concat3.pl0000775000177100017500000000072713205574202021550 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_langext_4_bad.pl0000775000177100017500000000103612671044616022061 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_EXAMPLE.pl0000775000177100017500000000072212770051725020461 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_initial.v0000664000177100017500000000154712473477707020670 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.916/test_regress/t/t_verilated_all_newest.pl0000775000177100017500000000134113205574202023552 0ustar wsnyderwsnyder#!/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_verilated_all.v"); my $root = ".."; compile ( # Can't use --coverage and --savable together, so cheat and compile inline verilator_flags2 => ['--cc --coverage-toggle --coverage-line --coverage-user --trace --vpi $root/include/verilated_save.cpp'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_real_param.pl0000775000177100017500000000071712671044616022511 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vams_basic.pl0000775000177100017500000000071712473477707021515 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_system.v0000664000177100017500000000114012473477707021446 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.916/test_regress/t/t_interface_modport_export.pl0000775000177100017500000000103112671044616024466 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_dpi_display.pl0000775000177100017500000000153313205574202021662 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.t 16= 10 10=0000000a dpii_display_call: 'Mod=top.t 16= 10 10=0000000a' *-* All Finished *-* }), ); ok(1); 1; verilator-3.916/test_regress/t/t_func_bad2.v0000664000177100017500000000052712473477707021057 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.916/test_regress/t/t_initial.pl0000775000177100017500000000071712473477707021037 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_recurse2_bad.v0000664000177100017500000000047513205574202022611 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*/); looped looped (); endmodule verilator-3.916/test_regress/t/t_embed1.v0000664000177100017500000000621412473477707020370 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.916/test_regress/t/t_dpi_vams.cpp0000664000177100017500000000223012671044616021331 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. #include #include "Vt_dpi_vams.h" //====================================================================== #if defined(VERILATOR) # include "Vt_dpi_vams__Dpi.h" #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef NEED_EXTERNS extern "C" { extern void dpii_call (double in, double* outp); } #endif void dpii_call (double in, double* outp) { *outp = in + 0.1; } //====================================================================== unsigned int main_time = 0; double sc_time_stamp () { return main_time; } VM_PREFIX* topp = NULL; int main (int argc, char *argv[]) { topp = new VM_PREFIX; Verilated::debug(0); topp->in = 1.1; topp->eval(); if (topp->out != 1.2) { VL_PRINTF("*-* All Finished *-*\n"); topp->final(); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results\n"); } return 0; } verilator-3.916/test_regress/t/t_param_while.pl0000775000177100017500000000072212671044616021657 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_array_noinl.pl0000775000177100017500000000102213205574202023707 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_array.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_getenv.pl0000775000177100017500000000117113205574202021640 0ustar 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"); $ENV{FOOBARTEST} = "gotit"; compile ( v_flags2 => ["--getenv FOOBARTEST"], expect=> 'gotit ', make_top_shell => 0, make_main => 0, verilator_make_gcc => 0, ); ok(1); 1; verilator-3.916/test_regress/t/t_unoptflat_simple_3.v0000664000177100017500000000230512671044616023024 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.916/test_regress/t/t_param_module.v0000664000177100017500000000231212671044616021660 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.916/test_regress/t/t_wire_types.pl0000775000177100017500000000106312671044616021560 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_vpi_sc.cpp0000664000177100017500000000035613205574202021012 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- #include "Vt_vpi_sc.h" VM_PREFIX* tb = NULL; int sc_main(int argc, char *argv[]) { tb = new VM_PREFIX("tb"); VL_PRINTF("*-* All Finished *-*\n"); tb->final(); return 0; } verilator-3.916/test_regress/t/t_inst_array_inl1.pl0000775000177100017500000000103613151152521022451 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_dpi_context.pl0000775000177100017500000000077012473477707021725 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_inst_slice.pl0000775000177100017500000000072213205574202021514 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_v_noinl.pl0000775000177100017500000000103612671044616022045 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_tri_inout2.v0000664000177100017500000000267312671044616021323 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.916/test_regress/t/t_math_shiftrs.pl0000775000177100017500000000071712473477707022101 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_stream.pl0000775000177100017500000000072212671044616020662 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_uniqueif_fail3.pl0000775000177100017500000000144013205574202022261 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_uniqueif.v"); compile ( v_flags2 => ['+define+FAILING_ASSERTION3'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], fails => $Self->{nc}, ); execute ( fails => $Self->{vlt}, expect=> '.*%Error: t_uniqueif.v:\d+: Assertion failed in top.t: \'unique if\' statement violated %Error: t/t_uniqueif.v:\d+: Verilog \$stop .*', ); ok(1); 1; verilator-3.916/test_regress/t/t_package_verb.v0000664000177100017500000000070613205574202021622 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.916/test_regress/t/t_array_pattern_2d.pl0000775000177100017500000000072213205622627022625 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_slice_struct_array_modport.v0000664000177100017500000000060513205574202024654 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Varun Koyyalagunta. typedef struct packed { logic p; } s_data; module m1 (output s_data data[1:0]); assign data[0].p = 0; assign data[1].p = 0; endmodule module top (output s_data data[2:0]); m1 m1_inst (.data(data[1:0])); endmodule verilator-3.916/test_regress/t/t_delay.pl0000775000177100017500000000100612473477707020474 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_dpi_string.v0000664000177100017500000000116212671044616021357 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.916/test_regress/t/t_vlt_warn.vlt0000664000177100017500000000110312473477707021417 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.916/test_regress/t/t_pipe_exit_bad.pf0000664000177100017500000000060312473477707022163 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.916/test_regress/t/t_clk_concat2.pl0000775000177100017500000000072713205574202021547 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_slice_struct_array_modport.pl0000775000177100017500000000105213205574202025022 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_func.v0000664000177100017500000000523712473477707021030 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.916/test_regress/t/t_pp_display.v0000664000177100017500000000430612473477707021377 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.916/test_regress/t/t_typedef_param.v0000664000177100017500000000417113205574202022031 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; 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]; localparam type three_t = reg [2:0]; three_t outna; three_t outa; TestNonAnsi #( .p_t (reg [2:0]) ) test (// Outputs .out (outna), /*AUTOINST*/ // Inputs .clk (clk), .in (in[2:0])); TestAnsi #( .p_t (reg [2:0])) testa (// Outputs .out (outa), /*AUTOINST*/ // Inputs .clk (clk), .in (in[2:0])); // 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 ); parameter type p_t = shortint; input clk; input p_t in; output p_t out; always @(posedge clk) begin out <= ~in; end endmodule module TestAnsi #( parameter type p_t = shortint ) ( input clk, input p_t in, output p_t out ); always @(posedge clk) begin out <= ~in; end endmodule // Local Variables: // verilog-typedef-regexp: "_t$" // End: verilator-3.916/test_regress/t/t_math_msvc_64.pl0000775000177100017500000000101712473477707021672 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_value.pl0000775000177100017500000000071712671044616021667 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mod_recurse.pl0000775000177100017500000000072213205574202021667 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_uniqueif_fail1.pl0000775000177100017500000000144013205574202022257 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_uniqueif.v"); compile ( v_flags2 => ['+define+FAILING_ASSERTION1'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], fails => $Self->{nc}, ); execute ( fails => $Self->{vlt}, expect=> '.*%Error: t_uniqueif.v:\d+: Assertion failed in top.t: \'unique if\' statement violated %Error: t/t_uniqueif.v:\d+: Verilog \$stop .*', ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_readmem_bad_notfound.v0000664000177100017500000000053212671044616024247 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.916/test_regress/t/t_interface_size_bad.v0000664000177100017500000000067613205574202023017 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Demonstrate deferred linking error messages // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Johan Bjork. interface foo_intf; logic a; endinterface module t (/*AUTOARG*/); localparam N = 4; foo_intf foo4 [N-1:0] (); foo_intf foo6 [5:0] (); baz baz4_inst (.foo(foo4)); baz baz6_inst (.foo(foo6)); endmodule module baz(foo_intf foo[4:0] ); endmodule verilator-3.916/test_regress/t/t_tri_gate.cpp0000664000177100017500000000232413205574202021322 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 VM_PREFIX_INCLUDE 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.916/test_regress/t/t_case_reducer.pl0000775000177100017500000000072212671044616022013 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_package_export.v0000664000177100017500000000245713205574202022212 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 pkg1; parameter PARAM2 = 16; parameter PARAM3 = 16; endpackage : pkg1 package pkg10; import pkg1::*; import pkg1::*; // Ignore if already `ifdef T_PACKAGE_EXPORT export *::*; // Not supported on all simulators `endif parameter PARAM1 = 8; endpackage package pkg11; import pkg10::*; endpackage package pkg20; import pkg1::*; `ifdef T_PACKAGE_EXPORT export pkg1::*; `endif parameter PARAM1 = 8; endpackage package pkg21; import pkg20::*; endpackage package pkg30; import pkg1::*; `ifdef T_PACKAGE_EXPORT export pkg1::PARAM2; export pkg1::PARAM3; `endif parameter PARAM1 = 8; endpackage package pkg31; import pkg30::*; endpackage module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [pkg11::PARAM1 : 0] bus11; reg [pkg11::PARAM2 : 0] bus12; reg [pkg11::PARAM3 : 0] bus13; reg [pkg21::PARAM1 : 0] bus21; reg [pkg21::PARAM2 : 0] bus22; reg [pkg21::PARAM3 : 0] bus23; reg [pkg31::PARAM1 : 0] bus31; reg [pkg31::PARAM2 : 0] bus32; reg [pkg31::PARAM3 : 0] bus33; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_math_div0.v0000664000177100017500000000031112671044616021063 0ustar wsnyderwsnydermodule t(y); output [3:0] y; // bug775 // verilator lint_off WIDTH assign y = ((0/0) ? 1 : 2) % 0; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_trace_ena.v0000664000177100017500000000144113205574202021127 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // verilator tracing_off integer b_trace_off; // verilator tracing_on integer c_trace_on; real r; // verilator tracing_off sub sub (); // verilator tracing_on always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; b_trace_off <= cyc; c_trace_on <= b_trace_off; r <= r + 0.1; if (cyc==4) begin if (c_trace_on != 2) $stop; end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module sub; integer inside_sub = 0; endmodule verilator-3.916/test_regress/t/t_math_imm.pl0000775000177100017500000000104612473477707021175 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_interface_mismodport_bad.v0000664000177100017500000000114712671044616024243 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.916/test_regress/t/t_tri_unconn.pl0000775000177100017500000000072212671044616021545 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gate_unsup.v0000664000177100017500000000126613205574202021365 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.916/test_regress/t/t_const_overflow_bad.v0000664000177100017500000000107613205574202023071 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.916/test_regress/t/t_gate_elim.pl0000775000177100017500000000071712473477707021334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 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.916/test_regress/t/t_func_real_param.v0000664000177100017500000000104312671044616022331 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.916/test_regress/t/t_interface_gen9.v0000664000177100017500000000121313205574202022065 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // bug998 module t1(input logic foo); initial begin $display("%m %d", foo); end endmodule module t(); logic [1:0] my_foo; generate genvar the_genvar; for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf //logic tmp_foo; //assign tmp_foo = my_foo[the_genvar]; t1 t (.foo(my_foo[the_genvar])); //t1 t (.foo(tmp_foo)); end endgenerate initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_stream.v0000664000177100017500000002616213205574202020510 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Glen Gibb. //module t; module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // The 'initial' code block below tests compilation-time // evaluation/optimization of the stream operator. All occurences of the stream // operator within this block are replaced prior to generation of C code. logic [3:0] dout; logic [31:0] dout32; logic [10:0] dout11; initial begin // Stream operator: << // Location: rhs of assignment // // Test slice sizes from 1 - 5 dout = { << {4'b0001}}; if (dout != 4'b1000) $stop; dout = { << 2 {4'b0001}}; if (dout != 4'b0100) $stop; dout = { << 3 {4'b0001}}; if (dout != 4'b0010) $stop; dout = { << 4 {4'b0001}}; if (dout != 4'b0001) $stop; dout = { << 5 {4'b0001}}; if (dout != 4'b0001) $stop; // Stream operator: >> // Location: rhs of assignment // // Right-streaming operator on RHS does not reorder bits dout = { >> {4'b0001}}; if (dout != 4'b0001) $stop; dout = { >> 2 {4'b0001}}; if (dout != 4'b0001) $stop; dout = { >> 3 {4'b0001}}; if (dout != 4'b0001) $stop; dout = { >> 4 {4'b0001}}; if (dout != 4'b0001) $stop; dout = { >> 5 {4'b0001}}; if (dout != 4'b0001) $stop; // Stream operator: << // Location: lhs of assignment { << {dout}} = 4'b0001; if (dout != 4'b1000) $stop; { << 2 {dout}} = 4'b0001; if (dout != 4'b0100) $stop; { << 3 {dout}} = 4'b0001; if (dout != 4'b0010) $stop; { << 4 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { << 5 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; // Stream operator: >> // Location: lhs of assignment { >> {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { >> 2 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { >> 3 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { >> 4 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { >> 5 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; // Stream operator: << // Location: lhs of assignment // RHS is *wider* than LHS /* verilator lint_off WIDTH */ { << {dout}} = 5'b00001; if (dout != 4'b1000) $stop; { << 2 {dout}} = 5'b00001; if (dout != 4'b0100) $stop; { << 3 {dout}} = 5'b00001; if (dout != 4'b0010) $stop; { << 4 {dout}} = 5'b00001; if (dout != 4'b0001) $stop; { << 5 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; /* verilator lint_on WIDTH */ // Stream operator: >> // Location: lhs of assignment // RHS is *wider* than LHS /* verilator lint_off WIDTH */ { >> {dout}} = 5'b01101; if (dout != 4'b0110) $stop; { >> 2 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; { >> 3 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; { >> 4 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; { >> 5 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; /* verilator lint_on WIDTH */ // Stream operator: << // Location: both sides of assignment { << {dout}} = { << {4'b0001}}; if (dout != 4'b0001) $stop; { << 2 {dout}} = { << 2 {4'b0001}}; if (dout != 4'b0001) $stop; { << 3 {dout}} = { << 3 {4'b0001}}; if (dout != 4'b0100) $stop; { << 4 {dout}} = { << 4 {4'b0001}}; if (dout != 4'b0001) $stop; { << 5 {dout}} = { << 5 {4'b0001}}; if (dout != 4'b0001) $stop; // Stream operator: << // Location: as an operand within a statement // // Test slice sizes from 1 - 5 if (4'({ << {4'b0001}}) != 4'b1000) $stop; if (4'({ << 2 {4'b0001}}) != 4'b0100) $stop; if (4'({ << 3 {4'b0001}}) != 4'b0010) $stop; if (4'({ << 4 {4'b0001}}) != 4'b0001) $stop; if (4'({ << 5 {4'b0001}}) != 4'b0001) $stop; // case dout32 = { << 3 { 32'b11010111000010100100010010010111 }}; if (dout32 != 32'he92910eb) $stop; dout11 = { << 4 { 11'b10010010111 }}; if (dout11 != 11'h3cc) $stop; end // The two always blocks below test run-time evaluation of the stream // operator in generated C code. // // Various stream operators are optimized away. Here's a brief summary: // // Stream op on RHS of assign // -------------------------- // X = { << a { Y } } --- C function evaluates stream operator // -- if log2(a) == int --> "fast" eval func // -- if log2(a) != int --> "slow" eval func // X = { >> a { Y } } --- stream operator is optimized away // // Stream op on LHS of assign // -------------------------- // Note: if Y.width() > X.width, then the MSBs of Y are used, not the LSBs! // { << a { X } } = Y --- stream operator is moved to RHS, eval as above // { >> a { X } } = Y --- stream operator is optimized away logic [31:0] din_i; logic [63:0] din_q; logic [95:0] din_w; // Stream op on RHS, left-stream operator logic [31:0] dout_rhs_ls_i; logic [63:0] dout_rhs_ls_q; logic [95:0] dout_rhs_ls_w; // Stream op on RHS, right-stream operator logic [31:0] dout_rhs_rs_i; logic [63:0] dout_rhs_rs_q; logic [95:0] dout_rhs_rs_w; // Stream op on both sides, left-stream operator logic [31:0] dout_bhs_ls_i; logic [63:0] dout_bhs_ls_q; logic [95:0] dout_bhs_ls_w; // Stream op on both sides, right-stream operator logic [31:0] dout_bhs_rs_i; logic [63:0] dout_bhs_rs_q; logic [95:0] dout_bhs_rs_w; // Stream operator on LHS (with concatenation on LHS) logic [3:0] din_lhs; logic [1:0] dout_lhs_ls_a, dout_lhs_ls_b; logic [1:0] dout_lhs_rs_a, dout_lhs_rs_b; // Addition operator on LHS, right-shift tests: // Testing various shift sizes to exercise fast + slow funcs logic [22:0] dout_rhs_ls_i_23_3; logic [22:0] dout_rhs_ls_i_23_4; logic [36:0] dout_rhs_ls_q_37_3; logic [36:0] dout_rhs_ls_q_37_4; always @* begin // Stream operator: << // Location: rhs of assignment // // Test each data type (I, Q, W) dout_rhs_ls_i = { << {din_i}}; dout_rhs_ls_q = { << {din_q}}; dout_rhs_ls_w = { << {din_w}}; // Stream operator: >> // Location: rhs of assignment dout_rhs_rs_i = { >> {din_i}}; dout_rhs_rs_q = { >> {din_q}}; dout_rhs_rs_w = { >> {din_w}}; // Stream operator: << // Location: lhs of assignment { << 2 {dout_lhs_ls_a, dout_lhs_ls_b}} = din_lhs; // Stream operator: >> // Location: lhs of assignment { >> 2 {dout_lhs_rs_a, dout_lhs_rs_b}} = din_lhs; // Stream operator: << // Location: both sides of assignment { << 5 {dout_bhs_ls_i}} = { << 5 {din_i}}; { << 5 {dout_bhs_ls_q}} = { << 5 {din_q}}; { << 5 {dout_bhs_ls_w}} = { << 5 {din_w}}; // Stream operator: >> // Location: both sides of assignment { >> 5 {dout_bhs_rs_i}} = { >> 5 {din_i}}; { >> 5 {dout_bhs_rs_q}} = { >> 5 {din_q}}; { >> 5 {dout_bhs_rs_w}} = { >> 5 {din_w}}; // Stream operator: << // Location: both sides of assignment { << 5 {dout_bhs_ls_i}} = { << 5 {din_i}}; { << 5 {dout_bhs_ls_q}} = { << 5 {din_q}}; { << 5 {dout_bhs_ls_w}} = { << 5 {din_w}}; // Stream operator: << // Location: rhs of assignment // // Verify both fast and slow paths (fast: sliceSize = power of 2) dout_rhs_ls_i_23_3 = { << 3 {din_i[22:0]}}; // SLOW dout_rhs_ls_i_23_4 = { << 4 {din_i[22:0]}}; // FAST dout_rhs_ls_q_37_3 = { << 3 {din_q[36:0]}}; // SLOW dout_rhs_ls_q_37_4 = { << 4 {din_q[36:0]}}; // FAST end always @(posedge clk) begin if (cyc != 0) begin cyc <= cyc + 1; if (cyc == 1) begin din_i <= 32'h_00_00_00_01; din_q <= 64'h_00_00_00_00_00_00_00_01; din_w <= 96'h_00_00_00_00_00_00_00_00_00_00_00_01; din_lhs <= 4'b_00_01; end if (cyc == 2) begin din_i <= 32'h_04_03_02_01; din_q <= 64'h_08_07_06_05_04_03_02_01; din_w <= 96'h_0c_0b_0a_09_08_07_06_05_04_03_02_01; din_lhs <= 4'b_01_11; if (dout_rhs_ls_i != 32'h_80_00_00_00) $stop; if (dout_rhs_ls_q != 64'h_80_00_00_00_00_00_00_00) $stop; if (dout_rhs_ls_w != 96'h_80_00_00_00_00_00_00_00_00_00_00_00) $stop; if (dout_rhs_rs_i != 32'h_00_00_00_01) $stop; if (dout_rhs_rs_q != 64'h_00_00_00_00_00_00_00_01) $stop; if (dout_rhs_rs_w != 96'h_00_00_00_00_00_00_00_00_00_00_00_01) $stop; if (dout_lhs_ls_a != 2'b_01) $stop; if (dout_lhs_ls_b != 2'b_00) $stop; if (dout_lhs_rs_a != 2'b_00) $stop; if (dout_lhs_rs_b != 2'b_01) $stop; if (dout_bhs_rs_i != 32'h_00_00_00_01) $stop; if (dout_bhs_rs_q != 64'h_00_00_00_00_00_00_00_01) $stop; if (dout_bhs_rs_w != 96'h_00_00_00_00_00_00_00_00_00_00_00_01) $stop; if (dout_bhs_ls_i != 32'h_00_00_00_10) $stop; if (dout_bhs_ls_q != 64'h_00_00_00_00_00_00_01_00) $stop; if (dout_bhs_ls_w != 96'h_00_00_00_00_00_00_00_00_00_00_00_04) $stop; if (dout_rhs_ls_i_23_3 != 23'h_10_00_00) $stop; if (dout_rhs_ls_i_23_4 != 23'h_08_00_00) $stop; if (dout_rhs_ls_q_37_3 != 37'h_04_00_00_00_00) $stop; if (dout_rhs_ls_q_37_4 != 37'h_02_00_00_00_00) $stop; end if (cyc == 3) begin // The values below test the strange shift-merge done at the end of // the fast stream operators. // All-1s in the bits being streamed should end up as all-1s. din_i <= 32'h_00_7f_ff_ff; din_q <= 64'h_00_00_00_1f_ff_ff_ff_ff; if (dout_rhs_ls_i != 32'h_80_40_c0_20) $stop; if (dout_rhs_ls_q != 64'h_80_40_c0_20_a0_60_e0_10) $stop; if (dout_rhs_ls_w != 96'h_80_40_c0_20_a0_60_e0_10_90_50_d0_30) $stop; if (dout_rhs_rs_i != 32'h_04_03_02_01) $stop; if (dout_rhs_rs_q != 64'h_08_07_06_05_04_03_02_01) $stop; if (dout_rhs_rs_w != 96'h_0c_0b_0a_09_08_07_06_05_04_03_02_01) $stop; if (dout_bhs_ls_i != 32'h_40_30_00_18) $stop; if (dout_bhs_ls_q != 64'h_06_00_c1_81_41_00_c1_80) $stop; if (dout_bhs_ls_w != 96'h_30_2c_28_20_01_1c_1a_04_14_0c_00_06) $stop; if (dout_bhs_rs_i != 32'h_04_03_02_01) $stop; if (dout_bhs_rs_q != 64'h_08_07_06_05_04_03_02_01) $stop; if (dout_bhs_rs_w != 96'h_0c_0b_0a_09_08_07_06_05_04_03_02_01) $stop; if (dout_lhs_ls_a != 2'b_11) $stop; if (dout_lhs_ls_b != 2'b_01) $stop; if (dout_lhs_rs_a != 2'b_01) $stop; if (dout_lhs_rs_b != 2'b_11) $stop; if (dout_rhs_ls_i_23_3 != 23'h_10_08_c0) $stop; if (dout_rhs_ls_i_23_4 != 23'h_08_10_18) $stop; if (dout_rhs_ls_q_37_3 != 37'h_04_02_30_10_44) $stop; if (dout_rhs_ls_q_37_4 != 37'h_02_04_06_08_0a) $stop; end if (cyc == 4) begin if (dout_rhs_ls_i_23_3 != 23'h_7f_ff_ff) $stop; if (dout_rhs_ls_i_23_4 != 23'h_7f_ff_ff) $stop; if (dout_rhs_ls_q_37_3 != 37'h_1f_ff_ff_ff_ff) $stop; if (dout_rhs_ls_q_37_4 != 37'h_1f_ff_ff_ff_ff) $stop; end if (cyc == 9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_func_lib_sub.v0000664000177100017500000000415612671044616021655 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.916/test_regress/t/t_var_pins_sc64.pl0000775000177100017500000000404413205574202022041 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.916/test_regress/t/t_alw_splitord.v0000664000177100017500000000757412473477707021750 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.916/test_regress/t/t_bitsel_slice.pl0000775000177100017500000000072212671044616022030 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_repeat_bad.v0000664000177100017500000000054612671044616022336 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.916/test_regress/t/t_math_synmul_mul.v0000664000177100017500000121176612473477707022463 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.916/test_regress/t/t_param_shift.v0000664000177100017500000000106413205574202021504 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Mandy Xu. module t #(parameter[95:0] P = 1) (input clk); localparam [32:0] M = 4; function [M:0] gen_matrix; gen_matrix[0] = 1>> M; endfunction reg [95: 0] lfsr = 0; always @(posedge clk) begin lfsr <= (1 >> P); end wire [95: 0] lfsr_w = 1 >> P; localparam [95: 0] lfsr_p = 1 >> P; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_lint_latch_bad.v0000664000177100017500000000075513205574202022144 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs bl, cl, bc, cc, // Inputs a ); input logic a; output logic bl; output logic cl; always_latch begin bl <= a; // No warning cl = a; end output logic bc; output logic cc; always_comb begin bc <= a; // Warning cc = a; end endmodule verilator-3.916/test_regress/t/t_tri_dangle.pl0000775000177100017500000000071712473477707021516 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_wide_io.v0000664000177100017500000000052113205574202022003 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder. // issue 1991 module t #( parameter[96:0] P = 97'h12344321_12344321_12344327 ) ( input [P&7 - 1:0] in, output [P&7 - 1:0] out ); wire out = in; endmodule verilator-3.916/test_regress/t/t_clk_vecgen1.pl0000775000177100017500000000103312473477707021557 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_func_under.pl0000775000177100017500000000072212671044616021517 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_wild.v0000664000177100017500000000576212473477707021174 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.916/test_regress/t/t_mem_cond.v0000664000177100017500000000075013205574202020771 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*/ // Outputs b, // Inputs clk, en, a ); // bug1017 input clk; input en; input a[1]; output logic b[1]; always_ff @ (posedge clk) begin b <= en ? a : b; end always @ (posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_struct_unaligned.v0000664000177100017500000000132113205574202022555 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: // Test an error where a shift amount was out of bounds and the compiler treats the // value as undefined (Issue #803) // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jeff Bush. module t (/*AUTOARG*/ // Inputs clk ); input clk; struct packed { logic flag; logic [130:0] data; } foo[1]; integer cyc=0; // Test loop always @ (posedge clk) begin cyc <= cyc + 1; foo[0].data <= 0; foo[0].flag <= !foo[0].flag; if (cyc==10) begin if (foo[0].data != 0) begin $display("bad data value %x", foo[0].data); $stop; end $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_interface1_modport.pl0000775000177100017500000000072713151152521023146 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_final.v0000664000177100017500000000111112671044616020300 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.916/test_regress/t/t_struct_pat_width.pl0000775000177100017500000000072313205574202022750 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_static_elab.v0000664000177100017500000000210713205574202021460 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Simple static elaboration case // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. module t (/*AUTOARG*/); typedef struct packed { logic [ 31 : 0 ] _five; } five_t; typedef enum { LOW_FIVE = 32'hdeadbeef, HIGH_FIVE } five_style_t; function five_t gimme_five (); automatic five_t result; result._five = 5; return result; endfunction function five_style_t gimme_high_five (); automatic five_style_t result; result = HIGH_FIVE; return result; endfunction localparam five_t FIVE = gimme_five(); localparam five_style_t THE_HIGH_FIVE = gimme_high_five(); initial begin if (FIVE._five != 5) begin $display("%%Error: Got 0b%b instead of 5", FIVE._five); $stop; end if (THE_HIGH_FIVE != HIGH_FIVE) begin $display("%%Error: Got 0b%b instead of HIGH_FIVE", THE_HIGH_FIVE); $stop; end $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_sys_file_scan_input.dat0000664000177100017500000000000612473477707023567 0ustar wsnyderwsnyder1 2 3 verilator-3.916/test_regress/t/t_math_reverse.pl0000775000177100017500000000071712473477707022072 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_unoptflat_simple_3_bad.pl0000775000177100017500000000076212671044616024010 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_interface_parameter_access.pl0000775000177100017500000000072213205574202024701 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_named_2.pl0000775000177100017500000000071712473477707022073 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_preproc_noline.v0000664000177100017500000000050112671044616022227 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define CHECK text \ multiline Hello in t_preproc_psl.v `ifdef NEVER not `else yes `endif Multi `CHECK line // Did we end up right? Line: `__LINE__ verilator-3.916/test_regress/t/t_var_dotted.v0000664000177100017500000001224512671044616021354 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.916/test_regress/t/t_param_ceil.pl0000775000177100017500000000071712473477707021502 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_default_warn.pl0000775000177100017500000000077213205574202023053 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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-WIDTH"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_enum_int.pl0000775000177100017500000000071712473477707021224 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_plusargs.pl0000775000177100017500000000040312473477707022134 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.916/test_regress/t/t_unopt_bound.pl0000775000177100017500000000072212671044616021723 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_cdc_async_bad.v0000664000177100017500000000404412473477707021766 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.916/test_regress/t/t_help.pl0000775000177100017500000000154213205574202020311 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); foreach my $prog ( "../bin/verilator", "../bin/verilator_coverage", "../bin/verilator_difftree", "../bin/verilator_profcfunc", ) { $Self->run(fails=>1, cmd=>["perl",$prog, "--help"], logfile=>"$Self->{obj_dir}/t_help.log", tee=>0, ); file_grep ("$Self->{obj_dir}/t_help.log", qr/DISTRIBUTION/i); } ok(1); 1; verilator-3.916/test_regress/t/t_order_clkinst.v0000664000177100017500000000444512473477707022101 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.916/test_regress/t/t_func_bad2.pl0000775000177100017500000000105512473477707021225 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_embed1_wrap.v0000664000177100017500000000455013205574202021400 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.916/test_regress/t/t_interface_down_inld.pl0000775000177100017500000000110312671044616023356 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_trace_public_sig.pl0000775000177100017500000000156513151152521022660 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_sys_time.v0000664000177100017500000000114112473477707021061 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.916/test_regress/t/t_select_plusloop.v0000664000177100017500000000340312473477707022444 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.916/test_regress/t/t_enum_public.pl0000775000177100017500000000115413205574202021662 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. if ($Self->{vlt}) { compile ( verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], make_top_shell => 0, make_main => 0, ); } else { compile ( ); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_signed.v0000664000177100017500000001316112671044616021501 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.916/test_regress/t/t_langext_3.pl0000775000177100017500000000075512671044616021261 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_case_x.v0000664000177100017500000000237312473477707020477 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.916/test_regress/t/t_flag_topmodule_inline.v0000664000177100017500000000077712473477707023602 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.916/test_regress/t/t_flag_werror.v0000664000177100017500000000036712473477707021547 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.916/test_regress/t/t_gate_elim.v0000664000177100017500000000423312473477707021160 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.916/test_regress/t/t_display_time.v0000664000177100017500000000161112473477707021712 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.916/test_regress/t/t_concat_large.pl0000775000177100017500000000072213205574202022001 0ustar 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.916/test_regress/t/t_func_dotted_inl2.pl0000775000177100017500000000104313151152521022573 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_bitsel_enum.pl0000775000177100017500000000072213205574202021666 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_implicit_port.pl0000775000177100017500000000077612671044616023304 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_order_multialways.pl0000775000177100017500000000071712473477707023154 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_debug_sigsegv_bt_bad.pl0000775000177100017500000000130712671044616023477 0ustar 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.916/test_regress/t/t_interface1.v0000664000177100017500000000143312671044616021237 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.916/test_regress/t/t_gen_cond_bitrange.pl0000775000177100017500000000071712671044616023022 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_real_abs.v0000664000177100017500000000221212671044616021775 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.916/test_regress/t/t_vlcov_merge.out0000664000177100017500000000046013205574202022060 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint0ffile1.sphl159' 0 C 'CoverPoint1ffile1.sphl159' 1 C 'CoverPoint2ffile1.sphl159' 20 C 'CoverPoint3ffile1.sphl159' 0 C 'CoverPoint4ffile1.sphl159' 1 C 'CoverPoint5ffile1.sphl159' 9 C 'CoverPoint6ffile1.sphl159' 22 verilator-3.916/test_regress/t/t_mem_packed_bad.pl0000775000177100017500000000122413205574202022251 0ustar 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=> q{%Error: t/t_mem_packed_bad.v:\d+: CONST '28'h0' unexpected in assignment to unpacked array %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_multi_io.pl0000775000177100017500000000110613205574202022034 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( # Disable inlining, this test is trivial without it verilator_flags2 => ["-Oi --trace"], verilator_flags3 => [], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gate_basic.v0000664000177100017500000000370512473477707021316 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.916/test_regress/t/t_math_pow.pl0000775000177100017500000000071712473477707021224 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_xinitial_unique.v0000664000177100017500000000051213205574202023404 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs value ); output reg [63:0] value; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_gen_defparam.v0000664000177100017500000000146112671044616021627 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.916/test_regress/t/t_alw_split_rst.pl0000775000177100017500000000113313205574202022243 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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, 0); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_dpi_import.v0000664000177100017500000002160713205574202021362 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; typedef struct packed { bit [47:0] lo; bit [47:0] hi; } str_t; typedef struct packed { int a; int b; } substr_t; // 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_struct (input str_t i, output str_t o); import "DPI-C" pure function void dpii_v_substruct(input substr_t i, output int 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; str_t i_t, o_t; substr_t i_ss; int o_ss; 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_t = {1'b1,wide[95-1:0]}; i_d = 32.1; i_ss.a = 32'h054321ab; i_ss.b = 32'h05a43b21; `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_struct (i_t,o_t); if (o_t !== ~i_t) $stop; dpii_v_substruct(i_ss,o_ss); if (o_ss !== i_ss.a - i_ss.b) $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.916/test_regress/t/t_package_twodeep.v0000664000177100017500000000103712671044616022340 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett // see bug 591 package pkg2; parameter PARAM2 = 16; endpackage // pkg2 package pkg1; import pkg2::*; parameter PARAM1 = 8; endpackage // pkg1 module t import pkg1::*; // Test SV 2012 import format (/*AUTOARG*/ // Inputs clk ); input clk; reg [PARAM1:0] bus1; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_for_funcbound.v0000664000177100017500000000262712473477707022070 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.916/test_regress/t/t_tri_array.v0000664000177100017500000000311312671044616021207 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; parameter NPAD = 4; tri pad [NPAD-1:0]; // Array wire [NPAD-1:0] data0 = crc[0 +: 4]; wire [NPAD-1:0] data1 = crc[8 +: 4]; wire [NPAD-1:0] en = crc[16 +: 4]; for (genvar g=0; g{cycles} = $Self->{benchmark}||0; $Self->{cycles} = 100 if $Self->{cycles}<100; $Self->{sim_time} = $Self->{cycles}*100; compile ( v_flags2 => ["+define+SIM_CYCLES=$Self->{cycles} --stats"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_dtree_inla.pl0000775000177100017500000000107712671044616022536 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_case_orig.pl0000775000177100017500000000071712473477707021341 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vlcov_data_b.dat0000664000177100017500000000026713205574202022141 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint2ffile1.sphl159' 10 C 'CoverPoint3ffile1.sphl159' 0 C 'CoverPoint4ffile1.sphl159' 1 C 'CoverPoint5ffile1.sphl159' 9 verilator-3.916/test_regress/t/t_preproc_def09.pl0000775000177100017500000000130213151152521022010 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_lint_blksync_bad.pl0000775000177100017500000000217312473477707022705 0ustar 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.916/test_regress/t/t_inst_wideconst.pl0000775000177100017500000000076212473477707022442 0ustar 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.916/test_regress/t/t_threads_counter_1.pl0000775000177100017500000000115513205574202022772 0ustar wsnyderwsnyder#!/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->skip("No thread support") if !$Self->cfg_with_threaded; top_filename("t/t_threads_counter.v"); compile ( verilator_flags2 => ['--cc --threads 1'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_msvc_64.v0000664000177100017500000000265513205574202021510 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.916/test_regress/t/t_select_bad_range2.pl0000775000177100017500000000117412671044616022714 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_if_blk.pl0000775000177100017500000000072212671044616021775 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_pipe_filter.out0000664000177100017500000000202012473477707022066 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.916/test_regress/t/t_interface_gen5.pl0000775000177100017500000000072713205574202022243 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_trace_cat_reopen_0000.out0000664000177100017500000000533013205574202023505 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 t $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.916/test_regress/t/t_select_index.v0000664000177100017500000000203412473477707021675 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.916/test_regress/t/t_mem_iforder.v0000664000177100017500000000411612473477707021522 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.916/test_regress/t/t_func_default_warn.v0000664000177100017500000000110713205574202022673 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test for warning (not error) on improperly width'ed // default function argument // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. function logic foo ( // Intentionally provide a non-width'ed default value // This should warn, not error out input logic x = 0 ); return x; endfunction module t (/*AUTOARG*/); logic foo_val; initial begin foo_val = foo(); if (foo_val != 1'b0) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_sys_readmem_bad_end.mem0000664000177100017500000000050312473477707023503 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.916/test_regress/t/t_assert_cover_off.pl0000775000177100017500000000101013151152521022674 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_func_lib.pl0000775000177100017500000000077312473477707021171 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_interface_gen12_noinl.pl0000775000177100017500000000102713205574202023512 0ustar wsnyderwsnyder#!/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_gen12.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vpi_get.v0000664000177100017500000000351512671044616020656 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.916/test_regress/t/t_preproc_undefineall.v0000664000177100017500000000073212473477707023252 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.916/test_regress/t/t_vpi_memory.pl0000775000177100017500000000151013205574202021542 0ustar 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->skip("Known compiler limitation") if $Self->cxx_version =~ /\(GCC\) 4.4/; 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 --vpi --no-l2name $Self->{t_dir}/t_vpi_memory.cpp"], ); execute ( iv_pli => 1, check_finished=>1 ); ok(1); 1; verilator-3.916/test_regress/t/t_math_signed_wire.pl0000775000177100017500000000072212671044616022677 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_cat_reopen_0100.out0000664000177100017500000000510213205574202023503 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 t $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.916/test_regress/t/t_mod_recurse1.v0000664000177100017500000000124013205574202021573 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*/); rec rec (); endmodule module rec; parameter DEPTH = 1; generate if (DEPTH==1) begin rec #(.DEPTH(DEPTH+1)) sub; end else if (DEPTH==2) begin rec #(.DEPTH(DEPTH+1)) subb; end else if (DEPTH==3) begin bottom #(.DEPTH(DEPTH+1)) bot; end endgenerate endmodule module bottom; parameter DEPTH = 1; initial begin if (DEPTH!=4) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_leak.pl0000775000177100017500000000115313123042406020266 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_gen_missing.v0000664000177100017500000000245613205574202021517 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.916/test_regress/t/t_array_query.pl0000775000177100017500000000072212671044616021732 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_enumeration.v0000664000177100017500000002773012671044616021554 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.916/test_regress/t/t_interface_param2.v0000664000177100017500000000174413205574202022416 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Adrian Wise //bug1104 module t (input clk); simple_bus sb_intf(clk); simple_bus #(.DWIDTH(16)) wide_intf(clk); mem mem(sb_intf.slave); cpu cpu(sb_intf.master); mem memW(wide_intf.slave); cpu cpuW(wide_intf.master); endmodule interface simple_bus #(AWIDTH = 8, DWIDTH = 8) (input logic clk); // Define the interface logic req, gnt; logic [AWIDTH-1:0] addr; logic [DWIDTH-1:0] data; modport slave( input req, addr, clk, output gnt, input data); modport master(input gnt, clk, output req, addr, output data); endinterface: simple_bus module mem(interface a); logic avail; always @(posedge a.clk) a.gnt <= a.req & avail; initial begin if ($bits(a.data != 16)) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module cpu(interface b); endmodule verilator-3.916/test_regress/t/t_dpi_dup_bad.pl0000775000177100017500000000143613205574202021615 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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: t.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.916/test_regress/t/t_clk_dpulse.pl0000775000177100017500000000071712473477707021533 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_dpi_export.v0000664000177100017500000000463113205574202021367 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_bit48; task dpix_t_bit48(input bit [47:0] i, output bit [47:0] o); o = ~i; endtask 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.916/test_regress/t/t_math_pow.v0000664000177100017500000000472412671044616021042 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. `ifdef VERILATOR `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) `else `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); end while(0) `endif module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [60:0] p; reg [60:0] a; reg [20:0] b; reg [60:0] shifted; always @* begin p = a[60:0] ** b[20:0]; shifted = 2 ** b[20:0]; end integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("%0x %x %x\n", cyc, p, shifted); `endif // Constant versions `checkh(61'h1 ** 21'h31, 61'h1); `checkh(61'h2 ** 21'h10, 61'h10000); `checkh(61'd10 ** 21'h3, 61'h3e8); `checkh(61'h3 ** 21'h7, 61'h88b); `ifndef VCS `checkh(61'h7ab3811219 ** 21'ha6e30, 61'h01ea58c703687e81); `endif if (cyc==1) begin a <= 61'h0; b <= 21'h0; end if (cyc==2) begin a <= 61'h0; b <= 21'h3; end if (cyc==3) begin a <= 61'h1; b <= 21'h31; end if (cyc==4) begin a <= 61'h2; b <= 21'h10; end if (cyc==5) begin a <= 61'd10; b <= 21'd3; end if (cyc==6) begin a <= 61'd3; b <= 21'd7; end if (cyc==7) begin a <= 61'h7ab3811219; b <= 21'ha6e30; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end case (cyc) 32'd00: ; 32'd01: ; 32'd02: ; // 0^x is indeterminate 32'd03: ; // 0^x is indeterminate 32'd04: `checkh(p, 61'h1); 32'd05: `checkh(p, 61'h10000); 32'd06: `checkh(p, 61'h3e8); 32'd07: `checkh(p, 61'h88b); 32'd08: `checkh(p, 61'h01ea58c703687e81); 32'd09: `checkh(p, 61'h01ea58c703687e81); default: $stop; endcase case (cyc) 32'd00: ; 32'd01: ; 32'd02: `checkh(shifted, 61'h0000000000000001); 32'd03: `checkh(shifted, 61'h0000000000000008); 32'd04: `checkh(shifted, 61'h0002000000000000); 32'd05: `checkh(shifted, 61'h0000000000010000); 32'd06: `checkh(shifted, 61'h0000000000000008); 32'd07: `checkh(shifted, 61'h0000000000000080); 32'd08: `checkh(shifted, 61'h0000000000000000); 32'd09: `checkh(shifted, 61'h0000000000000000); default: $stop; endcase end endmodule verilator-3.916/test_regress/t/t_select_lhs_oob.v0000664000177100017500000000410613205574202022173 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.916/test_regress/t/t_order_2d.v0000664000177100017500000000371613205574202020715 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire input_signal = crc[0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire output_signal; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .output_signal (output_signal), // Inputs .input_signal (input_signal)); // Aggregate outputs into a single result vector wire [63:0] result = {63'h0, output_signal}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h765b2e12b25ec97b if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( input input_signal, output output_signal ); // bug872 // verilator lint_off UNOPTFLAT wire some_signal[1:0][1:0]; assign some_signal[0][0] = input_signal; assign some_signal[0][1] = some_signal[0][0]; assign some_signal[1][0] = some_signal[0][1]; assign some_signal[1][1] = some_signal[1][0]; assign output_signal = some_signal[1][1]; endmodule verilator-3.916/test_regress/t/t_select_bad_range3.pl0000775000177100017500000000117513205574202022707 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Warning-SELRANGE: t/t_select_bad_range3.v:\d+: Selection index out of range: 13 outside 12:10 %Warning-SELRANGE: Use .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_math_real.v0000664000177100017500000001017713205574202021150 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2011 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. `define is_near_real(a,b) (( ((a)<(b)) ? (b)-(a) : (a)-(b)) < (((a)/(b))*0.0001)) module t (/*AUTOARG*/ // Inputs clk ); input clk; integer i; reg [63:0] b; real r, r2; integer cyc=0; realtime uninit; initial if (uninit != 0.0) $stop; sub_cast_bug374 sub (.cyc5(cyc[4:0]), .*); initial begin if (1_00_0.0_1 != 1000.01) $stop; // rtoi truncates if ($rtoi(36.7) != 36) $stop; if ($rtoi(36.5) != 36) $stop; if ($rtoi(36.4) != 36) $stop; // casting rounds if ((integer '(36.7)) != 37) $stop; if ((integer '(36.5)) != 37) $stop; if ((integer '(36.4)) != 36) $stop; // assignment rounds // verilator lint_off REALCVT i = 36.7; if (i != 37) $stop; i = 36.5; if (i != 37) $stop; i = 36.4; if (i != 36) $stop; r = 10'd38; if (r!=38.0) $stop; // verilator lint_on REALCVT // operators if ((-(1.5)) != -1.5) $stop; if ((+(1.5)) != 1.5) $stop; if (((1.5)+(1.25)) != 2.75) $stop; if (((1.5)-(1.25)) != 0.25) $stop; if (((1.5)*(1.25)) != 1.875) $stop; if (((1.5)/(1.25)) != 1.2) $stop; // if (((1.5)==(2)) != 1'b0) $stop; // note 2 becomes real 2.0 if (((1.5)!=(2)) != 1'b1) $stop; if (((1.5)> (2)) != 1'b0) $stop; if (((1.5)>=(2)) != 1'b0) $stop; if (((1.5)< (2)) != 1'b1) $stop; if (((1.5)<=(2)) != 1'b1) $stop; if (((1.5)==(1.5)) != 1'b1) $stop; if (((1.5)!=(1.5)) != 1'b0) $stop; if (((1.5)> (1.5)) != 1'b0) $stop; if (((1.5)>=(1.5)) != 1'b1) $stop; if (((1.5)< (1.5)) != 1'b0) $stop; if (((1.5)<=(1.5)) != 1'b1) $stop; if (((1.6)==(1.5)) != 1'b0) $stop; if (((1.6)!=(1.5)) != 1'b1) $stop; if (((1.6)> (1.5)) != 1'b1) $stop; if (((1.6)>=(1.5)) != 1'b1) $stop; if (((1.6)< (1.5)) != 1'b0) $stop; if (((1.6)<=(1.5)) != 1'b0) $stop; // if (((0.0)?(2.0):(1.1)) != 1.1) $stop; if (((1.5)?(2.0):(1.1)) != 2.0) $stop; // if (!1.7) $stop; if (!(!0.0)) $stop; if (1.8 && 0.0) $stop; if (!(1.8 || 0.0)) $stop; // i=0; for (r=1.0; r<2.0; r=r+0.1) i++; if (i!=10) $stop; // bug r = $bitstoreal($realtobits(1.414)); if (r != 1.414) $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.916/test_regress/t/t_case_genx_bad.pl0000775000177100017500000000117013151152521022114 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_tri_pullup.pl0000775000177100017500000000116513151152521021555 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_lint_modport_dir_bad.v0000664000177100017500000000145713205574202023373 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. interface dummy_if (); logic signal; modport slave (output signal); modport master (input signal); endinterface: dummy_if module sub ( input wire signal_i, output wire signal_o, dummy_if.master dummy_in, dummy_if.slave dummy_out ); assign dummy_in.signal = signal_i; assign signal_o = dummy_out.signal; endmodule module t (/*AUTOARG*/ // Outputs signal_o, // Inputs signal_i ); input signal_i; output signal_o; dummy_if dummy_if (); sub sub ( .signal_i(signal_i), .signal_o(signal_o), .dummy_in(dummy_if), .dummy_out(dummy_if) ); endmodule verilator-3.916/test_regress/t/t_gen_assign.pl0000775000177100017500000000074113151152521021472 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_const_dec_mixed_bad.pl0000775000177100017500000000114213151152521023306 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_param_concat_bad.pl0000775000177100017500000000150512671044616022624 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_gate_implicit.v0000664000177100017500000000343712473477707022051 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.916/test_regress/t/t_var_assign_landr.v0000664000177100017500000000472313205574202022530 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Use this file as a template for submitting bugs, etc. // This module takes a single clock input, and should either // $write("*-* All Finished *-*\n"); // $finish; // on success, or $stop. // // The code as shown applies a random vector to the Test // module, then calculates a CRC on the Test module's outputs. // // **If you do not wish for your code to be released to the public // please note it here, otherwise:** // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by ____YOUR_NAME_HERE____. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [255:0] sum; // Take CRC data and apply to testblock inputs wire [127:0] in = {~crc[63:0], crc[63:0]}; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [127:0] o1; // From test of Test.v wire [127:0] o2; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .o1 (o1[127:0]), .o2 (o2[127:0]), // Inputs .in (in[127:0])); // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x %x\n",$time, cyc, crc, o1, o2); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= {o1,o2} ^ {sum[254:0],sum[255]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 256'h008a080aaa000000140550404115dc7b008a080aaae7c8cd897bc1ca49c9350a if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs o1, o2, // Inputs in ); input [127:0] in; output logic [127:0] o1; output logic [127:0] o2; always_comb begin: b_test logic [127:0] tmpp; logic [127:0] tmp; tmp = '0; tmpp = '0; tmp[63:0] = in[63:0]; tmpp[63:0] = in[63:0]; tmpp[63:0] = {tmp[0+:32], tmp[32+:32]}; tmp[63:0] = {tmp[0+:32], tmp[32+:32]}; o1 = tmp; o2 = tmpp; end endmodule verilator-3.916/test_regress/t/t_dedupe_clk_gate.v0000664000177100017500000000256312671044616022322 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.916/test_regress/t/t_select_lhs_oob2.v0000664000177100017500000000621512473477707022302 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.916/test_regress/t/t_flag_define.v0000664000177100017500000000232613205574202021434 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder `define STRINGIFY(x) `"x`" module t; initial begin `ifdef D1A if (`STRINGIFY(`D4B) !== "") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D2A if (`STRINGIFY(`D2A) !== "VALA") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D3A if (`STRINGIFY(`D4B) !== "") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D3B if (`STRINGIFY(`D4B) !== "") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D4A if (`STRINGIFY(`D4A) !== "VALA") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D4B if (`STRINGIFY(`D4B) !== "") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D5A if (`STRINGIFY(`D5A) !== "VALA") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D5A if (`STRINGIFY(`D5B) !== "VALB") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_var_dotted_inl2.pl0000775000177100017500000000104213151152521022427 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_lint_modport_dir_bad.pl0000775000177100017500000000136013205574202023535 0ustar 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 -Wno-DECLFILENAME"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Error: t/t_lint_modport_dir_bad.v:\d+: Attempt to drive input-only modport: signal %Error: Exiting due to .*', ); ok(1); 1; verilator-3.916/test_regress/t/t_bind2.v0000664000177100017500000000407312671044616020217 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.916/test_regress/t/t_interface_down_inla.pl0000775000177100017500000000110312671044616023353 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_array_pattern_2d.v0000664000177100017500000000207313205622627022455 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. //bug991 module t (/*AUTOARG*/); logic [31:0] array_assign [3:0]; logic [31:0] array_other [3:0]; logic [31:0] larray_assign [0:3]; logic [31:0] larray_other [0:3]; initial begin array_assign[0] = 32'd1; array_assign[3:1] = '{32'd4, 32'd3, 32'd2}; array_other[0] = array_assign[0]+10; array_other[3:1] = array_assign[3:1]; if (array_other[0] != 11) $stop; if (array_other[1] != 2) $stop; if (array_other[2] != 3) $stop; if (array_other[3] != 4) $stop; larray_assign[0] = 32'd1; larray_assign[1:3] = '{32'd4, 32'd3, 32'd2}; larray_other[0] = larray_assign[0]+10; larray_other[1:3] = larray_assign[1:3]; if (larray_other[0] != 11) $stop; if (larray_other[1] != 4) $stop; if (larray_other[2] != 3) $stop; if (larray_other[3] != 2) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_clk_powerdn.pl0000775000177100017500000000072213151152521021663 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_lint_unused_iface.pl0000775000177100017500000000110313205574202023032 0ustar 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 => ["--lint-only -Wall -Wno-DECLFILENAME"], fails=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.916/test_regress/t/t_order_clkinst.pl0000775000177100017500000000105113151152521022212 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_mem_multidim.pl0000775000177100017500000000071712473477707022070 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_pipe_exit_bad.pl0000775000177100017500000000136413205574202022157 0ustar 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....*', ); ok(1); 1; verilator-3.916/test_regress/t/t_typedef_param.pl0000775000177100017500000000072213205574202022200 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_comb_use.pl0000775000177100017500000000115213205574202022200 0ustar 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 --bbox-sys"], fails=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_strwidth.pl0000775000177100017500000000074613151152521022243 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_param_const_part.v0000664000177100017500000000120113205574202022534 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t; function integer bottom_4bits; input [7:0] i; bottom_4bits = 0; bottom_4bits[3:0] = i[3:0]; endfunction function integer bottom_2_unknown; input [7:0] i; // bottom_4bits = 0; 'x bottom_2_unknown[1:0] = i[1:0]; endfunction localparam p = bottom_4bits(8'h13); localparam bu = bottom_2_unknown(8'h13); initial begin if (p != 3) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_xml_first.v0000664000177100017500000000145312671044616021227 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.916/test_regress/t/t_flag_define.pl0000775000177100017500000000077513205574202021613 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( v_flags2 => ["-f t/t_flag_define.vc"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_for_init_bug.v0000664000177100017500000000137313205574202021660 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.916/test_regress/t/t_lint_input_eq_bad.pl0000775000177100017500000000132412671044616023046 0ustar 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.916/test_regress/t/t_dos.v0000775000177100017500000000066512473477707020027 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.916/test_regress/t/t_var_bad_sv.v0000664000177100017500000000032612473477707021337 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.916/test_regress/t/t_inst_tree_inl1_pub0.pl0000775000177100017500000000112713205574202023225 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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|.*t\.ps): Clocked ', ); ok(1); 1; verilator-3.916/test_regress/t/t_clk_concat.v0000664000177100017500000000307713205574202021315 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // module some_module ( input wrclk ); logic [ 1 : 0 ] some_state; logic [1:0] some_other_state; always @(posedge wrclk) begin case (some_state) 2'b11: if (some_other_state == 0) some_state <= 2'b00; default: $display ("This is a display statement"); endcase if (wrclk) some_other_state <= 0; end endmodule `define BROKEN module t1( input [3:0] i_clks, input i_clk0, input i_clk1 ); some_module some_module ( `ifdef BROKEN .wrclk (i_clks[3]) `else .wrclk (i_clk1) `endif ); endmodule module t2( input [2:0] i_clks, input i_clk0, input i_clk1, input i_clk2, input i_data ); logic [3:0] the_clks; logic data_q; assign the_clks = {i_clk1, i_clk2, i_clk1, i_clk0}; always @(posedge i_clk0) begin data_q <= i_data; end t1 t1 ( .i_clks (the_clks), .i_clk0 (i_clk0), .i_clk1 (i_clk1) ); endmodule module t( input clk0 /*verilator clocker*/, input clk1 /*verilator clocker*/, input clk2 /*verilator clocker*/, input data_in ); logic [2:0] clks; assign clks = {1'b0, clk1, clk0}; t2 t2 ( .i_clks (clks), .i_clk0 (clk0), .i_clk1 (clk1), .i_clk2 (clk2), .i_data (data_in) ); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_math_signed4.pl0000775000177100017500000000072212671044616021735 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_ldflags.v0000664000177100017500000000123712473477707021640 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.916/test_regress/t/t_order_multialways.v0000664000177100017500000000234612473477707023003 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.916/test_regress/t/t_param_first.v0000664000177100017500000001073412671044616021531 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t(/*AUTOARG*/ // Inputs clk ); input clk; reg _ranit; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [4:0] par1; // From a1 of t_param_first_a.v wire [4:0] par2; // From a2 of t_param_first_a.v wire [4:0] par3; // From a3 of t_param_first_a.v wire [4:0] par4; // From a4 of t_param_first_a.v wire [1:0] varwidth1; // From a1 of t_param_first_a.v wire [2:0] varwidth2; // From a2 of t_param_first_a.v wire [3:0] varwidth3; // From a3 of t_param_first_a.v wire [3:0] varwidth4; // From a4 of t_param_first_a.v // End of automatics /*t_param_first_a AUTO_TEMPLATE ( .par (par@[])); .varwidth (varwidth@[])); */ parameter XX = 2'bXX; parameter THREE = 3; t_param_first_a #(1,5) a1 ( // Outputs .varwidth (varwidth1[1:0]), /*AUTOINST*/ // Outputs .par (par1[4:0])); // Templated t_param_first_a #(2,5) a2 ( // Outputs .varwidth (varwidth2[2:0]), /*AUTOINST*/ // Outputs .par (par2[4:0])); // Templated t_param_first_a #(THREE,5) a3 ( // Outputs .varwidth (varwidth3[3:0]), /*AUTOINST*/ // Outputs .par (par3[4:0])); // Templated t_param_first_a #(THREE,5) a4 ( // Outputs .varwidth (varwidth4[3:0]), /*AUTOINST*/ // Outputs .par (par4[4:0])); // Templated parameter THREE_BITS_WIDE = 3'b011; parameter THREE_2WIDE = 2'b11; parameter ALSO_THREE_WIDE = THREE_BITS_WIDE; parameter THREEPP_32_WIDE = 2*8*2+3; parameter THREEPP_3_WIDE = 3'd4*3'd4*3'd2+3'd3; // Yes folks VCS says 3 bits wide // Width propagation doesn't care about LHS vs RHS // But the width of a RHS/LHS on a upper node does affect lower nodes; // Thus must double-descend in width analysis. // VCS 7.0.1 is broken on this test! parameter T10 = (3'h7+3'h7)+4'h0; //initial if (T10!==4'd14) $stop; parameter T11 = 4'h0+(3'h7+3'h7); //initial if (T11!==4'd14) $stop; // Parameters assign LHS is affectively width zero. parameter T12 = THREE_2WIDE + THREE_2WIDE; initial if (T12!==2'd2) $stop; parameter T13 = THREE_2WIDE + 3; initial if (T13!==32'd6) $stop; // Must be careful about LSB's with extracts parameter [39:8] T14 = 32'h00_1234_56; initial if (T14[24:16]!==9'h34) $stop; // parameter THREEPP_32P_WIDE = 3'd4*3'd4*2+3'd3; parameter THREE_32_WIDE = 3%32; parameter THIRTYTWO = 2; // Param is 32 bits parameter [40:0] WIDEPARAM = 41'h12_3456789a; parameter [40:0] WIDEPARAM2 = WIDEPARAM; reg [7:0] eightb; reg [3:0] fourb; wire [7:0] eight = 8'b00010000; wire [1:0] eight2two = eight[THREE_32_WIDE+1:THREE_32_WIDE]; wire [2:0] threebits = ALSO_THREE_WIDE; // surefire lint_off CWCCXX initial _ranit = 0; always @ (posedge clk) begin if (!_ranit) begin _ranit <= 1; $write("[%0t] t_param: Running\n", $time); // $write(" %d %d %d\n", par1,par2,par3); if (par1!==5'd1) $stop; if (par2!==5'd2) $stop; if (par3!==5'd3) $stop; if (par4!==5'd3) $stop; if (varwidth1!==2'd2) $stop; if (varwidth2!==3'd2) $stop; if (varwidth3!==4'd2) $stop; if (varwidth4!==4'd2) $stop; if (threebits !== 3'b011) $stop; if (eight !== 8'b00010000) $stop; if (eight2two !== 2'b10) $stop; $write(" Params = %b %b\n %b %b\n", THREEPP_32_WIDE,THREEPP_3_WIDE, THIRTYTWO, THREEPP_32P_WIDE); if (THREEPP_32_WIDE !== 32'h23) $stop; if (THREEPP_3_WIDE !== 3'h3) $stop; if (THREEPP_32P_WIDE !== 32'h23) $stop; if (THIRTYTWO[1:0] !== 2'h2) $stop; if (THIRTYTWO !== 32'h2) $stop; if (THIRTYTWO !== 2) $stop; if ((THIRTYTWO[1:0]+2'b00) !== 2'b10) $stop; if ({1'b1,{THIRTYTWO[1:0]+2'b00}} !== 3'b110) $stop; if (XX===0 || XX===1 || XX===2 || XX===3) $stop; // Paradoxical but right, since 1'bx!=0 && !=1 // // Example of assignment LHS affecting expression widths. // verilator lint_off WIDTH // surefire lint_off ASWCMB // surefire lint_off ASWCBB eightb = (4'd8+4'd8)/4'd4; if (eightb!==8'd4) $stop; fourb = (4'd8+4'd8)/4'd4; if (fourb!==4'd0) $stop; fourb = (4'd8+8)/4'd4; if (fourb!==4'd4) $stop; // verilator lint_on WIDTH // surefire lint_on ASWCMB // surefire lint_on ASWCBB // $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_genvar_misuse_bad.v0000664000177100017500000000051312671044616022671 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.916/test_regress/t/t_var_bad_sameas.pl0000775000177100017500000000246712671044616022326 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_gen_local.v0000664000177100017500000000116412671044616021142 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.916/test_regress/t/t_lint_repeat_bad.pl0000775000177100017500000000137212671044616022505 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_var_pins_sc_uint.pl0000775000177100017500000000470313205574202022730 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc --pins-sc-uint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.916/test_regress/t/t_order_multidriven.pl0000775000177100017500000000120313151152521023104 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_var_life.v0000664000177100017500000000443612473477707021026 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.916/test_regress/t/t_clk_gater.v0000664000177100017500000000635512473477707021174 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.916/test_regress/t/t_math_imm2.pl0000775000177100017500000000116012473477707021254 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_select_runtime_range.v0000664000177100017500000000335412671044616023420 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (clk); input clk; reg [43:0] mi; reg [5:0] index; integer indexi; reg read; initial begin // Static mi = 44'b01010101010101010101010101010101010101010101; if (mi[0] !== 1'b1) $stop; if (mi[1 -: 2] !== 2'b01) $stop; `ifdef VERILATOR // verilator lint_off SELRANGE if (mi[-1] !== 1'bx && mi[-1] !== 1'b0) $stop; if (mi[0 -: 2] !== 2'b1x && 1'b0) $stop; if (mi[-1 -: 2] !== 2'bxx && 1'b0) $stop; // verilator lint_on SELRANGE `else if (mi[-1] !== 1'bx) $stop; if (mi[0 -: 2] !== 2'b1x) $stop; if (mi[-1 -: 2] !== 2'bxx) $stop; `endif end integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin mi = 44'h123; end if (cyc==2) begin index = 6'd43; indexi = 43; end if (cyc==3) begin read = mi[index]; if (read!==1'b0) $stop; read = mi[indexi]; if (read!==1'b0) $stop; end if (cyc==4) begin index = 6'd44; indexi = 44; end if (cyc==5) begin read = mi[index]; $display("-Illegal read value: %x",read); //if (read!==1'b1 && read!==1'bx) $stop; read = mi[indexi]; $display("-Illegal read value: %x",read); //if (read!==1'b1 && read!==1'bx) $stop; end if (cyc==6) begin indexi = -1; end if (cyc==7) begin read = mi[indexi]; $display("-Illegal read value: %x",read); //if (read!==1'b1 && read!==1'bx) $stop; end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_case_reducer.v0000664000177100017500000002544613205574202021645 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.916/test_regress/t/t_langext_2.pl0000775000177100017500000000076112671044616021255 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_select_param.v0000664000177100017500000000066512473477707021676 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.916/test_regress/t/t_lint_incabspath.v0000664000177100017500000000031212473477707022366 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.916/test_regress/t/t_display_signed_noopt.pl0000775000177100017500000000250512473477707023620 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_mem_slot.cpp0000664000177100017500000000235612671044616021357 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.916/test_regress/t/t_select_bound2.v0000664000177100017500000000424313205574202021741 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. // bug823 module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [6:0] in = crc[6:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [3:0] mask; // From test of Test.v wire [3:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[3:0]), .mask (mask[3:0]), // Inputs .clk (clk), .in (in[6:0])); // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, out & mask}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x out=%b mask=%b\n",$time, cyc, crc, out, mask); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h4e9d3a74e9d3f656 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, mask, // Inputs clk, in ); input clk; input [6:0] in; // Note much wider than any index output reg [3:0] out; output reg [3:0] mask; localparam [15:5] p = 11'h1ac; always @(posedge clk) begin // verilator lint_off WIDTH out <= p[15 + in -: 5]; // verilator lint_on WIDTH mask[3] <= ((15 + in - 5) < 12); mask[2] <= ((15 + in - 5) < 13); mask[1] <= ((15 + in - 5) < 14); mask[0] <= ((15 + in - 5) < 15); end endmodule verilator-3.916/test_regress/t/t_crazy_sel.pl0000775000177100017500000000072213205574202021353 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_nomod_bad.pl0000775000177100017500000000113012473477707022307 0ustar 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.916/test_regress/t/t_uniqueif_fail2.pl0000775000177100017500000000144013205574202022260 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_uniqueif.v"); compile ( v_flags2 => ['+define+FAILING_ASSERTION2'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], fails => $Self->{nc}, ); execute ( fails => $Self->{vlt}, expect=> '.*%Error: t_uniqueif.v:\d+: Assertion failed in top.t: \'unique if\' statement violated %Error: t/t_uniqueif.v:\d+: Verilog \$stop .*', ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_for.pl0000775000177100017500000000071712473477707021025 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_down_inlc.pl0000775000177100017500000000110312671044616023355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_func_noinl.pl0000775000177100017500000000071712473477707021540 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_select_bound2.pl0000775000177100017500000000072213205574202022110 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_sv_cpu.v0000664000177100017500000000644512671044616020525 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: System Verilog test of a complete CPU // // This code instantiates and runs a simple CPU written in System Verilog. // // This file ONLY is placed into the Public Domain, for any use, without // warranty. // Contributed 2012 by M W Lund, Atmel Corporation and Jeremy Bennett, Embecosm. module t (/*AUTOARG*/ // Inputs clk ); input clk; /*AUTOWIRE*/ // ************************************************************************** // Regs and Wires // ************************************************************************** reg rst; integer rst_count; integer clk_count; testbench testbench_i (/*AUTOINST*/ // Inputs .clk (clk), .rst (rst)); // ************************************************************************** // Reset Generation // ************************************************************************** initial begin rst = 1'b1; rst_count = 0; end always @( posedge clk ) begin if (rst_count < 2) begin rst_count++; end else begin rst = 1'b0; end end // ************************************************************************** // Drive simulation for 500 clock cycles // ************************************************************************** initial begin `ifdef TEST_VERBOSE $display( "[testbench] - Start of simulation ----------------------- " ); `endif clk_count = 0; end always @( posedge clk ) begin if (90 == clk_count) begin $finish (); end else begin clk_count++; end end final begin `ifdef TEST_VERBOSE $display( "[testbench] - End of simulation ------------------------- " ); `endif $write("*-* All Finished *-*\n"); end endmodule module testbench (/*AUTOARG*/ // Inputs clk, rst ); input clk; input rst; // ************************************************************************** // Local parameters // ************************************************************************** localparam NUMPADS = $size( pinout ); // ************************************************************************** // Regs and Wires // ************************************************************************** // **** Pinout **** `ifdef VERILATOR // see t_tri_array wire [NUMPADS:1] pad; // GPIO Pads (PORT{A,...,R}). `else wire pad [1:NUMPADS]; // GPIO Pads (PORT{A,...,R}). `endif // ************************************************************************** // Regs and Wires, Automatics // ************************************************************************** /*AUTOWIRE*/ // ************************************************************************** // Includes (Testbench extensions) // ************************************************************************** // N/A // ************************************************************************** // Chip Instance // ************************************************************************** chip i_chip ( /*AUTOINST*/ // Inouts .pad (pad[NUMPADS:1]), // Inputs .clk (clk), .rst (rst)); endmodule // test // Local Variables: // verilog-library-directories:("." "t_sv_cpu_code") // End: verilator-3.916/test_regress/t/t_cdc_async_bad.pl0000775000177100017500000000216613205574202022120 0ustar 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: t.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: t.rst6a_bad_n %Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: t.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.916/test_regress/t/t_for_break.pl0000775000177100017500000000071712473477707021340 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_misarray_bad.v0000664000177100017500000000140112671044616022703 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.916/test_regress/t/t_lint_implicit_def_bad.pl0000775000177100017500000000165112473477707023670 0ustar 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.916/test_regress/t/t_interface_gen.pl0000775000177100017500000000072713151152521022152 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_func_noinl.v0000664000177100017500000000477413205574202021354 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.916/test_regress/t/t_var_types.v0000664000177100017500000001745312671044616021243 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.916/test_regress/t/t_enum_name2.pl0000775000177100017500000000072213205574202021406 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_typo_bad.pl0000775000177100017500000000175613205574202023211 0ustar 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 ( verilator_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, fails => 1, # Used to be %Error: t/t_order_wireloop.v:\d+: Wire inputs its own output, creating circular logic .wire x=x. # However we no longer gate optimize this expect=> q{%Error: t/t_interface_typo_bad.v:\d+: Parent cell's interface is not found: foo_intf %Error: t/t_interface_typo_bad.v:\d+: Cannot find file containing interface: fo_intf %Error: t/t_interface_typo_bad.v:\d+: Found definition of 'the_foo' as a CELL but expected a variable .*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_comma_inl1.pl0000775000177100017500000000103613205574202022433 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_inst_comma.v"); compile ( v_flags2 => ['+define+USE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_clk_vecgen2.pl0000775000177100017500000000103312473477707021560 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_mod_interface_array1_noinl.pl0000775000177100017500000000102713205574202024634 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_mod_interface_array1.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_packed_sysfunct.pl0000775000177100017500000000071712671044616024164 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_ccall.pl0000775000177100017500000000071712473477707021521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gated_clk_1.v0000664000177100017500000000271312671044616021355 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.916/test_regress/t/t_var_nonamebegin.v0000664000177100017500000000224212473477707022362 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.916/test_regress/t/t_interface_gen2.v0000664000177100017500000000312612671044616022072 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.916/test_regress/t/t_select_plusloop.pl0000775000177100017500000000071712473477707022622 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_for_loop.pl0000775000177100017500000000071712473477707021225 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_bench_mux4k.v0000664000177100017500000001063413205574202021421 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.916/test_regress/t/t_interface2_noinl.pl0000775000177100017500000000105113205574202022575 0ustar wsnyderwsnyder#!/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_interface2.v"); compile ( verilator_flags2 => ["--top-module t -Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_port.v0000664000177100017500000000353413205574202021603 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.916/test_regress/t/t_assert_basic_cover.pl0000775000177100017500000000150213205574202023215 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_assert_basic.v"); compile ( verilator_flags2 => ['--assert --cc --coverage-user'], ); execute ( check_finished=>1, ); #Needs work print "-Info: NOT checking for coverage\n"; #file_grep ($Self->{coverage_filename}, qr/t=>'psl_cover',o=>'cover',c=>2\);/); #file_grep ($Self->{coverage_filename}, qr/DefaultClock.*,c=>1\);/); #file_grep ($Self->{coverage_filename}, qr/ToggleLogIf.*,c=>9\);/); ok(1); 1; verilator-3.916/test_regress/t/t_preproc_persist.v0000664000177100017500000000032613205574202022432 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. Inside `__FILE__. `include "t_preproc_persist_inc.v" verilator-3.916/test_regress/t/t_var_tieout.pl0000775000177100017500000000071712473477707021567 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_sel_range.v0000664000177100017500000000152512671044616022337 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.916/test_regress/t/t_param_chain.pl0000775000177100017500000000072212671044616021631 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_dupitems.pl0000775000177100017500000000071712473477707022233 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_a_first_sc.pl0000775000177100017500000000140713205574202021475 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 test runs the very first time we've executed Verilator --sc # after building so we make sure to run with --gdbbt, so if it dumps we'll # get a trace. top_filename("t/t_a_first_cc.v"); $DEBUG_QUIET = "--debug --debugi 0 --gdbbt --no-dump-tree"; compile ( verilator_flags2 => [$DEBUG_QUIET, "-sc --trace"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_const_overflow_bad.pl0000775000177100017500000000153513151152521023236 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_param_seg.v0000664000177100017500000000106713205574202021150 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Mandy Xu. // verilator lint_off WIDTH //bug1088 module t (/*AUTOARG*/ // Outputs err_count, // Inputs clk, syndromes ); input clk; input [7:0] syndromes; output reg [1:0] err_count = 0; localparam [95:0] M = 96'h4; wire [3:0] syn1 = syndromes[0+:M]; always @(posedge clk) begin err_count <= {1'b0, |syn1}; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_var_local.pl0000775000177100017500000000071712473477707021350 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_bad_hide.v0000664000177100017500000000066312473477707021624 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.916/test_regress/t/t_func_bad.v0000664000177100017500000000156012671044616020760 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.916/test_regress/t/t_case_66bits.v0000664000177100017500000000071512473477707021343 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.916/test_regress/t/t_dpi_name_bad.v0000664000177100017500000000066012473477707021614 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.916/test_regress/t/t_metacmt_onoff.v0000664000177100017500000000054312473477707022053 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.916/test_regress/t/t_package_export.pl0000775000177100017500000000107213205574202022353 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vcs} and $Self->unsupported("VCS unsupported"); compile ( v_flags2 => ['+define+T_PACKAGE_EXPORT',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_onehot.v0000664000177100017500000000434012473477707021520 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.916/test_regress/t/t_interface_parameter_access.v0000664000177100017500000000355313205574202024535 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Interface parameter getter // // A test of the import parameter used with modport // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader interface test_if #(parameter integer FOO = 1); // Interface variable logic data; // Modport modport mp( import getFoo, output data ); function integer getFoo (); return FOO; endfunction endinterface // test_if function integer identity (input integer x); return x; endfunction module t (/*AUTOARG*/ // Inputs clk ); input clk; test_if #( .FOO (identity(5)) ) the_interface (); testmod testmod_i (.clk (clk), .intf (the_interface), .intf_no_mp (the_interface) ); localparam THE_TOP_FOO = the_interface.FOO; initial begin if (THE_TOP_FOO != 5) begin $display("%%Error: THE_TOP_FOO = %0d", THE_TOP_FOO); $stop; end end endmodule module testmod ( input clk, test_if.mp intf, test_if intf_no_mp ); localparam THE_FOO = intf.FOO; localparam THE_OTHER_FOO = intf_no_mp.FOO; always @(posedge clk) begin if (THE_FOO != 5) begin $display("%%Error: THE_FOO = %0d", THE_FOO); $stop; end if (THE_OTHER_FOO != 5) begin $display("%%Error: THE_OTHER_FOO = %0d", THE_OTHER_FOO); $stop; end if (intf.FOO != 5) begin $display("%%Error: intf.FOO = %0d", intf.FOO); $stop; end if (intf_no_mp.FOO != 5) begin $display("%%Error: intf_no_mp.FOO = %0d", intf_no_mp.FOO); $stop; end // if (i.getFoo() != 5) begin // $display("%%Error: i.getFoo() = %0d", i.getFoo()); // $stop; // end $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_func_first.v0000664000177100017500000000123612473477707021374 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.916/test_regress/t/TestVpi.h0000664000177100017500000000257213205574202020251 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2013-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/test_regress/t/t_interface1_modport_noinl.pl0000775000177100017500000000103213205574202024337 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_interface1_modport.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mod_dup_bad.pl0000775000177100017500000000124712473477707021642 0ustar 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.916/test_regress/t/t_math_const.v0000664000177100017500000001122513205574202021346 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [39:0] con1,con2, con3; reg [31:0] w32; reg [31:0] v32 [2]; // surefire lint_off UDDSCN reg [200:0] conw3, conw4; // surefire lint_on UDDSCN reg [16*8-1:0] con__ascii; reg [31:0] win; // Test casting is proper on narrow->wide->narrow conversions // verilator lint_off WIDTH wire [49:0] wider = ({18'h0, win} | (1'b1<<32)) - 50'h111; wire [31:0] wider2 = ({win} | (1'b1<<32)) - 50'd111; // verilator lint_on WIDTH wire [31:0] narrow = wider[31:0]; wire [31:0] narrow2 = wider2[31:0]; // surefire lint_off ASWEMB // surefire lint_off ASWCMB // surefire lint_off CWECBB // surefire lint_off CWECSB // surefire lint_off STMINI integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin $write("[%0t] t_const: Running\n",$time); con1 = 4_0'h1000_0010; // Odd but legal _ in width con2 = 40'h10_0000_0010; con3 = con1 + 40'h10_1100_0101; if (con1[31:0]!== 32'h1000_0010 || con1[39:32]!==0) $stop; $display("%x %x %x\n", con2, con2[31:0], con2[39:32]); if (con2[31:0]!== 32'h10 || con2[39:32]!==8'h10) $stop; if (con3[31:0]!==32'h2100_0111 || con3[39:32]!==8'h10) $stop; // verilator lint_off WIDTH con1 = 10'h10 + 40'h80_1100_0131; // verilator lint_on WIDTH con2 = 40'h80_0000_0000 + 40'h13_7543_0107; if (con1[31:0]!== 32'h1100_0141 || con1[39:32]!==8'h80) $stop; if (con2[31:0]!== 32'h7543_0107 || con2[39:32]!==8'h93) $stop; // verilator lint_off WIDTH conw3 = 94'h000a_5010_4020_3030_2040_1050; // verilator lint_on WIDTH if (conw3[31:00]!== 32'h2040_1050 || conw3[63:32]!== 32'h4020_3030 || conw3[95:64]!== 32'h000a_5010 || conw3[128:96]!==33'h0) $stop; $display("%x... %x\n", conw3[15:0], ~| conw3[15:0]); if ((~| conw3[15:0]) !== 1'h0) $stop; if ((~& conw3[15:0]) !== 1'h1) $stop; // verilator lint_off WIDTH conw4 = 112'h7010_602a_5030_4040_3050_2060_1070; // verilator lint_on WIDTH if (conw4[31:00]!== 32'h2060_1070 || conw4[63:32]!== 32'h4040_3050 || conw4[95:64]!== 32'h602a_5030 || conw4[127:96]!==32'h7010) $stop; // conw4 = 144'h7000_7000_7010_602a_5030_4040_3050_2060_1070; w32 = 12; win <= 12; if ((32'hffff0000 >> w32) != 32'h 000ffff0) $stop; con__ascii = "abcdefghijklmnop"; if ( con__ascii !== {"abcd","efgh","ijkl","mnop"}) $stop; con__ascii = "abcdefghijklm"; if ( con__ascii !== {24'h0,"a","bcde","fghi","jklm"}) $stop; if ( 3'dx !== 3'hx) $stop; // Wide decimal if ( 94'd12345678901234567890123456789 != 94'h27e41b3246bec9b16e398115) $stop; if (-94'sd123456789012345678901234567 != 94'h3f99e1020ea70d57d360b479) $stop; // Increments w32 = 12; w32++; if (w32 != 13) $stop; w32 = 12; ++w32; if (w32 != 13) $stop; w32 = 12; w32--; if (w32 != 11) $stop; w32 = 12; --w32; if (w32 != 11) $stop; w32 = 12; w32 += 2; if (w32 != 14) $stop; w32 = 12; w32 -= 2; if (w32 != 10) $stop; w32 = 12; w32 *= 2; if (w32 != 24) $stop; w32 = 12; w32 /= 2; if (w32 != 6) $stop; w32 = 12; w32 &= 6; if (w32 != 4) $stop; w32 = 12; w32 |= 15; if (w32 != 15) $stop; w32 = 12; w32 ^= 15; if (w32 != 3) $stop; w32 = 12; w32 >>= 1; if (w32 != 6) $stop; w32 = 12; w32 <<= 1; if (w32 != 24) $stop; // Increments v32[1] = 12; v32[1]++; if (v32[1] != 13) $stop; v32[1] = 12; ++v32[1]; if (v32[1] != 13) $stop; v32[1] = 12; v32[1]--; if (v32[1] != 11) $stop; v32[1] = 12; --v32[1]; if (v32[1] != 11) $stop; v32[1] = 12; v32[1] += 2; if (v32[1] != 14) $stop; v32[1] = 12; v32[1] -= 2; if (v32[1] != 10) $stop; v32[1] = 12; v32[1] *= 2; if (v32[1] != 24) $stop; v32[1] = 12; v32[1] /= 2; if (v32[1] != 6) $stop; v32[1] = 12; v32[1] &= 6; if (v32[1] != 4) $stop; v32[1] = 12; v32[1] |= 15; if (v32[1] != 15) $stop; v32[1] = 12; v32[1] ^= 15; if (v32[1] != 3) $stop; v32[1] = 12; v32[1] >>= 1; if (v32[1] != 6) $stop; v32[1] = 12; v32[1] <<= 1; if (v32[1] != 24) $stop; end if (cyc==2) begin win <= 32'h123123; if (narrow !== 32'hfffffefb) $stop; if (narrow2 !== 32'hffffff9d) $stop; end if (cyc==3) begin if (narrow !== 32'h00123012) $stop; if (narrow2 !== 32'h001230b4) $stop; end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_dpi_var.v0000664000177100017500000000433612473477707020662 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.916/test_regress/t/t_order_wireloop.pl0000775000177100017500000000133613205574202022415 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2005 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( fails=>$Self->{v3}, # Used to be %Error: t/t_order_wireloop.v:\d+: Wire inputs its own output, creating circular logic .wire x=x. # However we no longer gate optimize this expect=> '%Warning-UNOPT: t/t_order_wireloop.v:\d+: Signal unoptimizable: Feedback to public clock or circular logic: bar ', ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_gen.pl0000775000177100017500000000071712671044616021022 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_unopt_converge_run_bad.pl0000775000177100017500000000114412473477707024130 0ustar 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.916/test_regress/t/t_tri_graph.v0000664000177100017500000000075212671044616021200 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.916/test_regress/t/t_sys_plusargs.v0000664000177100017500000000354413205574202021752 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; string sv_str; reg [7*8:1] p_in; string sv_in; 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; p_i = 0; if ($value$plusargs("INT=%d", p_i)!==1) $stop; if (p_i !== 32'd1234) $stop; p_i = 0; if ($value$plusargs("INT=%H", p_i)!==1) $stop; // tests uppercase % also if (p_i !== 32'h1234) $stop; p_i = 0; // Check octal and WIDTH if (!$value$plusargs("INT=%o", p_i)) $stop; if (p_i !== 32'o1234) $stop; p_str = "none"; if ($value$plusargs("IN%s", p_str)!==1) $stop; $display("str='%s'",p_str); if (p_str !== "T=1234") $stop; sv_str = "none"; if ($value$plusargs("IN%s", sv_str)!==1) $stop; $display("str='%s'",sv_str); if (sv_str != "T=1234") $stop; p_in = "IN%s"; `ifdef VERILATOR p_in = $c(p_in); // Prevent constant propagation `endif sv_str = "none"; if ($value$plusargs(p_in, sv_str)!==1) $stop; $display("str='%s'",sv_str); if (sv_str != "T=1234") $stop; sv_in = "INT=%d"; `ifdef VERILATOR if ($c1(0)) sv_in = "NEVER"; // Prevent constant propagation `endif p_i = 0; if ($value$plusargs(sv_in, p_i)!==1) $stop; $display("i='%d'",p_i); if (p_i !== 32'd1234) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_preproc_ttempty.out0000664000177100017500000000002113205574202023001 0ustar wsnyderwsnyder `TARGET_PACKAGE verilator-3.916/test_regress/t/t_interface_gen7.v0000664000177100017500000000273513205574202022075 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // bug998 interface intf #(parameter PARAM = 0) (); logic val; function integer func (); return 5; endfunction endinterface module t1(intf mod_intf); initial begin $display("%m %d", mod_intf.val); end endmodule module t(); intf #(.PARAM(1)) my_intf [1:0] (); generate genvar the_genvar; begin for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf begin assign my_intf[the_genvar].val = '1; t1 t (.mod_intf(my_intf[the_genvar])); end end end endgenerate generate genvar the_second_genvar; begin intf #(.PARAM(1)) my_intf [1:0] (); for (the_second_genvar = 0; the_second_genvar < 2; the_second_genvar++) begin : TestIf begin assign my_intf[the_second_genvar].val = '1; t1 t (.mod_intf(my_intf[the_second_genvar])); end end end endgenerate generate genvar the_third_genvar; begin for (the_third_genvar = 0; the_third_genvar < 2; the_third_genvar++) begin : TestIf begin intf #(.PARAM(1)) my_intf [1:0] (); assign my_intf[the_third_genvar].val = '1; t1 t (.mod_intf(my_intf[the_third_genvar])); end end end endgenerate initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_clk_condflop.v0000664000177100017500000000464112473477707021672 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.916/test_regress/t/t_dpi_accessors_macros_inc.vh0000664000177100017500000000167112671044616024410 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.916/test_regress/t/t_detectarray_3.v0000664000177100017500000000140712671044616021750 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Simple test of unoptflat // // Trigger the DETECTARRAY error on packed structure. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jie Xu. localparam ID_MSB = 1; module t (/*AUTOARG*/ // Inputs clk, res ); input clk; output [8:0][8:0] res; logic a = 1'b1; logic [8:0] b [8:0]; // where the error is reported logic [8:0][8:0] c; // where the error is reported // following just to make c as circular assign c[0] = c[0] | a << 1; assign b[0] = b[0] | a << 2; assign res[0] = c[0]; assign res[1] = b[0]; always @(posedge clk or negedge clk) begin if (res != 0) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_var_overwidth_bad.cpp0000664000177100017500000000233513205574202023217 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_var_overwidth_bad.h" #include "verilated.h" //====================================================================== double main_time; double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { Verilated::debug(0); VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out main_time = 0; topp->clk = 0; topp->eval(); main_time += 10; topp->clk = 0x2; // ILLEGAL topp->eval(); topp->final(); delete topp; topp=NULL; exit(0L); } verilator-3.916/test_regress/t/t_bitsel_struct2.pl0000775000177100017500000000072212671044616022337 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_emit_constw.pl0000775000177100017500000000075712473477707021745 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_dpi_exp_bad.v0000664000177100017500000000066413205574202021452 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" function dpix_f_bit48; function bit [47:0] dpix_f_bit48 (bit [47:0] i); dpix_f_bit48 = ~i; endfunction endmodule verilator-3.916/test_regress/t/t_blocking.v0000664000177100017500000000363212473477707021024 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.916/test_regress/t/t_hierarchy_identifier_bad.v0000664000177100017500000000210012671044616024174 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.916/test_regress/t/t_gen_cond_bitrange_bad.v0000664000177100017500000000457412671044616023464 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.916/test_regress/t/t_inst_sv.v0000664000177100017500000000300212473477707020710 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.916/test_regress/t/t_interface_array_modport.pl0000775000177100017500000000072213205574202024262 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_lib_sub.pl0000775000177100017500000000075012473477707022035 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_scope_map.pl0000775000177100017500000000116713205574202021332 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2015 by Todd Strader. This program is free software; you can # redistribute it and/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}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_banks.v0000664000177100017500000000337613205574202021153 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/); reg [5:0] addr; parameter BANKS = 6; parameter ROWS = 8; wire [2:0] bank; wire [2:0] row; integer a; integer used[BANKS][ROWS]; // Test loop initial begin for (a = 0; a < BANKS*ROWS; ++a) begin addr[5:0] = a[5:0]; hash (addr, bank, row); used [bank][row] ++; if (used [bank][row] > 1) begin $write ("Error: Hash failed addr=%x bank=%x row=%x\n", addr, bank, row); end end $write("*-* All Finished *-*\n"); $finish; end task hash (input [5:0] addr, output [2:0] bank, output [2:0] row); reg [1:0] third; reg [1:0] fourth; third = {addr[5], addr[4]}; fourth = {addr[3] ^ addr[1], addr[2] ^ addr[0]}; case (third) 2'h0: case (fourth) 2'h0: begin bank = 3'h0; row = {1'h0, addr[1:0]}; end 2'h1: begin bank = 3'h1; row = {1'h0, addr[1:0]}; end 2'h2: begin bank = 3'h2; row = {1'h0, addr[1:0]}; end 2'h3: begin bank = 3'h3; row = {1'h0, addr[1:0]}; end endcase 2'h1: case (fourth) 2'h0: begin bank = 3'h0; row = {1'h1, addr[1:0]}; end 2'h1: begin bank = 3'h1; row = {1'h1, addr[1:0]}; end 2'h2: begin bank = 3'h4; row = {1'h0, addr[1:0]}; end 2'h3: begin bank = 3'h5; row = {1'h0, addr[1:0]}; end endcase 2'h2: case (fourth) 2'h0: begin bank = 3'h2; row = {1'h1, addr[1:0]}; end 2'h1: begin bank = 3'h3; row = {1'h1, addr[1:0]}; end 2'h2: begin bank = 3'h4; row = {1'h1, addr[1:0]}; end 2'h3: begin bank = 3'h5; row = {1'h1, addr[1:0]}; end endcase 2'h3: $stop; endcase endtask endmodule verilator-3.916/test_regress/t/t_trace_cat_renew_0000.out0000664000177100017500000000533013205574202023335 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 t $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.916/test_regress/t/t_display_mcd.pl0000775000177100017500000000124013205574202021644 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the 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( 'To stdout To stderr *-* 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.916/test_regress/t/t_unroll_signed.v0000664000177100017500000000616212473477707022101 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.916/test_regress/t/t_dpi_qw.v0000664000177100017500000000155512713417237020506 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.916/test_regress/t/t_math_concat64.v0000664000177100017500000001524612473477707021672 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.916/test_regress/t/t_inst_dtree_inlad.pl0000775000177100017500000000112012671044616022667 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_mem_iforder.pl0000775000177100017500000000072413151152521021646 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_var_rsvd_port.v0000664000177100017500000000062412473477707022124 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.916/test_regress/t/t_select_little.v0000664000177100017500000000421512473477707022066 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.916/test_regress/t/t_trace_cat.v0000664000177100017500000000046212671044616021144 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.916/test_regress/t/t_dpi_var.pl0000775000177100017500000000110212713417237021004 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_unoptflat_simple.v0000664000177100017500000000111512671044616022600 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.916/test_regress/t/t_vlt_warn.pl0000775000177100017500000000112112473477707021230 0ustar 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.916/test_regress/t/t_trace_public_func.pl0000775000177100017500000000137313151152521023026 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_clk_latchgate.v0000664000177100017500000001130712473477707022017 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.916/test_regress/t/t_array_query.v0000664000177100017500000000242013205574202021547 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 typedef reg [7:0] r_t; 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; if ($left(r_t)!=7 || $right(r_t)!=0 || $size(r_t)!=8 || $bits(r_t) !=8) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_flag_topmod2_bad.v0000664000177100017500000000071712473477707022420 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.916/test_regress/t/t_var_overwidth_bad.pl0000775000177100017500000000125513205574202023053 0ustar 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_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/t_var_overwidth_bad.cpp"], ); execute ( fails=>1, expect=> qr{%Error: unknown:0: Testbench C set input 'clk' to value that overflows what the signal's width can fit Aborting....*} ); ok(1); 1; verilator-3.916/test_regress/t/t_math_width.pl0000775000177100017500000000072212671044616021517 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_type2.v0000664000177100017500000000113013205574202021424 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. package tt_pkg; typedef enum logic [1:0] {L0, L1, L2, L3} test_t; endpackage module t (/*AUTOARG*/ // Outputs ob ); output [1:0] ob; import tt_pkg::*; test_t a; test_t b; assign a = L0; assign ob = b; tt_buf #(.T_t(test_t)) u_test (.i(a), .o(b)); endmodule module tt_buf #( parameter type T_t = logic [0:0] ) ( input T_t i, output T_t o ); assign o = i; endmodule verilator-3.916/test_regress/t/t_sys_readmem.pl0000775000177100017500000000071712473477707021716 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_packed_struct.pl0000775000177100017500000000075613205574202023400 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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 => ["--trace"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_packed_value_list.pl0000775000177100017500000000071712671044616024455 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_werror_bad2.pl0000775000177100017500000000135313205574202022562 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_flag_werror.v"); compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, verilator_flags=> [qw(-cc -Werror-WIDTH)], expect=> q{%Error-WIDTH: t/t_flag_werror.v:\d+: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS.s CONST '6'h2e' generates 6 bits. %Error: Exiting due to}, ) if $Self->{v3}; ok(1); 1; verilator-3.916/test_regress/t/t_embed1_c.cpp0000664000177100017500000000770613205574202021174 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.916/test_regress/t/t_struct_param.v0000664000177100017500000000302013205574202021705 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Matt Myers. `define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); package config_pkg; typedef struct packed { int UPPER0; struct packed { int USE_QUAD0; int USE_QUAD1; int USE_QUAD2; } mac; int UPPER2; } config_struct; function automatic config_struct static_config(int selector); config_struct return_config; return_config = '0; return_config.UPPER0 = 10; return_config.UPPER2 = 20; return_config.mac.USE_QUAD0 = 4; return_config.mac.USE_QUAD2 = 6; case (selector) 1: return_config.mac.USE_QUAD1 = 5; endcase return (return_config); endfunction endpackage : config_pkg module t; import config_pkg::*; localparam config_struct MY_CONFIG = static_config(1); struct_submodule #(.MY_CONFIG(MY_CONFIG)) a_submodule_I (); endmodule : t module struct_submodule import config_pkg::*; #(parameter config_struct MY_CONFIG = '0); initial begin `checkd(MY_CONFIG.UPPER0, 10); `checkd(MY_CONFIG.mac.USE_QUAD0, 4); `checkd(MY_CONFIG.mac.USE_QUAD1, 5); `checkd(MY_CONFIG.mac.USE_QUAD2, 6); `checkd(MY_CONFIG.UPPER2, 20); $write("*-* All Finished *-*\n"); $finish; end endmodule : struct_submodule verilator-3.916/test_regress/t/t_sys_plusargs_bad.v0000664000177100017500000000101613205574202022550 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; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_param_package.v0000664000177100017500000000064212671044616021772 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.916/test_regress/t/t_param_long.v0000664000177100017500000002132112473477707021346 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.916/test_regress/t/t_func_tie_bad.pl0000775000177100017500000000113412473477707022002 0ustar 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.916/test_regress/t/t_func_lib.v0000664000177100017500000000041012473477707021004 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.916/test_regress/t/t_vpi_memory.v0000664000177100017500000000247312671044616021411 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.916/test_regress/t/t_inst_overwide.v0000664000177100017500000000212312473477707022107 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.916/test_regress/t/t_mem_first.v0000664000177100017500000000602213205574202021173 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer _mode; initial _mode = 0; // verilator lint_off LITENDIAN reg [7:0] mem_narrow [0:31]; //surefire lint_off_line RD_WRT WRTWRT NBAJAM reg [77:0] mem_wide [1024:0]; //surefire lint_off_line RD_WRT WRTWRT NBAJAM reg [7:0] mem_dly_narrow [0:1]; //surefire lint_off_line RD_WRT WRTWRT NBAJAM reg [77:0] mem_dly_wide [1:0]; //surefire lint_off_line RD_WRT WRTWRT NBAJAM reg [34:0] vec_wide; // verilator lint_on LITENDIAN reg [31:0] wrd0 [15:0]; wire [3:0] sel = 4'h3; wire [31:0] selout = wrd0[sel]; // Must take LSBs into account in bit extract widths. wire [15:14] sixt = 2'b10; // surefire lint_off_line ASWCBB wire [16:14] sixt2 = 3'b110; // surefire lint_off_line ASWCBB wire [3:0] sixfrom = 13; wire [4:0] sixfrom2 = 16; wire sixtext = sixt[sixfrom]; wire sixtext2 = sixt2[sixfrom2]; // Non-power of 2 memory overwriting checks reg [2:0] np2_mem [5:0] /*verilator public*/; reg [2:0] np2_guard [7:6] /*verilator public*/; integer i; always @ (posedge clk) begin if (_mode!=0) begin wrd0[0] = 32'h1; // for (i=0; i<32; i=i+1) begin //surefire lint_off_line STMFOR mem_narrow[i] = i[7:0]; mem_wide[i] = {i[7:0],70'hfeed}; end // for (i=0; i<32; i=i+1) begin //surefire lint_off_line STMFOR if (mem_narrow[i] !== i[7:0]) $stop; if (mem_wide[i] !== {i[7:0],70'hfeed}) $stop; end // vec_wide <= 0; // np2_guard[6] = 0; np2_guard[7] = 0; // $write("selout %b %b %b\n", selout, sixtext, sixtext2); end if (_mode == 1) begin _mode <= 2; // i=0; mem_dly_narrow[0] <= ~i[7:0]; mem_dly_wide[0] <= {~i[7:0],70'hface}; i=1; mem_dly_narrow[i] <= ~i[7:0]; mem_dly_wide[i] <= {~i[7:0],70'hface}; // for (i=0; i<16; i=i+1) begin //surefire lint_off_line STMFOR // verilator lint_off width np2_mem[i] = i[2:0]; // surefire lint_off_line ASWSBB // verilator lint_on width if (np2_guard[6]!=0 || np2_guard[7]!=0) $stop; end // verilator lint_off SELRANGE if (np2_mem[6] !== np2_mem[7]) begin $write("Mem[6]!=Mem[7] during randomize...\n"); //$stop; // Random value, so this can happen end // verilator lint_on SELRANGE //if (np2_mem[8] !== np2_mem[9]) $stop; // Enhancement: Illegal indexes, make sure map to X's // vec_wide[32:31] <= 2'b11; vec_wide[34] <= 1'b1; $display("%x",vec_wide); end if (_mode == 2) begin _mode <= 3; // for (i=0; i<2; i=i+1) begin //surefire lint_off_line STMFOR if (mem_dly_narrow[i] !== ~i[7:0]) $stop; if (mem_dly_wide[i] !== {~i[7:0],70'hface}) $stop; end // //$write ("VW %x %x\n", vec_wide[34:32], vec_wide[31:0]); if (vec_wide != {4'b101_1,31'd0}) $stop; // $write("*-* All Finished *-*\n"); $finish; end _mode <= _mode + 1; end endmodule verilator-3.916/test_regress/t/t_alw_split.v0000664000177100017500000000734312473477707021235 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.916/test_regress/t/t_interface_array_nocolon.v0000664000177100017500000000320013205574202024066 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Functionally demonstrate an array of interfaces // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Mike Popoloski. interface foo_intf ( input x ); endinterface module foo_subm ( input x ); endmodule module t (); localparam N = 3; wire [2:0] X = 3'b110; // Should not cause LITENDIAN warning, as no harm in array selections. // verilator lint_on LITENDIAN foo_intf foo1 [N] (.x(1'b1)); foo_subm sub1 [N] (.x(1'b1)); // Will cause LITENDIAN warning? // verilator lint_off LITENDIAN foo_intf foos [N] (.x(X)); foo_intf fool [1:3] (.x(X)); foo_intf foom [3:1] (.x(X)); foo_subm subs [N] (.x(X)); foo_subm subl [1:3] (.x(X)); foo_subm subm [3:1] (.x(X)); initial begin // Check numbering with 0 first // NC has a bug here if (foos[0].x !== 1'b1) $stop; if (foos[1].x !== 1'b1) $stop; if (foos[2].x !== 1'b0) $stop; // if (fool[1].x !== 1'b1) $stop; if (fool[2].x !== 1'b1) $stop; if (fool[3].x !== 1'b0) $stop; // if (foom[1].x !== 1'b0) $stop; if (foom[2].x !== 1'b1) $stop; if (foom[3].x !== 1'b1) $stop; // if (subs[0].x !== 1'b1) $stop; if (subs[1].x !== 1'b1) $stop; if (subs[2].x !== 1'b0) $stop; // if (subl[1].x !== 1'b1) $stop; if (subl[2].x !== 1'b1) $stop; if (subl[3].x !== 1'b0) $stop; // if (subm[1].x !== 1'b0) $stop; if (subm[2].x !== 1'b1) $stop; if (subm[3].x !== 1'b1) $stop; // $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_typedef_signed.pl0000775000177100017500000000071712671044616022364 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_relinc.pl0000775000177100017500000000123513205574202021625 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 => ["--relative-includes", "--lint-only $Self->{t_dir}/t_flag_relinc_dir/chip/t_flag_relinc_sub.v"], make_top_shell => 0, make_main => 0, verilator_make_gcc => 0, ); ok(1); 1; verilator-3.916/test_regress/t/t_for_break.v0000664000177100017500000000716612473477707021174 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.916/test_regress/t/t_clk_condflop.pl0000775000177100017500000000072213151152521022011 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_inst_array_inl0.pl0000775000177100017500000000104013151152521022443 0ustar wsnyderwsnyder#!/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.916/test_regress/t/bootstrap.pl0000775000177100017500000000121712671044616021061 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.916/test_regress/t/t_func_sum.pl0000775000177100017500000000071712473477707021225 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface1_noinl.pl0000775000177100017500000000102213205574202022572 0ustar wsnyderwsnyder#!/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.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_return.pl0000775000177100017500000000071712473477707021740 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_select_index2.pl0000775000177100017500000000102412671044616022113 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_func_public_trace.pl0000775000177100017500000000124112473477707023046 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_gen_cond_const.pl0000775000177100017500000000100012671044616022337 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_var_const.pl0000775000177100017500000000071712473477707021404 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_implicit_port.v0000664000177100017500000000106212671044616023120 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic oe; read r (.clk(clk), .data( ( ( oe == 1'd001 ) && implicit_write ) ) ); set s (.clk(clk), .enable(implicit_write)); read u (.clk(clk), .data(~implicit_also)); endmodule module set ( input clk, output enable ); assign enable = 1'b0; endmodule module read ( input clk, input data ); endmodule verilator-3.916/test_regress/t/t_dpi_accessors.v0000664000177100017500000000453112671044616022041 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.916/test_regress/t/t_flag_language.pl0000775000177100017500000000033012473477707022151 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.916/test_regress/t/t_flag_ldflags.pl0000775000177100017500000000237113205574202021767 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); $Self->run(cmd=>["cd $Self->{obj_dir}" ." && c++ -c ../../t/t_flag_ldflags_a.cpp" ." && ar r t_flag_ldflags_a.a t_flag_ldflags_a.o" ." && ranlib t_flag_ldflags_a.a "], check_finished=>0); $Self->run(cmd=>["cd $Self->{obj_dir}" ." && c++ -fPIC -c ../../t/t_flag_ldflags_so.cpp" ." && c++ -shared -o t_flag_ldflags_so.so -lc t_flag_ldflags_so.o"], check_finished=>0); compile ( # Pass multiple -D's so we check quoting works properly v_flags2 => ["-CFLAGS '-DCFLAGS_FROM_CMDLINE -DCFLAGS2_FROM_CMDLINE' ", "t/t_flag_ldflags_c.cpp", "t_flag_ldflags_a.a", "t_flag_ldflags_so.so",], ); execute ( check_finished=>1, run_env => "LD_LIBRARY_PATH=$Self->{obj_dir}", ); ok(1); 1; verilator-3.916/test_regress/t/t_unopt_bound.v0000664000177100017500000000120613205574202021541 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.916/test_regress/t/t_alw_split.pl0000775000177100017500000000112612671044616021364 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_math_sign_extend.v0000664000177100017500000001102513205574202022525 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This test demonstrates an issue with sign extension. // Assigning to localparms larger than 32 bits broke in 3.862 // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Mike Thyer. module t (/*AUTOARG*/ // Inputs clk ); input clk; localparam [ 0:0] one1_lp = 1; localparam [ 1:0] one2_lp = 1; localparam [ 2:0] one3_lp = 1; localparam [ 3:0] one4_lp = 1; localparam [ 4:0] one5_lp = 1; localparam [ 5:0] one6_lp = 1; localparam [ 6:0] one7_lp = 1; localparam [ 7:0] one8_lp = 1; localparam [ 8:0] one9_lp = 1; localparam [ 9:0] one10_lp = 1; localparam [19:0] one20_lp = 1; localparam [29:0] one30_lp = 1; localparam [30:0] one31_lp = 1; localparam [31:0] one32_lp = 1; localparam [32:0] one33_lp = 1; localparam [33:0] one34_lp = 1; localparam [34:0] one35_lp = 1; localparam [35:0] one36_lp = 1; localparam [36:0] one37_lp = 1; localparam [37:0] one38_lp = 1; localparam [38:0] one39_lp = 1; localparam [39:0] one40_lp = 1; localparam [49:0] one50_lp = 1; localparam [59:0] one60_lp = 1; localparam [60:0] one61_lp = 1; localparam [61:0] one62_lp = 1; localparam [62:0] one63_lp = 1; localparam [63:0] one64_lp = 1; localparam [64:0] one65_lp = 1; localparam [65:0] one66_lp = 1; localparam [66:0] one67_lp = 1; localparam [67:0] one68_lp = 1; localparam [68:0] one69_lp = 1; localparam [69:0] one70_lp = 1; bit all_ok = 1; initial begin `ifdef TEST_VERBOSE $display("one1_lp : %x %d", one1_lp, one1_lp==1); $display("one2_lp : %x %d", one2_lp, one2_lp==1); $display("one3_lp : %x %d", one3_lp, one3_lp==1); $display("one4_lp : %x %d", one4_lp, one4_lp==1); $display("one5_lp : %x %d", one5_lp, one5_lp==1); $display("one6_lp : %x %d", one6_lp, one6_lp==1); $display("one7_lp : %x %d", one7_lp, one7_lp==1); $display("one8_lp : %x %d", one8_lp, one8_lp==1); $display("one9_lp : %x %d", one9_lp, one9_lp==1); $display("one10_lp: %x %d", one10_lp, one10_lp==1); $display("one20_lp: %x %d", one20_lp, one20_lp==1); $display("one30_lp: %x %d", one30_lp, one30_lp==1); $display("one31_lp: %x %d", one31_lp, one31_lp==1); $display("one32_lp: %x %d", one32_lp, one32_lp==1); $display("one33_lp: %x %d", one33_lp, one33_lp==1); $display("one34_lp: %x %d", one34_lp, one34_lp==1); $display("one35_lp: %x %d", one35_lp, one35_lp==1); $display("one36_lp: %x %d", one36_lp, one36_lp==1); $display("one37_lp: %x %d", one37_lp, one37_lp==1); $display("one38_lp: %x %d", one38_lp, one38_lp==1); $display("one39_lp: %x %d", one39_lp, one39_lp==1); $display("one40_lp: %x %d", one40_lp, one40_lp==1); $display("one50_lp: %x %d", one50_lp, one50_lp==1); $display("one60_lp: %x %d", one60_lp, one60_lp==1); $display("one61_lp: %x %d", one61_lp, one61_lp==1); $display("one62_lp: %x %d", one62_lp, one62_lp==1); $display("one63_lp: %x %d", one63_lp, one63_lp==1); $display("one64_lp: %x %d", one64_lp, one64_lp==1); $display("one65_lp: %x %d", one65_lp, one65_lp==1); $display("one66_lp: %x %d", one66_lp, one66_lp==1); $display("one67_lp: %x %d", one67_lp, one67_lp==1); $display("one68_lp: %x %d", one68_lp, one68_lp==1); $display("one69_lp: %x %d", one69_lp, one69_lp==1); $display("one70_lp: %x %d", one70_lp, one70_lp==1); `endif all_ok &= one1_lp == 1; all_ok &= one2_lp == 1; all_ok &= one3_lp == 1; all_ok &= one4_lp == 1; all_ok &= one5_lp == 1; all_ok &= one6_lp == 1; all_ok &= one7_lp == 1; all_ok &= one8_lp == 1; all_ok &= one9_lp == 1; all_ok &= one10_lp == 1; all_ok &= one20_lp == 1; all_ok &= one30_lp == 1; all_ok &= one31_lp == 1; all_ok &= one32_lp == 1; all_ok &= one33_lp == 1; all_ok &= one34_lp == 1; all_ok &= one35_lp == 1; all_ok &= one36_lp == 1; all_ok &= one37_lp == 1; all_ok &= one38_lp == 1; all_ok &= one39_lp == 1; all_ok &= one40_lp == 1; all_ok &= one50_lp == 1; all_ok &= one60_lp == 1; all_ok &= one61_lp == 1; all_ok &= one62_lp == 1; all_ok &= one63_lp == 1; all_ok &= one64_lp == 1; all_ok &= one65_lp == 1; all_ok &= one66_lp == 1; all_ok &= one67_lp == 1; all_ok &= one68_lp == 1; all_ok &= one69_lp == 1; all_ok &= one70_lp == 1; if (!all_ok) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_trace_timescale.cpp0000664000177100017500000000215513205574202022652 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 VM_PREFIX_INCLUDE unsigned long long main_time = 0; double sc_time_stamp() { return ((double)main_time) / VL_TIME_MULTIPLIER; } 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; tfp->set_time_resolution("1ps"); tfp->set_time_unit("1ns"); top->trace(tfp,99); tfp->open("obj_dir/t_trace_timescale/t_trace_timescale.vcd"); top->clk = 0; while (main_time < 190*VL_TIME_MULTIPLIER) { top->clk = !top->clk; top->eval(); tfp->dump((unsigned int)(main_time)); // Advance by 0.5 time units, to make sure our fractional // time is working correctly main_time += VL_TIME_MULTIPLIER/2; } tfp->close(); top->final(); printf ("*-* All Finished *-*\n"); return 0; } verilator-3.916/test_regress/t/t_langext_2.v0000664000177100017500000000216312671044616021102 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.916/test_regress/t/t_optm_if_array.v0000664000177100017500000000172413205574202022045 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs dinitout, // Inputs clk, rstn ); input clk; input rstn; output [31:0] dinitout; wire zero; assign zero = 1'd0; reg [31:0] dinit [0:1]; wire [31:0] dinitout = dinit[0] | dinit[1]; reg rstn_r; // .pl file checks that this signal gets optimized away always @(posedge clk) begin rstn_r <= rstn; end always @(posedge clk) begin if ((rstn_r == 0)) begin // Will optimize away dinit[0] <= '0; end else begin dinit[0] <= {31'd0, zero}; end end always @(posedge clk) begin if ((rstn_r == 0)) begin // Will optimize away dinit[1] <= 1234; end else begin dinit[1] <= 1234; end end initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_sys_readmem_h.mem0000664000177100017500000000075512473477707022367 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.916/test_regress/t/t_func_paramed.pl0000775000177100017500000000071712473477707022032 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_mnpipe.pl0000775000177100017500000000072413151152521021703 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_func_v.v0000664000177100017500000000120212671044616020470 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.916/test_regress/t/t_func_named.v0000664000177100017500000000153412671044616021317 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.916/test_regress/t/t_vlcov_rewrite.pl0000775000177100017500000000155713205574202022261 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); foreach my $basename ("t_vlcov_data_a.dat", "t_vlcov_data_b.dat", "t_vlcov_data_c.dat", "t_vlcov_data_d.dat", ) { $Self->run(cmd=>["../bin/verilator_coverage", "t/${basename}", "--write", "$Self->{obj_dir}/${basename}" ], tee=>0, ); ok(files_identical("$Self->{obj_dir}/${basename}", "t/${basename}")); } 1; verilator-3.916/test_regress/t/t_flag_xinitial_0.pl0000775000177100017500000000111413205574202022405 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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 0"], ); execute ( check_finished=>1, ); file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/VL_RAND_RESET/); ok(1); 1; verilator-3.916/test_regress/t/t_param_ceil.v0000664000177100017500000000175412473477707021333 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.916/test_regress/t/t_extend.pl0000775000177100017500000000072113151152521020642 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_assert_synth_parallel.pl0000775000177100017500000000133013205574202023756 0ustar wsnyderwsnyder#!/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.t: synthesis parallel_case' ); ok(1); 1; verilator-3.916/test_regress/t/t_wire_types.v0000664000177100017500000000313112671044616021405 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.916/test_regress/t/t_mem_slot.pl0000775000177100017500000000116012473477707021216 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_tri_eqcase.v0000664000177100017500000000705012671044616021336 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.916/test_regress/t/t_func_flip.pl0000775000177100017500000000071712473477707021353 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vpi_sc.pl0000775000177100017500000000115413205574202020643 0ustar 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 ( # Must not make shell/main or hides bug make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe --vpi --sc $Self->{t_dir}/t_vpi_sc.cpp"], ); execute ( check_finished=>1 ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_block_redecl_bad.pl0000775000177100017500000000144212671044616023633 0ustar 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.916/test_regress/t/t_param_func.pl0000775000177100017500000000065113205574202021474 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_interface_typo_bad.v0000664000177100017500000000075513205574202023036 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Todd Strader. //bug1097 interface foo_intf; endinterface module submod ( foo_intf foo ); endmodule module t (/*AUTOARG*/); // Intentional typo, compiler should point this out, or that fo_intf does // not match foo_intf on the submod port map fo_intf the_foo; submod submod_inst ( .foo (the_foo) ); endmodule verilator-3.916/test_regress/t/t_tri_array.pl0000775000177100017500000000114612671044616021364 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # When fix, update ifdefs in t_sv_cpu files; search for t_tri_array $Self->{vlt} and $Self->unsupported("Verilator unsupported, tristate arrays"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vlcov_rank.out0000664000177100017500000000041413205574202021713 0ustar wsnyderwsnyderTests: Covered, Rank, RankPts, Filename 2, 2, 1, "t/t_vlcov_data_a.dat" 3, 1, 3, "t/t_vlcov_data_b.dat" 1, 3, 1, "t/t_vlcov_data_c.dat" 1, 0, 0, "t/t_vlcov_data_d.dat" verilator-3.916/test_regress/t/t_math_sign_extend.pl0000775000177100017500000000072213205574202022700 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_enum_type_pins.pl0000775000177100017500000000106013205574202022412 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_clk_gen.v0000664000177100017500000000446212473477707020640 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.916/test_regress/t/t_case_onehot.pl0000775000177100017500000000071712473477707021675 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_multi_ref_bad.pl0000775000177100017500000000227412671044616023025 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_named.v0000664000177100017500000000213712473477707021477 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.916/test_regress/t/t_clk_condflop_nord.pl0000775000177100017500000000101113151152521023023 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_math_pow2.v0000664000177100017500000000244012671044616021115 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Aggregate outputs into a single result vector //wire [31:0] pow32b = {24'h0,crc[15:8]}**crc[7:0]; // Overflows wire [3:0] pow4b = crc[7:4]**crc[3:0]; wire [63:0] result = {60'h0, pow4b}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h1fec4b2b71cf8024 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_final.pl0000775000177100017500000000072212671044616020460 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_signed2.pl0000775000177100017500000000071712473477707021752 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_unpacked.v0000664000177100017500000000077412671044616022423 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.916/test_regress/t/t_gen_if.v0000664000177100017500000000212712473477707020461 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.916/test_regress/t/t_mem_slice_conc_bad.v0000664000177100017500000000466013205574202022761 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.916/test_regress/t/t_bitsel_struct3.v0000664000177100017500000000264313205574202022164 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // A test case for struct signal bit selection. // // This test is to check that bit selection of multi-dimensional signal inside // of a packed struct works. Currently +: and -: blow up with packed structs. // // This file ONLY is placed into the Public Domain, for any use, without // warranty, 2013 by Jie Xu. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t(/*AUTOARG*/ // Inputs clk ); input clk; typedef struct packed { logic [15:0] channel; logic [15:0] others; } buss_t; buss_t b; reg [7:0] a; reg [7:0] c; reg [7:0] d; union packed { logic [31:0] [7:0] idx; struct packed { logic [15:0] z, y, x; logic [25:0] [7:0] r; } nam; } gpr; reg [14:0] gpr_a; initial begin b = {16'h8765,16'h4321}; a = b[19:12]; // This works c = b[8+:8]; // This fails d = b[11-:8]; // This fails `checkh(a, 8'h54); `checkh(c, 8'h43); `checkh(d, 8'h32); gpr = 256'h12346789_abcdef12_3456789a_bcdef123_456789ab_cdef1234_56789abc_def12345; `checkh (gpr[255:255-14], 15'h091a); gpr_a = gpr.nam.z[15:1]; `checkh (gpr_a, 15'h091a); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_enum_overlap_bad.v0000664000177100017500000000043212473477707022531 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.916/test_regress/t/t_select_negative.v0000664000177100017500000000356112473477707022376 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.916/test_regress/t/t_enum_type_methods.v0000664000177100017500000000450713205574202022744 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); `define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t (/*AUTOARG*/ // Inputs clk ); input clk; typedef enum [3:0] { E01 = 1, E03 = 3, E04 = 4 } my_t; integer cyc=0; my_t e; int arrayfits [e.num]; // Check can use as constant string all; // Check constification initial begin e = E03; `checkh(e.first, E01); `checkh(e.last, E04); `checkh(e.last(), E04); `checkh(e.next, E04); `checkh(e.next(), E04); `checkh(e.next(1), E04); //Unsup: `checkh(e.next(2), E01); `checkh(e.prev, E01); `checkh(e.prev(1), E01); //Unsup: `checkh(e.prev(2), E04); `checkh(e.num, 3); `checks(e.name, "E03"); // all = ""; for (my_t e = e.first; e != e.last; e = e.next) begin all = {all, e.name}; end e = e.last; all = {all, e.name}; `checks(all, "E01E03E04"); end // Check runtime always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin // Setup e <= E01; end else if (cyc==1) begin `checks(e.name, "E01"); `checkh(e.next, E03); `checkh(e.next(1), E03); //Unsup: `checkh(e.next(2), E04); `checkh(e.prev, E04); `checkh(e.prev(1), E04); //Unsup: `checkh(e.prev(2), E03); e <= E03; end else if (cyc==2) begin `checks(e.name, "E03"); `checkh(e.next, E04); `checkh(e.next(1), E04); //Unsup: `checkh(e.next(2), E01); `checkh(e.prev, E01); `checkh(e.prev(1), E01); //Unsup: `checkh(e.prev(2), E04); e <= E04; end else if (cyc==3) begin `checks(e.name, "E04"); `checkh(e.next, E01); `checkh(e.next(1), E01); //Unsup: `checkh(e.next(2), E03); `checkh(e.prev, E03); `checkh(e.prev(1), E03); //Unsup: `checkh(e.prev(2), E01); e <= E01; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_struct_portsel.pl0000775000177100017500000000072212671044616022463 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_array.pl0000775000177100017500000000072212671044616022111 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_svl2.pl0000775000177100017500000000071412473477707021302 0ustar 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.916/test_regress/t/t_param.pl0000775000177100017500000000071712473477707020506 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_huge.v0000664000177100017500000001577012473477707021165 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.916/test_regress/t/t_inst_sv.pl0000775000177100017500000000071712473477707021073 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_display_l.pl0000775000177100017500000000072213205574202021340 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_concat_large_bad.pl0000775000177100017500000000121013205574202022600 0ustar 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 ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Warning-WIDTHCONCAT: t/t_concat_large_bad.v:\d+: More than a 8k bit replication is probably wrong: 32768 %Warning-WIDTHCONCAT: Use .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_hierarchy_identifier.v0000664000177100017500000000206212671044616023375 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter SIZE = 8; integer cnt = 0; logic [SIZE-1:0] vld_for; logic vld_if = 1'b0; logic vld_else = 1'b0; genvar i; // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if (cnt==SIZE) begin : \0escaped___name $write("*-* All Finished *-*\n"); $finish; end : \0escaped___name generate for (i=0; i0) begin : generate_if_if always @ (posedge clk) vld_if <= 1'b1; end : generate_if_if else begin : generate_if_else always @ (posedge clk) vld_else <= 1'b1; end : generate_if_else endgenerate endmodule : t verilator-3.916/test_regress/t/t_tri_select.cpp0000664000177100017500000000276413205574202021671 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.916/test_regress/t/t_mem.pl0000775000177100017500000000071712473477707020164 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_cover_sva_notflat.pl0000775000177100017500000000147713205574202023106 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ['--assert --cc --coverage-user'], ); execute ( check_finished=>1, ); #if ($Self->{nc}) ... # See t_assert_cover.pl for NC version # Allow old Perl format dump, or new binary dump # Check that the hierarchy doesn't include __PVT__ # Otherwise our coverage reports would look really ugly file_grep ($Self->{coverage_filename}, qr/(top\.t\.sub.*.cyc_eq_5)/) if $Self->{vlt}; ok(1); 1; verilator-3.916/test_regress/t/t_for_count.pl0000775000177100017500000000071712473477707021404 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 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.916/test_regress/t/t_gen_div0.pl0000775000177100017500000000071712671044616021066 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_topmod2_bad.pl0000775000177100017500000000131512473477707022564 0ustar 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.916/test_regress/t/TestSimulator.h0000664000177100017500000000514613205574202021472 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2013-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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" #include 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 string buf; ostringstream os; os< ["--lint-only --bbox-unsup"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.916/test_regress/t/t_dpi_2exp_bad.pl0000775000177100017500000000114712473477707021724 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_trace_timescale.pl0000775000177100017500000000142313205574202022503 0ustar wsnyderwsnyder#!/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_timescale.cpp"], make_flags => 'CPPFLAGS_ADD=-DVL_TIME_MULTIPLIER=1000', ); execute ( check_finished=>1, ); vcd_identical ("$Self->{obj_dir}/$Self->{name}.vcd", "t/$Self->{name}.out"); ok(1); 1; verilator-3.916/test_regress/t/t_clk_concat4.v0000664000177100017500000000343313205574202021375 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // module some_module ( input wrclk ); logic [ 1 : 0 ] some_state; logic [1:0] some_other_state; always @(posedge wrclk) begin case (some_state) 2'b11: if (some_other_state == 0) some_state <= 2'b00; default: $display ("This is a display statement"); endcase if (wrclk) some_other_state <= 0; end endmodule `define BROKEN module t1( input [3:0] i_clks, input i_clk0, input i_clk1 ); generate genvar i; for (i = 0; i < 2; i = i + 1) begin: a_generate_block some_module some_module ( `ifdef BROKEN .wrclk (i_clks[3]) `else .wrclk (i_clk1) `endif ); end endgenerate endmodule module t2( input [2:0] i_clks, input i_clk0, input i_clk1, input i_clk2, input i_data ); logic [3:0] the_clks; logic data_q; assign the_clks[3] = i_clk1; assign the_clks[2] = i_clk2; assign the_clks[1] = i_clk1; assign the_clks[0] = i_clk0; always @(posedge i_clk0) begin data_q <= i_data; end t1 t1 ( .i_clks (the_clks), .i_clk0 (i_clk0), .i_clk1 (i_clk1) ); endmodule module t( input clk0 /*verilator clocker*/, input clk1 /*verilator clocker*/, input clk2 /*verilator clocker*/, input data_in ); logic [2:0] clks; assign clks = {1'b0, clk1, clk0}; t2 t2 ( .i_clks (clks), .i_clk0 (clk0), .i_clk1 (clk1), .i_clk2 (clk2), .i_data (data_in) ); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_cover_sva_notflat.v0000664000177100017500000000215013205574202022722 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.916/test_regress/t/t_preproc_persist.pl0000775000177100017500000000161413205574202022604 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/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 ( # Override default flags v_flags => [''], v_other_filenames => ["t_preproc_persist2.v"], verilator_flags => ["-E -P +incdir+t"], verilator_flags2 => ['',], verilator_flags3 => ['',], verilator_make_gcc => 0, make_top_shell => 0, stdout_filename => $stdout_filename, ); ok(files_identical($stdout_filename, "t/$Self->{name}.out")); 1; verilator-3.916/test_regress/t/t_inst_mism.v0000664000177100017500000000135412671044616021222 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.916/test_regress/t/t_dpi_display_c.cpp0000664000177100017500000000235513205574202022333 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.916/test_regress/t/t_select_param.pl0000775000177100017500000000072012473477707022037 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mod_dup_ign.v0000664000177100017500000000065412473477707021521 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.916/test_regress/t/t_lint_colonplus_bad.pl0000775000177100017500000000141213205574202023227 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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, fails => 1, expect=> q{%Warning-COLONPLUS: t/t_lint_colonplus_bad.v:\d+: Perhaps instead of ':\+' the intent was '\+:'\? %Warning-COLONPLUS: Use .* .*%Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_anon.v0000664000177100017500000000103112671044616021547 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // Anonymous struct packed { logic [31:0] val1; logic [31:0] val2; } struct1; struct packed { logic [31:0] val3; logic [31:0] val4; } struct2; module t ( output [63:0] s1, output [63:0] s2 ); initial struct1 = 64'h123456789_abcdef0; always_comb s1 = struct1; initial struct2 = 64'h123456789_abcdef0; always_comb s2 = struct2; endmodule verilator-3.916/test_regress/t/t_interface_gen3.pl0000775000177100017500000000072713151152521022235 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_pp_dupdef.pl0000775000177100017500000000101412473477707021343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_math_pow3.pl0000775000177100017500000000071412671044616021271 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_down.pl0000775000177100017500000000072713151152521022350 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_trace_complex.pl0000775000177100017500000000216413151152521022203 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_debug_sigsegv_bad.pl0000775000177100017500000000134412671044616023013 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_math_pick.v0000664000177100017500000000427112671044616021160 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.916/test_regress/t/t_math_signed4.v0000664000177100017500000001035512671044616021567 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0) `define checkf(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0) module t (/*AUTOARG*/); bit fail; localparam signed [3:0] bug737_p1 = 4'b1000; wire [3:0] bug737_a = 4'b1010; reg [5:0] bug737_y; reg signed [3:0] w4_s; reg signed [4:0] w5_s; reg [3:0] w4_u; reg [4:0] w5_u; reg signed [8:0] w9_s; real r; initial begin // verilator lint_off WIDTH bug737_y = bug737_a + (bug737_p1 + 4'sb0); `checkh(bug737_y, 6'b010010); //bug737 // 6u +[6u] 4s +[6s] 6s bug737_y = 6'b001010 + (4'sb1000 + 6'sb0); `checkh(bug737_y, 6'b010010); //bug737, getx 000010 // 6u +[6u] 4s +[6s] 6s bug737_y = 6'b001010 + (4'b1000 + 6'sb0); `checkh(bug737_y, 6'b010010); //ok bug737_y = 6'b001010 + (6'sb111000 + 6'sb0); `checkh(bug737_y, 6'b000010); //ok // v--- sign extends to 6-bits bug737_y = 6'sb001010 + (4'sb1000 + 6'sb0); `checkh(bug737_y, 6'b000010); //ok // From t_math_signed_3 w4_s = 4'sb1111 - 1'b1; `checkh(w4_s,33'he); w4_s = 4'sb1111 - 5'b00001; `checkh(w4_s,33'he); w4_s = 4'sb1111 - 1'sb1; `checkh(w4_s,4'h0); w5_s = 4'sb1111 - 1'sb1; `checkh(w5_s,4'h0); w4_s = 4'sb1111 - 4'sb1111; `checkh(w4_s,4'h0); w5_s = 4'sb1111 - 4'sb1111; `checkh(w5_s,5'h0); // The assign LHS being signed or unsigned does not matter per IEEE // The upper add being signed DOES matter propagating to lower w4_s = 4'sb1111 - (1'sb1 + 4'b0); //1'sb1 not extended as unsigned add `checkh(w4_s,4'he); w4_s = 4'sb1111 - (1'sb1 + 4'sb0); //1'sb1 does sign extend `checkh(w4_s,4'h0); w4_s = 4'b1111 - (1'sb1 + 4'sb0); //1'sb1 does *NOT* sign extend `checkh(w4_s,4'he); // BUG, Verilator says 'h0 w5_u = 4'b1111 + 4'b0001; // Extends to 5 bits due to LHS `checkh(w5_u, 5'b10000); w4_u = 4'b1111 + 4'b0001; // Normal case `checkh(w4_u, 4'b0000); // Another example of promotion, the add is 4 bits wide w4_u = 3'b111 + 3'b010; `checkh(w4_u, 4'b1001); // w4_u = 3'sb111 * 3'sb001; // Signed output, LHS does not matter `checkh(w4_u, 4'sb1111); w4_s = 3'sb111 * 3'sb001; // Signed output `checkh(w4_s, 4'sb1111); w4_s = 3'b111 * 3'sb001; // Unsigned output `checkh(w4_s, 4'b0111); // Conditionals get width from parent; are assignment-like w4_u = 1'b0 ? 4'b0 : (2'b01+2'b11); `checkh(w4_u, 4'b0100); w4_u = 1'b0 ? 4'b0 : (6'b001000+6'b001000); `checkh(w4_u, 4'b0000); // If RHS is larger, that larger size is used w4_u = 5'b10000 / 5'b00100; `checkh(w4_u, 4'b0100); // bug754 w5_u = 4'sb0010 << -2'sd1; // << 3 `ifdef VCS `checkh(w5_u, 5'b00000); // VCS E-2014.03 bug `else `checkh(w5_u, 5'b10000); // VCS E-2014.03 bug `endif w5_u = 4'sb1000 << 0; // Sign extends `checkh(w5_u, 5'b11000); // Reals do not propagate to children r = 1.0 + ( 1 + (1 / 2)); `checkf(r, 2.0); // Self determined sign extension r = $itor(3'sb111); `checkf(r, -1.0); // If any part of case is real, all is real case (22) 22.0: ; 22.1: $stop; default: $stop; endcase // bug759 w5_u = { -4'sd7 }; `checkh(w5_u, 5'b01001); w5_u = {2{ -2'sd1 }}; `checkh(w5_u, 5'b01111); // Don't break concats.... w5_u = {{0{1'b1}}, -4'sd7 }; `checkh(w5_u, 5'b01001); w9_s = { -4'sd7, -4'sd7 }; `checkh(w9_s, 9'b010011001); {w5_u, {w4_u}} = 9'b10101_1100; `checkh(w5_u, 5'b10101); `checkh(w4_u, 4'b1100); {w4_u} = 4'b1011; `checkh(w4_u, 4'b1011); if (fail) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_clk_concat5.pl0000775000177100017500000000072713205574202021552 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_gen_for_shuffle.pl0000775000177100017500000000071712473477707022541 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_pull2_bad.v0000664000177100017500000000045513205574202021734 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.916/test_regress/t/t_alw_combdly.pl0000775000177100017500000000071712473477707021702 0ustar 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.916/test_regress/t/t_typedef_port.v0000664000177100017500000000437312473477707021743 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.916/test_regress/t/t_math_signed7.v0000664000177100017500000000202513205574202021556 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Iztok Jeras. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) module t (/*AUTOARG*/ // Inputs clk ); input clk; reg alu_ltu, alu_lts; logic [3:0] in_op1; logic [3:0] in_op2; reg aaa_ltu, aaa_lts; always @(posedge clk) begin in_op1 = 4'sb1110; in_op2 = 4'b0010; aaa_ltu = in_op1 < in_op2; // bug999 aaa_lts = $signed(in_op1) < $signed(in_op2); `checkh (aaa_ltu, 1'b0); `checkh (aaa_lts, 1'b1); end generate if (1) begin always @(posedge clk) begin in_op1 = 4'sb1110; in_op2 = 4'b0010; alu_ltu = in_op1 < in_op2; // bug999 alu_lts = $signed(in_op1) < $signed(in_op2); `checkh (alu_ltu, 1'b0); `checkh (alu_lts, 1'b1); $write("*-* All Finished *-*\n"); $finish; end end endgenerate endmodule verilator-3.916/test_regress/t/t_tri_gate_bufif0.pl0000775000177100017500000000134313151152521022405 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_unopt_converge.v0000664000177100017500000000062612473477707022271 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.916/test_regress/t/t_var_bad_sameas.v0000664000177100017500000000112412473477707022155 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.916/test_regress/t/t_inside_wild.pl0000775000177100017500000000072212671044616021661 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_blksync_bad.v0000664000177100017500000000150413205574202022507 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.916/test_regress/t/t_struct_unpacked_bad.pl0000775000177100017500000000112612671044616023372 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_tri_ifbegin.pl0000775000177100017500000000067212671044616021654 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_var_in_assign_bad.v0000664000177100017500000000065712473477707022670 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.916/test_regress/t/t_case_inside.pl0000775000177100017500000000072212671044616021635 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_clk_dsp.v0000664000177100017500000000723512473477707020656 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.916/test_regress/t/t_inst_first.v0000664000177100017500000000674212671044616021412 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk, fastclk ); input clk; input fastclk; genvar unused; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire o_com; // From b of t_inst_first_b.v wire o_seq_d1r; // From b of t_inst_first_b.v // End of automatics integer _mode; // initial _mode=0 reg na,nb,nc,nd,ne; wire ma,mb,mc,md,me; wire da,db,dc,dd,de; reg [7:0] wa,wb,wc,wd,we; wire [7:0] qa,qb,qc,qd,qe; wire [5:0] ra; wire [4:0] rb; wire [29:0] rc; wire [63:0] rd; reg [5:0] sa; reg [4:0] sb; reg [29:0] sc; reg [63:0] sd; reg _guard1; initial _guard1=0; wire [104:0] r_wide = {ra,rb,rc,rd}; reg _guard2; initial _guard2=0; wire [98:0] r_wide0 = {rb,rc,rd}; reg _guard3; initial _guard3=0; wire [93:0] r_wide1 = {rc,rd}; reg _guard4; initial _guard4=0; wire [63:0] r_wide2 = {rd}; reg _guard5; initial _guard5=0; wire [168:0] r_wide3 = {ra,rb,rc,rd,rd}; reg [127:0] _guard6; initial _guard6=0; t_inst_first_a a ( .clk (clk), // Outputs .o_w5 ({ma,mb,mc,md,me}), .o_w5_d1r ({da,db,dc,dd,de}), .o_w40 ({qa,qb,qc,qd,qe}), .o_w104 ({ra,rb,rc,rd}), // Inputs .i_w5 ({na,nb,nc,nd,ne}), .i_w40 ({wa,wb,wc,wd,we}), .i_w104 ({sa,sb,sc,sd}) ); reg i_seq; reg i_com; wire [15:14] o2_comhigh; t_inst_first_b b ( .o2_com (o2_comhigh), .i2_com ({i_com,~i_com}), .wide_for_trace (128'h1234_5678_aaaa_bbbb_cccc_dddd), .wide_for_trace_2 (_guard6 + 128'h1234_5678_aaaa_bbbb_cccc_dddd), /*AUTOINST*/ // Outputs .o_seq_d1r (o_seq_d1r), .o_com (o_com), // Inputs .clk (clk), .i_seq (i_seq), .i_com (i_com)); // surefire lint_off STMINI initial _mode = 0; always @ (posedge fastclk) begin if (_mode==1) begin if (o_com !== ~i_com) $stop; if (o2_comhigh !== {~i_com,i_com}) $stop; end end always @ (posedge clk) begin //$write("[%0t] t_inst: MODE = %0x NA=%x MA=%x DA=%x\n", $time, _mode, // {na,nb,nc,nd,ne}, {ma,mb,mc,md,me}, {da,db,dc,dd,de}); $write("[%0t] t_inst: MODE = %0x IS=%x OS=%x\n", $time, _mode, i_seq, o_seq_d1r); if (_mode==0) begin $write("[%0t] t_inst: Running\n", $time); _mode<=1; {na,nb,nc,nd,ne} <= 5'b10110; {wa,wb,wc,wd,we} <= {8'ha, 8'hb, 8'hc, 8'hd, 8'he}; {sa,sb,sc,sd} <= {6'hf, 5'h3, 30'h12345, 32'h0abc_abcd, 32'h7654_3210}; // i_seq <= 1'b1; i_com <= 1'b1; end else if (_mode==1) begin _mode<=2; if ({ma,mb,mc,md,me} !== 5'b10110) $stop; if ({qa,qb,qc,qd,qe} !== {8'ha,8'hb,8'hc,8'hd,8'he}) $stop; if ({sa,sb,sc,sd} !== {6'hf, 5'h3, 30'h12345, 32'h0abc_abcd, 32'h7654_3210}) $stop; end else if (_mode==2) begin _mode<=3; if ({da,db,dc,dd,de} !== 5'b10110) $stop; if (o_seq_d1r !== ~i_seq) $stop; // $write("*-* All Finished *-*\n"); $finish; end if (|{_guard1,_guard2,_guard3,_guard4,_guard5,_guard6}) begin $write("Guard error %x %x %x %x %x\n",_guard1,_guard2,_guard3,_guard4,_guard5); $stop; end end // surefire lint_off UDDSDN wire _unused_ok = |{1'b1, r_wide0, r_wide1,r_wide2,r_wide3,r_wide}; endmodule verilator-3.916/test_regress/t/t_math_trig.v0000664000177100017500000001244113205574202021166 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2011 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. module t (/*AUTOARG*/ // Inputs clk ); input clk; real r, r2; integer cyc=0; task check(integer line, real got, real ex); if (got != ex) begin if ((got - ex) > 0.000001) begin $display("%%Error: Line %0d: Bad result, got=%0.99g expect=%0.99g",line,got,ex); $stop; end end endtask initial begin // Check constant propagation // Note $abs is not defined in SystemVerilog (as of 2012) check(`__LINE__, $ceil(-1.2), -1); check(`__LINE__, $ceil(1.2), 2); check(`__LINE__, $exp(1.2), 3.3201169227365472380597566370852291584014892578125); check(`__LINE__, $exp(0.0), 1); check(`__LINE__, $exp(-1.2), 0.301194211912202136627314530414878390729427337646484375); check(`__LINE__, $floor(-1.2), -2); check(`__LINE__, $floor(1.2), 1); check(`__LINE__, $ln(1.2), 0.1823215567939545922460098381634452380239963531494140625); //check(`__LINE__, $ln(0), 0); // Bad value //check(`__LINE__, $ln(-1.2), 0); // Bad value check(`__LINE__, $log10(1.2), 0.07918124604762481755226843915806966833770275115966796875); //check(`__LINE__, $log10(0), 0); // Bad value //check(`__LINE__, $log10(-1.2), 0); check(`__LINE__, $pow(2.3,1.2), 2.71689843249914897427288451581262052059173583984375); check(`__LINE__, $pow(2.3,-1.2), 0.368066758785732861536388327294844202697277069091796875); //check(`__LINE__, $pow(-2.3,1.2),0); // Bad value check(`__LINE__, $sqrt(1.2), 1.095445115010332148841598609578795731067657470703125); //check(`__LINE__, $sqrt(-1.2), 0); // Bad value check(`__LINE__, ((1.5)**(1.25)), 1.660023); `ifndef VERILATOR check(`__LINE__, $acos (0.2), 1.369438406); // Arg1 is -1..1 check(`__LINE__, $acosh(1.2), 0.622362503); check(`__LINE__, $asin (0.2), 0.201357920); // Arg1 is -1..1 check(`__LINE__, $asinh(1.2), 1.015973134); check(`__LINE__, $atan (0.2), 0.197395559); check(`__LINE__, $atan2(0.2,2.3), 0.086738338); // Arg1 is -1..1 check(`__LINE__, $atanh(0.2), 0.202732554); // Arg1 is -1..1 check(`__LINE__, $cos (1.2), 0.362357754); check(`__LINE__, $cosh (1.2), 1.810655567); check(`__LINE__, $hypot(1.2,2.3), 2.594224354); check(`__LINE__, $sin (1.2), 0.932039085); check(`__LINE__, $sinh (1.2), 1.509461355); check(`__LINE__, $tan (1.2), 2.572151622); check(`__LINE__, $tanh (1.2), 0.833654607); `endif end real sum_ceil; real sum_exp; real sum_floor; real sum_ln; real sum_log10; real sum_pow1; real sum_pow2; real sum_sqrt; real sum_acos; real sum_acosh; real sum_asin; real sum_asinh; real sum_atan; real sum_atan2; real sum_atanh; real sum_cos ; real sum_cosh; real sum_hypot; real sum_sin; real sum_sinh; real sum_tan; real sum_tanh; // Test loop always @ (posedge clk) begin r = $itor(cyc)/10.0 - 5.0; // Crosses 0 `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d r=%g s_ln=%0.12g\n",$time, cyc, r, sum_ln); `endif cyc <= cyc + 1; if (cyc==0) begin end else if (cyc<90) begin // Setup sum_ceil += 1.0+$ceil(r); sum_exp += 1.0+$exp(r); sum_floor += 1.0+$floor(r); if (r > 0.0) sum_ln += 1.0+$ln(r); if (r > 0.0) sum_log10 += 1.0+$log10(r); // Pow requires if arg1<0 then arg1 integral sum_pow1 += 1.0+$pow(2.3,r); if (r >= 0.0) sum_pow2 += 1.0+$pow(r,2.3); if (r >= 0.0) sum_sqrt += 1.0+$sqrt(r); `ifndef VERILATOR if (r>=-1.0 && r<=1.0) sum_acos += 1.0+$acos (r); if (r>=1.0) sum_acosh += 1.0+$acosh(r); if (r>=-1.0 && r<=1.0) sum_asin += 1.0+$asin (r); sum_asinh += 1.0+$asinh(r); sum_atan += 1.0+$atan (r); if (r>=-1.0 && r<=1.0) sum_atan2 += 1.0+$atan2(r,2.3); if (r>=-1.0 && r<=1.0) sum_atanh += 1.0+$atanh(r); sum_cos += 1.0+$cos (r); sum_cosh += 1.0+$cosh (r); sum_hypot += 1.0+$hypot(r,2.3); sum_sin += 1.0+$sin (r); sum_sinh += 1.0+$sinh (r); sum_tan += 1.0+$tan (r); sum_tanh += 1.0+$tanh (r); `endif end else if (cyc==99) begin check (`__LINE__, sum_ceil, 85); check (`__LINE__, sum_exp, 608.06652950); check (`__LINE__, sum_floor, 4); check (`__LINE__, sum_ln, 55.830941633); check (`__LINE__, sum_log10, 46.309585076); check (`__LINE__, sum_pow1, 410.98798177); check (`__LINE__, sum_pow2, 321.94765689); check (`__LINE__, sum_sqrt, 92.269677253); `ifndef VERILATOR check (`__LINE__, sum_acos, 53.986722862); check (`__LINE__, sum_acosh, 72.685208498); check (`__LINE__, sum_asin, 21); check (`__LINE__, sum_asinh, 67.034973416); check (`__LINE__, sum_atan, 75.511045389); check (`__LINE__, sum_atan2, 21); check (`__LINE__, sum_atanh, 0); check (`__LINE__, sum_cos, 72.042023124); check (`__LINE__, sum_cosh, 1054.0178222); check (`__LINE__, sum_hypot, 388.92858406); check (`__LINE__, sum_sin, 98.264184989); check (`__LINE__, sum_sinh, 0); check (`__LINE__, sum_tan, 1.7007946043); check (`__LINE__, sum_tanh, 79.003199681); `endif $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_preproc.out0000664000177100017500000002750613205574202021234 0ustar wsnyderwsnyder`line 1 "t/t_preproc.v" 1 `line 5 "t/t_preproc.v" 0 `line 7 "t/t_preproc.v" 0 `line 1 "t/t_preproc_inc2.vh" 1 `line 2 "t/t_preproc_inc2.vh" 0 At file "t/t_preproc_inc2.vh" line 4 `line 6 "t/t_preproc_inc2.vh" 0 `line 1 "t/t_preproc_inc3.vh" 1 `line 2 "inc3_a_filename_from_line_directive" 0 `line 6 "inc3_a_filename_from_line_directive" 0 At file "inc3_a_filename_from_line_directive" line 10 `line 12 "inc3_a_filename_from_line_directive" 0 `line 15 "inc3_a_filename_from_line_directive" 0 `line 19 "inc3_a_filename_from_line_directive" 2 `line 6 "t/t_preproc_inc2.vh" 0 `line 8 "t/t_preproc_inc2.vh" 2 `line 7 "t/t_preproc.v" 0 `line 9 "t/t_preproc.v" 0 `line 12 "t/t_preproc.v" 0 /*verilator pass_thru comment*/ `line 14 "t/t_preproc.v" 0 /*verilator pass_thru_comment2*/ `line 16 "t/t_preproc.v" 0 `line 19 "t/t_preproc.v" 0 wire [3:0] q = { 1'b1 , 1'b0 , 1'b1 , 1'b1 }; `line 29 "t/t_preproc.v" 0 text. `line 31 "t/t_preproc.v" 0 foo bar foobar2 `line 36 "t/t_preproc.v" 0 `line 40 "t/t_preproc.v" 0 `line 45 "t/t_preproc.v" 0 first part `line 46 "t/t_preproc.v" 0 second part `line 46 "t/t_preproc.v" 0 third part { `line 47 "t/t_preproc.v" 0 a, `line 47 "t/t_preproc.v" 0 b, `line 47 "t/t_preproc.v" 0 c} Line_Preproc_Check 48 `line 50 "t/t_preproc.v" 0 `line 52 "t/t_preproc.v" 0 `line 54 "t/t_preproc.v" 0 deep deep `line 58 "t/t_preproc.v" 0 "Inside: `nosubst" "`nosubst" `line 63 "t/t_preproc.v" 0 x y LLZZ x y p q LLZZ p q r s LLZZ r s LLZZ p q LLZZ p q r s LLZZ r s `line 69 "t/t_preproc.v" 0 firstline comma","line LLZZ firstline comma","line `line 71 "t/t_preproc.v" 0 x y LLZZ "x" y `line 74 "t/t_preproc.v" 0 (a,b)(a,b) `line 77 "t/t_preproc.v" 0 $display("left side: \"right side\"") `line 80 "t/t_preproc.v" 0 bar_suffix more `line 83 "t/t_preproc.v" 0 `line 85 "t/t_preproc.v" 0 $c("Zap(\"",bug1,"\");");; `line 86 "t/t_preproc.v" 0 $c("Zap(\"","bug2","\");");; `line 88 "t/t_preproc.v" 0 `line 91 "t/t_preproc.v" 0 `line 94 "t/t_preproc.v" 0 initial begin $display("pre thrupre thrumid thrupost post: \"right side\""); $display("left side: \"right side\""); $display("left side: \"right side\""); $display("left_side: \"right_side\""); $display("na: \"right_side\""); $display("prep ( midp1 left_side midp2 ( outp ) ): \"right_side\""); $display("na: \"nana\""); $display("left_side right_side: \"left_side right_side\""); $display(": \"\""); $display("left side: \"right side\""); $display("left side: \"right side\""); $display("standalone"); `line 115 "t/t_preproc.v" 0 $display("twoline: \"first second\""); $write("*-* All Finished *-*\n"); $finish; end endmodule `line 125 "t/t_preproc.v" 0 `line 128 "t/t_preproc.v" 0 `line 133 "t/t_preproc.v" 0 module add1 ( input wire d1, output wire o1); `line 134 "t/t_preproc.v" 0 wire tmp_d1 = d1; `line 134 "t/t_preproc.v" 0 wire tmp_o1 = tmp_d1 + 1; `line 134 "t/t_preproc.v" 0 assign o1 = tmp_o1 ; endmodule module add2 ( input wire d2, output wire o2); `line 137 "t/t_preproc.v" 0 wire tmp_d2 = d2; `line 137 "t/t_preproc.v" 0 wire tmp_o2 = tmp_d2 + 1; `line 137 "t/t_preproc.v" 0 assign o2 = tmp_o2 ; endmodule `line 140 "t/t_preproc.v" 0 `line 146 "t/t_preproc.v" 0 `line 151 "t/t_preproc.v" 0 `line 151 "t/t_preproc.v" 0 generate for (i=0; i<(3); i=i+1) begin `line 151 "t/t_preproc.v" 0 psl cover { m5k.f .ctl._ctl_mvldx_m1.d[i] & ~m5k.f .ctl._ctl_mvldx_m1.q[i] & !m5k.f .ctl._ctl_mvldx_m1.cond & ((m5k.f .ctl.alive & m5k.f .ctl.alive_m1))} report "fondNoRise: m5kc_fcl._ctl_mvldx_m1"; `line 151 "t/t_preproc.v" 0 psl cover { ~m5k.f .ctl._ctl_mvldx_m1.d[i] & m5k.f .ctl._ctl_mvldx_m1.q[i] & !m5k.f .ctl._ctl_mvldx_m1.cond & ((m5k.f .ctl.alive & m5k.f .ctl.alive_m1))} report "fondNoFall: m5kc_fcl._ctl_mvldx_m1"; `line 151 "t/t_preproc.v" 0 end endgenerate `line 153 "t/t_preproc.v" 0 module prot(); `protected I!#r#e6<_Q{{E2+]I3<[3s)1@D|'E''i!O?]jD>Jo_![Cl) #nj1]p,3^1~,="E@QZB\T)eU\pC#C|7=\$J$##A[@-@{Qk] `line 159 "t/t_preproc.v" 0 `endprotected endmodule `line 163 "t/t_preproc.v" 0 `line 173 "t/t_preproc.v" 0 begin addr <= (({regs[6], regs[7]} + 1)); rd <= 1; end and begin addr <= (({regs[6], regs[7]})); wdata <= (rdata); wr <= 1; end begin addr <= ({regs[6], regs[7]} + 1); rd <= 1; end begin addr <= ({regs[6], regs[7]}); wdata <= (rdata); wr <= 1; end more `line 177 "t/t_preproc.v" 0 `line 180 "t/t_preproc.v" 0 `line 1 "t/t_preproc_inc4.vh" 1 `line 2 "t/t_preproc_inc4.vh" 0 `line 5 "t/t_preproc_inc4.vh" 0 `line 7 "t/t_preproc_inc4.vh" 2 `line 180 "t/t_preproc.v" 0 `line 181 "t/t_preproc.v" 0 `line 184 "t/t_preproc.v" 0 `line 186 "t/t_preproc.v" 0 `line 190 "t/t_preproc.v" 0 `line 193 "t/t_preproc.v" 0 $blah("ab,cd","e,f"); $blah(this.logfile,vec); $blah(this.logfile,vec[1,2,3]); $blah(this.logfile,{blah.name(), " is not foo"}); `line 199 "t/t_preproc.v" 0 `line 202 "t/t_preproc.v" 0 `pragma foo = 1 `default_nettype none `default_nettype uwire `line 206 "t/t_preproc.v" 0 `line 209 "t/t_preproc.v" 0 `line 213 "t/t_preproc.v" 0 Line_Preproc_Check 213 `line 215 "t/t_preproc.v" 0 `line 218 "t/t_preproc.v" 0 (p,q) `line 225 "t/t_preproc.v" 0 (x,y) Line_Preproc_Check 226 `line 228 "t/t_preproc.v" 0 `line 231 "t/t_preproc.v" 0 beginend beginend "beginend" `line 239 "t/t_preproc.v" 0 `\esc`def `line 245 "t/t_preproc.v" 0 Not a \`define `line 247 "t/t_preproc.v" 0 x,y)--bee submacro has comma paren `line 255 "t/t_preproc.v" 0 $display("10 %d %d", $bits(foo), 10); `line 260 "t/t_preproc.v" 0 `line 265 "t/t_preproc.v" 0 `line 268 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 assign a3 = ~b3 ; `line 282 "t/t_preproc.v" 0 `line 284 "t/t_preproc.v" 0 \ `line 293 "t/t_preproc.v" 0 `line 293 "t/t_preproc.v" 0 `line 293 "t/t_preproc.v" 0 def i `line 295 "t/t_preproc.v" 0 `line 297 "t/t_preproc.v" 0 `line 301 "t/t_preproc.v" 0 `line 307 "t/t_preproc.v" 0 1 /*verilator NOT IN DEFINE*/ (nodef) 2 /*verilator PART OF DEFINE*/ (hasdef) 3 `line 309 "t/t_preproc.v" 0 /*verilator NOT PART OF DEFINE*/ (nodef) `line 310 "t/t_preproc.v" 0 4 `line 310 "t/t_preproc.v" 0 /*verilator PART OF DEFINE*/ (nodef) `line 311 "t/t_preproc.v" 0 5 also in `line 311 "t/t_preproc.v" 0 also3 (nodef) HAS a NEW `line 314 "t/t_preproc.v" 0 LINE `line 316 "t/t_preproc.v" 0 `line 318 "t/t_preproc.v" 0 `line 331 "t/t_preproc.v" 0 `line 334 "t/t_preproc.v" 0 EXP: clxx_scen clxx_scen EXP: clxx_scen "clxx_scen" EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", " end"}); end while(0); `line 340 "t/t_preproc.v" 0 do `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 if (start("t/t_preproc.v", 340)) begin `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 message({"Blah-", "clx_scen", " end"}); `line 340 "t/t_preproc.v" 0 end `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 while(0); `line 342 "t/t_preproc.v" 0 `line 344 "t/t_preproc.v" 0 `line 348 "t/t_preproc.v" 0 `line 348 "t/t_preproc.v" 0 `line 349 "t/t_preproc.v" 0 EXP: This is fooed This is fooed EXP: This is fooed_2 This is fooed_2 `line 356 "t/t_preproc.v" 0 np np `line 367 "t/t_preproc.v" 0 `line 370 "t/t_preproc.v" 0 `line 378 "t/t_preproc.v" 0 `line 382 "t/t_preproc.v" 0 hello3hello3hello3 hello4hello4hello4hello4 `line 388 "t/t_preproc.v" 0 `line 1 "t/t_preproc_inc4.vh" 1 `line 2 "t/t_preproc_inc4.vh" 0 `line 5 "t/t_preproc_inc4.vh" 0 `line 7 "t/t_preproc_inc4.vh" 2 `line 388 "t/t_preproc.v" 0 `line 389 "t/t_preproc.v" 0 `line 397 "t/t_preproc.v" 0 Line_Preproc_Check 401 Line_Preproc_Check 407 "FOO \ BAR " "arg_line1 \ arg_line2" "FOO \ BAR " `line 410 "t/t_preproc.v" 0 Line_Preproc_Check 410 `line 414 "t/t_preproc.v" 0 abc `line 424 "t/t_preproc.v" 0 EXP: sonet_frame sonet_frame `line 430 "t/t_preproc.v" 0 EXP: sonet_frame sonet_frame EXP: sonet_frame sonet_frame `line 440 "t/t_preproc.v" 0 EXP: module zzz ; endmodule module zzz ; endmodule module zzz ; endmodule `line 447 "t/t_preproc.v" 0 EXP: module a_b ; endmodule module a_b ; endmodule module a_b ; endmodule `line 452 "t/t_preproc.v" 0 integer foo; module t; initial begin : \`LEX_CAT(a[0],_assignment) `line 464 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\`LEX_CAT(a[0],_assignment) "); end initial begin : \a[0]_assignment_a[1] `line 471 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\a[0]_assignment_a[1] "); end initial begin : \`CAT(pp,suffix) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(pp,suffix) "); end initial begin : \`CAT(ff,bb) `line 485 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(ff,bb) "); end initial begin : \`zzz `line 491 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\`zzz "); end initial begin : \`FOO `line 498 "t/t_preproc.v" 0 $write("GOT%%m='%m' OTHER_EXP='%s'\n OUR_EXP='%s'", "t.bar ","t.\\`FOO "); end initial begin : \xx`FOO `line 500 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\xx`FOO "); end initial begin : \`UNKNOWN $write("GOT%%m='%m' EXP='%s'\n", "t.\\`UNKNOWN "); end initial begin : \`DEF_NO_EXPAND $write("GOT%%m='%m' EXP='%s'\n", "t.\\`DEF_NO_EXPAND "); end initial $write("GOT='%s' EXP='%s'\n", "foo bar baz", "foo bar baz"); initial $write("GOT='%s' EXP='%s'\n", "foo `A(bar) baz", "foo `A(bar) baz"); initial $write("Slashed=`%s'\n", "1//2.3"); initial `line 531 "t/t_preproc.v" 0 $display("%s%s","a1","b2c3\n"); endmodule `line 534 "t/t_preproc.v" 0 `line 537 "t/t_preproc.v" 0 $display("RAM0"); $display("CPU"); `line 542 "t/t_preproc.v" 0 `line 547 "t/t_preproc.v" 0 XXE_FAMILY = XXE_ $display("XXE_ is defined"); `line 554 "t/t_preproc.v" 0 XYE_FAMILY = XYE_ $display("XYE_ is defined"); `line 561 "t/t_preproc.v" 0 XXS_FAMILY = XXS_some $display("XXS_some is defined"); `line 568 "t/t_preproc.v" 0 XYS_FAMILY = XYS_foo $display("XYS_foo is defined"); `line 575 "t/t_preproc.v" 0 `line 577 "t/t_preproc.v" 0 `line 585 "t/t_preproc.v" 0 `line 592 "t/t_preproc.v" 0 `line 599 "t/t_preproc.v" 0 `line 606 "t/t_preproc.v" 0 `line 608 "t/t_preproc.v" 0 `line 610 "t/t_preproc.v" 0 (.mySig (myInterface.pa5), `line 614 "t/t_preproc.v" 0 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 634 "t/t_preproc.v" 2 verilator-3.916/test_regress/t/t_func_check.pl0000775000177100017500000000076212473477707021476 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_lint_multidriven_bad.v0000664000177100017500000000127713205574202023413 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.916/test_regress/t/t_var_nonamebegin.out0000664000177100017500000000240413205574202022702 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 t $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.916/test_regress/t/t_param_bit_sel.v0000664000177100017500000000132312671044616022015 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.916/test_regress/t/t_interface_param2.pl0000775000177100017500000000103213205574202022555 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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, bug1104"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_extend.v0000664000177100017500000000332412473477707020521 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.916/test_regress/t/t_mem_twoedge.v0000664000177100017500000000512413205574202021504 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.916/test_regress/t/t_struct_unpacked_bad.v0000664000177100017500000000067112671044616023225 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.916/test_regress/t/t_interface_down_inlb.pl0000775000177100017500000000110312671044616023354 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_func_real_abs.pl0000775000177100017500000000072212671044616022152 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_cat.cpp0000664000177100017500000000326613205574202021457 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 VM_PREFIX_INCLUDE 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) VL_SNPRINTF(name,1000,"obj_dir/t_trace_cat/simpart_%04d.vcd", (int)main_time); #elif defined(T_TRACE_CAT_REOPEN) VL_SNPRINTF(name,1000,"obj_dir/t_trace_cat_reopen/simpart_%04d.vcd", (int)main_time); #elif defined(T_TRACE_CAT_RENEW) VL_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.916/test_regress/t/t_dpi_vams.pl0000775000177100017500000000110512671044616021165 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe","$Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_package_ddecl.v0000664000177100017500000000137613205574202021743 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.916/test_regress/t/t_var_dotted_inl1.pl0000775000177100017500000000103613151152521022431 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_dist_portability.pl0000775000177100017500000000623713205574202022754 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. use IO::File; my $root = ".."; my $Debug; if (!-r "$root/.git") { $Self->skip("Not in a git repository"); } else { uint(); printfll(); cstr(); vsnprintf(); } ok(1); sub uint { ### Must trim output before and after our file list #my $files = "*/*.c* */*.h test_regress/t/*.c* test_regress/t/*.h"; # src isn't clean, and probably doesn't need to be (yet?) my $files = "include/*.c* include/*.h test_c/*.c* test_regress/t/*.c* test_regress/t/*.h"; my $cmd = "cd $root && fgrep -n int $files | sort"; print "C $cmd\n"; my $grep = `$cmd`; my %names; foreach my $line (split /\n/, $grep) { $line =~ s!//.*$!!; next if $line !~ /uint\d+_t\b/; next if $line =~ /vl[su]int\d+_t/; next if $line =~ /typedef/; next if $line =~ m!include/svdpi.h!; # Not ours if ($line =~ /^([^:]+)/) { $names{$1} = 1; print "$line\n"; } } if (keys %names) { $Self->error("Files with uint32*_t instead of vluint32s: ",join(' ',sort keys %names)); } } sub printfll { my $files = "src/*.c* src/*.h include/*.c* include/*.h test_c/*.c* test_regress/t/*.c* test_regress/t/*.h"; my $cmd = "cd $root && fgrep -n ll $files | sort"; print "C $cmd\n"; my $grep = `$cmd`; my %names; foreach my $line (split /\n/, $grep) { next if $line !~ /%[a-z0-9]*ll/; next if $line !~ /\blong\S+long\b/; # Assume a cast print "$line\n"; if ($line =~ /^([^:]+)/) { $names{$1} = 1; } else { $names{UNKNOWN} = 1; } } if (keys %names) { $Self->error("Files with %ll instead of VL_PRI64: ",join(' ',sort keys %names)); } } sub cstr { my $files = "src/*.c* src/*.h include/*.c* include/*.h test_c/*.c* test_regress/t/*.c* test_regress/t/*.h"; my $cmd = "cd $root && grep -n -P 'c_str|begin|end' $files | sort"; print "C $cmd\n"; my $grep = `$cmd`; my %names; foreach my $line (split /\n/, $grep) { if ($line =~ /^([^:]+).*\(\)[a-z0-9_().->]*[.->]+(c_str|r?begin|r?end)\(\)/) { next if $line =~ /lintok-begin-on-ref/; print "$line\n"; $names{$1} = 1; } } if (keys %names) { $Self->error("Files with potential c_str() lifetime issue: ",join(' ',sort keys %names)); } } sub vsnprintf { # Note do not do test_regress, as VPI files need to compile without verilatedos.h my $files = "src/*.c* src/*.h include/*.c* include/*.h test_c/*.c*"; my $cmd = "cd $root && grep -n -P '(snprintf|vsnprintf)' $files | sort"; print "C $cmd\n"; my $grep = `$cmd`; my %names; foreach my $line (split /\n/, $grep) { if ($line =~ /\b(snprintf|vsnprintf)\b/) { next if $line =~ /# *define\s*VL_V?SNPRINTF/; print "$line\n"; $names{$1} = 1; } } if (keys %names) { $Self->error("Files with vsnprintf, use VL_VSNPRINTF: ",join(' ',sort keys %names)); } } 1; verilator-3.916/test_regress/t/t_flag_stats.pl0000775000177100017500000000107113205574202021505 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); compile ( verilator_flags2 => ["--stats --stats-vars"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_assert_synth_full.pl0000775000177100017500000000132013205574202023123 0ustar wsnyderwsnyder#!/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.t: synthesis full_case' ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_portsel.v0000664000177100017500000000425112671044616022313 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.916/test_regress/t/t_case_write1.v0000664000177100017500000000172712473477707021445 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.916/test_regress/t/t_assert_elab_bad.pl0000775000177100017500000000144413205574202022454 0ustar wsnyderwsnyder#!/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_elab.v"); unlink("$Self->{obj_dir}/t_assert_elab_bad.log"); compile ( v_flags2 => ['+define+FAILING_ASSERTIONS', $Self->{v3}?'--assert':($Self->{nc}?'+assert':'')], fails => 1, ); execute ( fails => $Self->{vlt}, ); file_grep ("$Self->{obj_dir}/vlt_compile.log", qr/%Warning-USERFATAL: Parameter 5 is invalid...string and constant both work/); ok(1); 1; verilator-3.916/test_regress/t/t_sys_rand.v0000664000177100017500000000144312473477707021054 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.916/test_regress/t/t_unopt_converge_print_bad.pl0000775000177100017500000000125612473477707024464 0ustar 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.916/test_regress/t/t_inst_dff.v0000664000177100017500000000563412671044616021021 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; localparam WIDTH = 31; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [WIDTH-1:0] b; // From test of Test.v wire [WIDTH-1:0] c; // From test of Test.v // End of automatics reg rst_l; Test #(.WIDTH(WIDTH)) test (/*AUTOINST*/ // Outputs .b (b[WIDTH-1:0]), .c (c[WIDTH-1:0]), // Inputs .clk (clk), .rst_l (rst_l), .in (in[WIDTH-1:0])); // Aggregate outputs into a single result vector wire [63:0] result = {1'h0, c, 1'b0, b}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; rst_l <= ~1'b1; end else if (cyc<10) begin sum <= 64'h0; rst_l <= ~1'b1; // Hold reset while summing end else if (cyc<20) begin rst_l <= ~1'b0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hbcfcebdb75ec9d32 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs b, c, // Inputs clk, rst_l, in ); parameter WIDTH = 5; input clk; input rst_l; input [WIDTH-1:0] in; output wire [WIDTH-1:0] b; output wire [WIDTH-1:0] c; dff # ( .WIDTH (WIDTH), .RESET ('0), // Although this is a single bit, the parameter must be the specified type .RESET_WIDTH (1) ) sub1 ( .clk(clk), .rst_l(rst_l), .q(b), .d(in) ); dff # ( .WIDTH (WIDTH), .RESET ({ 1'b1, {(WIDTH-1){1'b0}} }), .RESET_WIDTH (WIDTH)) sub2 ( .clk(clk), .rst_l(rst_l), .q(c), .d(in) ); endmodule module dff (/*AUTOARG*/ // Outputs q, // Inputs clk, rst_l, d ); parameter WIDTH = 1; parameter RESET = {WIDTH{1'b0}}; parameter RESET_WIDTH = WIDTH; input clk; input rst_l; input [WIDTH-1:0] d; output reg [WIDTH-1:0] q; always_ff @(posedge clk or negedge rst_l) begin if ($bits(RESET) != RESET_WIDTH) $stop; // verilator lint_off WIDTH if (~rst_l) q <= RESET; // verilator lint_on WIDTH else q <= d; end endmodule verilator-3.916/test_regress/t/t_interface_down_inlad.pl0000775000177100017500000000112412671044616023522 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_inst_first.pl0000775000177100017500000000072212671044616021553 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_rsvd.pl0000775000177100017500000000071712473477707021234 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_down_inlcd.pl0000775000177100017500000000112412671044616023524 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_param_default_bad.pl0000775000177100017500000000125613205574202022775 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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: Internal Error: t/t_param_default_bad.v:6: ../V3Param.cpp:\d+: Parameter without initial value %Error: Internal Error: See the manual and http://www.veripool.org/verilator for more assistance. .*%Error: Command Failed.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_param_avec.v0000664000177100017500000000205313205574202021304 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t (/*AUTOARG*/ // Inputs clk ); input clk; sub #(.IDX(0), .CHK(10)) i0; sub #(.IDX(2), .CHK(12)) i2; sub #(.IDX(7), .CHK(17)) i7; always @ (posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule module sub (); function integer get_element; input integer index; input integer array_arg[7:0]; get_element = array_arg[index]; endfunction parameter integer IDX = 5; parameter integer CHK = 5; localparam integer array[0:7] = '{10, 11, 12, 13, 14, 15, 16, 17}; localparam element1 = array[IDX]; localparam elementf = get_element(IDX, array); initial begin `checkh (element1, CHK); `checkh (elementf, CHK); end endmodule verilator-3.916/test_regress/t/t_string.pl0000775000177100017500000000072213205574202020666 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_escape.v0000664000177100017500000000322512473477707021342 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.916/test_regress/t/t_var_nonamebegin.pl0000775000177100017500000000145613205574202022517 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.t.genblk1 d3a: {mod}.d3nameda top.t.d3nameda b2: {mod} top.t b3n: {mod}.b3named: top.t.b3named b3: {mod} top.t b4: {mod} top.t t1 {mod}.tsk top.t t2 {mod}.tsk top.t *-* All Finished *-*'), ); if ($Self->{vlt}) { vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out"); } ok(1); 1; verilator-3.916/test_regress/t/t_xml_tag.v0000664000177100017500000000124313205574202020641 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Chris Randall. module m ( input clk_ip, // verilator tag clk_ip input rst_ip, output foo_op); // verilator tag foo_op // This is a comment typedef struct packed { logic clk; /* verilator tag this is clk */ logic k; /* verilator lint_off UNUSED */ logic enable; // verilator tag enable logic data; // verilator tag data } my_struct; // verilator tag my_struct // This is a comment my_struct this_struct [2]; // verilator tag this_struct endmodule verilator-3.916/test_regress/t/t_mem_multidim.v0000664000177100017500000000564612671044616021712 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.916/test_regress/t/t_trace_array.v0000664000177100017500000000110213205574202021474 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (clk); input clk; integer cyc=0; // Trace would overflow at 256KB which is 256 kb dump, 16 kb in a chunk typedef struct packed { logic [1024*1024:0] d; } s1_t; // 128 b s1_t biggie; always @ (posedge clk) begin cyc <= cyc + 1; biggie [ cyc +: 32 ] <= 32'hfeedface; if (cyc == 5) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_assert_casez.pl0000775000177100017500000000077513205574202022056 0ustar wsnyderwsnyder#!/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'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_foreach.pl0000775000177100017500000000072213205574202020767 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_pp_circdef_bad.pl0000775000177100017500000000120212671044616022265 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_case_write2.v0000664000177100017500000000172712473477707021446 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.916/test_regress/t/t_assign_inline.v0000664000177100017500000000206013205574202022026 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Mike Thyer. module t (/*AUTOARG*/ // Inputs clk ); input clk; int cycle=0; // verilator lint_off UNOPTFLAT reg [7:0] a_r; wire [7:0] a_w; reg [7:0] b_r; reg [7:0] c_d_r, c_q_r; assign a_w = a_r; always @(*) begin a_r = 0; b_r = a_w; // Substituting the a_w assignment to get b_r = 0 is wrong, as a_r is not "complete" a_r = c_q_r; c_d_r = c_q_r; end // stimulus + checks always @(posedge clk) begin cycle <= cycle+1; if (cycle==0) begin c_q_r <= 8'b0; end else begin c_q_r <= c_d_r+1; `ifdef TEST_VERBOSE $display("[%0t] a_r=%0d, b_r=%0d", $time, a_r, b_r); // a_r and b_r should always be the same `endif end if (cycle >= 10) begin if (b_r==9) begin $write("*-* All Finished *-*\n"); $finish; end else begin $stop; end end end endmodule verilator-3.916/test_regress/t/t_sys_file_autoflush.pl0000775000177100017500000000114012473477707023304 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_func_range.pl0000775000177100017500000000071712473477707021515 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_verilated_debug.pl0000775000177100017500000000113213205574202022501 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_debug} = 1; compile ( verilator_flags2 => [], ); execute ( check_finished=>1, ); ok(files_identical("$Self->{obj_dir}/vlt_sim.log", "t/$Self->{name}.out")); ok(1); 1; verilator-3.916/test_regress/t/t_assert_dup_bad.pl0000775000177100017500000000121312473477707022355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_sys_file_basic_input.dat0000664000177100017500000000021612671044616023714 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.916/test_regress/t/t_lint_implicit_def_bad.v0000664000177100017500000000070712473477707023520 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.916/test_regress/t/t_clk_dsp.pl0000775000177100017500000000071712473477707021025 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_down_inlbd.pl0000775000177100017500000000112412671044616023523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_var_bad_hide2.pl0000775000177100017500000000132012671044616022033 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_for_loop.v0000664000177100017500000000346312473477707021055 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.916/test_regress/t/t_tri_unconn.v0000664000177100017500000001051612671044616021376 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.916/test_regress/t/t_func_const_packed_struct_bad.v0000664000177100017500000000154213205574202025072 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Todd Strader. module t; typedef struct packed { logic [ 31 : 0 ] a; logic [ 31 : 0 ] b; } params_t; localparam P24 = f_add2(7, 8, 9); initial begin // Should never get here $write("*-* All Finished *-*\n"); $finish; end function integer f_add(input params_t [ 1 : 0 ] params); f_add = params[0].a+params[1].b; if (f_add == 15) $fatal(2, "f_add = 15"); endfunction // Speced ok: function called from function function integer f_add2(input [31:0] a, input [31:0] b, input [31:0] c); params_t [ 1 : 0 ] params; params[0] = '{a:a, b:555}; params[1] = '{a:12345, b:b}; f_add2 = f_add(params)+c; endfunction endmodule verilator-3.916/test_regress/t/t_gen_missing.pl0000775000177100017500000000077412473477707021713 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_inst_dtree_inlbc.pl0000775000177100017500000000112012671044616022667 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_inst_overwide.pl0000775000177100017500000000102113205574202022232 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( make_top_shell=>0, verilator_flags2 => [qw(-sc -Wno-WIDTH)], verilator_make_gcc=>0, ); #No execute () ok(1); 1; verilator-3.916/test_regress/t/t_select_set.v0000664000177100017500000000216312473477707021364 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.916/test_regress/t/t_math_swap.v0000664000177100017500000001014112473477707021210 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.916/test_regress/t/t_dpi_sys_c.cpp0000664000177100017500000000244513151152521021500 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.916/test_regress/t/t_sys_time.pl0000775000177100017500000000071712473477707021242 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_gen7_noinl.pl0000775000177100017500000000102613205574202023435 0ustar wsnyderwsnyder#!/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_gen7.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_udp.v0000664000177100017500000000726612473477707020033 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.916/test_regress/t/t_cellarray.pl0000775000177100017500000000113013205574202021330 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( v_flags2 => ["--stats"], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Gate assign merged\s+(\d+)/i, 28); }; ok(1); 1; verilator-3.916/test_regress/t/t_lint_block_redecl_bad.v0000664000177100017500000000065512671044616023467 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.916/test_regress/t/t_dpi_sys.pl0000775000177100017500000000077012473477707021057 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_local.v0000664000177100017500000000077113205574202021465 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs a, y ); input [1:0] a; output [3:0] y; Test #(.C(2)) test (.*); endmodule module Test #(C = 3, localparam O = 1 << C) (input [C-1:0] a, output reg [O-1:0] y); initial begin if (O != 4) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_inst_comma_inl0.pl0000775000177100017500000000104013205574202022425 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_inst_comma.v"); compile ( v_flags2 => ['+define+NOUSE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_anon.pl0000775000177100017500000000102412671044616021722 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_array.pl0000775000177100017500000000072212671044616021665 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_const_packed_array_bad.pl0000775000177100017500000000220613205574202025033 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2017 by Todd Strader. This program is free software; you can # redistribute it and/or 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-USERFATAL: f_add = 15 %Warning-USERFATAL: Use "/* verilator lint_off USERFATAL */" and lint_on around source to disable this message. %Error: t/t_func_const_packed_array_bad.v:11: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_add2' %Error: t/t_func_const_packed_array_bad.v:22: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing Called from: t/t_func_const_packed_array_bad.v:30: f_add() with parameters: params = [0 = 32'h7, 1 = 32'h8] Called from: t/t_func_const_packed_array_bad.v:11: f_add2() with parameters: a = ?32?sh7 b = ?32?sh8 c = ?32?sh9 }, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface1_modport_trace.pl0000775000177100017500000000104713151152521024320 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_init_concat.pl0000775000177100017500000000071712473477707021700 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 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.916/test_regress/t/t_dpi_export.pl0000775000177100017500000000127012713417237021543 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_math_imm2.cpp0000664000177100017500000000236112671044616021411 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.916/test_regress/t/t_mem_multi_io.v0000664000177100017500000000222612473477707021711 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.916/test_regress/t/t_select_lhs_oob.pl0000775000177100017500000000072212473477707022366 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_types.pl0000775000177100017500000000106312473477707021415 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_dpi_logic_bad.v0000664000177100017500000000070213205574202021744 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 time (yet?) import "DPI-C" dpii_fa_bit = function int oth_f_int1(input time i); initial begin $stop; end endmodule verilator-3.916/test_regress/t/t_math_imm.v0000664000177100017500000000615312473477707021030 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.916/test_regress/t/t_case_genx_bad.v0000664000177100017500000000056412473477707021777 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.916/test_regress/t/t_var_vec_sel.v0000664000177100017500000000117012671044616021504 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.916/test_regress/t/t_mem_multi_io3_sc.pl0000775000177100017500000000123113205574202022603 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_mem_multi_io3.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io3.cpp --sc -Oi"], verilator_flags3 => [], ); ok(1); 1; verilator-3.916/test_regress/t/t_func_grey.v0000664000177100017500000000273412473477707021217 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.916/test_regress/t/t_array_pattern_packed.v0000664000177100017500000001523712671044616023407 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic [1:0] [3:0] [3:0] array_simp; // big endian array logic [3:0] array_oned; initial begin array_oned = '{2:1'b1, 0:1'b1, default:1'b0}; if (array_oned != 4'b0101) $stop; array_simp[0] = '{ 4'd3, 4'd2, 4'd1, 4'd0}; if (array_simp[0] !== 16'h3210) $stop; // verilator lint_off WIDTH array_simp[0] = '{ 3 ,2 ,1, 0 }; // verilator lint_on WIDTH if (array_simp[0] !== 16'h3210) $stop; // Doesn't seem to work for unpacked arrays in other simulators //if (array_simp[0] !== 16'h3210) $stop; //array_simp[0] = '{ 1:4'd3, default:13}; //if (array_simp[0] !== 16'hDD3D) $stop; array_simp = '{ '{ 4'd3, 4'd2, 4'd1, 4'd0 }, '{ 4'd1, 4'd2, 4'd3, 4'd4 }}; if (array_simp !== 32'h3210_1234) $stop; // IEEE says '{} allowed only on assignments, not !=, ==. // Doesn't seem to work for unpacked arrays in other simulators array_simp = '{2{ '{4'd3, 4'd2, 4'd1, 4'd0 } }}; if (array_simp !== 32'h3210_3210) $stop; array_simp = '{2{ '{4{ 4'd3 }} }}; if (array_simp !== 32'h3333_3333) $stop; // Not legal in other simulators - replication doesn't match // However IEEE suggests this is legal. //array_simp = '{2{ '{2{ 4'd3, 4'd2 }} }}; // Note it's not '{3,2} $write("*-* All Finished *-*\n"); $finish; end //==================== // parameters for array sizes localparam WA = 4; // address dimension size localparam WB = 4; // bit dimension size localparam NO = 11; // number of access events // 2D packed arrays logic [WA-1:0] [WB-1:0] array_bg; // big endian array /* verilator lint_off LITENDIAN */ logic [0:WA-1] [0:WB-1] array_lt; // little endian array /* verilator lint_on LITENDIAN */ integer cnt = 0; // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if ((cnt[30:2]==(NO-1)) && (cnt[1:0]==2'd3)) begin $write("*-* All Finished *-*\n"); $finish; end // big endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaults (all bits 1'b0) if (cnt[30:2]== 0) array_bg <= '0; else if (cnt[30:2]== 1) array_bg <= '0; else if (cnt[30:2]== 2) array_bg <= '0; else if (cnt[30:2]== 3) array_bg <= '0; else if (cnt[30:2]== 4) array_bg <= '0; else if (cnt[30:2]== 5) array_bg <= '0; else if (cnt[30:2]== 6) array_bg <= '0; else if (cnt[30:2]== 7) array_bg <= '0; else if (cnt[30:2]== 8) array_bg <= '0; else if (cnt[30:2]== 9) array_bg <= '0; else if (cnt[30:2]==10) array_bg <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]== 0) begin end else if (cnt[30:2]== 1) array_bg <= '{ 3 ,2 ,1, 0 }; else if (cnt[30:2]== 2) array_bg <= '{default:13}; else if (cnt[30:2]== 3) array_bg <= '{0:4, 1:5, 2:6, 3:7}; else if (cnt[30:2]== 4) array_bg <= '{2:15, default:13}; else if (cnt[30:2]== 5) array_bg <= '{WA { {WB/2 {2'b10}} }}; else if (cnt[30:2]== 6) array_bg <= '{cnt[3:0]+0, cnt[3:0]+1, cnt[3:0]+2, cnt[3:0]+3}; end else if (cnt[1:0]==2'd2) begin // chack array agains expected value if (cnt[30:2]== 0) begin if (array_bg !== 16'b0000000000000000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 1) begin if (array_bg !== 16'b0011001000010000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 2) begin if (array_bg !== 16'b1101110111011101) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 3) begin if (array_bg !== 16'b0111011001010100) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 4) begin if (array_bg !== 16'b1101111111011101) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 5) begin if (array_bg !== 16'b1010101010101010) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 6) begin if (array_bg !== 16'b1001101010111100) begin $display("%b", array_bg); $stop(); end end end // little endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaults (all bits 1'b0) if (cnt[30:2]== 0) array_lt <= '0; else if (cnt[30:2]== 1) array_lt <= '0; else if (cnt[30:2]== 2) array_lt <= '0; else if (cnt[30:2]== 3) array_lt <= '0; else if (cnt[30:2]== 4) array_lt <= '0; else if (cnt[30:2]== 5) array_lt <= '0; else if (cnt[30:2]== 6) array_lt <= '0; else if (cnt[30:2]== 7) array_lt <= '0; else if (cnt[30:2]== 8) array_lt <= '0; else if (cnt[30:2]== 9) array_lt <= '0; else if (cnt[30:2]==10) array_lt <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]== 0) begin end else if (cnt[30:2]== 1) array_lt <= '{ 3 ,2 ,1, 0 }; else if (cnt[30:2]== 2) array_lt <= '{default:13}; else if (cnt[30:2]== 3) array_lt <= '{3:4, 2:5, 1:6, 0:7}; else if (cnt[30:2]== 4) array_lt <= '{1:15, default:13}; else if (cnt[30:2]== 5) array_lt <= '{WA { {WB/2 {2'b10}} }}; else if (cnt[30:2]==10) array_lt <= '{cnt[3:0]+0, cnt[3:0]+1, cnt[3:0]+2, cnt[3:0]+3}; end else if (cnt[1:0]==2'd2) begin // chack array agains expected value if (cnt[30:2]== 0) begin if (array_lt !== 16'b0000000000000000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 1) begin if (array_lt !== 16'b0011001000010000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 2) begin if (array_lt !== 16'b1101110111011101) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 3) begin if (array_lt !== 16'b0111011001010100) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 4) begin if (array_lt !== 16'b1101111111011101) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 5) begin if (array_lt !== 16'b1010101010101010) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==10) begin if (array_lt !== 16'b1001101010111100) begin $display("%b", array_lt); $stop(); end end end endmodule verilator-3.916/test_regress/t/t_lint_declfilename.v0000664000177100017500000000037212473477707022670 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.916/test_regress/t/t_array_packed_sysfunct.pl0000775000177100017500000000071712671044616023756 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_array_modport.v0000664000177100017500000000120413205574202024105 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Connecting an interface array slice to a module's portmap // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. interface foo_intf; logic a; modport m(input a); endinterface module foo_mod ( foo_intf foo, foo_intf.m bars[4] ); endmodule module t (/*AUTOARG*/); localparam N = 4; foo_intf foos [N-1:0] (); foo_intf bars [N] (); //foo_intf foos (); foo_mod foo_mod ( .foo (foos[2]), .bars (bars) //.foo (foos) ); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_assert_elab.pl0000775000177100017500000000072213205574202021644 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_public_sig.cpp0000664000177100017500000000204213205574202023017 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->t->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.916/test_regress/t/t_lint_incabspath.pl0000775000177100017500000000112212473477707022537 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_hierarchy_unnamed.pl0000775000177100017500000000102412671044616023050 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_display_signed.pl0000775000177100017500000000237712473477707022410 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the 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.916/test_regress/t/t_unoptflat_simple_bad.pl0000775000177100017500000000076012671044616023564 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_interface_modport_inl.pl0000775000177100017500000000115213151152521023720 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_flag_f.pl0000775000177100017500000000076012473477707020622 0ustar 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.916/test_regress/t/t_preproc_inc3.vh0000664000177100017500000000070312473477707021766 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.916/test_regress/t/t_lint_pkg_colon_bad.pl0000775000177100017500000000165613205574202023176 0ustar 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=> quotemeta( qq{%Error: t/t_lint_pkg_colon_bad.v:6: syntax error, unexpected ::, expecting ')' or ',' %Error: t/t_lint_pkg_colon_bad.v:6: Perhaps 'mispkg' is a package which needs to be predeclared? (IEEE 2012 26.3) %Error: t/t_lint_pkg_colon_bad.v:7: syntax error, unexpected ::, expecting ',' or ';' }).'%Error: Exiting due to.*' ); ok(1); 1; verilator-3.916/test_regress/t/t_assign_inline.pl0000775000177100017500000000076713205574202022213 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ["-O0 -OG"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_star.v0000664000177100017500000000134513205574202022202 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; counter_io c_data(); counter_ansi c1 (.clk, .*); counter_ansi c2 (.clk, .c_data); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==20) begin if (c_data.value != 12345) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule interface counter_io; integer value; endinterface module counter_ansi ( input clk, counter_io c_data ); always_ff @ (posedge clk) begin c_data.value <= 12345; end endmodule : counter_ansi verilator-3.916/test_regress/t/t_case_orig.v0000664000177100017500000001010712473477707021162 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.916/test_regress/t/t_initial_edge.v0000664000177100017500000000434412671044616021637 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.916/test_regress/t/t_enum_type_methods.pl0000775000177100017500000000072212671044616023117 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_unsized_bad.pl0000775000177100017500000000154313205574202022677 0ustar 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=> quotemeta( qq{%Error: t/t_lint_unsized_bad.v:7: Too many digits for 32 bit number: 'd123456789123456789123456789 %Error: t/t_lint_unsized_bad.v:7: As that number was unsized ('d...) it is limited to 32 bits (IEEE 2012 5.7.1) }).'%Error: Exiting due to.*' ); ok(1); 1; verilator-3.916/test_regress/t/t_dpi_2exp_bad.v0000664000177100017500000000076212473477707021555 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.916/test_regress/t/t_mod_interface_array1.pl0000775000177100017500000000072213205574202023436 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_embed1.pl0000775000177100017500000000316013205574202020514 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_cast.pl0000775000177100017500000000071712473477707020340 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_set_link.pl0000775000177100017500000000071712473477707022066 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_detectarray_2.pl0000775000177100017500000000077313205574202022116 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ["-Wno-CLKDATA"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_display_signed.v0000664000177100017500000000270012473477707022225 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.916/test_regress/t/t_inst_missing.pl0000775000177100017500000000106213151152521022060 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_mem_banks.pl0000775000177100017500000000072213205574202021314 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_func.v0000664000177100017500000000142513205574202021323 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This test examines Verilator against paramter definition with functions. // Particularly the function takes in argument which is multi-dimentional. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Roland Kruse and Jie Xu. module test#( parameter size = 4, parameter p = sum({32'h1,32'h2,32'h3,32'h4}, size)) (input clk, input logic sel, output [p:0] res); logic [p:0] cc = 'h45; assign res = sel ? cc : {(p+1){1'b1}}; function integer sum; input [3:0][31:0] values; input int size; sum = 0; begin for (int i = 0; i < size; i ++) sum += values[i]; end endfunction endmodule verilator-3.916/test_regress/t/t_dist_untracked.pl0000775000177100017500000000342313205574202022364 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 %warns; my $prefix; my $summary; { my $status = `cd $root && git ls-files -o --exclude-standard`; print "ST $status\n" if $Debug; foreach my $file (sort split /\n/, $status) { next if $file =~ /nodist/; if (_has_tabs("$root/$file")) { $warns{$file} = "File not in git or .gitignore (with tabs): $file"; $summary = "Files untracked in git or .gitignore (with tabs):" } else { $warns{$file} = "File not in git or .gitignore: $file"; $summary ||= "Files untracked in git or .gitignore:" } } } if (keys %warns) { # First warning lists everything as that's shown in the driver summary $Self->error($summary." ",join(' ',sort keys %warns)); foreach my $file (sort keys %warns) { $Self->error($warns{$file}); } } } sub _has_tabs { my $filename = shift; my $contents = file_contents($filename); if ($filename =~ /\.out$/) { # Ignore golden files } elsif ($contents =~ /[\001\002\003\004\005\006]/) { # Ignore binrary files } elsif ($contents =~ /\t/) { return 1; } return 0; } ok(1); 1; verilator-3.916/test_regress/t/t_lint_unused_iface_bad.pl0000775000177100017500000000153713205574202023653 0ustar 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, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect => '%Warning-UNDRIVEN: t/t_lint_unused_iface_bad.v:\d+: Signal is not driven: sig_udrv %Warning-UNDRIVEN: Use .* %Warning-UNUSED: t/t_lint_unused_iface_bad.v:\d+: Signal is not used: sig_uusd %Error: Exiting due to .*', ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_public.out0000664000177100017500000000507013205574202022206 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 t $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.916/test_regress/t/t_interface_arraymux.v0000664000177100017500000000500413205574202023075 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by John Stevenson. package pkg; typedef logic [31:0] unique_id_t; typedef struct packed { unique_id_t foo; } inner_thing_t; typedef struct packed { inner_thing_t bar; inner_thing_t baz; } outer_thing_t; endpackage import pkg::*; interface the_intf #(parameter M=5); outer_thing_t [M-1:0] things; logic valid; modport i ( output things, output valid); modport t ( input things, input valid); endinterface module ThingMuxOH #( parameter NTHINGS = 1, parameter M = 5 ) ( input logic [NTHINGS-1:0] select_oh, the_intf.t things_in [NTHINGS-1:0], the_intf.i thing_out ); endmodule module Thinker #( parameter M = 5, parameter N = 2) ( input logic clk, input logic reset, input unique_id_t uids[0:N-1], the_intf.t thing_inp, the_intf.i thing_out ); the_intf #(.M(M)) curr_things [N-1:0] (); the_intf #(.M(M)) prev_things [N-1:0] (); the_intf #(.M(M)) curr_thing (); the_intf #(.M(M)) prev_thing (); logic [N-1:0] select_oh; // 1st mux: ThingMuxOH #( .NTHINGS ( N ), .M ( M )) curr_thing_mux( .select_oh( select_oh ), .things_in( curr_things ), .thing_out( curr_thing )); // 2nd mux, comment this out and no problem: ThingMuxOH #( .NTHINGS ( N ), .M ( M )) prev_thing_mux( .select_oh( select_oh ), .things_in( prev_things ), .thing_out( prev_thing )); endmodule module t ( input logic clk, input logic reset ); localparam M = 5; localparam N = 2; unique_id_t uids[0:N-1]; the_intf #(.M(M)) thing_inp(); the_intf #(.M(M)) thing_out(); Thinker #( .M ( M ), .N ( N )) thinker( .clk ( clk ), .reset ( reset ), .uids ( uids ), .thing_inp( thing_inp ), .thing_out( thing_out )); // Previously there was a problem in V3Inst if non-default parameters was used localparam K = 2; the_intf #(.M(K)) thing_inp2(); the_intf #(.M(K)) thing_out2(); Thinker #( .M ( K ), .N ( N )) thinker2( .clk ( clk ), .reset ( reset ), .uids ( uids ), .thing_inp( thing_inp2 ), .thing_out( thing_out2 )); endmodule verilator-3.916/test_regress/t/t_clk_concat6.pl0000775000177100017500000000072713205574202021553 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_inst_aport.pl0000775000177100017500000000103112671044616021543 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_func_dotted.v0000664000177100017500000000762412473477707021537 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.916/test_regress/t/t_interface_gen11.v0000664000177100017500000000124713205574202022145 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // bug998 interface intf #(parameter PARAM = 0) (); logic val; function integer func (); return 5; endfunction endinterface module t1(intf mod_intf); initial begin $display("%m %d", mod_intf.val); end endmodule module t2(intf mod_intfs [1:0]); generate begin t1 t(.mod_intf(mod_intfs[0])); end endgenerate endmodule module t(); intf #(.PARAM(1)) my_intf [1:0] (); t2 t2 (.mod_intfs(my_intf)); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_var_rsvd.v0000664000177100017500000000121112671044616021036 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. // verilator lint_off SYMRSVDWORD module t (/*AUTOARG*/ // Inputs bool ); input bool; // BAD reg vector; // OK, as not public reg switch /*verilator public*/; // Bad typedef struct packed { logic [31:0] vector; // OK, as not public } test; test t; // global is a 1800-2009 reserved word, but we allow it when possible. reg global; initial begin t.vector = 1; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_dpi_export_c.cpp0000664000177100017500000001216213205574202022204 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 svBitVecVal dpix_f_bit15(const svBitVecVal* i); extern svBitVecVal dpix_f_bit48(const svBitVecVal* 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_vec48[2] = {0xab782a12,0x8a413bd9}; svBitVecVal o_vec48[2] = {0,0}; dpix_t_bit48(i_vec48, o_vec48); CHECK_RESULT(int, o_vec48[0], ~i_vec48[0]); #ifdef VCS // VCS has bug where doesn't clean input CHECK_RESULT(int, o_vec48[1], (~i_vec48[1])); #else CHECK_RESULT(int, o_vec48[1], (~i_vec48[1])&0x0000ffffUL); #endif } { 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.916/test_regress/t/t_clk_dpulse.v0000664000177100017500000000205212473477707021354 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.916/test_regress/t/t_enum_func.v0000664000177100017500000000235212473477707021211 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.916/test_regress/t/t_flag_f__2.vc0000664000177100017500000000012512473477707021167 0ustar wsnyderwsnyder +define+GOT_DEF1 // -DNON_DEF /* +define+NON_DEF */ +define+GOT_DEF2=1 verilator-3.916/test_regress/t/t_unroll_genf.v0000664000177100017500000000075613205574202021530 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. //bug830 module sub(); endmodule function integer cdiv(input integer x); begin cdiv = 10; end endfunction module t (/*AUTOARG*/); genvar j; generate for (j = 0; j < cdiv(10); j=j+1) sub sub(); endgenerate initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_xml_first.pl0000775000177100017500000000122513205574202021366 0ustar 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, ); ok(files_identical("$out_filename", "t/$Self->{name}.out")); 1; verilator-3.916/test_regress/t/t_math_mul.v0000664000177100017500000000277312473477707021047 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.916/test_regress/t/t_initial_edge_bad.pl0000775000177100017500000000125412671044616022613 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_lint_width_bad.pl0000775000177100017500000000261613151152521022333 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{.*%Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator VAR 'XS' expects 4 bits on the Initial value, but Initial value's CONST '\?32\?bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' generates 32 bits. %Warning-WIDTH: Use .* %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator ASSIGNW expects 5 bits on the Assign RHS, but Assign RHS's VARREF 'in' generates 4 bits. %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator SHIFTL expects 5 bits on the LHS, but LHS's CONST '1'h1' generates 1 bits. %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator ASSIGNW expects 6 bits on the Assign RHS, but Assign RHS's SHIFTL generates 7 bits. %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator ADD expects 3 bits on the LHS, but LHS's VARREF 'one' generates 1 bits. %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator ADD expects 3 bits on the RHS, but RHS's VARREF 'one' generates 1 bits. %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_eq.pl0000775000177100017500000000071712473477707021024 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_avec.pl0000775000177100017500000000103113205574202021450 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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, bug477"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_gen12.v0000664000177100017500000000104613205574202022143 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // bug1005 module foo_module; generate for (genvar i = 0; i < 2; i = i + 1) begin : my_gen_block logic baz; end endgenerate endmodule module bar_module; foo_module foo(); endmodule module t; bar_module bar(); initial begin bar.foo.my_gen_block[0].baz = 1; if (bar.foo.my_gen_block[0].baz) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_package.pl0000775000177100017500000000071712473477707021001 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_bitsel_const_bad.v0000664000177100017500000000073112671044616022514 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.916/test_regress/t/t_pipe_filter.pl0000775000177100017500000000143213151152521021655 0ustar 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.916/test_regress/t/t_lint_pkg_colon_bad.v0000664000177100017500000000034513205574202023017 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (input mispkg::foo_t a); reg mispkgb::bar_t b; endmodule verilator-3.916/test_regress/t/t_mem_slot.v0000664000177100017500000000111612671044616021033 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.916/test_regress/t/t_math_imm2.v0000664000177100017500000000231512473477707021106 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.916/test_regress/t/t_unopt_combo_isolate.pl0000775000177100017500000000117112473477707023445 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_sv_cpu.pl0000775000177100017500000000266612671044616020677 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # 22-Mar-2012: Modifications for this test contributed by Jeremy Bennett, # Embecosm. compile ( # Taken from the original VCS command line. v_flags2 => ["t/t_sv_cpu_code/timescale.sv", "t/t_sv_cpu_code/program_h.sv", "t/t_sv_cpu_code/pads_h.sv", "t/t_sv_cpu_code/ports_h.sv", "t/t_sv_cpu_code/pinout_h.sv", "t/t_sv_cpu_code/genbus_if.sv", "t/t_sv_cpu_code/pads_if.sv", "t/t_sv_cpu_code/adrdec.sv", "t/t_sv_cpu_code/pad_gpio.sv", "t/t_sv_cpu_code/pad_vdd.sv", "t/t_sv_cpu_code/pad_gnd.sv", "t/t_sv_cpu_code/pads.sv", "t/t_sv_cpu_code/ports.sv", "t/t_sv_cpu_code/ac_dig.sv", "t/t_sv_cpu_code/ac_ana.sv", "t/t_sv_cpu_code/ac.sv", "t/t_sv_cpu_code/cpu.sv", "t/t_sv_cpu_code/chip.sv"], vcs_flags2 => ["-R -sverilog +memcbk -y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code"], verilator_flags2 => ["-y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code --top-module t"], iv_flags2 => ["-yt/t_sv_cpu_code -It/t_sv_cpu_code -Y.sv"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_display_real_noopt.pl0000775000177100017500000000262612473477707023276 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_package_export_bad.pl0000775000177100017500000000216713205574202023167 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 scope/variable: PARAM2 %Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM3 %Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM2 %Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM3 %Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM2 %Error: t/t_package_export.v:\d+: Can\'t find definition of scope/variable: PARAM3 %Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_package_dimport.v0000664000177100017500000000303312671044616022345 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.916/test_regress/t/t_savable.pl0000775000177100017500000000132412671044616021003 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_clk_concat6.v0000664000177100017500000000353013205574202021375 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // module some_module ( input [3:0] i_clks ); logic [ 1 : 0 ] some_state; logic [1:0] some_other_state; logic the_clk; assign the_clk = i_clks[3]; always @(posedge the_clk) begin case (some_state) 2'b11: if (some_other_state == 0) some_state <= 2'b00; default: $display ("This is a display statement"); endcase if (the_clk) some_other_state <= 0; $write("*-* All Finished *-*\n"); $finish; end endmodule `define BROKEN module t1( input [3:0] i_clks, input i_clk0, input i_clk1 ); some_module some_module ( .i_clks (i_clks) ); endmodule module ident( input i_ident, output o_ident ); assign o_ident = i_ident; endmodule module t2( input [2:0] i_clks, input i_clk0, input i_clk1, input i_clk2, input i_data ); logic [3:0] the_clks; logic data_q; logic ident_clk1; always @(posedge i_clk0) begin data_q <= i_data; end ident ident ( .i_ident (i_clk1), .o_ident (ident_clk1) ); t1 t1 ( .i_clks ({ident_clk1, i_clk2, ident_clk1, i_clk0}), .i_clk0 (i_clk0), .i_clk1 (i_clk1) ); endmodule module t( /*AUTOARG*/ // Inputs clk /*verilator clocker*/ /*verilator public_flat*/, input clk0 /*verilator clocker*/, input clk1 /*verilator clocker*/, input clk2 /*verilator clocker*/, input data_in ); input clk; logic [2:0] clks; assign clks = {1'b0, clk1, clk0}; t2 t2 ( .i_clks (clks), .i_clk0 (clk0), .i_clk1 (clk), .i_clk2 (clk2), .i_data (data_in) ); endmodule verilator-3.916/test_regress/t/t_var_const.v0000664000177100017500000000105512671044616021214 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.916/test_regress/t/t_func_public.v0000664000177100017500000001262612473477707021530 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.916/test_regress/t/t_interface_missing_bad.v0000664000177100017500000000076413205574202023514 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Missing interface test // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. // Interface intentionally not defined //interface foo_intf; // logic a; //endinterface module foo_mod ( foo_intf foo ); endmodule module t (/*AUTOARG*/); foo_intf the_foo (); foo_mod foo_mod ( .foo (the_foo) ); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_preproc_persist.out0000664000177100017500000000014513205574202022773 0ustar wsnyderwsnyderInside "t/t_preproc_persist.v". Inside "t/t_preproc_persist_inc.v". Inside "t/t_preproc_persist2.v". verilator-3.916/test_regress/t/t_unroll_complexcond.v0000664000177100017500000000173613205574202023123 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This files is used to generated the BLKLOOPINIT error which // is actually caused by not being able to unroll the for loop. // // // 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; reg [3:0] tmp [3:0]; initial begin tmp[0] = 4'b0000; tmp[2] = 4'b0010; tmp[3] = 4'b0011; end // Test loop always @ (posedge clk) begin int i; int j; for (i = 0;(i < 4) && (i > 1); i++) begin tmp[i] <= tmp[i-i]; end if (tmp[0] != 4'b0000) $stop; if (tmp[3] != 4'b0011) $stop; j = 0; for (i=$c32("1"); i<3; ++i) j++; if (j!=2) $stop; j = 0; for (i=1; i<$c32("3"); ++i) j++; if (j!=2) $stop; j = 0; for (i=1; i<3; i=i+$c32("1")) j++; if (j!=2) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_clk_powerdn.v0000664000177100017500000000611512473477707021542 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.916/test_regress/t/t_dpi_import_c.cpp0000664000177100017500000001530413205574202022176 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 typedef struct { int a; int b; } substruct_t; #ifdef NEED_EXTERNS extern "C" { // If get ncsim: *F,NOFDPI: Function {foo} not found in default libdpi. // Then probably forgot to list a function here. 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_struct (const svBitVecVal* i, svBitVecVal* o); extern void dpii_v_substruct (const svBitVecVal* i, int* 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_v_struct (const svBitVecVal* i, svBitVecVal* o); extern void dpii_v_substruct (const svBitVecVal* i, int* o); extern void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o); extern void dpii_v_bit95(const svBitVecVal* i, svBitVecVal* o); extern void dpii_v_bit96(const svBitVecVal* i, svBitVecVal* o); extern int dpii_f_strlen (const char* i); 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_fa_bit(int i); } #endif //====================================================================== unsigned char dpii_f_bit (unsigned char i) { return VL_MASK_I(1) & ~i; } svBitVecVal dpii_f_bit8 (const svBitVecVal *i) { return VL_MASK_I(8) & ~*i; } svBitVecVal dpii_f_bit9 (const svBitVecVal *i) { return VL_MASK_I(9) & ~*i; } svBitVecVal dpii_f_bit16(const svBitVecVal *i) { return VL_MASK_I(16) & ~*i; } svBitVecVal dpii_f_bit17(const svBitVecVal *i) { return VL_MASK_I(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.5f; } void dpii_v_bit (unsigned char i, unsigned char *o) { *o = VL_MASK_I(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.5f; } void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o) { o[0] = ~i[0]; o[1] = ~i[1]; o[2] = ~i[2]; } void dpii_v_substruct (const svBitVecVal* i, int* o) { // To be most like other tools, this should automagically take the substruct_t // as an argument, and not require this cast... substruct_t* issp = (substruct_t*) i; o[0] = issp->b - issp->a; } 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] = VL_MASK_I(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.916/test_regress/t/t_select_bound1.v0000664000177100017500000000420113205574202021732 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. // bug823 module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [2:0] in = crc[2:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [3:0] mask; // From test of Test.v wire [3:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[3:0]), .mask (mask[3:0]), // Inputs .clk (clk), .in (in[2:0])); // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, out & mask}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x out=%b mask=%b\n",$time, cyc, crc, out, mask); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'ha9d3a7a69d2bea75 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, mask, // Inputs clk, in ); input clk; input [2:0] in; output reg [3:0] out; output reg [3:0] mask; localparam [15:5] p = 11'h1ac; always @(posedge clk) begin // verilator lint_off WIDTH out <= p[15 + in -: 5]; // verilator lint_on WIDTH mask[3] <= ((15 + in - 5) < 12); mask[2] <= ((15 + in - 5) < 13); mask[1] <= ((15 + in - 5) < 14); mask[0] <= ((15 + in - 5) < 15); end endmodule verilator-3.916/test_regress/t/t_concat_opt.v0000664000177100017500000000341213205574202021337 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Jie Xu. // // The test was added together with the concat optimization. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [31:0] in_a; reg [31:0] in_b; reg [31:0] in_c; reg [31:0] in_d; reg [31:0] in_e; reg [15:0] in_f; wire [31:0] in_g; assign in_g = in_a << 4; reg [31:0] out_x; reg [31:0] out_y; reg [31:0] out_z; reg [31:0] out_o; reg [31:0] out_p; reg [31:0] out_q; assign out_x = {in_a[31:16] & in_f, in_a[15:0] & in_f}; assign out_y = {in_a[31:18] & in_b[31:18], in_a[17:0] & in_b[17:0]}; assign out_z = {in_c[31:14] & in_d[31:14] & in_e[31:14], in_c[13:0] & in_d[13:0] & in_e[13:0]}; assign out_o = out_z | out_y; assign out_p = {in_a[31:16] & in_f | in_e[31:16], in_a[15:0] & in_f | in_e[15:0]}; assign out_q = {{in_a[31:25] ^ in_g[31:25], in_a[24:16] ^ in_g[24:16]}, {in_a[15:5] ^ in_g[15:5], in_a[4:0] ^ in_g[4:0]}}; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; in_a <= cyc; in_b <= cyc + 1; in_c <= cyc + 3; in_d <= cyc + 8; in_e <= cyc; in_f <= cyc[15:0]; if (out_x != (in_a & {2{in_f}})) $stop; if (out_y != (in_a&in_b)) $stop; if (out_z != (in_e&in_d&in_c)) $stop; if (out_o != (((in_a&in_b)|(in_c&in_e&in_d)))) $stop; if (out_p != (in_a & {2{in_f}} | in_e)) $stop; if (out_q != (in_a ^ in_g)) $stop; if (cyc==100) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_interface_param1.v0000664000177100017500000000165112671044616022421 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jie Xu. //bug692 module t (/*AUTOARG*/ // Inputs clk ); input wire clk; wire [31:0] result; test_if #(.id(3)) s(); sub_test U_SUB_TEST(s.a.b, result); // the line causing error endmodule : t // --------------------------------------------------------------------------- module sub_test ( input [31:0] b, output [31:0] c ); assign c = b; endmodule // --------------------------------------------------------------------------- interface test_if #(parameter id = 0) (); typedef struct packed { logic a; logic [31:0] b; } aType; aType a; typedef struct packed { logic c; logic [31:0] d; } bType; bType b; modport master (input a, output b); endinterface verilator-3.916/test_regress/t/t_math_signed_wire.v0000664000177100017500000000200212671044616022517 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.916/test_regress/t/t_gen_forif.v0000664000177100017500000000442312473477707021171 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.916/test_regress/t/t_sv_cpu_code/0000775000177100017500000000000013206353162021311 5ustar wsnyderwsnyderverilator-3.916/test_regress/t/t_sv_cpu_code/program_h.sv0000664000177100017500000000201412671044616023644 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.916/test_regress/t/t_sv_cpu_code/timescale.sv0000664000177100017500000000041112671044616023633 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.916/test_regress/t/t_sv_cpu_code/ports_h.sv0000664000177100017500000000172712671044616023356 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.916/test_regress/t/t_sv_cpu_code/pad_gnd.sv0000664000177100017500000000102112671044616023257 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.916/test_regress/t/t_sv_cpu_code/adrdec.sv0000664000177100017500000000215312671044616023114 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.916/test_regress/t/t_sv_cpu_code/ports.sv0000664000177100017500000001020713165153320023030 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. `ifdef VERILATOR //TODO `define PACKED packed `else `define packed `endif module ports #( parameter ID = 1 ) ( // *************************************************************************** // Module Interface (interfaces, outputs, and inputs) // *************************************************************************** genbus_if.slave dbus, pads_if.mp_dig padsif, // - System - input logic clk, input logic rst ); // *************************************************************************** // Regs and Wires // *************************************************************************** // **** Internal Data Bus **** logic [15:0] sdata; logic ws; logic [15:0] mdata; logic [15:0] adr; logic [1:0] we; logic [1:0] re; // **** Interal Registers **** struct `PACKED { logic [7:0][1:0] in; logic [7:0] dir; logic [7:0] out; struct `PACKED { logic [7:2] reserved; logic pullupen; logic slewlim; } cfg; } port [PORTID_A:PORTID_D]; // *************************************************************************** // "dbus" Connection // *************************************************************************** always_comb begin: dbus_Connect dbus.sConnect( .id(ID), .rst(rst), .sdata(sdata), .ws(ws), .mdata(mdata), .adr(adr), .we(we), .re(re) ); end // *************************************************************************** // Register Access // For PORTA...PORTD (Excluding I and O) // +0x00 DIR // +0x01 OUT // +0x02 IN // +0x03 CFG // *************************************************************************** always_comb begin padsif.Init(); end // **** Register Write **** always_ff @( posedge clk ) begin // - Local Variables - integer i, j; // **** Setup Port Registers **** for ( j = PORTID_A; j <= PORTID_D; j++ ) begin if ( padsif.IsPort( j ) ) begin if ( ((adr[3:2] == j[1:0]) && (adr[1] == 1'b0)) | rst ) begin if ( we[0] ) port[j].dir <= mdata[7:0]; if ( we[1] ) port[j].out <= mdata[15:8]; end end else begin port[j].dir <= 8'h00; port[j].out <= 8'h00; end end end // **** Regiser Read **** always_comb begin: RegisterRead // - Local Variables - integer i, j; logic [7:0] data [PORTID_D:PORTID_A][3:0]; // **** Output to "dbus" **** // - Setup read multiplexer - for ( j = PORTID_A; j <= PORTID_D; j++ ) begin if ( padsif.IsPort( j ) ) data[j] = '{ port[j].dir, port[j].out, 8'h00, 8'h00 }; else data[j] = '{ 8'h00, 8'h00, 8'h00, 8'h00 }; end // - Connect "genbusif" - sdata = { 8'h00, data[ adr[3:2] ][ adr[1:0] ] }; ws = 1'b0; end // *************************************************************************** // Output // *************************************************************************** always_comb begin // - Local Variables - integer i, j; // **** Defaults **** for ( i = 1; i <= $size( pinout ); i++ ) begin padsif.pullup_en [i] = 1'b0; padsif.pulldown_en [i] = 1'b0; padsif.output_en [i] = 1'b0; padsif.output_val [i] = 1'b0; padsif.slew_limit_en[i] = 1'b0; padsif.input_en [i] = 1'b0; end // **** Connect to Pads **** for ( i = 1; i <= $size( pinout ); i++ ) begin j = pinout[i].id; if ( PINID_D7 >= j ) begin padsif.output_en [i] = port[j[4:3]].dir[j[2:0]]; padsif.output_val[i] = port[j[4:3]].out[j[2:0]]; end end end endmodule // ports verilator-3.916/test_regress/t/t_sv_cpu_code/ac_dig.sv0000664000177100017500000000645312671044616023107 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. module ac_dig #( parameter ID = 1 ) ( // *************************************************************************** // Module Interface (interfaces, outputs, and inputs) // *************************************************************************** // **** Interfaces **** genbus_if.slave dbus, // **** Outputs **** output logic acenable, // **** Inputs **** input logic acout, // - System - input logic clk, input logic rst ); // *************************************************************************** // Regs and Wires // *************************************************************************** // **** Internal Data Bus **** logic [15:0] sdata; logic ws; logic [15:0] mdata; logic [15:0] adr; logic [1:0] we; logic [1:0] re; // **** User Registers **** struct packed { logic [7:1] reserved; logic enable; } control; struct packed { logic [7:1] reserved; logic acout; } status; // **** Internals **** logic [1:0] sync; // *************************************************************************** // Assignments // *************************************************************************** assign acenable = control.enable; // *************************************************************************** // "dbus" Connection // *************************************************************************** always_comb begin `ifdef VERILATOR //TODO dbus.sConnect( .id(ID), .rst(rst), .sdata(sdata), .ws(ws), .mdata(mdata), .adr(adr ), .we(we), .re(re) ); `else dbus.sConnect( .id(ID), .rst(rst), .sdata(sdata), .ws(ws), .mdata(mdata), .adr(adr[1:0]), .we(we), .re(re) ); `endif // dbus.sConnect( ID, rst, sdata, ws, mdata, adr, we, re ); end // *************************************************************************** // Register Access // *************************************************************************** // **** Register Write **** always_ff @( posedge clk ) begin if ( rst ) control <= 8'h00; else if ( (adr[1:0] == 2'b00) & we[0] ) control <= mdata[7:0]; end // **** Regiser Read **** always_comb begin: RegisterRead // - Local Variables - logic [7:0] data[0:3]; // Read access concatination. // - Setup read multiplexer - data = '{ control, status, 8'h00, 8'h00 }; // - Connect "genbusif" - sdata = { 8'h00, data[ adr[1:0] ] }; ws = 1'b0; end // *************************************************************************** // Status // *************************************************************************** // **** Synchronization **** always_ff @( posedge clk ) begin if ( rst ) sync <= 2'b00; else if ( control.enable ) sync <= {sync[0], acout}; end always_comb begin // - Defaults - status = {$size(status){1'b0}}; // - Set register values - status.acout = sync[1]; end endmodule // ac_dig verilator-3.916/test_regress/t/t_sv_cpu_code/rom.sv0000664000177100017500000000147212671044616022472 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.916/test_regress/t/t_sv_cpu_code/ac.sv0000664000177100017500000000350512671044616022257 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.916/test_regress/t/t_sv_cpu_code/pinout_h.sv0000664000177100017500000000322612671044616023521 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.916/test_regress/t/t_sv_cpu_code/pads_h.sv0000664000177100017500000000535312671044616023135 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.916/test_regress/t/t_sv_cpu_code/pad_gpio.sv0000664000177100017500000000211112671044616023446 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. //***************************************************************************** // PAD_GPIO - General Purpose I/O Pad (Dummy!!!!) //***************************************************************************** module pad_gpio #( parameter ID = 0 ) ( input logic pullup_en, input logic pulldown_en, input logic output_en, input logic output_val, input logic slew_limit_en, input logic input_en, output logic input_val, inout wire ana, inout wire pad ); // **** Analog <-> pad connection **** `ifndef VERILATOR //TODO alias alias ana = pad; `endif // **** Digital driver <-> pad connection **** assign pad = (output_en) ? output_val : 1'bz; // **** Digital pull-up/pull-down <-> pad connection **** // TO BE ADDED!!!! // **** Digital input <-> pad connection **** assign input_val = (input_en) ? pad : 1'b0; endmodule // pad_gpio verilator-3.916/test_regress/t/t_sv_cpu_code/cpu.sv0000664000177100017500000001331012671044616022456 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. module cpu #( parameter // ... ID = 1 ) // Not used! ( // *************************************************************************** // Module Interface (interfaces, outputs, and inputs) // *************************************************************************** // **** Interfaces **** genbus_if.master dbus, // **** Outputs **** // N/A // **** Inputs **** input logic clk, input logic rst ); // *************************************************************************** // Regs and Wires // *************************************************************************** // **** Program Memory **** logic [15:0] rom_out; // **** Register File (RF) **** logic [7:0] rf[0:15]; // **** Fetch Stage **** logic [7:0] pc; // PC -> Program counter. logic [15:0] ir; // IR -> Instruction Register. // **** Decode **** logic [3:0] idec_rd; logic idec_rd_we; logic [7:0] idec_rd_data; logic [3:0] idec_rs; logic [7:0] idec_nextpc; // New PC if change of program flow. logic idec_coff; // Indicates a change of program flow. logic [7:0] idec_mem_adr; logic idec_mem_re; logic idec_mem_we; // **** Memory **** logic [7:0] mem_data; // Data from peripheral. logic mem_ws; // Waitstate. // *************************************************************************** // Program Memory (ROM) Interface // *************************************************************************** always_comb begin: ROM // - Local Variables - integer i; reg [15:0] irom [0:255]; // - Set default - for ( i = 0; i < 256; i++ ) begin if ( i < $size(rom) ) irom[i] = rom[i]; else irom[i] = 16'h0000; end rom_out = irom[pc[7:0]]; end // *************************************************************************** // Register File (RF) // *************************************************************************** always_ff @( posedge clk ) begin: RegFile // - Local Variables - integer i; // - Register File - for ( i = 0; i < 16; i++ ) begin if ( rst ) rf[i][7:0] <= 8'h00; else if ( idec_rd_we & (idec_rd == i[3:0]) ) rf[i] <= idec_rd_data; end end // *************************************************************************** // Fetch Stage // *************************************************************************** // **** Program Counter (PC) / Instruction Register (IR) **** always_ff @( posedge clk ) begin if ( rst ) begin pc <= 8'h00; ir <= 16'h0000; end else //if ( ~mem_ws ) begin if ( ~idec_coff ) begin pc <= pc + 1; ir <= rom_out; // Fetch Instruction. end else begin pc <= idec_nextpc; ir <= 16'h0000; // Insert no operation (NOP). end end end // *************************************************************************** // Decode/Execute Stage // *************************************************************************** always_comb begin // - Defaults - idec_rd = 4'h0; idec_rd_we = 1'b0; idec_rd_data = 8'h00; idec_rs = 4'h0; idec_nextpc = 8'h00; idec_coff = 1'b0; idec_mem_adr = 8'h00; idec_mem_re = 1'b0; idec_mem_we = 1'b0; casez ( ir ) 16'h0000:; // NOP (<=> Default) 16'h1???: // JMP imm begin idec_nextpc = ir[7:0]; idec_coff = 1'b1; end 16'h4???: // LDI rd, imm begin idec_rd = ir[8+:4]; idec_rd_we = 1'b1; idec_rd_data = ir[0+:8]; end 16'h8???: begin // STS imm, rs idec_mem_adr = ir[0+:8]; idec_mem_we = 1'b1; idec_rs = ir[8+:4]; end 16'h9???: begin // LDS rd, imm idec_mem_adr = ir[0+:8]; idec_mem_we = 1'b1; idec_rd = ir[8+:4]; idec_rd_we = 1'b1; idec_rd_data = mem_data[0+:8]; end endcase end // *************************************************************************** // Memory Access ("Stage") // *************************************************************************** // **** Connect to "dbus" **** always_comb begin: Conntect reg [15:0] sdata16; dbus.mConnect ( ID, // ID sdata16, // sdata mem_ws, // ws {2{rf[idec_rs]}}, // mdata // adr {8'h00, idec_mem_adr[7:1], 1'b0}, // we {idec_mem_adr[0],~idec_mem_adr[0]} & {2{idec_mem_we}}, // re {idec_mem_adr[0],~idec_mem_adr[0]} & {2{idec_mem_re}} ); // - Connect 16-bit databus to 8-bit CPU - mem_data = ( idec_mem_adr[0] ) ? sdata16[15:8] : sdata16[7:0]; end mPreAdrDecode_resp busproperty; always_comb begin: PreAdrDecode // verilator lint_off WIDTH busproperty = dbus.mPreAdrDecode( 0, idec_mem_adr ); // verilator lint_on WIDTH end endmodule // cpu verilator-3.916/test_regress/t/t_sv_cpu_code/chip.sv0000664000177100017500000000654212671044616022623 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. // ***************************************************************************** // Top level of System Verilog evalution (Full chip level) // ***************************************************************************** module chip #( parameter NUMPADS = $size( pinout ) ) ( // **** Pinout **** `ifdef VERILATOR // see t_tri_array inout wire [NUMPADS:1] pad, `else inout wire pad [1:NUMPADS], `endif // **** Inputs !!!! **** input logic clk, input logic rst ); // *************************************************************************** // Local Parameters // *************************************************************************** localparam NSLAVES = 2; // *************************************************************************** // PADS // *************************************************************************** // **** Interface **** pads_if padsif(); // **** Pad Instansiations **** pads // #( ) i_pads ( /*AUTOINST*/ // Interfaces .padsif (padsif.mp_pads), // Inouts .pad (pad), // Inputs .clk (clk), .rst (rst)); // *************************************************************************** // "dbus" Interface // *************************************************************************** genbus_if #( .NSLAVES(NSLAVES) ) dbus( .clk(clk), .rst(rst), .test_mode(1'b0) ); adrdec // #( ) i_adrdec ( /*AUTOINST*/ // Interfaces .dbus (dbus.adrdec)); // *************************************************************************** // CPU ("dbus" Master) // *************************************************************************** cpu #( .ID(1) ) i_cpu ( /*AUTOINST*/ // Interfaces .dbus (dbus.master), // Inputs .clk (clk), .rst (rst)); // *************************************************************************** // PORTS ("dbus" Slave #1) // *************************************************************************** ports #( .ID(1) ) i_ports ( /*AUTOINST*/ // Interfaces .dbus (dbus.slave), .padsif (padsif.mp_dig), // Inputs .clk (clk), .rst (rst)); // *************************************************************************** // Analog Comparator ("dbus" Slave #2) // *************************************************************************** ac #( .ID(2) ) i_ac ( /*AUTOINST*/ // Interfaces .dbus (dbus.slave), .padsif (padsif.mp_ana), // Inputs .clk (clk), .rst (rst)); endmodule // chip verilator-3.916/test_regress/t/t_sv_cpu_code/pad_vdd.sv0000664000177100017500000000101612671044616023270 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.916/test_regress/t/t_sv_cpu_code/pads_if.sv0000664000177100017500000000570312671044616023303 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.916/test_regress/t/t_sv_cpu_code/ac_ana.sv0000664000177100017500000000202612671044616023073 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.916/test_regress/t/t_sv_cpu_code/pads.sv0000664000177100017500000000523312671044616022623 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. module pads #( parameter NUMPADS = $size( pinout ) ) ( // *************************************************************************** // Module Interface // *************************************************************************** // **** Interfaces **** pads_if.mp_pads padsif, // **** Pinout **** `ifdef VERILATOR // see t_tri_array inout wire [NUMPADS:1] pad, `else inout wire pad [1:NUMPADS], `endif // **** Inputs **** input logic clk, input logic rst ); // *************************************************************************** // Code Section // *************************************************************************** `ifdef VERILATOR // see t_tri_array tri [NUMPADS:1] _anahack; `endif genvar i; for ( i = 1; i <= NUMPADS; i++ ) begin `ifdef VCS localparam t_padtype p_type = t_padtype'(pinout_wa[i][pinout_wa_padtype]); localparam t_pinid p_id = t_pinid'(pinout_wa[i][pinout_wa_id]); `else localparam t_padtype p_type = pinout[i].padtype; localparam t_pinid p_id = pinout[i].id; `endif case ( p_type ) PADTYPE_GPIO: pad_gpio #( .ID( i ) ) i_pad_gpio( .pad (pad [i]), // Outputs .input_val (padsif.input_val [i]), // Inouts `ifdef VERILATOR // see t_tri_array .ana (_anahack [i]), `else .ana (padsif.ana [i]), `endif // Inputs .pullup_en (padsif.pullup_en [i]), .pulldown_en (padsif.pulldown_en [i]), .output_en (padsif.output_en [i]), .output_val (padsif.output_val [i]), .slew_limit_en (padsif.slew_limit_en[i]), .input_en (padsif.input_en [i]) /*AUTOINST*/); PADTYPE_VDD: begin pad_vdd #( .ID( i ) ) i_pad_vdd( .pad (pad[i]) /*AUTOINST*/); // Not SV standard, yet... assign padsif.input_val[i] = (); end PADTYPE_GND: begin pad_gnd #( .ID( i ) ) i_pad_gnd(.pad (pad[i]) /*AUTOINST*/); end endcase end endmodule // pads verilator-3.916/test_regress/t/t_sv_cpu_code/genbus_if.sv0000664000177100017500000001505012671044616023633 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. typedef struct packed { bit [1:0] size; } mPreAdrDecode_resp; interface genbus_if #( parameter DSIZE = 2, SSIZE = DSIZE, ASIZE = 16, NMASTERS = 1, NSLAVES = 1, DMSB = (DSIZE<<3) - 1, SMSB = SSIZE - 1, AMSB = ASIZE - 1 ) ( // **** Inputs **** // - System - input logic clk, // Device Clock. input logic rst, // Device Reset. input logic test_mode // Test mode. ); // *************************************************************************** // Interface Variables // *************************************************************************** // **** Master **** logic [DMSB:0] m_sdata[1:NMASTERS]; // Slave data. logic m_ws [1:NMASTERS]; // Slave wait state. logic [DMSB:0] m_mdata[1:NMASTERS]; // Master data. logic [AMSB:0] m_adr [1:NMASTERS]; // Address. logic [SMSB:0] m_we [1:NMASTERS]; // Write enable. logic [SMSB:0] m_re [1:NMASTERS]; // Read enable. // **** Slave **** logic [DMSB:0] s_sdata[1:NSLAVES]; // Slave data (from slave). logic s_ws [1:NSLAVES]; // Slave wait state (from slave). logic [DMSB:0] s_mdata[1:NSLAVES]; // Master data (to slave). logic [AMSB:0] s_adr [1:NSLAVES]; // Address (to slave). logic [SMSB:0] s_we [1:NSLAVES]; // Write enable (to slave). logic [SMSB:0] s_re [1:NSLAVES]; // Read enable (to slave). // **** Address Decoder **** logic s_sel [1:NSLAVES]; // Slave select (to slave). // *************************************************************************** // Modports // *************************************************************************** modport master( import mConnect, import mPreAdrDecode, input m_sdata, input m_ws, output m_mdata, output m_adr, output m_we, output m_re ); // - Slaves - modport slave( import sConnect, output s_sdata, output s_ws, input s_mdata, input s_adr, input s_we, input s_re, input s_sel ); // UNSUPPORTED // for (genvar i = 1; i <= NSLAVES; i++ ) // begin: mps // modport slave( // import sConnect, // output .s_sdata( s_sdata[i] ), // output .s_ws ( s_ws [i] ), // input .s_mdata( s_mdata[i] ), // input .s_adr ( s_adr [i] ), // input .s_we ( s_we [i] ), // input .s_re ( s_re [i] ), // input .s_sel ( s_sel [i] ) // ); // end // blocks modport adrdec( import aNumSlaves, input s_adr, output s_sel ); // *************************************************************************** // Bus Multiplexers // *************************************************************************** always_comb begin: busmux // - Local Variables - integer i; // - Defautls - m_sdata[1] = {(DSIZE<<3){1'b0}}; m_ws [1] = 1'b0; for ( i = 1; i <= NSLAVES; i++ ) begin m_sdata[1] |= s_sdata[i]; m_ws [1] |= s_ws [i]; s_mdata[i] = m_mdata[1]; s_adr [i] = m_adr [1]; s_we [i] = m_we [1]; s_re [i] = m_re [1]; end end // *************************************************************************** // Master Functions and Tasks // *************************************************************************** function automatic void mConnect( input integer id, output logic [DMSB:0] sdata, output logic ws, input logic [DMSB:0] mdata, input logic [AMSB:0] adr, input logic [SMSB:0] we, input logic [SMSB:0] re ); begin m_mdata[id] = mdata; m_adr [id] = adr; m_we [id] = we; m_re [id] = re; sdata = m_sdata[id]; ws = m_ws [id]; end endfunction function automatic mPreAdrDecode_resp mPreAdrDecode( input integer id, input logic [AMSB:0] adr ); begin // ToDo: Add parameterized address decoding!!!! // Example code: if ( adr[0] ) mPreAdrDecode.size = 2'b01; // Word (16-bit) memory. else mPreAdrDecode.size = 2'b10; // Double Word (32-bit) memory. end endfunction // *************************************************************************** // Slave Functions and Tasks // *************************************************************************** function automatic void sConnect( input integer id, input logic rst, input logic [DMSB:0] sdata, input logic ws, output logic [DMSB:0] mdata, output logic [AMSB:0] adr, output logic [SMSB:0] we, output logic [SMSB:0] re ); begin s_sdata[id] = sdata & {(DSIZE<<3){s_sel[id]}}; // verilator lint_off WIDTH s_ws [id] = ws & {SSIZE{s_sel[id]}}; // verilator lint_on WIDTH mdata = s_mdata[id] & {16{~rst}}; adr = s_adr [id]; we = (s_we [id] & {SSIZE{s_sel[id]}}) | {SSIZE{rst}}; re = s_re [id] & {SSIZE{s_sel[id]}}; end endfunction // *************************************************************************** // Address Decoder Functions and Tasks // *************************************************************************** function automatic integer aNumSlaves; aNumSlaves = NSLAVES; endfunction endinterface // genbus_if verilator-3.916/test_regress/t/t_order_2d.pl0000775000177100017500000000072213205574202021060 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_modport.pl0000775000177100017500000000072713151152521023065 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_init_concat.v0000664000177100017500000000341712473477707021527 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.916/test_regress/t/t_assert_basic.v0000664000177100017500000000232013205574202021645 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg toggle; integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; always @ (negedge clk) begin AssertionFalse1: assert (cyc<100); assert (!(cyc==5) || toggle); // FIX cover {cyc==3 || cyc==4}; // FIX cover {cyc==9} report "DefaultClock,expect=1"; // FIX cover {(cyc==5)->toggle} report "ToggleLogIf,expect=1"; end always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; toggle <= !cyc[0]; if (cyc==7) assert (cyc[0] == cyc[1]); // bug743 if (cyc==9) begin `ifdef FAILING_ASSERTIONS assert (0) else $info; assert (0) else $info("Info message"); assert (0) else $info("Info message, cyc=%d", cyc); InWarningBlock: assert (0) else $warning("Warning.... 1.0=%f 2.0=%f", 1.0, 2.0); InErrorBlock: assert (0) else $error("Error...."); assert (0) else $fatal(1,"Fatal...."); `endif end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_func_dotted_inl0.pl0000775000177100017500000000104113151152521022567 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_dpi_name_bad.pl0000775000177100017500000000115112473477707021761 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_tri_gate_notif0.pl0000775000177100017500000000134313151152521022431 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_preproc_persist2.v0000664000177100017500000000032613205574202022514 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. Inside `__FILE__. `include "t_preproc_persist_inc.v" verilator-3.916/test_regress/t/t_flag_lib.v0000664000177100017500000000032612473477707020770 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.916/test_regress/t/t_unoptflat_simple_2_bad.pl0000775000177100017500000000137313205574202023777 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_unoptflat_simple_2.v"); # Compile only compile ( verilator_flags3 => [], verilator_flags2 => ["--report-unoptflat"], fails => 1, expect=> '.*%Warning-UNOPTFLAT: Widest candidate vars to split: %Warning-UNOPTFLAT: t/t_unoptflat_simple_2.v:\d+: t.x, width 3, fanout \d+ .*%Error: Exiting due to ', ); ok(1); 1; verilator-3.916/test_regress/t/t_param_long.pl0000775000177100017500000000071712473477707021525 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_unoptflat_simple_2.v0000664000177100017500000000120712671044616023023 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.916/test_regress/t/t_func_sum.v0000664000177100017500000000362212473477707021052 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.916/test_regress/t/t_interface_array_bad.v0000664000177100017500000000214213205574202023151 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Demonstrate deferred linking error messages // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. interface foo_intf; logic a; endinterface function integer the_other_func (input integer val); return val; endfunction module t (/*AUTOARG*/); localparam N = 4; foo_intf foos [N-1:0] (); logic [ 7 : 0 ] bar; // Non-constant dotted select is not allowed assign foos[bar].a = 1'b1; baz baz_inst (); // Unsure how to produce V3Param AstCellRef visitor errors //assign baz_inst.x = 1'b1; //assign baz_inst.N = 1'b1; //assign baz_inst.7 = 1'b1; //assign baz_inst.qux_t = 1'b1; //assign baz_inst.the_func = 1'b1; //assign baz_inst.the_lp = 1'b1; //assign bar.x = 1'b1; //assign fake_inst.x = 1'b1; //assign the_other_func.x = 1'b1; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule module baz; typedef integer qux_t; function integer the_func (input integer val); return val; endfunction localparam the_lp = 5; endmodule verilator-3.916/test_regress/t/t_flag_relinc_dir/0000775000177100017500000000000013206353162022123 5ustar wsnyderwsnyderverilator-3.916/test_regress/t/t_flag_relinc_dir/chip/0000775000177100017500000000000013206353162023046 5ustar wsnyderwsnyderverilator-3.916/test_regress/t/t_flag_relinc_dir/chip/t_flag_relinc_sub.v0000664000177100017500000000064713205574202026704 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2017 by Wilson Snyder. This program is free software; you can // redistribute it and/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/t_flag_relinc.vh" module t_flag_relinc_sub (); initial begin `all_finished; $finish; end endmodule verilator-3.916/test_regress/t/t_flag_relinc_dir/include/0000775000177100017500000000000013206353162023546 5ustar wsnyderwsnyderverilator-3.916/test_regress/t/t_flag_relinc_dir/include/t_flag_relinc.vh0000664000177100017500000000052213205574202026673 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. `define all_finished $write("*-* All Finished *-*\n") verilator-3.916/test_regress/t/t_func_bad_width.v0000664000177100017500000000065412473477707022175 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.916/test_regress/t/t_math_strwidth.v0000664000177100017500000000066212473477707022115 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.916/test_regress/t/t_flag_parameter.pl0000775000177100017500000000116713205574202022335 0ustar 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 ( # It is not possible to put them into the options file v_flags2 => ['-Gstring1="\"New String\"" -pvalue+string2="\"New String\"" -f t/t_flag_parameter.vc'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_dist_install.pl0000775000177100017500000000301513205574202022047 0ustar 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.916/test_regress/t/t_interface_modport_import.pl0000775000177100017500000000072212671044616024465 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_array_nocolon.pl0000775000177100017500000000072213205574202024245 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mod_interface_array2.pl0000775000177100017500000000072213205574202023437 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_nest.pl0000775000177100017500000000071712473477707021352 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_dpi_vams.v0000664000177100017500000000076713205574202021022 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. //`begin_keywords "VAMS-2.3" `begin_keywords "1800+VAMS" module t (/*AUTOARG*/ // Outputs out, // Inputs in ); input in; wreal in; output out; wreal out; import "DPI-C" context function void dpii_call(input real in, output real out); initial begin dpii_call(in,out); $finish; end endmodule verilator-3.916/test_regress/t/t_trace_cat_renew_0100.out0000664000177100017500000000510213205574202023333 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 t $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.916/test_regress/t/t_case_deep.pl0000775000177100017500000000104612473477707021312 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_math_pow4.pl0000775000177100017500000000072212671044616021271 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_initial_dlyass_bad.pl0000775000177100017500000000115112671044616023202 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_math_trig.pl0000775000177100017500000000071712473477707021364 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_table_fsm.pl0000775000177100017500000000071712473477707021342 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_dist_whitespace.pl0000775000177100017500000000473113205574202022543 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 my %files = %{get_manifest_files($root)}; foreach my $file (sort keys %files) { my $filename = "$root/$file"; my $contents = file_contents($filename); if ($file =~ /\.out$/) { # Ignore golden files } elsif ($contents =~ /[\001\002\003\004\005\006]/) { # Ignore binrary files } elsif ($contents =~ /[ \t]\n/) { if ($ENV{HARNESS_UPDATE_GOLDEN}) { $contents =~ s/[ \t]+\n/\n/g; $warns{$file} = "Updated whitespace at $file"; write_wholefile($filename, $contents); next; } my @lines = split(/\n/, $contents); my $line_no = 0; foreach my $line (@lines) { $line_no++; # Trim trailing carriage-return (ascii 0xd) and form feed (0xc), # as we expect a few of those $line =~ s/[\x{d}\x{c}]//g; if ($line =~ /\s$/) { $warns{$file} = "Trailing whitespace at $file:$line_no"; $warns{$file} .= " (last character is ASCII " . ord(substr($line, -1, 1)) . ")"; } } } } if (keys %warns) { # First warning lists everything as that's shown in the driver summary if ($ENV{HARNESS_UPDATE_GOLDEN}) { $Self->error("Updated files with whitespace errors: ",join(' ',sort keys %warns)); $Self->error("To auto-fix: HARNESS_UPDATE_GOLDEN=1 {command} or --golden"); } else { $Self->error("Files have whitespace errors: ",join(' ',sort keys %warns)); $Self->error("To auto-fix: HARNESS_UPDATE_GOLDEN=1 {command} or --golden"); } foreach my $file (sort keys %warns) { $Self->error($warns{$file}); } } ok(1); 1; sub get_manifest_files { my $root = shift; `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" if $Self->{verbose}; my %files; foreach my $file (split /\s+/,$manifest_files) { next if $file eq ''; $files{$file} |= 1; } return \%files; } verilator-3.916/test_regress/t/t_gen_inc.pl0000775000177100017500000000071712473477707021010 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_star.pl0000775000177100017500000000072713205574202022356 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_flag_woff.v0000664000177100017500000000073012671044616021147 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t; // width warnings off due to command line wire A = 15'd1234; // width warnings off due to command line + manual switch // verilator lint_off WIDTH wire B = 15'd1234; // this turnon does nothing as off on command line // verilator lint_on WIDTH wire C = 15'd1234; endmodule verilator-3.916/test_regress/t/t_interface_twod.v0000664000177100017500000000154212671044616022214 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.916/test_regress/t/t_math_shiftrs.v0000664000177100017500000000226412473477707021727 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.916/test_regress/t/t_concat_large.v0000664000177100017500000000066413205574202021635 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/); wire [32767:0] a; initial begin // verilator lint_off WIDTHCONCAT a = {32768{1'b1}}; // verilator lint_on WIDTHCONCAT if (a[32000] != 1'b1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_vpi_get.pl0000775000177100017500000000147513205574202021023 0ustar 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->skip("Known compiler limitation") if $Self->cxx_version =~ /\(GCC\) 4.4/; compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --vpi --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.916/test_regress/t/t_param_local.pl0000775000177100017500000000072213205574202021632 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_struct_unpacked.pl0000775000177100017500000000072212671044616022565 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_array_pattern_packed.pl0000775000177100017500000000072212671044616023551 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_missing_bad.pl0000775000177100017500000000150413151152521022667 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( v_flags2 => ["--lint-only --Wall -Wno-DECLFILENAME"], fails=>1, expect=> q{%Warning-PINNOCONNECT: t/t_inst_missing_bad.v:8: Cell pin is not connected: __pinNumber2 %Warning-PINNOCONNECT: Use .* %Warning-PINCONNECTEMPTY: t/t_inst_missing_bad.v:8: Cell pin connected by name with empty reference: nc %Warning-PINMISSING: t/t_inst_missing_bad.v:8: Cell has missing pin: missing %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_preproc_inc_bad.pl0000775000177100017500000000126012473477707022511 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_param_first_b.v0000664000177100017500000000067112671044616022031 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_param_first_b (/*AUTOARG*/ // Outputs par, varwidth ); parameter X = 1; parameter FIVE = 0; // Overridden parameter TWO = 2; output [4:0] par; output [X:0] varwidth; wire [4:0] par = X; wire [X:0] varwidth = (FIVE==5)?TWO:0; endmodule verilator-3.916/test_regress/t/t_trace_complex.v0000664000177100017500000000420412671044616022042 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. bit global_bit; module t (clk); input clk; integer cyc=0; typedef struct packed { bit b1; bit b0; } strp_t; typedef struct packed { strp_t x1; strp_t x0; } strp_strp_t; typedef union packed { strp_t x1; strp_t x0; } unip_strp_t; typedef bit [2:1] arrp_t; typedef arrp_t [4:3] arrp_arrp_t; typedef strp_t [4:3] arrp_strp_t; typedef bit arru_t [2:1]; typedef arru_t arru_arru_t [4:3]; typedef arrp_t arru_arrp_t [4:3]; typedef strp_t arru_strp_t [4:3]; strp_t v_strp; strp_strp_t v_strp_strp; unip_strp_t v_unip_strp; arrp_t v_arrp; arrp_arrp_t v_arrp_arrp; arrp_strp_t v_arrp_strp; arru_t v_arru; arru_arru_t v_arru_arru; arru_arrp_t v_arru_arrp; arru_strp_t v_arru_strp; real v_real; real v_arr_real [2]; string v_string; typedef struct packed { logic [31:0] data; } str32_t; str32_t [1:0] v_str32x2; // If no --trace-struct, this packed array is traced as 63:0 initial v_str32x2[0] = 32'hff; initial v_str32x2[1] = 0; p #(.PARAM(2)) p2 (); p #(.PARAM(3)) p3 (); always @ (posedge clk) begin cyc <= cyc + 1; v_strp <= ~v_strp; v_strp_strp <= ~v_strp_strp; v_unip_strp <= ~v_unip_strp; v_arrp_strp <= ~v_arrp_strp; v_arrp <= ~v_arrp; v_arrp_arrp <= ~v_arrp_arrp; v_real <= v_real + 0.1; v_string <= "foo"; v_arr_real[0] <= v_arr_real[0] + 0.2; v_arr_real[1] <= v_arr_real[1] + 0.3; for (integer b=3; b<=4; b++) begin v_arru[b] <= ~v_arru[b]; v_arru_strp[b] <= ~v_arru_strp[b]; v_arru_arrp[b] <= ~v_arru_arrp[b]; for (integer a=3; a<=4; a++) begin v_arru_arru[a][b] = ~v_arru_arru[a][b]; end end v_str32x2[0] <= v_str32x2[0] - 1; v_str32x2[1] <= v_str32x2[1] + 1; if (cyc == 5) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module p; parameter PARAM = 1; initial global_bit = 1; endmodule verilator-3.916/test_regress/t/t_struct_init_trace.pl0000775000177100017500000000103513151152521023077 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_interface_gen10_noinl.pl0000775000177100017500000000102713205574202023510 0ustar wsnyderwsnyder#!/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_gen10.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_slice.v0000664000177100017500000000361113205574202021343 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Varun Koyyalagunta. // bug1015 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] i = crc[1:0]; logic [1:0] o [13:10] ; Test test (/*AUTOINST*/ // Outputs .o (o/*[1:0].[3:0]*/), // Inputs .i (i[1:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, 6'h0,o[13], 6'h0,o[12], 6'h0,o[11], 6'h0,o[10]}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x sum=%x\n",$time, cyc, crc, result, sum); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hb42b2f48a0a9375a if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( output logic [1:0] o [3:0], //but this works //logic [N-1:0] o input [1:0] i); parameter N = 4; logic [1:0] a [3:0]; initial a = '{2'h0,2'h1,2'h2,2'h3}; sub sub [N-1:0] (.o (o), // many-to-many .a (a), // many-to-many .i (i)); // many-to-one endmodule module sub ( input logic [1:0] i, input logic [1:0] a, output logic [1:0] o ); assign o = i + a; endmodule verilator-3.916/test_regress/t/t_lint_unsup_mixed.v0000664000177100017500000000076613205574202022605 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder. module t ( input wire clk, input wire a, input wire b ); integer q; // bug1120 always @ (a or posedge clk) begin if (a) q = 0; else q = q + 1; end // bug934 integer qb; always @((a && b) or posedge clk) begin if (a) qb = 0; else qb = qb + 1; end endmodule verilator-3.916/test_regress/t/t_pipe_filter_inc.vh0000664000177100017500000000041412473477707022532 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.916/test_regress/t/t_sys_system.pl0000775000177100017500000000071712473477707021630 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_genfor_hier.pl0000775000177100017500000000072213205574202021647 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_wide.v0000664000177100017500000000153112473477707021173 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.916/test_regress/t/t_var_dotted_inl0.pl0000775000177100017500000000104013151152521022423 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_dpi_shortcircuit2.pl0000775000177100017500000000115713205574202023023 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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_shortcircuit_c.cpp"], verilator_flags2 => ["-Wno-DECLFILENAME"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_eq.v0000664000177100017500000000347212473477707020654 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.916/test_regress/t/t_func_endian.pl0000775000177100017500000000071712473477707021657 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_overwide_bad.pl0000775000177100017500000000251713205574202023053 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_inst_overwide.v"); compile ( v_flags2 => ["--lint-only"], make_top_shell=>0, verilator_flags=> [qw(-cc)], verilator_make_gcc=>0, fails=>$Self->{v3}, expect=> q{%Warning-WIDTH: t/t_inst_overwide.v:\d+: Output port connection 'outy_w92' expects 92 bits on the pin connection, but pin connection's VARREF 'outc_w30' generates 30 bits. %Warning-WIDTH: Use .* to disable this message. %Warning-WIDTH: t/t_inst_overwide.v:\d+: Output port connection 'outz_w22' expects 22 bits on the pin connection, but pin connection's VARREF 'outd_w73' generates 73 bits. %Warning-WIDTH: t/t_inst_overwide.v:\d+: Input port connection 'inw_w31' expects 31 bits on the pin connection, but pin connection's VARREF 'ina_w1' generates 1 bits. %Warning-WIDTH: t/t_inst_overwide.v:\d+: Input port connection 'inx_w11' expects 11 bits on the pin connection, but pin connection's VARREF 'inb_w61' generates 61 bits. %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_clk_latch.v0000664000177100017500000000617312473477707021163 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.916/test_regress/t/t_typedef_signed.v0000664000177100017500000000370313205574202022202 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.916/test_regress/t/t_tri_public.pl0000775000177100017500000000067513205574202021523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_unpacked_array_order.v0000664000177100017500000000153713205574202023377 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Duraid Madina. module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter logic [1:0] t0 [ 2][ 2] = '{'{2'd0, 2'd1}, '{2'd2, 2'd3}}; parameter logic [1:0] t1 [0:1][0:1] = '{'{2'd0, 2'd1}, '{2'd2, 2'd3}}; parameter logic [1:0] t2 [1:0][1:0] = '{'{2'd3, 2'd2}, '{2'd1, 2'd0}}; always @ (posedge clk) begin if (t0[0][0] != t1[0][0]) $stop; if (t0[0][1] != t1[0][1]) $stop; if (t0[1][0] != t1[1][0]) $stop; if (t0[1][1] != t1[1][1]) $stop; if (t0[0][0] != t2[0][0]) $stop; if (t0[0][1] != t2[0][1]) $stop; if (t0[1][0] != t2[1][0]) $stop; if (t0[1][1] != t2[1][1]) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_concat_opt.pl0000775000177100017500000000071713205574202021515 0ustar 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.916/test_regress/t/t_flag_csplit.v0000664000177100017500000000172512671044616021511 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.916/test_regress/t/t_interface_gen.v0000664000177100017500000000345112671044616022011 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.916/test_regress/t/t_math_div.pl0000775000177100017500000000071712473477707021201 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_initial_dlyass.pl0000775000177100017500000000077712671044616022411 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_struct_nest.pl0000775000177100017500000000102412671044616021740 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_case_huge_sub2.v0000664000177100017500000002254112473477707022112 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.916/test_regress/t/t_var_overwidth_bad.v0000664000177100017500000000070413205574202022700 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; always @ (posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_func_mlog2.pl0000775000177100017500000000071712473477707021441 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_outoforder.v0000664000177100017500000000237312473477707022275 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.916/test_regress/t/t_struct_init.v0000664000177100017500000000624213205574202021561 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]; `ifdef T_STRUCT_INIT_BAD const b4_t b4_const_c = '{b1: 1'b1, b1: 1'b0, b0:1'b0, b2: 1'b1, b3: 1'b1}; `endif initial begin pack3_t tsu; tsu = 6'b110110; // 543210 if (tsu!=6'b110110) $stop; if (tsu[5:4]!=2'b11) $stop; if (tsu[5:4] == tsu[1:0]) $stop; // Not a good extraction test if LSB subtraction doesn't matter if (tsu.pvec!=6'b110110) $stop; if (tsu.pvec[6:5]!=2'b11) $stop; if (tsu.pack2[5:1] != 5'b11011) $stop; if (tsu.pack2.msb != 1'b1) $stop; if (tsu.pack2.lsb != 1'b0) $stop; if (tsu.pack2.four.quad0 != 4'b1011) $stop; if (tsu.pack2.four.quad1.b0 != 1'b1) $stop; if (tsu.pack2.four.quad1.b1 != 1'b1) $stop; if (tsu.pack2.four.quad1.b2 != 1'b0) $stop; if (tsu.pack2.four.quad1.b3 != 1'b1) $stop; // tsu = 1'b0 ? '0 : '{pvec: 6'b101011}; if (tsu!=6'b101011) $stop; // arr[0] = 6'b101010; arr[1] = 6'b010101; if (arr[0].four !== 4'b0101) $stop; if (arr[1].four !== 4'b1010) $stop; // // Initialization begin b4_t q = '{1'b1, 1'b1, 1'b0, 1'b0}; if (q != 4'b1100) $stop; end begin b4_t q = '{3{1'b1}, 1'b0}; if (q != 4'b1110) $stop; end begin b4_t q = '{4{1'b1}}; // Repeats the {} if (q != 4'b1111) $stop; end begin b4x2_t m = '{4'b1001, '{1'b1, 1'b0, 1'b1, 1'b1}}; if (m != 8'b10011011) $stop; end begin b4_t q = '{default:1'b1}; if (q != 4'b1111) $stop; end begin b4_t q = '{b0:1'b1, b2:1'b1, b3:1'b1, b1:1'b0}; if (q != 4'b1101) $stop; end begin b4_t q = '{b2:1'b0, default:1'b1}; if (q != 4'b1011) $stop; end if (b4_const_a != 4'b1001) $stop; if (b4_const_b != 4'b1001) $stop; if (b4_wire != 4'b1010) $stop; if (pat(4'b1100, 4'b1100)) $stop; if (pat('{1'b1, 1'b0, 1'b1, 1'b1}, 4'b1011)) $stop; $write("*-* All Finished *-*\n"); $finish; end function pat(b4_t in, logic [3:0] cmp); if (in !== cmp) $stop; pat = 1'b0; endfunction endmodule verilator-3.916/test_regress/t/t_inst_aport.v0000664000177100017500000000474012671044616021404 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.916/test_regress/t/t_rnd.v0000664000177100017500000000170412473477707020015 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.916/test_regress/t/t_gen_lsb.pl0000775000177100017500000000072212671044616021000 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_default_bad.pl0000775000177100017500000000111412473477707022623 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_dist_manifest.pl0000775000177100017500000000435613205574202022220 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 my %files = %{get_manifest_files($root)}; 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; sub get_manifest_files { my $root = shift; `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" if $Self->{verbose}; my %files; foreach my $file (split /\s+/,$manifest_files) { next if $file eq ''; $files{$file} |= 1; } return \%files; } verilator-3.916/test_regress/t/t_initial_inc.vh0000664000177100017500000000044312473477707021663 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.916/test_regress/t/t_assert_basic_off.pl0000775000177100017500000000101013151152521022637 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_interface_size_bad.pl0000775000177100017500000000153513205574202023163 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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=> q{%Error: t/t_interface_size_bad.v:\d+: Illegal IFACEREF port connection 'foo', mismatch between port which is an interface array of size 5, and expression which is an interface array of size 4. %Error: t/t_interface_size_bad.v:\d+: Illegal IFACEREF port connection 'foo', mismatch between port which is an interface array of size 5, and expression which is an interface array of size 6. %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_array_partial.pl0000775000177100017500000000071712473477707023275 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_port_bad.v0000664000177100017500000000051112473477707021667 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.916/test_regress/t/t_func_const_packed_struct_bad2.pl0000775000177100017500000000237613205574202025333 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2017 by Todd Strader. This program is free software; you can # redistribute it and/or 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-USERFATAL: f_add = 15 %Warning-USERFATAL: Use "/* verilator lint_off USERFATAL */" and lint_on around source to disable this message. %Error: t/t_func_const_packed_struct_bad2.v:19: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_add2' %Error: t/t_func_const_packed_struct_bad2.v:30: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing Called from: t/t_func_const_packed_struct_bad2.v:42: f_add() with parameters: params = [0 = '{a: 32'h7, foo: 6'hb, sub_params: '{b: 32'h37, bar: 8'h6f}}, 1 = '{a: 32'h3039, foo: 6'hc, sub_params: '{b: 32'h8, bar: 8'h70}}] Called from: t/t_func_const_packed_struct_bad2.v:19: f_add2() with parameters: a = ?32?sh7 b = ?32?sh8 c = ?32?sh9 }, ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_sformat_noopt.pl0000775000177100017500000000144213205574202023150 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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"], ); if ($Self->cxx_version =~ /clang version 3.8/) { $Self->skip("Known clang bug"); #Here: if (VL_UNLIKELY(VL_NEQ_W(12, __Vtemp1, vlSymsp->TOP__t.__PVT__str))) } else{ execute ( check_finished=>1, ); } ok(1); 1; verilator-3.916/test_regress/t/t_interface.v0000664000177100017500000000617712671044616021170 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.916/test_regress/t/t_mem_multi_io2.v0000664000177100017500000000140712671044616021760 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.916/test_regress/t/t_verilated_threaded.pl0000775000177100017500000000145513205574202023203 0ustar wsnyderwsnyder#!/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->skip("No thread support") if !$Self->cfg_with_threaded; top_filename("t/t_verilated_all.v"); my $root = ".."; compile ( # Can't use --coverage and --savable together, so cheat and compile inline verilator_flags2 => ['--cc --coverage-toggle --coverage-line --coverage-user --trace --threads 1 --vpi $root/include/verilated_save.cpp'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_pipe_filter.v0000664000177100017500000000065012473477707021533 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.916/test_regress/t/t_param_sel.v0000664000177100017500000000376612473477707021207 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.916/test_regress/t/t_interface_down.v0000664000177100017500000000261112671044616022204 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.916/test_regress/t/t_struct_packed_write_read.pl0000775000177100017500000000071712671044616024433 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_range.v0000664000177100017500000000260312473477707021340 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.916/test_regress/t/t_preproc_inc2.vh0000664000177100017500000000040012473477707021757 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.916/test_regress/t/t_inst_recurse_bad.pl0000775000177100017500000000133613205574202022675 0ustar 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+: Unsupported: Recursive multiple modules \(module instantiates something leading back to itself\): looped %Error: t/t_inst_recurse_bad.v:\d+: Note self-recursion \(module instantiating itself directly\) is supported. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_typedef_port.pl0000775000177100017500000000071712473477707022112 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_defaults.pl0000775000177100017500000000072213205574202022202 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_tri.v0000664000177100017500000000103412473477707021035 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.916/test_regress/t/t_initial_edge.pl0000775000177100017500000000077712671044616022016 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_display_noopt.pl0000775000177100017500000001161013205574202022242 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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=>dequote( q{[0] In top.t: Hi [0] In top.t.sub (sub) [0] In top.t.sub.subblock (sub) [0] In top.t.sub2 (sub2) [0] In top.t.sub2.subblock2 (sub2) [0] Back \ Quote " [0] %b=000001100 %0b=1100 %b=00000101010111011101110111100110011001100 %0b=101010111011101110111100110011001100 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0b=1010101111000001001000110100010101100111100000010010001101000101011001111000 [0] %B=000001100 %0B=1100 %B=00000101010111011101110111100110011001100 %0B=101010111011101110111100110011001100 %B=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0B=1010101111000001001000110100010101100111100000010010001101000101011001111000 [0] %d= 12 %0d=12 %d= 46099320012 %0d=46099320012 [0] %D= 12 %0D=12 %D= 46099320012 %0D=46099320012 [0] %h=00c %0h=c %h=00abbbbcccc %0h=abbbbcccc %h=00abc1234567812345678 %0h=abc1234567812345678 [0] %H=00c %0H=c %H=00abbbbcccc %0H=abbbbcccc %H=00abc1234567812345678 %0H=abc1234567812345678 [0] %o=014 %0o=14 %o=00527356746314 %0o=527356746314 %o=012570110642547402215053170 %0o=12570110642547402215053170 [0] %O=014 %0O=14 %O=00527356746314 %0O=527356746314 %O=012570110642547402215053170 %0O=12570110642547402215053170 [0] %x=00c %0x=c %x=00abbbbcccc %0x=abbbbcccc %x=00abc1234567812345678 %0x=abc1234567812345678 [0] %X=00c %0X=c %X=00abbbbcccc %0X=abbbbcccc %X=00abc1234567812345678 %0X=abc1234567812345678 [0] %C=m %0C=m [0] %c=m %0c=m [0] %v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 < [0] %V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 < [0] %p='hc %0p='hc %p='habbbbcccc %0p='habbbbcccc %p='habc1234567812345678 %0p='habc1234567812345678 [0] %P='hc %0P='hc %P='habbbbcccc %0P='habbbbcccc %P='habc1234567812345678 %0P='habc1234567812345678 [0] %P="sv-str" [0] %u=dcba %0u=dcba [0] %U=dcba %0U=dcba [0] %D= 12 %d= 12 %01d=12 %06d=000012 %6d= 12 [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. hello, from a concatenated string. hello, from a concatenated format string [0]. extra argument: 0000000000000000 0000000000000000: pre argument [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.916/test_regress/t/t_mem_multi_io2_cc.pl0000775000177100017500000000127313205574202022570 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_mem_multi_io2.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io2.cpp -Oi"], verilator_flags3 => [], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_vlt_warn.v0000664000177100017500000000122412473477707021063 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.916/test_regress/t/t_lint_restore_bad.pl0000775000177100017500000000133713151152521022676 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_crazy_sel.v0000664000177100017500000000151613205574202021204 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Dotted reference that uses another dotted reference // as the select expression // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. interface foo_intf; logic a; endinterface function integer the_other_func (input integer val); return val; endfunction module t (/*AUTOARG*/); genvar the_genvar; generate for (the_genvar = 0; the_genvar < 4; the_genvar++) begin: foo_loop foo foo_inst(); end endgenerate bar bar_inst(); logic x; assign x = foo_loop[bar_inst.THE_LP].foo_inst.y; //localparam N = 2; //assign x = foo_loop[N].foo_inst.y; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule module foo(); logic y; endmodule module bar(); localparam THE_LP = 2; endmodule verilator-3.916/test_regress/t/t_lint_implicit_bad.pl0000775000177100017500000000204412473477707023047 0ustar 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.916/test_regress/t/t_flag_fi.cpp0000664000177100017500000000134013205574202021110 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, 2017 by Wilson Snyder. #include #include "Vt_flag_fi.h" //====================================================================== unsigned int main_time = 0; double sc_time_stamp () { return main_time; } VM_PREFIX* topp = NULL; bool gotit = false; void myfunction() { gotit = true; } int main (int argc, char *argv[]) { topp = new VM_PREFIX; Verilated::debug(0); topp->eval(); if (!gotit) { vl_fatal (__FILE__, __LINE__, "dut", "Never got call to myfunction"); } topp->final(); return 0; } verilator-3.916/test_regress/t/t_dpi_imp_gen_c.cpp0000664000177100017500000000206213205574202022277 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" //====================================================================== #if defined(VERILATOR) # include "Vt_dpi_imp_gen__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 dpi_genvarTest(); } #endif //====================================================================== // Called from our Verilog code to run the tests void dpi_genvarTest () { const char *scopeName = svGetNameFromScope(svGetScope()); printf("scope name : %s\n", scopeName); } verilator-3.916/test_regress/t/t_gen_for0.v0000664000177100017500000000146512473477707020735 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.916/test_regress/t/t_debug_fatalsrc_bad.pl0000775000177100017500000000132512473477707023155 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_unopt_array.v0000664000177100017500000000370212671044616021562 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.916/test_regress/t/t_lint_once_bad.v0000664000177100017500000000072712473477707022016 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.916/test_regress/t/t_inst_prepost.v0000664000177100017500000000102312671044616021742 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.916/test_regress/t/t_var_types_bad.pl0000775000177100017500000000227212671044616022213 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_case_auto1.pl0000775000177100017500000000071712473477707021432 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_clk_latch_edgestyle.pl0000775000177100017500000000120213151152521023337 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_math_cond_huge.pl0000775000177100017500000000071712473477707022352 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_enum_large_methods.v0000664000177100017500000000237113205574202023052 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); `define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t (/*AUTOARG*/ // Inputs clk ); input clk; typedef enum { E01 = 'h1, ELARGE = 'hf00d } my_t; integer cyc=0; my_t e; string all; // Check runtime always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin // Setup e <= E01; end else if (cyc==1) begin `checks(e.name, "E01"); `checkh(e.next, ELARGE); e <= ELARGE; end else if (cyc==3) begin `checks(e.name, "ELARGE"); `checkh(e.next, E01); `checkh(e.prev, E01); e <= E01; end else if (cyc==20) begin e <= 'h11; // Unknown end else if (cyc==20) begin `checks(e.name, ""); // Unknown end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_inst_darray.pl0000775000177100017500000000072213205574202021677 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_public.v0000664000177100017500000000330013205574202021336 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, 2017 by Rob Stoddard. module t (/*AUTOARG*/ // Outputs out, // Inputs data, up_down, clk, reset ); //----------Output Ports-------------- output [7:0] out; //------------Input Ports-------------- //input [7:0] data ; input [7:0] data; input up_down, clk, reset; //------------Internal Variables-------- reg [7:0] out; logic [7:0] q_out; //-------------Code Starts Here------- always @(posedge clk) if (reset) begin // active high reset out <= 8'b0 ; end else if (up_down) begin out <= out + 1; end else begin out <= q_out; end // verilator lint_off PINMISSING sub_mod sub_mod ( .clk(clk), .data(data), .reset(reset), .q(q_out) ); // verilator lint_on PINMISSING endmodule module sub_mod (/*AUTOARG*/ // Outputs q, test_out, // Inouts test_inout, // Inputs data, clk, reset ); //-----------Input Ports--------------- input [7:0] data /*verilator public*/; input clk, reset; inout test_inout; // Get rid of this, the problem goes away. //-----------Output Ports--------------- output [7:0] q; output test_out; // Not assigned, no problem. logic [7:0] que; // Uncomment this line, the error goes away. //assign test_inout = que; assign q = que; always @ ( posedge clk) if (~reset) begin que <= 8'b0; end else begin que <= data; end endmodule verilator-3.916/test_regress/t/t_inst_recurse2_bad.pl0000775000177100017500000000116513205574202022757 0ustar 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_recurse2_bad.v:\d+: Unsupported: Identically recursive module \(module instantiates itself, without changing parameters\): looped %Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_timescale.out0000664000177100017500000002551413205574202022703 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Tue Jun 20 19:31:48 2017 $end $timescale 1ps $end $scope module top $end $var wire 1 $ clk $end $scope module t $end $var wire 1 $ clk $end $var wire 32 # cyc [31:0] $end $upscope $end $upscope $end $enddefinitions $end #0 b00000000000000000000000000000001 # 1$ #500 0$ #1000 b00000000000000000000000000000010 # 1$ #1500 0$ #2000 b00000000000000000000000000000011 # 1$ #2500 0$ #3000 b00000000000000000000000000000100 # 1$ #3500 0$ #4000 b00000000000000000000000000000101 # 1$ #4500 0$ #5000 b00000000000000000000000000000110 # 1$ #5500 0$ #6000 b00000000000000000000000000000111 # 1$ #6500 0$ #7000 b00000000000000000000000000001000 # 1$ #7500 0$ #8000 b00000000000000000000000000001001 # 1$ #8500 0$ #9000 b00000000000000000000000000001010 # 1$ #9500 0$ #10000 b00000000000000000000000000001011 # 1$ #10500 0$ #11000 b00000000000000000000000000001100 # 1$ #11500 0$ #12000 b00000000000000000000000000001101 # 1$ #12500 0$ #13000 b00000000000000000000000000001110 # 1$ #13500 0$ #14000 b00000000000000000000000000001111 # 1$ #14500 0$ #15000 b00000000000000000000000000010000 # 1$ #15500 0$ #16000 b00000000000000000000000000010001 # 1$ #16500 0$ #17000 b00000000000000000000000000010010 # 1$ #17500 0$ #18000 b00000000000000000000000000010011 # 1$ #18500 0$ #19000 b00000000000000000000000000010100 # 1$ #19500 0$ #20000 b00000000000000000000000000010101 # 1$ #20500 0$ #21000 b00000000000000000000000000010110 # 1$ #21500 0$ #22000 b00000000000000000000000000010111 # 1$ #22500 0$ #23000 b00000000000000000000000000011000 # 1$ #23500 0$ #24000 b00000000000000000000000000011001 # 1$ #24500 0$ #25000 b00000000000000000000000000011010 # 1$ #25500 0$ #26000 b00000000000000000000000000011011 # 1$ #26500 0$ #27000 b00000000000000000000000000011100 # 1$ #27500 0$ #28000 b00000000000000000000000000011101 # 1$ #28500 0$ #29000 b00000000000000000000000000011110 # 1$ #29500 0$ #30000 b00000000000000000000000000011111 # 1$ #30500 0$ #31000 b00000000000000000000000000100000 # 1$ #31500 0$ #32000 b00000000000000000000000000100001 # 1$ #32500 0$ #33000 b00000000000000000000000000100010 # 1$ #33500 0$ #34000 b00000000000000000000000000100011 # 1$ #34500 0$ #35000 b00000000000000000000000000100100 # 1$ #35500 0$ #36000 b00000000000000000000000000100101 # 1$ #36500 0$ #37000 b00000000000000000000000000100110 # 1$ #37500 0$ #38000 b00000000000000000000000000100111 # 1$ #38500 0$ #39000 b00000000000000000000000000101000 # 1$ #39500 0$ #40000 b00000000000000000000000000101001 # 1$ #40500 0$ #41000 b00000000000000000000000000101010 # 1$ #41500 0$ #42000 b00000000000000000000000000101011 # 1$ #42500 0$ #43000 b00000000000000000000000000101100 # 1$ #43500 0$ #44000 b00000000000000000000000000101101 # 1$ #44500 0$ #45000 b00000000000000000000000000101110 # 1$ #45500 0$ #46000 b00000000000000000000000000101111 # 1$ #46500 0$ #47000 b00000000000000000000000000110000 # 1$ #47500 0$ #48000 b00000000000000000000000000110001 # 1$ #48500 0$ #49000 b00000000000000000000000000110010 # 1$ #49500 0$ #50000 b00000000000000000000000000110011 # 1$ #50500 0$ #51000 b00000000000000000000000000110100 # 1$ #51500 0$ #52000 b00000000000000000000000000110101 # 1$ #52500 0$ #53000 b00000000000000000000000000110110 # 1$ #53500 0$ #54000 b00000000000000000000000000110111 # 1$ #54500 0$ #55000 b00000000000000000000000000111000 # 1$ #55500 0$ #56000 b00000000000000000000000000111001 # 1$ #56500 0$ #57000 b00000000000000000000000000111010 # 1$ #57500 0$ #58000 b00000000000000000000000000111011 # 1$ #58500 0$ #59000 b00000000000000000000000000111100 # 1$ #59500 0$ #60000 b00000000000000000000000000111101 # 1$ #60500 0$ #61000 b00000000000000000000000000111110 # 1$ #61500 0$ #62000 b00000000000000000000000000111111 # 1$ #62500 0$ #63000 b00000000000000000000000001000000 # 1$ #63500 0$ #64000 b00000000000000000000000001000001 # 1$ #64500 0$ #65000 b00000000000000000000000001000010 # 1$ #65500 0$ #66000 b00000000000000000000000001000011 # 1$ #66500 0$ #67000 b00000000000000000000000001000100 # 1$ #67500 0$ #68000 b00000000000000000000000001000101 # 1$ #68500 0$ #69000 b00000000000000000000000001000110 # 1$ #69500 0$ #70000 b00000000000000000000000001000111 # 1$ #70500 0$ #71000 b00000000000000000000000001001000 # 1$ #71500 0$ #72000 b00000000000000000000000001001001 # 1$ #72500 0$ #73000 b00000000000000000000000001001010 # 1$ #73500 0$ #74000 b00000000000000000000000001001011 # 1$ #74500 0$ #75000 b00000000000000000000000001001100 # 1$ #75500 0$ #76000 b00000000000000000000000001001101 # 1$ #76500 0$ #77000 b00000000000000000000000001001110 # 1$ #77500 0$ #78000 b00000000000000000000000001001111 # 1$ #78500 0$ #79000 b00000000000000000000000001010000 # 1$ #79500 0$ #80000 b00000000000000000000000001010001 # 1$ #80500 0$ #81000 b00000000000000000000000001010010 # 1$ #81500 0$ #82000 b00000000000000000000000001010011 # 1$ #82500 0$ #83000 b00000000000000000000000001010100 # 1$ #83500 0$ #84000 b00000000000000000000000001010101 # 1$ #84500 0$ #85000 b00000000000000000000000001010110 # 1$ #85500 0$ #86000 b00000000000000000000000001010111 # 1$ #86500 0$ #87000 b00000000000000000000000001011000 # 1$ #87500 0$ #88000 b00000000000000000000000001011001 # 1$ #88500 0$ #89000 b00000000000000000000000001011010 # 1$ #89500 0$ #90000 b00000000000000000000000001011011 # 1$ #90500 0$ #91000 b00000000000000000000000001011100 # 1$ #91500 0$ #92000 b00000000000000000000000001011101 # 1$ #92500 0$ #93000 b00000000000000000000000001011110 # 1$ #93500 0$ #94000 b00000000000000000000000001011111 # 1$ #94500 0$ #95000 b00000000000000000000000001100000 # 1$ #95500 0$ #96000 b00000000000000000000000001100001 # 1$ #96500 0$ #97000 b00000000000000000000000001100010 # 1$ #97500 0$ #98000 b00000000000000000000000001100011 # 1$ #98500 0$ #99000 b00000000000000000000000001100100 # 1$ #99500 0$ #100000 b00000000000000000000000001100101 # 1$ #100500 0$ #101000 b00000000000000000000000001100110 # 1$ #101500 0$ #102000 b00000000000000000000000001100111 # 1$ #102500 0$ #103000 b00000000000000000000000001101000 # 1$ #103500 0$ #104000 b00000000000000000000000001101001 # 1$ #104500 0$ #105000 b00000000000000000000000001101010 # 1$ #105500 0$ #106000 b00000000000000000000000001101011 # 1$ #106500 0$ #107000 b00000000000000000000000001101100 # 1$ #107500 0$ #108000 b00000000000000000000000001101101 # 1$ #108500 0$ #109000 b00000000000000000000000001101110 # 1$ #109500 0$ #110000 b00000000000000000000000001101111 # 1$ #110500 0$ #111000 b00000000000000000000000001110000 # 1$ #111500 0$ #112000 b00000000000000000000000001110001 # 1$ #112500 0$ #113000 b00000000000000000000000001110010 # 1$ #113500 0$ #114000 b00000000000000000000000001110011 # 1$ #114500 0$ #115000 b00000000000000000000000001110100 # 1$ #115500 0$ #116000 b00000000000000000000000001110101 # 1$ #116500 0$ #117000 b00000000000000000000000001110110 # 1$ #117500 0$ #118000 b00000000000000000000000001110111 # 1$ #118500 0$ #119000 b00000000000000000000000001111000 # 1$ #119500 0$ #120000 b00000000000000000000000001111001 # 1$ #120500 0$ #121000 b00000000000000000000000001111010 # 1$ #121500 0$ #122000 b00000000000000000000000001111011 # 1$ #122500 0$ #123000 b00000000000000000000000001111100 # 1$ #123500 0$ #124000 b00000000000000000000000001111101 # 1$ #124500 0$ #125000 b00000000000000000000000001111110 # 1$ #125500 0$ #126000 b00000000000000000000000001111111 # 1$ #126500 0$ #127000 b00000000000000000000000010000000 # 1$ #127500 0$ #128000 b00000000000000000000000010000001 # 1$ #128500 0$ #129000 b00000000000000000000000010000010 # 1$ #129500 0$ #130000 b00000000000000000000000010000011 # 1$ #130500 0$ #131000 b00000000000000000000000010000100 # 1$ #131500 0$ #132000 b00000000000000000000000010000101 # 1$ #132500 0$ #133000 b00000000000000000000000010000110 # 1$ #133500 0$ #134000 b00000000000000000000000010000111 # 1$ #134500 0$ #135000 b00000000000000000000000010001000 # 1$ #135500 0$ #136000 b00000000000000000000000010001001 # 1$ #136500 0$ #137000 b00000000000000000000000010001010 # 1$ #137500 0$ #138000 b00000000000000000000000010001011 # 1$ #138500 0$ #139000 b00000000000000000000000010001100 # 1$ #139500 0$ #140000 b00000000000000000000000010001101 # 1$ #140500 0$ #141000 b00000000000000000000000010001110 # 1$ #141500 0$ #142000 b00000000000000000000000010001111 # 1$ #142500 0$ #143000 b00000000000000000000000010010000 # 1$ #143500 0$ #144000 b00000000000000000000000010010001 # 1$ #144500 0$ #145000 b00000000000000000000000010010010 # 1$ #145500 0$ #146000 b00000000000000000000000010010011 # 1$ #146500 0$ #147000 b00000000000000000000000010010100 # 1$ #147500 0$ #148000 b00000000000000000000000010010101 # 1$ #148500 0$ #149000 b00000000000000000000000010010110 # 1$ #149500 0$ #150000 b00000000000000000000000010010111 # 1$ #150500 0$ #151000 b00000000000000000000000010011000 # 1$ #151500 0$ #152000 b00000000000000000000000010011001 # 1$ #152500 0$ #153000 b00000000000000000000000010011010 # 1$ #153500 0$ #154000 b00000000000000000000000010011011 # 1$ #154500 0$ #155000 b00000000000000000000000010011100 # 1$ #155500 0$ #156000 b00000000000000000000000010011101 # 1$ #156500 0$ #157000 b00000000000000000000000010011110 # 1$ #157500 0$ #158000 b00000000000000000000000010011111 # 1$ #158500 0$ #159000 b00000000000000000000000010100000 # 1$ #159500 0$ #160000 b00000000000000000000000010100001 # 1$ #160500 0$ #161000 b00000000000000000000000010100010 # 1$ #161500 0$ #162000 b00000000000000000000000010100011 # 1$ #162500 0$ #163000 b00000000000000000000000010100100 # 1$ #163500 0$ #164000 b00000000000000000000000010100101 # 1$ #164500 0$ #165000 b00000000000000000000000010100110 # 1$ #165500 0$ #166000 b00000000000000000000000010100111 # 1$ #166500 0$ #167000 b00000000000000000000000010101000 # 1$ #167500 0$ #168000 b00000000000000000000000010101001 # 1$ #168500 0$ #169000 b00000000000000000000000010101010 # 1$ #169500 0$ #170000 b00000000000000000000000010101011 # 1$ #170500 0$ #171000 b00000000000000000000000010101100 # 1$ #171500 0$ #172000 b00000000000000000000000010101101 # 1$ #172500 0$ #173000 b00000000000000000000000010101110 # 1$ #173500 0$ #174000 b00000000000000000000000010101111 # 1$ #174500 0$ #175000 b00000000000000000000000010110000 # 1$ #175500 0$ #176000 b00000000000000000000000010110001 # 1$ #176500 0$ #177000 b00000000000000000000000010110010 # 1$ #177500 0$ #178000 b00000000000000000000000010110011 # 1$ #178500 0$ #179000 b00000000000000000000000010110100 # 1$ #179500 0$ #180000 b00000000000000000000000010110101 # 1$ #180500 0$ #181000 b00000000000000000000000010110110 # 1$ #181500 0$ #182000 b00000000000000000000000010110111 # 1$ #182500 0$ #183000 b00000000000000000000000010111000 # 1$ #183500 0$ #184000 b00000000000000000000000010111001 # 1$ #184500 0$ #185000 b00000000000000000000000010111010 # 1$ #185500 0$ #186000 b00000000000000000000000010111011 # 1$ #186500 0$ #187000 b00000000000000000000000010111100 # 1$ #187500 0$ #188000 b00000000000000000000000010111101 # 1$ #188500 0$ #189000 b00000000000000000000000010111110 # 1$ #189500 0$ verilator-3.916/test_regress/t/t_clk_latch.pl0000775000177100017500000000105113151152521021274 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_display_wide.v0000664000177100017500000000561212473477707021711 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.916/test_regress/t/t_interface_gen11.pl0000775000177100017500000000072713205574202022320 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_case_write2.out0000664000177100017500000001155712473477707022012 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.916/test_regress/t/t_lint_ifdepth_bad.v0000664000177100017500000000217313205574202022470 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 value = 19; initial begin if (value==1) begin end else if (value==2) begin end else if (value==3) begin end else if (value==4) begin end else if (value==5) begin end else if (value==6) begin end else if (value==7) begin end else if (value==8) begin end else if (value==9) begin end else if (value==10) begin end else if (value==11) begin end // Warn about this one else if (value==12) begin end end initial begin unique0 if (value==1) begin end else if (value==2) begin end else if (value==3) begin end else if (value==4) begin end else if (value==5) begin end else if (value==6) begin end else if (value==7) begin end else if (value==8) begin end else if (value==9) begin end else if (value==10) begin end else if (value==11) begin end // Warn about this one else if (value==12) begin end end endmodule verilator-3.916/test_regress/t/t_param_no_parentheses.pl0000775000177100017500000000071712473477707023603 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_ddeep_width.v0000664000177100017500000000116312671044616022656 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.916/test_regress/t/t_case_nest.v0000664000177100017500000000713312671044616021165 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.916/test_regress/t/t_hierarchy_identifier.pl0000775000177100017500000000071712671044616023553 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_preproc_ttempty.pl0000775000177100017500000000153113205574202022617 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/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 ( # Override default flags v_flags => [''], verilator_flags => ["-E -P +incdir+t"], verilator_flags2 => ['',], verilator_flags3 => ['',], verilator_make_gcc => 0, make_top_shell => 0, stdout_filename => $stdout_filename, ); ok(files_identical($stdout_filename, "t/$Self->{name}.out")); 1; verilator-3.916/test_regress/t/t_param_default.v0000664000177100017500000000055213205574202022014 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 m #(parameter int Foo); endmodule module t (/*AUTOARG*/); m #(10) foo(); initial begin if (foo.Foo != 10) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/.gitattributes0000664000177100017500000000002012473477707021401 0ustar wsnyderwsnydert_dos*.pl -crlf verilator-3.916/test_regress/t/t_flag_future.pl0000775000177100017500000000110012473477707021674 0ustar 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.916/test_regress/t/t_interface_mp_func_noinl.pl0000775000177100017500000000102413205574202024222 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_mp_func.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_slice_bad.v0000664000177100017500000000311213165156133021752 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.916/test_regress/t/t_func_types.v0000664000177100017500000000401412473477707021406 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.916/test_regress/t/t_mem_slice_conc_bad.pl0000775000177100017500000000101112473477707023137 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_detectarray_3.pl0000775000177100017500000000101012671044616022107 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ["-Wno-UNOPTFLAT -Wno-WIDTH"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_for1.pl0000775000177100017500000000071712473477707021106 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_setout_bad.pl0000775000177100017500000000131212473477707022555 0ustar 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.916/test_regress/t/t_select_bad_tri.pl0000775000177100017500000000117012473477707022343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_gen_intdot2.pl0000775000177100017500000000071712473477707021622 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_dtree_inlbd.pl0000775000177100017500000000112012671044616022670 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_alw_split_rst.v0000664000177100017500000000740713205574202022104 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 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] in = crc[3:0]; wire clken = crc[4]; wire rstn = !(cyc < 20 || (crc[11:8]==0)); /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [3:0] ff_out; // From test of Test.v wire [3:0] fg_out; // From test of Test.v wire [3:0] fh_out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .ff_out (ff_out[3:0]), .fg_out (fg_out[3:0]), .fh_out (fh_out[3:0]), // Inputs .clk (clk), .clken (clken), .rstn (rstn), .in (in[3:0])); // Aggregate outputs into a single result vector wire [63:0] result = {52'h0, ff_out, fg_out, fh_out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h77979747fd1b3a5a if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs ff_out, fg_out, fh_out, // Inputs clk, clken, rstn, in ); input clk; input clken; input rstn; input [3:0] in; output reg [3:0] ff_out; reg [3:0] ff_10; reg [3:0] ff_11; reg [3:0] ff_12; reg [3:0] ff_13; always @(posedge clk) begin if ((rstn == 0)) begin ff_10 <= 0; ff_11 <= 0; ff_12 <= 0; ff_13 <= 0; end else begin ff_10 <= in; ff_11 <= ff_10; ff_12 <= ff_11; ff_13 <= ff_12; ff_out <= ff_13; end end output reg [3:0] fg_out; reg [3:0] fg_10; reg [3:0] fg_11; reg [3:0] fg_12; reg [3:0] fg_13; always @(posedge clk) begin if (clken) begin if ((rstn == 0)) begin fg_10 <= 0; fg_11 <= 0; fg_12 <= 0; fg_13 <= 0; end else begin fg_10 <= in; fg_11 <= fg_10; fg_12 <= fg_11; fg_13 <= fg_12; fg_out <= fg_13; end end end output reg [3:0] fh_out; reg [3:0] fh_10; reg [3:0] fh_11; reg [3:0] fh_12; reg [3:0] fh_13; always @(posedge clk) begin if ((rstn == 0)) begin fh_10 <= 0; fh_11 <= 0; fh_12 <= 0; fh_13 <= 0; end else begin if (clken) begin fh_10 <= in; fh_11 <= fh_10; fh_12 <= fh_11; fh_13[3:1] <= fh_12[3:1]; fh_13[0] <= fh_12[0]; fh_out <= fh_13; end end end endmodule verilator-3.916/test_regress/t/t_preproc_kwd.pl0000775000177100017500000000071712473477707021725 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_pp_pragmas.pl0000775000177100017500000000071712473477707021537 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_tri_pullup.cpp0000664000177100017500000000240412671044616021731 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.916/test_regress/t/t_var_rsvd_bad.pl0000775000177100017500000000127013205574202022013 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_var_rsvd_port.v"); compile ( fails=>$Self->{v3}, expect=> q{%Warning-SYMRSVDWORD: t/t_var_rsvd_port.v:\d+: Symbol matches C\+\+ keyword: 'bool' .* %Warning-SYMRSVDWORD: t/t_var_rsvd_port.v:\d+: Symbol matches C\+\+ keyword: 'switch' %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_parameter.v0000664000177100017500000000241213205574202022156 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder `define check(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: Wrong parameter value", `__FILE__,`__LINE__); $stop; end while(0); module t; parameter string1 = "Original String"; parameter string2 = "Original String"; parameter real11 = 0.1; parameter real12 = 0.1; parameter real21 = 0.1; parameter real22 = 0.1; parameter real31 = 0.1; parameter real32 = 0.1; parameter int11 = 1; parameter int12 = 1; parameter int21 = 1; parameter int22 = 1; parameter int31 = 1; parameter int32 = 1; parameter int41 = 1; parameter int42 = 1; initial begin `check(string1,"New String"); `check(string2,"New String"); `check(real11,0.2); `check(real12,0.2); `check(real21,400); `check(real22,400); `check(real31,20); `check(real32,20); `check(int11,16); `check(int12,16); `check(int21,16); `check(int22,16); `check(int31,123); `check(int32,123); `check(int41,32'hdeadbeef); `check(int42,32'hdeadbeef); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_gen_upscope.pl0000775000177100017500000000156613205574202021676 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the 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.t.b.gen[0].tag created tag with scope = top.t.b.gen[1].tag created tag with scope = top.t.tag mod a has scope = top.t mod a has tag = top.t.tag mod b has scope = top.t.b mod b has tag = top.t.tag mod c has scope = top.t.b.gen[0].c mod c has tag = top.t.b.gen[0].tag mod c has scope = top.t.b.gen[1].c mod c has tag = top.t.b.gen[1].tag *-* All Finished *-*}), ); ok(1); 1; verilator-3.916/test_regress/t/t_param_sel_range.pl0000775000177100017500000000114512671044616022506 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_interface_gen4.pl0000775000177100017500000000072713205574202022242 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_dist_cinclude.pl0000775000177100017500000000335413205574202022175 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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/ && $line !~ m!sys/time.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.916/test_regress/t/t_inst_mnpipe.v0000664000177100017500000000266712473477707021570 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.916/test_regress/t/t_trace_cat.pl0000775000177100017500000000142613151152521021303 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_unopt_combo.v0000664000177100017500000000547512473477707021567 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.916/test_regress/t/t_xml_tag.pl0000775000177100017500000000122413205574202021011 0ustar 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, ); ok(files_identical("$out_filename", "t/$Self->{name}.out")); 1; verilator-3.916/test_regress/t/t_interface_noinl.pl0000775000177100017500000000101413205574202022512 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_future.v0000664000177100017500000000036712473477707021541 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.916/test_regress/t/t_flag_names.v0000664000177100017500000000076713205574202021314 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder. module t; sub sub (); endmodule module sub; string scope; initial begin scope = $sformatf("%m"); $write("[%0t] In %s\n", $time, scope); `ifdef VERILATOR if (scope != "top.l2Name.sub") $stop; `else if (scope != "top.t.sub") $stop; `endif $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_vams_basic.v0000664000177100017500000000177012473477707021344 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.916/test_regress/t/t_struct_array.v0000664000177100017500000000151512671044616021741 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.916/test_regress/t/t_vgen.pl0000775000177100017500000000130413205574202020314 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. if (eval "use Bit::Vector; return 2;" != 2) { $Self->error("Please install Bit::Vector"); } top_filename("$Self->{obj_dir}/vgen.v"); $Self->run(cmd=>["./vgen.pl", "-o $Self->{top_filename}", #"--seed 0", ]); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_vliw.v0000664000177100017500000000551412473477707021227 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.916/test_regress/t/t_gen_missing_bad.pl0000775000177100017500000000161612473477707022515 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_genvar_misuse_bad.pl0000775000177100017500000000123212671044616023041 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_order_first.v0000664000177100017500000000253112671044616021540 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs fastclk ); input fastclk; t_netlist tnetlist (.also_fastclk (fastclk), /*AUTOINST*/ // Inputs .fastclk (fastclk)); endmodule module t_netlist (/*AUTOARG*/ // Inputs fastclk, also_fastclk ); // surefire lint_off ASWEMB input fastclk; input also_fastclk; integer _mode; initial _mode = 0; // This entire module should optimize to nearly nothing... // verilator lint_off UNOPTFLAT reg [4:0] a,a2,b,c,d,e; // verilator lint_on UNOPTFLAT initial a=5'd1; always @ (posedge fastclk) begin b <= a+5'd1; c <= b+5'd1; // Better for ordering if this moves before previous statement end // verilator lint_off UNOPT always @ (d or /*AS*/a or c) begin e = d+5'd1; a2 = a+5'd1; // This can be pulled out of the middle of the always d = c+5'd1; // Better for ordering if this moves before previous statement end // verilator lint_on UNOPT always @ (posedge also_fastclk) begin if (_mode==5) begin if (a2 != 5'd2) $stop; if (e != 5'd5) $stop; $write("*-* All Finished *-*\n"); $finish; end _mode <= _mode + 1; end endmodule verilator-3.916/test_regress/t/t_threads_counter_2.pl0000775000177100017500000000115513205574202022773 0ustar wsnyderwsnyder#!/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->skip("No thread support") if !$Self->cfg_with_threaded; top_filename("t/t_threads_counter.v"); compile ( verilator_flags2 => ['--cc --threads 2'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_case_write1.pl0000775000177100017500000000121313151152521021556 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_case_itemwidth.pl0000775000177100017500000000071712473477707022377 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_setout_bad_noinl.pl0000775000177100017500000000136612473477707023765 0ustar 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.916/test_regress/t/t_stream3.pl0000775000177100017500000000072212671044616020745 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_primitive.v0000664000177100017500000000120713205574202022374 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jie Xu. module t ( clk ); input clk; integer cyc; initial cyc = 0; reg a; reg b; reg z; sub_t sub_t_i (z, a, b); always @ (posedge clk) begin cyc <= cyc + 1; a <= cyc[0]; b <= cyc[1]; if (cyc > 10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule primitive CINV (a, b); output b; input a; assign b = ~a; endprimitive module sub_t (z, x, y); input x, y; output z; assign z = x & y; endmodule verilator-3.916/test_regress/t/t_package_abs.pl0000775000177100017500000000071712671044616021613 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_clk_first.v0000664000177100017500000001114412671044616021176 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk, fastclk ); input clk /*verilator sc_clock*/; input fastclk /*verilator sc_clock*/; reg reset_l; int cyc; initial reset_l = 0; always @ (posedge clk) begin if (cyc==0) reset_l <= 1'b1; else if (cyc==1) reset_l <= 1'b0; else if (cyc==10) reset_l <= 1'b1; end t_clk t (/*AUTOINST*/ // Inputs .clk (clk), .fastclk (fastclk), .reset_l (reset_l)); endmodule module t_clk (/*AUTOARG*/ // Inputs clk, fastclk, reset_l ); input clk /*verilator sc_clock*/; input fastclk /*verilator sc_clock*/; input reset_l; // surefire lint_off STMINI // surefire lint_off CWECSB // surefire lint_off NBAJAM reg _ranit; initial _ranit=0; // surefire lint_off UDDSMX reg [7:0] clk_clocks; initial clk_clocks = 0; // surefire lint_off_line WRTWRT wire [7:0] clk_clocks_d1r; wire [7:0] clk_clocks_d1sr; wire [7:0] clk_clocks_cp2_d1r; wire [7:0] clk_clocks_cp2_d1sr; // verilator lint_off MULTIDRIVEN reg [7:0] int_clocks; initial int_clocks = 0; // verilator lint_on MULTIDRIVEN reg [7:0] int_clocks_copy; // verilator lint_off GENCLK reg internal_clk; initial internal_clk = 0; reg reset_int_; // verilator lint_on GENCLK always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] CLK1 %x\n", $time, reset_l); `endif if (!reset_l) begin clk_clocks <= 0; int_clocks <= 0; internal_clk <= 1'b1; reset_int_ <= 0; end else begin internal_clk <= ~internal_clk; if (!_ranit) begin _ranit <= 1; `ifdef TEST_VERBOSE $write("[%0t] t_clk: Running\n",$time); `endif reset_int_ <= 1; end end end reg [7:0] sig_rst; always @ (posedge clk or negedge reset_l) begin `ifdef TEST_VERBOSE $write("[%0t] CLK2 %x sr=%x\n", $time, reset_l, sig_rst); `endif if (!reset_l) begin sig_rst <= 0; end else begin sig_rst <= sig_rst + 1; // surefire lint_off_line ASWIBB end end always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] CLK3 %x cc=%x sr=%x\n", $time, reset_l, clk_clocks, sig_rst); `endif if (!reset_l) begin clk_clocks <= 0; end else begin clk_clocks <= clk_clocks + 8'd1; if (clk_clocks == 4) begin if (sig_rst !== 4) $stop; if (clk_clocks_d1r !== 3) $stop; if (int_clocks !== 2) $stop; if (int_clocks_copy !== 2) $stop; if (clk_clocks_d1r !== clk_clocks_cp2_d1r) $stop; if (clk_clocks_d1sr !== clk_clocks_cp2_d1sr) $stop; $write("*-* All Finished *-*\n"); $finish; end end end reg [7:0] resetted; always @ (posedge clk or negedge reset_int_) begin `ifdef TEST_VERBOSE $write("[%0t] CLK4 %x\n", $time, reset_l); `endif if (!reset_int_) begin resetted <= 0; end else begin resetted <= resetted + 8'd1; end end always @ (int_clocks) begin int_clocks_copy = int_clocks; end always @ (negedge internal_clk) begin int_clocks <= int_clocks + 8'd1; end t_clk_flop flopa (.clk(clk), .clk2(fastclk), .a(clk_clocks), .q(clk_clocks_d1r), .q2(clk_clocks_d1sr)); t_clk_flop flopb (.clk(clk), .clk2(fastclk), .a(clk_clocks), .q(clk_clocks_cp2_d1r), .q2(clk_clocks_cp2_d1sr)); t_clk_two two (/*AUTOINST*/ // Inputs .fastclk (fastclk), .reset_l (reset_l)); endmodule module t_clk_flop (/*AUTOARG*/ // Outputs q, q2, // Inputs clk, clk2, a ); parameter WIDTH=8; input clk; input clk2; input [(WIDTH-1):0] a; output [(WIDTH-1):0] q; output [(WIDTH-1):0] q2; reg [(WIDTH-1):0] q; reg [(WIDTH-1):0] q2; always @ (posedge clk) q<=a; always @ (posedge clk2) q2<=a; endmodule module t_clk_two (/*AUTOARG*/ // Inputs fastclk, reset_l ); input fastclk; input reset_l; // verilator lint_off GENCLK reg clk2; // verilator lint_on GENCLK reg [31:0] count; t_clk_twob tb (.*); wire reset_h = ~reset_l; always @ (posedge fastclk) begin if (reset_h) clk2 <= 0; else clk2 <= ~clk2; end always @ (posedge clk2) begin if (reset_h) count <= 0; else count <= count + 1; end endmodule module t_clk_twob (/*AUTOARG*/ // Inputs fastclk, reset_l ); input fastclk; input reset_l; always @ (posedge fastclk) begin // Extra line coverage point, just to make sure coverage // hierarchy under inlining lands properly if (reset_l) ; end endmodule verilator-3.916/test_regress/t/t_func_outfirst.pl0000775000177100017500000000071712473477707022300 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_gen12.pl0000775000177100017500000000072713205574202022321 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_math_shift_sel.v0000664000177100017500000000423313205574202022201 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 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 [106:0] in = {~crc[42:0], crc[63:0]}; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [7:0] out1; // From test of Test.v wire [7:0] out2; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out1 (out1[7:0]), .out2 (out2[7:0]), // Inputs .in (in[106:0])); // Aggregate outputs into a single result vector wire [63:0] result = {48'h0, out1, out1}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hc746017202a24ecc if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out1, out2, // Inputs 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 [106:0] in; output [7:0] out1, out2; // verilator lint_off WIDTH // Better written as onibble[99 +: 8]. Verilator will convert it. wire [7:0] out1 = (in >>> 99) & 255; // verilator lint_on WIDTH wire [7:0] out2 = in[106:99]; endmodule verilator-3.916/test_regress/t/t_math_shift_rep.v0000664000177100017500000000344412671044616022216 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; //bug765; disappears if add this wire //wire [7:0] a = (crc[7] ? {7'b0,crc[0]} : crc[7:0]); // favor low values wire [7:0] a = crc[7:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [15:0] y; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .y (y[15:0]), // Inputs .a (a[7:0])); // Aggregate outputs into a single result vector wire [63:0] result = {48'h0, y}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h0 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs y, // Inputs a ); input signed [7:0] a; output [15:0] y; // verilator lint_off WIDTH assign y = ~66'd0 <<< {4{a}}; // verilator lint_on WIDTH endmodule verilator-3.916/test_regress/t/t_math_div.v0000664000177100017500000000542512473477707021031 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.916/test_regress/t/t_metacmt_onoff.pl0000775000177100017500000000161212473477707022222 0ustar 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.916/test_regress/t/t_interface_down_inlbc.pl0000775000177100017500000000112412671044616023522 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_dpi_sys.v0000664000177100017500000000140112473477707020676 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.916/test_regress/t/t_struct_init_bad.pl0000775000177100017500000000120513205574202022532 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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 ( v_flags2 => ['+define+T_STRUCT_INIT_BAD'], fails => 1, expect=> '%Error: t/t_struct_init.v:\d+: Assignment pattern contains duplicate entry: b1 %Error: Exiting due to.*' ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_local.pl0000775000177100017500000000071712671044616021316 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_circ_bad.pl0000775000177100017500000000131312473477707022305 0ustar 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.916/test_regress/t/t_var_in_assign_bad.pl0000775000177100017500000000150612473477707023033 0ustar 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.916/test_regress/t/t_bitsel_wire_array_bad.pl0000775000177100017500000000117613205574202023700 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # Comple time only test compile ( verilator_flags2 => ["--lint-only"], fails=>1, expect=> '.*%Error: t/t_bitsel_wire_array_bad.v:\d+: Illegal assignment of constant to unpacked array %Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_multiwire.pl0000775000177100017500000000071712473477707022265 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_nomod_bad.v0000664000177100017500000000026012473477707022141 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.916/test_regress/t/t_param_real.pl0000775000177100017500000000072213205574202021463 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_unused_iface.v0000664000177100017500000000174613205574202022676 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. interface dummy_if (); logic signal; modport slave ( input signal ); modport master ( output signal ); endinterface: dummy_if module sub ( input wire signal_i, output wire signal_o, dummy_if.master dummy_in, dummy_if.slave dummy_out ); assign dummy_in.signal = signal_i; assign signal_o = dummy_out.signal; endmodule module t (/*AUTOARG*/ // Outputs signal_o, // Inputs signal_i ); input signal_i; output signal_o; // verila tor lint_off UUSD // verila tor lint_off UNDRIVEN dummy_if dummy_if (); // verila tor lint_on UUSD // verila tor lint_on UNDRIVEN dummy_if uusd_if (); sub sub ( .signal_i(signal_i), .signal_o(signal_o), .dummy_in(dummy_if), .dummy_out(dummy_if) ); endmodule verilator-3.916/test_regress/t/t_sys_file_basic.pl0000775000177100017500000000146612473477707022366 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_sys_plusargs_bad.pl0000775000177100017500000000072313205574202022725 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_types.pl0000775000177100017500000000071712473477707021565 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_defparam.pl0000775000177100017500000000111212473477707022201 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_order_doubleloop.pl0000775000177100017500000000105113151152521022707 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_func_task_bad.pl0000775000177100017500000000111612473477707022163 0ustar 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.916/test_regress/t/t_display_l.v0000664000177100017500000000054513205574202021172 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: $display() test for %l // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Todd Strader. module t (/*AUTOARG*/); initial begin assert (0 == 0) else $fatal(2, "%l %m : %d", 0); $display("%l %m"); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_detectarray_2.v0000664000177100017500000000153212671044616021746 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.916/test_regress/t/t_func_under.v0000664000177100017500000000130112671044616021340 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.916/test_regress/t/t_assert_dup_bad.v0000664000177100017500000000063112473477707022207 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.916/test_regress/t/t_gen_for2.v0000664000177100017500000000115513205574202020711 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Johan Bjork. parameter N = 5; interface intf; logic [N-1:0] data; endinterface module t ( input logic clk ); intf localinterface [N-1:0](); generate genvar i,j; for(i = 0; i < N; i++) begin logic [N-1:0] dummy; for(j = 0; j < N; j++) begin assign dummy[j] = localinterface[j].data[i]; end end endgenerate initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_sys_readmem_bad_digit.mem0000664000177100017500000000044312473477707024040 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.916/test_regress/t/t_dpi_qw.pl0000775000177100017500000000106112713417237020647 0ustar 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.916/test_regress/t/t_math_pow3.v0000664000177100017500000001001412671044616021112 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); fail=1; end while(0) module t (/*AUTOARG*/); bit fail; // IEEE says for ** the size is L(i). Thus Icarus Verilog is wrong in sizing some of the below. initial begin // NC=67b6cfc1b29a21 VCS=c1b29a20(wrong) IV=67b6cfc1b29a21 Verilator=67b6cfc1b29a21 $display("15 ** 14 = %0x expect 67b6cfc1b29a21", 64'b1111 ** 64'b1110); // NC=1 VCS=0 IV=0 Verilator=1 (wrong,fixed) $display("15 **-4'sd2 = %0x expect 0 (per IEEE negative power)", ((-4'd1 ** -4'sd2))); // NC=1 VCS=0 IV=67b6cfc1b29a21(wrong) Verilator=1 $display("15 ** 14 = %0x expect 1 (LSB 4-bits of 67b6cfc1b29a21)", ((-4'd1 ** -4'd2))); // NC=1 VCS=0 IV=67b6cfc1b29a21(wrong) Verilator=1 $display("15 ** 14 = %0x expect 1 (LSB 4-bits of 67b6cfc1b29a21)", ((4'd15 ** 4'd14))); // NC=8765432187654321 VCS=8765432187654000(wrong) IV=8765432187654321 Verilator=8765432187654321 $display("64'big ** 1 = %0x expect %0x", 64'h8765432187654321 ** 1, 64'h8765432187654321); $display("\n"); `checkh( (64'b1111 ** 64'b1110), 64'h67b6cfc1b29a21); `checkh( (-4'd1 ** -4'sd2), 4'h0); //bug730 `checkh( (-4'd1 ** -4'd2), 4'h1); `checkh( (4'd15 ** 4'd14), 4'h1); `checkh( (64'h8765432187654321 ** 4'h1), 64'h8765432187654321); `checkh((-8'sh3 ** 8'h3) , 8'he5 ); // a**b (-27) `checkh((-8'sh1 ** 8'h2) , 8'h1 ); // -1^odd=-1, -1^even=1 `checkh((-8'sh1 ** 8'h3) , 8'hff ); // -1^odd=-1, -1^even=1 `checkh(( 8'h0 ** 8'h3) , 8'h0 ); // 0 `checkh(( 8'h1 ** 8'h3) , 8'h1 ); // 1 `checkh(( 8'h3 ** 8'h3) , 8'h1b ); // a**b (27) `checkh(( 8'sh3 ** 8'h3) , 8'h1b ); // a**b (27) `checkh(( 8'h6 ** 8'h3) , 8'hd8 ); // a**b (216) `checkh(( 8'sh6 ** 8'h3) , 8'hd8 ); // a**b (216) `checkh((-8'sh3 ** 8'sh3), 8'he5 ); // a**b `checkh((-8'sh1 ** 8'sh2), 8'h1 ); // -1^odd=-1, -1^even=1 `checkh((-8'sh1 ** 8'sh3), 8'hff ); // -1^odd=-1, -1^even=1 `checkh(( 8'h0 ** 8'sh3), 8'h0 ); // 0 `checkh(( 8'h1 ** 8'sh3), 8'h1 ); // 1 `checkh(( 8'h3 ** 8'sh3), 8'h1b ); // a**b (27) `checkh(( 8'sh3 ** 8'sh3), 8'h1b ); // a**b (27) `checkh(( 8'h6 ** 8'sh3), 8'hd8 ); // a**b (216) `checkh(( 8'sh6 ** 8'sh3), 8'hd8 ); // a**b (216) `checkh((-8'sh3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h0 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'sh3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h0 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'sh3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh3 ** -8'sh3), 8'h0 ); // 0 (a<-1) // NCVERILOG bug `checkh((-8'sh1 ** -8'sh2), 8'h1 ); // -1^odd=-1, -1^even=1 `checkh((-8'sh1 ** -8'sh3), 8'hff); // -1^odd=-1, -1^even=1 // `checkh(( 8'h0 ** -8'sh3), 8'hx ); // x // NCVERILOG bug `checkh(( 8'h1 ** -8'sh3), 8'h1 ); // 1**b always 1 `checkh(( 8'h3 ** -8'sh3), 8'h0 ); // 0 // NCVERILOG bug `checkh(( 8'sh3 ** -8'sh3), 8'h0 ); // 0 // NCVERILOG bug if (fail) $stop; else $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_stream2.v0000664000177100017500000000373512671044616020602 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [67:0] left; // From test of Test.v wire [67:0] right; // From test of Test.v // End of automatics wire [6:0] amt = crc[6:0]; wire [67:0] in = {crc[3:0], crc[63:0]}; Test test (/*AUTOINST*/ // Outputs .left (left[67:0]), .right (right[67:0]), // Inputs .amt (amt[6:0]), .in (in[67:0])); wire [63:0] result = (left[63:0] ^ {60'h0, left[67:64]} ^ right[63:0] ^ {60'h0, right[67:64]}); // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x amt=%x left=%x right=%x\n", $time, cyc, crc, result, amt, left, right); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h0da01049b480c38a if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs left, right, // Inputs amt, in ); input [6:0] amt; input [67:0] in; // amt must be constant output wire [67:0] left; output wire [67:0] right; assign right = { << 33 {in}}; assign left = { >> 33 {in}}; endmodule verilator-3.916/test_regress/t/t_var_pinsizes.cpp0000664000177100017500000000065513205574202022245 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- #include VM_PREFIX_INCLUDE 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.916/test_regress/t/t_math_shift_over_bad.pl0000775000177100017500000000121413205574202023344 0ustar 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: Internal Error: .*: Value too wide for 32-bits expected in this context 64\'h123456789abcdef .', ); ok(1); 1; verilator-3.916/test_regress/t/t_select_loop.v0000664000177100017500000000241412473477707021541 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.916/test_regress/t/t_mod_interface_array2_noinl.pl0000775000177100017500000000102713205574202024635 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_mod_interface_array2.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_decoration.v0000664000177100017500000000110313205574202022506 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (clk); input clk; integer a_very_long_name_which_we_will_hash_eventually=0; always @ (posedge clk) begin a_very_long_name_which_we_will_hash_eventually <= a_very_long_name_which_we_will_hash_eventually + 1; if (a_very_long_name_which_we_will_hash_eventually == 5) begin fin(); end end task fin; $write("*-* All Finished *-*\n"); $finish; endtask endmodule verilator-3.916/test_regress/t/t_mem_slice_dtype_bad.v0000664000177100017500000000155613205574402023167 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Alex Solomatnikov. typedef logic [$clog2(26+1)-1:0] way_cnt_t; module t(/*AUTOARG*/ // Inputs clk ); input logic clk; int cyc; //bug795 way_cnt_t completed_cnt [31:0][1:0]; way_cnt_t completed_cnt_dp [1:0]; assign completed_cnt_dp = completed_cnt[id]; always_ff @(posedge clk) begin completed_cnt[id] <= completed_cnt_dp + 1; end // bug796 logic [4:0] id; logic [39:0] way_mask; logic [39:0] addr[31:0][1:0]; always_ff @(posedge clk) begin cyc <= cyc + 1; id <= cyc[4:0]; if (cyc==1) begin way_mask <= '0; id <= 1; end else if (cyc==2) begin assert((addr[id] & way_mask) == 0); end end endmodule verilator-3.916/test_regress/t/t_interface_gen9_noinl.pl0000775000177100017500000000102613205574202023437 0ustar wsnyderwsnyder#!/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_gen9.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_rnd.pl0000775000177100017500000000071712473477707020171 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_delay.v0000664000177100017500000000135012473477707020325 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.916/test_regress/t/t_flag_lib.pl0000775000177100017500000000032312473477707021136 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.916/test_regress/t/t_case_huge.pl0000775000177100017500000000125613205574202021306 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ["--stats"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10); file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 8); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_ena_sc.pl0000775000177100017500000000123113151152521021756 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_lint_ifdepth_bad.pl0000775000177100017500000000151212473477707022657 0ustar 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.916/test_regress/t/t_var_life.pl0000775000177100017500000000127212671044616021157 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_func_return.v0000664000177100017500000000314012671044616021545 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.916/test_regress/t/t_param_package.pl0000775000177100017500000000072212671044616022142 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_notfound_bad.pl0000775000177100017500000000172512671044616022705 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_vpi_sc.v0000664000177100017500000000074313205574202020475 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; // bug1081 - We don't use VPI, just need SC with VPI initial begin $write("%0t: Hello\n", $time); $write("*-* All Finished *-*\n"); $finish; end endmodule : t verilator-3.916/test_regress/t/t_func_dotted_inl1.pl0000775000177100017500000000103713151152521022575 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_udp_lint.pl0000775000177100017500000000114312473477707021216 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_assert_comp.v0000664000177100017500000000060013205574202021521 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*/); if (0) begin $warning("User compile-time warning"); $error("User compile-time error"); end initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_udp_noname.v0000664000177100017500000000136612671044616021350 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.916/test_regress/t/t_var_escape.pl0000775000177100017500000000173013151152521021464 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_assert_comp_bad.v0000664000177100017500000000046113205574202022334 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*/); if (1) begin $warning("User compile-time warning"); $error("User compile-time error"); end endmodule verilator-3.916/test_regress/t/t_math_cmp.v0000664000177100017500000001043612473477707021024 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.916/test_regress/t/t_math_arith.v0000664000177100017500000001101712671044616021335 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg _ranit; reg [2:0] xor3; reg [1:0] xor2; reg [0:0] xor1; reg [2:0] ma, mb; reg [9:0] mc; reg [4:0] mr1; reg [30:0] mr2; reg [67:0] sh1; reg [67:0] shq; wire foo, bar; assign {foo,bar} = 2'b1_0; // surefire lint_off STMINI initial _ranit = 0; wire [4:0] cond_check = (( xor2 == 2'b11) ? 5'h1 : (xor2 == 2'b00) ? 5'h2 : (xor2 == 2'b01) ? 5'h3 : 5'h4); wire ctrue = 1'b1 ? cond_check[1] : cond_check[0]; wire cfalse = 1'b0 ? cond_check[1] : cond_check[0]; wire cif = cond_check[2] ? cond_check[1] : cond_check[0]; wire cifn = (!cond_check[2]) ? cond_check[1] : cond_check[0]; wire [4:0] doubleconc = {1'b0, 1'b1, 1'b0, cond_check[0], 1'b1}; wire zero = 1'b0; wire one = 1'b1; wire [5:0] rep6 = {6{one}}; // verilator lint_off WIDTH localparam [3:0] bug764_p11 = 1'bx; // verilator lint_on WIDTH always @ (posedge clk) begin if (!_ranit) begin _ranit <= 1; if (rep6 != 6'b111111) $stop; if (!one) $stop; if (~one) $stop; if (( 1'b0 ? 3'h3 : 1'b0 ? 3'h2 : 1'b1 ? 3'h1 : 3'h0) !== 3'h1) $stop; // verilator lint_off WIDTH if (( 8'h10 + 1'b0 ? 8'he : 8'hf) !== 8'he) $stop; // + is higher than ? // verilator lint_on WIDTH // surefire lint_off SEQASS xor1 = 1'b1; xor2 = 2'b11; xor3 = 3'b111; // verilator lint_off WIDTH if (1'b1 & | (!xor3)) $stop; // verilator lint_on WIDTH if ({1{xor1}} != 1'b1) $stop; if ({4{xor1}} != 4'b1111) $stop; if (!(~xor1) !== ~(!xor1)) $stop; if ((^xor1) !== 1'b1) $stop; if ((^xor2) !== 1'b0) $stop; if ((^xor3) !== 1'b1) $stop; if (~(^xor2) !== 1'b1) $stop; if (~(^xor3) !== 1'b0) $stop; if ((^~xor1) !== 1'b0) $stop; if ((^~xor2) !== 1'b1) $stop; if ((^~xor3) !== 1'b0) $stop; if ((~^xor1) !== 1'b0) $stop; if ((~^xor2) !== 1'b1) $stop; if ((~^xor3) !== 1'b0) $stop; xor1 = 1'b0; xor2 = 2'b10; xor3 = 3'b101; if ((^xor1) !== 1'b0) $stop; if ((^xor2) !== 1'b1) $stop; if ((^xor3) !== 1'b0) $stop; if (~(^xor2) !== 1'b0) $stop; if (~(^xor3) !== 1'b1) $stop; if ((^~xor1) !== 1'b1) $stop; if ((^~xor2) !== 1'b0) $stop; if ((^~xor3) !== 1'b1) $stop; if ((~^xor1) !== 1'b1) $stop; if ((~^xor2) !== 1'b0) $stop; if ((~^xor3) !== 1'b1) $stop; ma = 3'h3; mb = 3'h4; mc = 10'h5; mr1 = ma * mb; // Lint ASWESB: Assignment width mismatch mr2 = 30'h5 * mc; // Lint ASWESB: Assignment width mismatch if (mr1 !== 5'd12) $stop; if (mr2 !== 31'd25) $stop; // Lint CWECBB: Comparison width mismatch sh1 = 68'hf_def1_9abc_5678_1234; shq = sh1 >> 16; if (shq !== 68'hf_def1_9abc_5678) $stop; shq = sh1 << 16; // Lint ASWESB: Assignment width mismatch if (shq !== 68'h1_9abc_5678_1234_0000) $stop; // surefire lint_on SEQASS // Test display extraction widthing $display("[%0t] %x %x %x(%d)", $time, shq[2:0], shq[2:0]<<2, xor3[2:0], xor3[2:0]); // bug736 //verilator lint_off WIDTH if ((~| 4'b0000) != 4'b0001) $stop; if ((~| 4'b0010) != 4'b0000) $stop; if ((~& 4'b1111) != 4'b0000) $stop; if ((~& 4'b1101) != 4'b0001) $stop; //verilator lint_on WIDTH // bug764 //verilator lint_off WIDTH // X does not sign extend if (bug764_p11 !== 4'b000x) $stop; if (~& bug764_p11 !== 1'b1) $stop; //verilator lint_on WIDTH // However IEEE says for constants in 2012 5.7.1 that smaller-sizes do extend if (4'bx !== 4'bxxxx) $stop; if (4'bz !== 4'bzzzz) $stop; if (4'b1 !== 4'b0001) $stop; $write("*-* All Finished *-*\n"); $finish; end end reg [63:0] m_data_pipe2_r; reg [31:0] m_corr_data_w0, m_corr_data_w1; reg [7:0] m_corr_data_b8; initial begin m_data_pipe2_r = 64'h1234_5678_9abc_def0; {m_corr_data_b8, m_corr_data_w1, m_corr_data_w0} = { m_data_pipe2_r[63:57], 1'b0, //m_corr_data_b8 [7:0] m_data_pipe2_r[56:26], 1'b0, //m_corr_data_w1 [31:0] m_data_pipe2_r[25:11], 1'b0, //m_corr_data_w0 [31:16] m_data_pipe2_r[10:04], 1'b0, //m_corr_data_w0 [15:8] m_data_pipe2_r[03:01], 1'b0, //m_corr_data_w0 [7:4] m_data_pipe2_r[0], 3'b000 //m_corr_data_w0 [3:0] }; if (m_corr_data_w0 != 32'haf36de00) $stop; if (m_corr_data_w1 != 32'h1a2b3c4c) $stop; if (m_corr_data_b8 != 8'h12) $stop; end endmodule verilator-3.916/test_regress/t/t_langext_1_bad.pl0000775000177100017500000000104012671044616022051 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_verilated_debug.v0000664000177100017500000000053113205574202022332 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // Test loop always @ (posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_enumeration.pl0000775000177100017500000000102612671044616021713 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_vpi_get.cpp0000664000177100017500000001754713205574202021176 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_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, .value = {.integer = 0} }; // check size of object int vpisize = vpi_get(vpiSize, handle); CHECK_RESULT(vpisize, size); // icarus verilog does not support vpiScalar, vpiVector or vpi*Range if (TestSimulator::has_get_scalar()) { int vpiscalar = vpi_get(vpiScalar, handle); CHECK_RESULT((bool)vpiscalar, (bool)scalar); int vpivector = vpi_get(vpiVector, handle); CHECK_RESULT((bool)vpivector, (bool)!scalar); } // Icarus only supports ranges on memories if (!scalar && !(TestSimulator::is_icarus() && type != vpiMemory)) { TestVpiHandle left_h, right_h; // check coherency for vectors // get left hand side of range left_h = vpi_handle(vpiLeftRange, handle); CHECK_RESULT_NZ(left_h); vpi_get_value(left_h, &value); int coherency = value.value.integer; // get right hand side of range right_h = vpi_handle(vpiRightRange, handle); CHECK_RESULT_NZ(right_h); vpi_get_value(right_h, &value); TEST_MSG("%d:%d\n", coherency, value.value.integer); coherency -= value.value.integer; // calculate size & check coherency = abs(coherency) + 1; CHECK_RESULT(coherency, size); } // Only check direction on ports if (type == vpiPort) { // check direction of object int vpidir = vpi_get(vpiDirection, handle); // Don't check port directions in verilator // see #681 if (!TestSimulator::is_verilator()) { CHECK_RESULT(vpidir, direction); } } // check type of object int vpitype = vpi_get(vpiType, handle); if (!(TestSimulator::is_verilator() && type == vpiPort)) { // Don't check for ports in verilator // see #681 CHECK_RESULT(vpitype, type); } return 0; // Ok } struct params { const char* signal; struct { unsigned int size; unsigned int direction; unsigned int scalar; int type; } attributes, children; } values[] = { {"onebit", {1, vpiNoDirection, 1, vpiReg}, {0, 0, 0, 0}}, {"twoone", {2, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}}, {"onetwo", {2, vpiNoDirection, 0, TestSimulator::is_verilator() ? vpiReg : vpiMemory}, {0, 0, 0, 0}}, {"fourthreetwoone", {2, vpiNoDirection, 0, vpiMemory}, {2, vpiNoDirection, 0, vpiMemoryWord}}, {"clk", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, {"testin", {16, vpiInput, 0, vpiPort}, {0, 0, 0, 0}}, {"testout", {24, vpiOutput, 0, vpiPort}, {0, 0, 0, 0}}, {"sub.subin", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, {"sub.subout", {1, vpiOutput, 1, vpiPort}, {0, 0, 0, 0}}, {NULL, {0, 0, 0, 0}, {0, 0, 0, 0}} }; int mon_check_props() { struct params* value = values; while (value->signal) { TestVpiHandle h = VPI_HANDLE(value->signal); CHECK_RESULT_NZ(h); TEST_MSG("%s\n", value->signal); if (int status = _mon_check_props(h, value->attributes.size, value->attributes.direction, value->attributes.scalar, value->attributes.type)) return status; if (value->children.size) { int size = 0; TestVpiHandle iter_h = vpi_iterate(vpiMemoryWord, h); while (TestVpiHandle word_h = vpi_scan(iter_h.nofree())) { // check size and range if (int status = _mon_check_props(word_h, value->children.size, value->children.direction, value->children.scalar, value->children.type)) return status; size++; } CHECK_RESULT(size, value->attributes.size); } value++; } return 0; } int mon_check() { // Callback from initial block in monitor if (int status = mon_check_props()) return status; return 0; // Ok } //====================================================================== #ifdef IS_VPI static int mon_check_vpi() { vpiHandle href = vpi_handle(vpiSysTfCall, 0); s_vpi_value vpi_value; vpi_value.format = vpiIntVal; vpi_value.value.integer = mon_check(); vpi_put_value(href, &vpi_value, NULL, vpiNoDelay); return 0; } static s_vpi_systf_data vpi_systf_data[] = { {vpiSysFunc, vpiIntFunc, (PLI_BYTE8*)"$mon_check", (PLI_INT32(*)(PLI_BYTE8*))mon_check_vpi, 0, 0, 0}, 0 }; // cver entry void vpi_compat_bootstrap(void) { p_vpi_systf_data systf_data_p; systf_data_p = &(vpi_systf_data[0]); while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++); } // icarus entry void (*vlog_startup_routines[])() = { vpi_compat_bootstrap, 0 }; #else double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { double sim_time = 1100; Verilated::commandArgs(argc, argv); Verilated::debug(0); VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out #ifdef VERILATOR # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif #endif #if VM_TRACE Verilated::traceEverOn(true); VL_PRINTF("Enabling waves...\n"); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_vpi_var/simx.vcd"); #endif topp->eval(); topp->clk = 0; main_time += 10; while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += 1; topp->eval(); VerilatedVpi::callValueCbs(); topp->clk = !topp->clk; //mon_do(); #if VM_TRACE if (tfp) tfp->dump (main_time); #endif } if (!Verilated::gotFinish()) { vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish"); } topp->final(); #if VM_TRACE if (tfp) tfp->close(); #endif delete topp; topp=NULL; exit(0L); } #endif verilator-3.916/test_regress/t/t_static_elab.pl0000775000177100017500000000072213205574202021632 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_static.v0000664000177100017500000000334013205574202021345 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; function int f_no_no (); int st = 2; st++; return st; endfunction function int f_no_st (); static int st = 2; st++; return st; endfunction function int f_no_au (); automatic int st = 2; st++; return st; endfunction function static int f_st_no (); int st = 2; st++; return st; endfunction function static int f_st_st (); static int st = 2; st++; return st; endfunction function static int f_st_au (); automatic int st = 2; st++; return st; endfunction function automatic int f_au_no (); int st = 2; st++; return st; endfunction function automatic int f_au_st (); static int st = 2; st++; return st; endfunction function automatic int f_au_au (); automatic int st = 2; st++; return st; endfunction initial begin if (f_no_no() != 3) $stop; if (f_no_no() != 4) $stop; if (f_no_st() != 3) $stop; if (f_no_st() != 4) $stop; if (f_no_au() != 3) $stop; if (f_no_au() != 3) $stop; // if (f_st_no() != 3) $stop; if (f_st_no() != 4) $stop; if (f_st_st() != 3) $stop; if (f_st_st() != 4) $stop; if (f_st_au() != 3) $stop; if (f_st_au() != 3) $stop; // if (f_au_no() != 3) $stop; if (f_au_no() != 3) $stop; if (f_au_st() != 3) $stop; if (f_au_st() != 4) $stop; if (f_au_au() != 3) $stop; if (f_au_au() != 3) $stop; // $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_preproc.pl0000775000177100017500000000364113165225640021041 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_case_huge_sub.v0000664000177100017500000004007712473477707022034 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.916/test_regress/t/t_tri_pull01.v0000664000177100017500000000373212671044616021215 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.916/test_regress/t/t_lint_latch_bad.pl0000775000177100017500000000206313205574202022307 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only -Wwarn-style -Wno-DECLFILENAME"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> quotemeta( '%Warning-COMBDLY: t/t_lint_latch_bad.v:24: Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=). %Warning-COMBDLY: Use "/* verilator lint_off COMBDLY */" and lint_on around source to disable this message. %Warning-COMBDLY: *** See the manual before disabling this, %Warning-COMBDLY: else you may end up with different sim results. %Error: Exiting due to 1 warning').'.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_func_const_packed_struct_bad.pl0000775000177100017500000000225713205574202025247 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2017 by Todd Strader. This program is free software; you can # redistribute it and/or 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-USERFATAL: f_add = 15 %Warning-USERFATAL: Use "/* verilator lint_off USERFATAL */" and lint_on around source to disable this message. %Error: t/t_func_const_packed_struct_bad.v:13: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_add2' %Error: t/t_func_const_packed_struct_bad.v:24: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing Called from: t/t_func_const_packed_struct_bad.v:32: f_add() with parameters: params = [0 = '{a: 32'h7, b: 32'h22b}, 1 = '{a: 32'h3039, b: 32'h8}] Called from: t/t_func_const_packed_struct_bad.v:13: f_add2() with parameters: a = ?32?sh7 b = ?32?sh8 c = ?32?sh9 }, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_array.v0000664000177100017500000000241212473477707021402 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.916/test_regress/t/t_inst_first_b.v0000664000177100017500000000147712671044616021713 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_inst_first_b (/*AUTOARG*/ // Outputs o_seq_d1r, o_com, o2_com, // Inputs clk, i_seq, i_com, i2_com, wide_for_trace, wide_for_trace_2 ); // verilator inline_module input clk; input i_seq; output o_seq_d1r; input i_com; output o_com; input [1:0] i2_com; output [1:0] o2_com; input [127:0] wide_for_trace; input [127:0] wide_for_trace_2; /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) // End of automatics reg o_seq_d1r; always @ (posedge clk) begin o_seq_d1r <= ~i_seq; end wire [1:0] o2_com = ~i2_com; wire o_com = ~i_com; endmodule verilator-3.916/test_regress/t/t_pp_circdef_bad.v0000664000177100017500000000061512671044616022123 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.916/test_regress/t/t_func_const_struct_bad.v0000664000177100017500000000163613205574202023567 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Todd Strader. module t; typedef struct packed { logic [ 31 : 0 ] a; logic [ 31 : 0 ] b; } params_t; localparam params_t P = '{a:5, b:1}; localparam P6 = f_add(P); localparam P14 = f_add2(2, 3, f_add(P)); localparam P24 = f_add2(7, 8, 9); initial begin // Should never get here $write("*-* All Finished *-*\n"); $finish; end function integer f_add(input params_t params); f_add = params.a+params.b; if (f_add == 15) $fatal(2, "f_add = 15"); endfunction // Speced ok: function called from function function integer f_add2(input [31:0] a, input [31:0] b, input [31:0] c); params_t params; params = '{ a: a, b: b }; f_add2 = f_add(params)+c; endfunction endmodule verilator-3.916/test_regress/t/t_func_numones.pl0000775000177100017500000000071712473477707022105 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_bind.v0000664000177100017500000000251612671044616020135 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.916/test_regress/t/t_flag_getenv.v0000664000177100017500000000026013205574202021465 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.916/test_regress/t/t_dpi_string.pl0000775000177100017500000000077312671044616021537 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_math_const.pl0000775000177100017500000000071712473477707021545 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_math_concat0.pl0000775000177100017500000000071712473477707021746 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_sys_readmem_bad_end.v0000664000177100017500000000055512671044616023166 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.916/test_regress/t/t_func_paramed.v0000664000177100017500000000303612473477707021656 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, ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_upscope.v0000664000177100017500000000371012671044616021525 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. /* Acceptable answer 1 created tag with scope = top.t.tag created tag with scope = top.t.b.gen[0].tag created tag with scope = top.t.b.gen[1].tag mod a has scope = top.t mod a has tag = top.t.tag mod b has scope = top.t.b mod b has tag = top.t.tag mod c has scope = top.t.b.gen[0].c mod c has tag = top.t.b.gen[0].tag mod c has scope = top.t.b.gen[1].c mod c has tag = top.t.b.gen[1].tag */ /* Acceptable answer 2 created tag with scope = top.t.tag created tag with scope = top.t.b.gen[0].tag created tag with scope = top.t.b.gen[1].tag mod a has scope = top.t mod a has tag = top.t.tag mod b has scope = top.t.b mod b has tag = top.t.tag mod c has scope = top.t.b.gen[0].c mod c has tag = top.t.tag mod c has scope = top.t.b.gen[1].c mod c has tag = top.t.tag */ module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; tag tag (); b b (); always @ (t.cyc) begin if (t.cyc == 2) $display("mod a has scope = %m"); if (t.cyc == 2) $display("mod a has tag = %0s", tag.scope); end always @(posedge clk) begin cyc <= cyc + 1; if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module b (); genvar g; generate for (g=0; g<2; g++) begin : gen tag tag (); c c (); end endgenerate always @ (t.cyc) begin if (t.cyc == 3) $display("mod b has scope = %m"); if (t.cyc == 3) $display("mod b has tag = %0s", tag.scope); end endmodule module c (); always @ (t.cyc) begin if (t.cyc == 4) $display("mod c has scope = %m"); if (t.cyc == 4) $display("mod c has tag = %0s", tag.scope); end endmodule module tag (); bit [100*8-1:0] scope; initial begin $sformat(scope,"%m"); $display("created tag with scope = %0s",scope); end endmodule verilator-3.916/test_regress/t/t_trace_primitive.pl0000775000177100017500000000110313205574202022540 0ustar wsnyderwsnyder#!/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. compile ( v_flags2 => ["--trace"], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/simx.vcd", "sub_t_i"); }; ok(1); 1; verilator-3.916/test_regress/t/t_display_real.pl0000775000177100017500000000252212473477707022052 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, expect=> quotemeta( '[0] e=0.000000e+00 e1=0.000000e+00 e30=0e+00 e32=0.00e+00 [0] f=0.000000 f1=0.000000e+00 f30=0e+00 f32=0.00e+00 [0] g=0 g1=0.000000e+00 g30=0e+00 g32=0.00e+00 [0] e=1.000000e+00 e1=1.000000e+00 e30=1e+00 e32=1.00e+00 [0] f=1.000000 f1=1.000000e+00 f30=1e+00 f32=1.00e+00 [0] g=1 g1=1.000000e+00 g30=1e+00 g32=1.00e+00 [0] e=1.000000e-01 e1=1.000000e-01 e30=1e-01 e32=1.00e-01 [0] f=0.100000 f1=1.000000e-01 f30=1e-01 f32=1.00e-01 [0] g=0.1 g1=1.000000e-01 g30=1e-01 g32=1.00e-01 [0] e=1.234500e-15 e1=1.234500e-15 e30=1e-15 e32=1.23e-15 [0] f=0.000000 f1=1.234500e-15 f30=1e-15 f32=1.23e-15 [0] g=1.2345e-15 g1=1.234500e-15 g30=1e-15 g32=1.23e-15 [0] e=2.579000e+15 e1=2.579000e+15 e30=3e+15 e32=2.58e+15 [0] f=2579000000000000.000000 f1=2.579000e+15 f30=3e+15 f32=2.58e+15 [0] g=2.579e+15 g1=2.579000e+15 g30=3e+15 g32=2.58e+15 r8= 3 n1=1 n2=0.1 n1=1 n2=0.1 r8= 3 '), ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_complex_structs.pl0000775000177100017500000000227213151152521023772 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t_trace_complex.v"); compile ( verilator_flags2 => ['--cc --trace --trace-structs --no-trace-params'], ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_strp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_strp_strp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp /); file_grep_not ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp_arrp /); file_grep_not ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp_strp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru\(/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arru\(/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arrp\(/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_strp\(/); vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out"); ok(1); 1; verilator-3.916/test_regress/t/t_var_pins_sc1.pl0000775000177100017500000000410513205574202021746 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -pins-bv 1 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.916/test_regress/t/t_arraysel_wide.v0000664000177100017500000000113013205574202022033 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs nnext, // Inputs inibble, onibble ); input [3:0] inibble; input [106:0] onibble; output reg [3:0] nnext [0:7]; // verilator lint_off WIDTH wire [2:0] selline = (onibble >>> 102) & 7; // verilator lint_on WIDTH always_comb begin for (integer i=0; i<8; i=i+1) begin nnext[i] = '0; end nnext[selline] = inibble; end endmodule verilator-3.916/test_regress/t/t_lint_inherit.pl0000775000177100017500000000064712473477707022100 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_xml_tag.out0000664000177100017500000000354513205574202021212 0ustar wsnyderwsnyder verilator-3.916/test_regress/t/t_mod_dup_ign.pl0000775000177100017500000000110012473477707021655 0ustar 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.916/test_regress/t/t_interface_param1.pl0000775000177100017500000000102412671044616022564 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_array_type_methods.v0000664000177100017500000000145513205574202023115 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); `define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t (/*AUTOARG*/ // Inputs clk ); input clk; logic [2:0] foo [1:0]; initial begin foo[0] = 3'b101; foo[1] = 3'b011; `checkh(foo.or, 3'b111); `checkh(foo.and, 3'b001); `checkh(foo.xor, 3'b110); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_func_regfirst.pl0000775000177100017500000000071712473477707022246 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_assert_cover.v0000664000177100017500000000644513205574202021716 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.916/test_regress/t/t_slice_cond.pl0000775000177100017500000000065113205574202021463 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_named.pl0000775000177100017500000000071712473477707021652 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_check.v0000664000177100017500000000246012473477707021322 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.916/test_regress/t/t_gen_forif.pl0000775000177100017500000000075512473477707021346 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_preproc_inc4.vh0000664000177100017500000000030012473477707021760 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.916/test_regress/t/t_clk_concat5.v0000664000177100017500000000337613205574202021404 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // module some_module ( input [3:0] i_clks ); logic [ 1 : 0 ] some_state; logic [1:0] some_other_state; always @(posedge i_clks[3]) begin case (some_state) 2'b11: if (some_other_state == 0) some_state <= 2'b00; default: $display ("This is a display statement"); endcase if (i_clks[3]) some_other_state <= 0; $write("*-* All Finished *-*\n"); $finish; end endmodule `define BROKEN module t1( input [3:0] i_clks, input i_clk0, input i_clk1 ); some_module some_module ( .i_clks (i_clks) ); endmodule module t2( input [2:0] i_clks, input i_clk0, input i_clk1, input i_clk2, input i_data ); logic [3:0] the_clks; logic data_q; assign the_clks[3] = i_clk1; assign the_clks[2] = i_clk2; assign the_clks[1] = i_clk1; assign the_clks[0] = i_clk0; always @(posedge i_clk0) begin data_q <= i_data; end t1 t1 ( .i_clks (the_clks), .i_clk0 (i_clk0), .i_clk1 (i_clk1) ); endmodule module t( /*AUTOARG*/ // Inputs clk /*verilator clocker*/, input clk0 /*verilator clocker*/, input clk1 /*verilator clocker*/, input clk2 /*verilator clocker*/, input data_in ); input clk; logic [2:0] clks; assign clks = {1'b0, clk1, clk0}; t2 t2 ( .i_clks (clks), .i_clk0 (clk0), .i_clk1 (clk), .i_clk2 (clk2), .i_data (data_in) ); // initial begin // $write("*-* All Finished *-*\n"); // $finish; // end endmodule verilator-3.916/test_regress/t/t_gen_for_overlap.pl0000775000177100017500000000072212671044616022536 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_leak.cpp0000664000177100017500000000444113151152521020436 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.916/test_regress/t/t_unroll_genf.pl0000775000177100017500000000072213205574202021672 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_cat_reopen.pl0000775000177100017500000000151613151152521022653 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_langext_1.v0000664000177100017500000000204312671044616021076 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.916/test_regress/t/t_func_regfirst.v0000664000177100017500000000240712473477707022073 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.916/test_regress/t/t_sys_file_basic.v0000664000177100017500000001473313205574202022174 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. `include "verilated.v" module t; `verilator_file_descriptor file; integer chars; reg [1*8:1] letterl; reg [8*8:1] letterq; reg [16*8:1] letterw; reg [16*8:1] letterz; real r; string s; reg [7:0] v_a,v_b,v_c,v_d; reg [31:0] v_worda; reg [31:0] v_wordb; `ifdef TEST_VERBOSE `define verbose 1'b1 `else `define verbose 1'b0 `endif initial begin // Display formatting `ifdef verilator if (file != 0) $stop; $fwrite(file, "Never printed, file closed\n"); if (!$feof(file)) $stop; `endif `ifdef AUTOFLUSH // The "w" is required so we get a FD not a MFD file = $fopen("obj_dir/t_sys_file_autoflush/t_sys_file_autoflush.log","w"); `else // The "w" is required so we get a FD not a MFD file = $fopen("obj_dir/t_sys_file_basic/t_sys_file_basic_test.log","w"); `endif if ($feof(file)) $stop; $fdisplay(file, "[%0t] hello v=%x", $time, 32'h12345667); $fwrite(file, "[%0t] %s\n", $time, "Hello2"); $fflush(file); $fclose(file); `ifdef verilator if (file != 0) $stop(1); // Also test arguments to stop $fwrite(file, "Never printed, file closed\n"); `endif begin // Check for opening errors // The "r" is required so we get a FD not a MFD file = $fopen("obj_dir/t_sys_file_basic/DOES_NOT_EXIST","r"); if (|file) $stop; // Should not exist, IE must return 0 end begin // Check quadword access; a little strange, but it's legal to open "." file = $fopen(".","r"); $fclose(file); end begin // Check read functions w/string s = "t/t_sys_file_basic_input.dat"; file = $fopen(s,"r"); if ($feof(file)) $stop; $fclose(file); end begin // Check read functions file = $fopen("t/t_sys_file_basic_input.dat","r"); if ($feof(file)) $stop; // $fgetc if ($fgetc(file) != "h") $stop; if ($fgetc(file) != "i") $stop; if ($fgetc(file) != "\n") $stop; // $fgets chars = $fgets(letterl, file); if (`verbose) $write("c=%0d l=%s\n", chars, letterl); if (chars != 1) $stop; if (letterl != "l") $stop; chars = $fgets(letterq, file); if (`verbose) $write("c=%0d q=%x=%s", chars, letterq, letterq); // Output includes newline if (chars != 5) $stop; if (letterq != "\0\0\0quad\n") $stop; letterw = "5432109876543210"; chars = $fgets(letterw, file); if (`verbose) $write("c=%0d w=%s", chars, letterw); // Output includes newline if (chars != 10) $stop; if (letterw != "\0\0\0\0\0\0widestuff\n") $stop; // $sscanf if ($sscanf("x","")!=0) $stop; if ($sscanf("z","z")!=0) $stop; chars = $sscanf("blabcdefghijklmnop", "%s", letterq); if (`verbose) $write("c=%0d sa=%s\n", chars, letterq); if (chars != 1) $stop; if (letterq != "ijklmnop") $stop; chars = $sscanf("xa=1f xb=12898971238912389712783490823_237904689_02348923", "xa=%x xb=%x", letterq, letterw); if (`verbose) $write("c=%0d xa=%x xb=%x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h1f) $stop; if (letterw != 128'h38971278349082323790468902348923) $stop; chars = $sscanf("ba=10 bb=110100101010010101012 note_the_two ", "ba=%b bb=%b%s", letterq, letterw, letterz); if (`verbose) $write("c=%0d xa=%x xb=%x z=%0s\n", chars, letterq, letterw, letterz); if (chars != 3) $stop; if (letterq != 64'h2) $stop; if (letterw != 128'hd2a55) $stop; if (letterz != {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0","2"}) $stop; chars = $sscanf("oa=23 ob=125634123615234123681236", "oa=%o ob=%o", letterq, letterw); if (`verbose) $write("c=%0d oa=%x ob=%x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h13) $stop; if (letterw != 128'h55ce14f1a9c29e) $stop; chars = $sscanf("r=0.1 d=-236123", "r=%g d=%d", r, letterq); if (`verbose) $write("c=%0d d=%d\n", chars, letterq); if (chars != 2) $stop; if (r != 0.1) $stop; if (letterq != 64'hfffffffffffc65a5) $stop; s = "r=0.2 d=-236124"; chars = $sscanf(s, "r=%g d=%d", r, letterq); if (`verbose) $write("c=%0d d=%d\n", chars, letterq); if (chars != 2) $stop; if (r != 0.2) $stop; if (letterq != 64'hfffffffffffc65a4) $stop; // $fscanf if ($fscanf(file,"")!=0) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "xa=%x xb=%x", letterq, letterw); if (`verbose) $write("c=%0d xa=%0x xb=%0x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h1f) $stop; if (letterw != 128'h23790468902348923) $stop; if (!sync("\n")) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "ba=%b bb=%b %s", letterq, letterw, letterz); if (`verbose) $write("c=%0d ba=%0x bb=%0x z=%0s\n", chars, letterq, letterw, letterz); if (chars != 3) $stop; if (letterq != 64'h2) $stop; if (letterw != 128'hd2a55) $stop; if (letterz != "\0\0\0\0note_the_two") $stop; if (!sync("\n")) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "oa=%o ob=%o", letterq, letterw); if (`verbose) $write("c=%0d oa=%0x ob=%0x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h13) $stop; if (letterw != 128'h1573) $stop; if (!sync("\n")) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "d=%d", letterq); if (`verbose) $write("c=%0d d=%0x\n", chars, letterq); if (chars != 1) $stop; if (letterq != 64'hfffffffffffc65a5) $stop; if (!sync("\n")) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "%c%s", letterl, letterw); if (`verbose) $write("c=%0d q=%c s=%s\n", chars, letterl, letterw); if (chars != 2) $stop; if (letterl != "f") $stop; if (letterw != "\0\0\0\0\0redfishblah") $stop; chars = $fscanf(file, "%c", letterl); if (`verbose) $write("c=%0d l=%x\n", chars, letterl); if (chars != 1) $stop; if (letterl != "\n") $stop; // msg1229 v_a = $fgetc(file); v_b = $fgetc(file); v_c = $fgetc(file); v_d = $fgetc(file); v_worda = { v_d, v_c, v_b, v_a }; if (v_worda != "4321") $stop; v_wordb[7:0] = $fgetc(file); v_wordb[15:8] = $fgetc(file); v_wordb[23:16] = $fgetc(file); v_wordb[31:24] = $fgetc(file); if (v_wordb != "9876") $stop; if ($fgetc(file) != "\n") $stop; $fclose(file); end $write("*-* All Finished *-*\n"); $finish(0); // Test arguments to finish end function sync; input [7:0] cexp; reg [7:0] cgot; begin cgot = $fgetc(file); if (`verbose) $write("sync=%x='%c'\n", cgot,cgot); sync = (cgot == cexp); end endfunction endmodule verilator-3.916/test_regress/t/t_var_pinsizes.v0000664000177100017500000000253213205574202021724 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. // Also check that SystemC is ordering properly // verilator lint_on IMPERFECTSCH module t (/*AUTOARG*/ // Outputs o1, o8, o16, o32, o64, o65, o128, o513, o1a2, o94a3, obv1, obv16, // Inputs clk, i1, i8, i16, i32, i64, i65, i128, i513, i1a2, i94a3, ibv1, ibv16 ); input clk; input i1; input [7:0] i8; input [15:0] i16; input [31:0] i32; input [63:0] i64; input [64:0] i65; input [127:0] i128; input [512:0] i513; input i1a2 [1:0]; input [93:0] i94a3 [2:0]; output o1; output [7:0] o8; output [15:0] o16; output [31:0] o32; output [63:0] o64; output [64:0] o65; output [127:0] o128; output [512:0] o513; output o1a2 [1:0]; output [93:0] o94a3 [2:0]; input [0:0] ibv1 /*verilator sc_bv*/; input [15:0] ibv16 /*verilator sc_bv*/; output [0:0] obv1 /*verilator sc_bv*/; output [15:0] obv16 /*verilator sc_bv*/; always @ (posedge clk) begin o1 <= i1; o8 <= i8; o16 <= i16; o32 <= i32; o64 <= i64; o65 <= i65; o128 <= i128; o513 <= i513; obv1 <= ibv1; obv16 <= ibv16; o1a2 <= i1a2; o94a3 <= i94a3; end endmodule verilator-3.916/test_regress/t/t_select_little_pack.pl0000775000177100017500000000071712671044616023225 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inside.pl0000775000177100017500000000072212671044616020642 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_module.pl0000775000177100017500000000074612671044616022042 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_preproc_def09.v0000664000177100017500000000341112473477707021670 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.916/test_regress/t/t_uniqueif.pl0000775000177100017500000000103313151152521021175 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_order.pl0000775000177100017500000000071712473477707020521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_stats.v0000664000177100017500000000045513205574202021341 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (b); output reg [31:0] b; initial begin b = 22; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_case_write1.out0000664000177100017500000001674712473477707022017 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.916/test_regress/t/t_func_const_packed_struct_bad2.v0000664000177100017500000000220713205574202025153 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Todd Strader. module t; typedef struct packed { logic [ 31 : 0 ] b; logic [ 7 : 0 ] bar; } sub_params_t; typedef struct packed { logic [ 31 : 0 ] a; logic [ 5 : 0 ] foo; sub_params_t sub_params; } params_t; localparam P24 = f_add2(7, 8, 9); initial begin // Should never get here $write("*-* All Finished *-*\n"); $finish; end function integer f_add(input params_t [ 1 : 0 ] params); f_add = params[0].a+params[1].sub_params.b; if (f_add == 15) $fatal(2, "f_add = 15"); endfunction // Speced ok: function called from function function integer f_add2(input [31:0] a, input [31:0] b, input [31:0] c); params_t [ 1 : 0 ] params; sub_params_t sp0; sub_params_t sp1; sp0 = '{b:55, bar:111}; params[0] = '{a:a, foo:11, sub_params:sp0}; sp1 = '{b:b, bar:112}; params[1] = '{a:12345, foo:12, sub_params:sp1}; f_add2 = f_add(params)+c; endfunction endmodule verilator-3.916/test_regress/t/t_param_const_part.pl0000775000177100017500000000072213205574202022714 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func.v0000664000177100017500000000640413205574202020145 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; reg [2:0] value; reg [31:0] rglobal; reg [31:0] vec [1:0]; reg [31:0] n; initial begin rglobal = 1; value = 2; if (add(value) != 3'd3) $stop; if (rglobal != 2) $stop; if (add(add(3'd1)) != 3'd3) $stop; if (rglobal != 4) $stop; if (munge4(4'b0010) != 4'b1011) $stop; if (toint(2) != 3) $stop; if (rglobal != 5) $stop; setit; incr(rglobal,rglobal,32'h10); if (rglobal != 32'h17) $stop; nop(32'h11); empty; empty(); rglobal = 32'h00000001; flipupperbit(rglobal,4'd4); flipupperbit(rglobal,4'd12); if (rglobal !== 32'h10100001) $stop; if (nil_func(32'h12,32'h12) != 32'h24) $stop; nil_task(32'h012,32'h112,rglobal); if (rglobal !== 32'h124) $stop; vec[0] = 32'h333; vec[1] = 32'habc; incr(vec[1],vec[0],vec[1]); if (vec[0] != 32'h333) $stop; if (vec[1] != 32'hdef) $stop; // verilator lint_off SELRANGE incr(vec[2],vec[0],vec[2]); // Reading/Writing past end of vector! // verilator lint_on SELRANGE n=1; nil(); if (n !== 10) $stop; // Functions called as tasks rglobal = 32'h4; if (inc_and_return(32'h2) != 32'h6) $stop; if (rglobal !== 32'h6) $stop; rglobal = 32'h6; inc_and_return(32'h3); if (rglobal !== 32'h9) $stop; $write("*-* All Finished *-*\n"); $finish; end function [2:0] add; input [2:0] fromv; begin add = fromv + 3'd1; begin : named reg [31:0] flocal; flocal = 1; rglobal = rglobal + flocal; end : named // SystemVerilog end labels end endfunction function [3:0] munge4; input [3:0] fromv; // Different fromv than the 'fromv' signal above reg one; begin : named reg [1:0] flocal; // Function calling a function one = 1'b1; munge4 = {one, add(fromv[2:0])}; end endfunction task setit; reg [31:0] temp; begin temp = rglobal + 32'h1; rglobal = temp + 32'h1; end endtask task incr ( // Check a V2K style input/output list output [31:0] z, input [31:0] a, inc ); z = a + inc; endtask task nop; input [31:0] a; begin end endtask task empty; endtask task flipupperbit; inout [31:0] vector; input [3:0] bitnum; reg [4:0] bitnum2; begin bitnum2 = {1'b1, bitnum}; // A little math to test constant propagation vector[bitnum2] = vector[bitnum2] ^ 1'b1; end endtask task nil_task; input [31:0] a; input [31:0] b; output [31:0] q; // verilator no_inline_task q = nil_func(a, b); endtask function void nil; n = 10; endfunction function [31:0] nil_func; input [31:0] fa; input [31:0] fb; // verilator no_inline_task nil_func = fa + fb; endfunction function integer toint; input integer fa; toint = fa + 32'h1; endfunction function [31:0] inc_and_return; input [31:0] inc; rglobal = rglobal + inc; return rglobal; endfunction endmodule verilator-3.916/test_regress/t/t_slice_cond.v0000664000177100017500000000163113205574202021311 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs dataout, // Inputs clk, sel, d0, d1 ); input clk; input sel; logic [7:0] data [1:0][3:0]; input [7:0] d0, d1; output wire [8*2*4-1:0] dataout; always_comb begin for ( integer j = 0; j <= 1; j++ ) begin if (sel) data[j] = '{ d0, d1, 8'h00, 8'h00 }; else data[j] = '{ 8'h00, 8'h00, 8'h00, 8'h00 }; end for ( integer j = 0; j <= 1; j++ ) begin data[j] = sel ? '{ d0, d1, 8'h00, 8'h00 } : '{ 8'h00, 8'h00, 8'h00, 8'h00 }; end end assign dataout = {data[0][0], data[0][1], data[0][2], data[0][3], data[1][0], data[1][1], data[1][2], data[1][3]}; endmodule verilator-3.916/test_regress/t/t_mem_cond.pl0000775000177100017500000000072213205574202021141 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_scope_map.cpp0000664000177100017500000001205413205574202021473 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 #include #include #include "Vt_scope_map.h" using namespace std; 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_scope_map *top = new Vt_scope_map("top"); Verilated::debug(0); Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; top->trace(tfp,99); tfp->open("obj_dir/t_scope_map/simx.vcd"); top->CLK = 0; top->eval(); tfp->dump((unsigned int)(main_time)); ++main_time; const VerilatedScopeNameMap* scopeMapp = Verilated::scopeNameMap(); for (VerilatedScopeNameMap::const_iterator it = scopeMapp->begin(); it != scopeMapp->end(); it++) { #ifdef TEST_VERBOSE VL_PRINTF("---------------------------------------------\n"); VL_PRINTF("Scope = %s\n", it->first); it->second->scopeDump(); #endif VerilatedVarNameMap * varNameMap = it->second->varsp(); if (varNameMap == NULL) { VL_PRINTF("%%Error: Bad varsp()\n"); return -1; } for (VerilatedVarNameMap::iterator varIt = varNameMap->begin(); varIt != varNameMap->end(); ++varIt) { VerilatedVar * var = &varIt->second; int varLeft = var->range().left(); int varRight = var->range().right(); #ifdef TEST_VERBOSE VL_PRINTF("\tVar = %s\n", varIt->first); VL_PRINTF("\t Type = %d\n", var->vltype()); VL_PRINTF("\t EntSize = %d\n", var->entSize()); VL_PRINTF("\t Dims = %d\n", var->dims()); VL_PRINTF("\t Range = %d:%d\n", varLeft, varRight); VL_PRINTF("\t Is RW = %d\n", var->isPublicRW()); #endif if (varRight != 0) { VL_PRINTF("%%Error: Was expecting right range value = 0\n"); return -1; } int varBits = varLeft + 1; // First expect an incrementing byte pattern vluint8_t * varData = reinterpret_cast(var->datap()); for (int i = 0; i < varBits / 8; i++) { #ifdef TEST_VERBOSE VL_PRINTF("%02x ", varData[i]); #endif vluint8_t expected = i % 0xff; if (varData[i] != expected) { VL_PRINTF("%%Error: Data mismatch, got 0x%02x, expected 0x%02x\n", varData[i], expected); return -1; } } // Extra bits all set high initially if (varBits % 8 != 0) { vluint8_t got = varData[ varBits / 8 ]; vluint8_t expected = ~(0xff << ( varBits % 8 )); if (got != expected) { VL_PRINTF("%%Error: Data mismatch, got 0x%02x, expected 0x%02x\n", got, expected); return -1; } } #ifdef TEST_VERBOSE VL_PRINTF("\n"); #endif // Clear out the data memset(varData, 0, ( varBits + 7 ) / 8); } } top->CLK = 0; top->eval(); tfp->dump((unsigned int)(main_time)); ++main_time; // Posedge on clock, expect all the public bits to flip top->CLK = 1; top->eval(); tfp->dump((unsigned int)(main_time)); ++main_time; for (VerilatedScopeNameMap::const_iterator it = scopeMapp->begin(); it != scopeMapp->end(); ++it) { VerilatedVarNameMap * varNameMap = it->second->varsp(); if (varNameMap == NULL) { VL_PRINTF("%%Error: Bad varsp()\n"); return -1; } for (VerilatedVarNameMap::iterator varIt = varNameMap->begin(); varIt != varNameMap->end(); ++varIt) { VerilatedVar * var = &varIt->second; int varLeft = var->range().left(); int varBits = varLeft + 1; vluint8_t * varData = reinterpret_cast(var->datap()); // Check that all bits are high now for (int i = 0; i < varBits / 8; i++) { vluint8_t expected = 0xff; if (varData[i] != expected) { VL_PRINTF("%%Error: Data mismatch (%s), got 0x%02x, expected 0x%02x\n", varIt->first, varData[i], expected); return -1; } } if (varBits % 8 != 0) { vluint8_t got = varData[ varBits / 8 ]; vluint8_t expected = ~(0xff << ( varBits % 8 )); if (got != expected) { VL_PRINTF("%%Error: Data mismatch (%s), got 0x%02x, expected 0x%02x\n", varIt->first, got, expected); return -1; } } } } top->CLK = 0; top->eval(); tfp->dump((unsigned int)(main_time)); ++main_time; tfp->close(); top->final(); VL_PRINTF ("*-* All Finished *-*\n"); return 0; } verilator-3.916/test_regress/t/t_parse_delay.v0000664000177100017500000000072212671044616021506 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.916/test_regress/t/t_clk_condflop_nord.v0000664000177100017500000000464113205574202022672 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.916/test_regress/t/t_mem_shift.pl0000775000177100017500000000113612671044616021342 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_threads_counter.v0000664000177100017500000000070613205574202022402 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2017 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc!=0) begin if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.916/test_regress/t/t_mem_multi_io2_sc.pl0000775000177100017500000000124613151152521022604 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_lint_blksync_loop.pl0000775000177100017500000000117412473477707023130 0ustar 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.916/test_regress/t/t_math_repl.v0000664000177100017500000000573113205574202021167 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 b; always @* begin rf[63:32] = biu[63:32] & {32{b}}; rf[31:0] = {32{b}}; rf2 = rf; rf2[31:0] = ~{32{b}}; 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]}; wire [95:0] widerep = {2{({2{({2{ {b,b}, {b,{2{b}}}, {{2{b}},b}, {2{({2{b}})}} }})}})}}; wire [1:0] w = {2{b}}; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("cyc=%0d d=%x %x %x %x %x %x\n", cyc, b, rf, rf2, dualasr, sl_mask, sr_mask); `endif if (cyc==1) begin biu <= 64'h12451282_abadee00; b <= 1'b0; src1 <= 32'h00000001; src0 <= 32'h9a4f1235; sr <= 32'h0f19f567; mask <= 32'h7af07ab4; end if (cyc==2) begin biu <= 64'h12453382_abad8801; b <= 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; if (widerep != '0) $stop; end if (cyc==3) begin biu <= 64'h12422382_77ad8802; b <= 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; if (widerep != '1) $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"); if (widerep != '1) $stop; $finish; end end end endmodule verilator-3.916/test_regress/t/t_sys_readmem_bad_notfound.pl0000775000177100017500000000104512473477707024433 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify 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.916/test_regress/t/t_inst_missing_bad.v0000664000177100017500000000060712671044616022534 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/); wire ok = 1'b0; sub sub (.ok(ok), , .nc()); endmodule module sub (input ok, input none, input nc, input missing); initial if (ok && none && nc && missing) begin end // No unused warning endmodule verilator-3.916/test_regress/t/t_func_gen.v0000664000177100017500000000155212671044616021004 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.916/test_regress/t/t_lint_inherit.v0000664000177100017500000000167313205574202021705 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.916/test_regress/t/t_interface_inl.pl0000775000177100017500000000114213151152521022153 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_sv_conditional.v0000664000177100017500000003462013205574202022226 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.916/test_regress/t/t_trace_cat.out0000664000177100017500000001177413205574202021507 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 t $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.916/test_regress/t/t_if_deep.v0000664000177100017500000001345112473477707020627 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.916/test_regress/t/t_interface_modport_import.v0000664000177100017500000000162012671044616024312 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.916/test_regress/t/t_preproc_noline.pl0000775000177100017500000000135413151152521022374 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); my $stdout_filename = "$Self->{obj_dir}/$Self->{name}__test.vpp"; top_filename("t/t_preproc_noline.v"); compile ( verilator_flags2 => ['-E -P'], verilator_make_gcc=>0, stdout_filename => $stdout_filename, ); ok(files_identical($stdout_filename, "t/$Self->{name}.out")); 1; verilator-3.916/test_regress/t/t_enum_func.pl0000775000177100017500000000071712473477707021365 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_fifo.v0000664000177100017500000000527412671044616021006 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; wire [65:0] outData; // From fifo of fifo.v wire [15:0] inData = crc[15:0]; wire [1:0] inWordPtr = crc[17:16]; wire wrEn = crc[20]; wire [1:0] wrPtr = crc[33:32]; wire [1:0] rdPtr = crc[34:33]; fifo fifo ( // Outputs .outData (outData[65:0]), // Inputs .clk (clk), .inWordPtr (inWordPtr[1:0]), .inData (inData[15:0]), .rdPtr (rdPtr), .wrPtr (wrPtr), .wrEn (wrEn)); always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%b q=%x\n",$time, cyc, crc, outData); cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc==90) begin if (outData[63:0] != 64'hd9bcbc276f0984ea) $stop; end else if (cyc==91) begin if (outData[63:0] != 64'hef77cd9b13a866f0) $stop; end else if (cyc==92) begin if (outData[63:0] != 64'h2750cd9b13a866f0) $stop; end else if (cyc==93) begin if (outData[63:0] != 64'h4ea0bc276f0984ea) $stop; end else if (cyc==94) begin if (outData[63:0] != 64'h9d41bc276f0984ea) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module fifo (/*AUTOARG*/ // Outputs outData, // Inputs clk, inWordPtr, inData, wrPtr, rdPtr, wrEn ); parameter fifoDepthLog2 = 1; parameter fifoDepth = 1< ['--cc --trace --trace-structs'], ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x); ok(1); 1; verilator-3.916/test_regress/t/t_lint_width.v0000664000177100017500000000063112473477707021375 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (); // This isn't a width violation, as +/- 1'b1 is a common idiom // that's fairly harmless wire [4:0] five = 5'd5; wire [4:0] suma = five + 1'b1; wire [4:0] sumb = 1'b1 + five; wire [4:0] sumc = five - 1'b1; endmodule verilator-3.916/test_regress/t/t_interface_array_nocolon_bad.pl0000775000177100017500000000210513205574202025050 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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-LITENDIAN: t/t_interface_array_nocolon_bad.v:\d+: Little endian cell range connecting to vector: MSB < LSB of cell range: 0:2 %Warning-LITENDIAN: Use [^\n]+ %Warning-LITENDIAN: t/t_interface_array_nocolon_bad.v:\d+: Little endian cell range connecting to vector: MSB < LSB of cell range: 1:3 %Warning-LITENDIAN: t/t_interface_array_nocolon_bad.v:\d+: Little endian cell range connecting to vector: MSB < LSB of cell range: 0:2 %Warning-LITENDIAN: t/t_interface_array_nocolon_bad.v:\d+: Little endian cell range connecting to vector: MSB < LSB of cell range: 1:3 %Error: Exiting due to}, ); ok(1); 1; verilator-3.916/test_regress/t/t_var_port_bad.pl0000775000177100017500000000105512473477707022044 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( fails=>1, expect=> '%Error: t/t_var_port_bad.v:\d+: Input/output/inout does not appear in port list: b %Error: Exiting due to.*', ); ok(1); 1; verilator-3.916/test_regress/t/t_pp_lib_library.v0000664000177100017500000000045212473477707022222 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.916/test_regress/t/t_math_shift_over_bad.v0000664000177100017500000000052413205574202023176 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2016 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs o, // Inputs clk, i ); input clk; input [31:0] i; output [31:0] o; assign o = i << 64'h01234567_89abcdef; endmodule verilator-3.916/test_regress/t/t_trace_public_func.cpp0000664000177100017500000000205013205574202023167 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->t->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.916/test_regress/t/t_typedef.v0000664000177100017500000000257713205574202020661 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; initial begin typedef logic [3:0][7:0] instr_mem_t; instr_mem_t a; a[0] = 8'h12; if (a[0] != 8'h12) $stop; end 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 with different clocking: t.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 with different clocking: 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.916/test_regress/t/t_math_signed5.pl0000775000177100017500000000072212671044616021736 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_for_local.v0000664000177100017500000000224712473477707021175 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.916/test_regress/t/t_interface_down_gen.pl0000775000177100017500000000122013151152521023166 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_if_deep.pl0000775000177100017500000000104612473477707020775 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_select_bad_range.pl0000775000177100017500000000133612671044616022632 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_inst_tree_inl0_pub1_norelcfuncs.pl0000775000177100017500000000227713205574202025635 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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', '--norelative-cfuncs'], ); if ($Self->{vlt}) { # Fewer optimizations than t_inst_tree_inl0_pub1 which allows # relative CFuncs: file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 31); # Should not find any 'this->' except some 'this->__VlSymsp' my @files = `ls $Self->{obj_dir}/*.cpp`; foreach my $file (@files) { chomp $file; my $text = file_contents($file); $text =~ s/this->__VlSymsp//g; if ($text =~ m/this->/) { $Self->error("$file has unexpected this-> refs when --norelative-cfuncs"); } } } execute ( check_finished=>1, expect=> '\] (%m|.*t\.ps): Clocked ', ); ok(1); 1; verilator-3.916/test_regress/t/t_flag_language.v0000664000177100017500000000052412473477707022005 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.916/test_regress/t/t_verilated_all_oldest.pl0000775000177100017500000000141013205574202023534 0ustar wsnyderwsnyder#!/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_verilated_all.v"); my $root = ".."; compile ( # Can't use --coverage and --savable together, so cheat and compile inline verilator_flags2 => ['--cc --coverage-toggle --coverage-line --coverage-user --trace --vpi $root/include/verilated_save.cpp'], make_flags => 'DRIVER_STD=oldest', ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_uniqueif.v0000664000177100017500000000437512671044616021053 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; integer a, b, c, d, e, f, g, h, i, j, k, l; always @ (posedge clk) begin cyc <= cyc + 1; //==================== // Positive test cases //==================== // Single if, which is untrue sometimes unique0 if (cyc > 5) a <= 17; // single if with else unique0 if (cyc < 3) b <= 17; else b <= 19; // multi if, some cases may not be true unique0 if (cyc < 3) c <= 17; else if (cyc > 3) c <= 19; // multi if with else, else clause hit in some cases unique0 if (cyc < 3) d <= 17; else if (cyc > 3) d <= 19; else d <= 21; // single if with else unique if (cyc < 3) f <= 17; else f <= 19; // multi if unique if (cyc < 3) g <= 17; else if (cyc >= 3) g <= 19; // multi if with else, else clause hit in some cases unique if (cyc < 3) h <= 17; else if (cyc > 3) h <= 19; else h <= 21; //==================== // Negative test cases //==================== `ifdef FAILING_ASSERTION1 $display("testing fail 1: %d", cyc); // multi if, multiple cases true unique0 if (cyc < 3) i <= 17; else if (cyc < 5) i <= 19; `endif `ifdef FAILING_ASSERTION2 // multi if, multiple cases true unique if (cyc < 3) j <= 17; else if (cyc < 5) j <= 19; `endif `ifdef FAILING_ASSERTION3 // multi if, no cases true unique if (cyc > 1000) k <= 17; else if (cyc > 2000) k <= 19; `endif `ifdef FAILING_ASSERTION4 // Single if, which is untrue sometimes. // The LRM states: "A software tool shall also issue an error if it determines that no condition' // is true, or it is possible that no condition is true, and the final if does not have a // corresponding else." In this case, the final if is the only if, but I think the clause // still applies. unique if (cyc > 5) l <= 17; `endif if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.916/test_regress/t/t_case_huge_sub3.v0000664000177100017500000003140113205574202022064 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.916/test_regress/t/t_gen_div0.v0000664000177100017500000000130612671610517020707 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.916/test_regress/t/t_order_b.v0000664000177100017500000000062512473477707020647 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.916/test_regress/t/t_initarray_nonarray.pl0000775000177100017500000000065113205574202023274 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_inst_dtree_inlcd.pl0000775000177100017500000000112012671044616022671 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_vams_wreal.v0000664000177100017500000000531513205574202021352 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, in ); input clk; input [15:0] in; wreal aout; integer cyc=0; real vin; wreal vpass; through through (.vin, .vpass); real gnd; wire out; within_range within_range (/*AUTOINST*/ // Interfaces .vpass (vpass), .gnd (gnd), // Outputs .out (out)); // wreal bus declaration wreal vin_upper_bus[1:0]; // wreal nets declaration wreal vout_split_0; wreal vout_split_1; wreal_bus wreal_bus( .vin_bus(vin_upper_bus[1:0]), .vout_split_0(vout_split_0), .vout_split_1(vout_split_1)); // implicit declaration of wreal `ifdef VERILATOR wreal wreal_implicit_net; // implicit declaration of wreal not supported yet `endif // verilator lint_off IMPLICIT first_level first_level(.in(cyc[0]), .out(wreal_implicit_net)); // verilator lint_on IMPLICIT parameter real lsb = 1; // verilator lint_off WIDTH assign aout = $itor(in) * lsb; // verilator lint_on WIDTH always @ (posedge clk) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d aout=%d (%f-%f=%f)\n",$time, cyc, out, vin, gnd, within_range.in_int); `endif if (cyc==0) begin // Setup gnd = 0.0; vin = 0.2; end else if (cyc==2) begin if (out != 0) $stop; end else if (cyc==3) begin gnd = 0.0; vin = 0.6; end else if (cyc==4) begin if (out != 1) $stop; end else if (cyc==5) begin gnd = 0.6; vin = 0.8; end else if (cyc==6) begin if (out != 0) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module through (input wreal vin, output wreal vpass); assign vpass = vin; endmodule module within_range (input wreal vpass, input wreal gnd, output out); parameter real V_MIN = 0.5; parameter real V_MAX = 10; wreal in_int = vpass - gnd; wire out = (V_MIN <= in_int && in_int <= V_MAX); endmodule module wreal_bus (input wreal vin_bus [1:0], output wreal vout_split_0, output wreal vout_split_1); assign vout_split_0 = vin_bus[0]; assign vout_split_1 = vin_bus[1]; endmodule module first_level (input in, `ifdef VERILATOR output wreal out `else output out // Implicity becomes real `endif ); second_level second_level(.in(in), .out(out)); endmodule module second_level (input in, output out); wreal out; assign out = in ? 1.23456: 7.8910; endmodule verilator-3.916/test_regress/t/tsub/0000775000177100017500000000000013206353162017452 5ustar wsnyderwsnyderverilator-3.916/test_regress/t/tsub/t_flag_f_tsub_inc.v0000664000177100017500000000010112473477707023301 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module `define GOT_DEF5 verilator-3.916/test_regress/t/tsub/t_flag_f_tsub.v0000664000177100017500000000010112473477707022450 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module `define GOT_DEF6 verilator-3.916/test_regress/t/tsub/t_flag_f_tsub.vc0000664000177100017500000000013512473477707022622 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module +define+GOT_DEF4=1 +incdir+. t_flag_f_tsub.v verilator-3.916/test_regress/t/t_langext_4.pl0000775000177100017500000000101712671044616021252 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_extend_class.v0000664000177100017500000000226712473477707021713 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.916/test_regress/t/t_inst_mism.pl0000775000177100017500000000072212671044616021371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_syncasyncnet_bad.v0000664000177100017500000000415712473477707023614 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.916/test_regress/t/t_interface_gen11_noinl.pl0000775000177100017500000000102713205574202023511 0ustar wsnyderwsnyder#!/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_gen11.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_inst_v2k.pl0000775000177100017500000000107012473477707021136 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_unopt_combo_bad.pl0000775000177100017500000000213413205574202022511 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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: t.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+: t.c %Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: ALWAYS %Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: t.b %Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: ALWAYS %Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: t.c %Error: Exiting due to ' ); execute ( ) if !$Self->{vlt}; ok(1); 1; verilator-3.916/test_regress/t/t_mem_file.pl0000775000177100017500000000071712473477707021163 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_param_default_bad.v0000664000177100017500000000037213205574202022622 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 m #(parameter int Foo); endmodule module t (/*AUTOARG*/); m foo(); endmodule verilator-3.916/test_regress/t/t_gen_intdot.v0000664000177100017500000000411512473477707021363 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.916/test_regress/t/t_math_signed6.v0000664000177100017500000000164513205574202021564 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Iztok Jeras. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) module t (/*AUTOARG*/); // signed source logic signed [8-1:0] src; // destination structure struct packed { logic signed [16-1:0] s; logic unsigned [16-1:0] u; } dst; initial begin // bug882 // verilator lint_off WIDTH src = 8'sh05; dst = '{s: src, u: src}; `checkh (dst.s, 16'h0005); `checkh (dst.u, 16'h0005); src = 8'shf5; dst = '{s: src, u: src}; `checkh (dst.s, 16'hfff5); `checkh (dst.u, 16'hfff5); // verilator lint_on WIDTH $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_case_wild.pl0000775000177100017500000000071712473477707021340 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_crc.pl0000775000177100017500000000104612473477707021164 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_interface_down_inlab.pl0000775000177100017500000000112412671044616023520 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_struct_unaligned.pl0000775000177100017500000000106513205574202022733 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # Note: need to run at a higher optimization level to reproduce the issue $Self->{benchmark} = 1; compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_clk_2in_vec.pl0000775000177100017500000000117512671044616021550 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_package_verb.pl0000775000177100017500000000072212671044616022000 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_shift.v0000664000177100017500000000233012473477707021201 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.916/test_regress/t/t_tri_array_bufif.pl0000775000177100017500000000071712473477707022555 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_display_mcd.v0000664000177100017500000000057313205574202021503 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t; initial begin $fwrite(32'h8000_0001, "To stdout\n"); $fflush(32'h8000_0001); $fwrite(32'h8000_0002, "To stderr\n"); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.916/test_regress/t/t_func_outp.v0000664000177100017500000000317212473477707021235 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.916/test_regress/t/t_pp_underline_bad.pl0000775000177100017500000000120012473477707022664 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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.916/test_regress/t/t_dpi_import.pl0000775000177100017500000000115712473477707021553 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_var_pins_scui.pl0000775000177100017500000000404613205574202022227 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. $Self->{vlt} or $Self->skip("Verilator only test"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -pins-uint8 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.916/test_regress/t/t_dpi_logic_bad.pl0000775000177100017500000000124312473477707022140 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/test_regress/t/t_param_seg.pl0000775000177100017500000000072213205574202021316 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_mem_packed_assign.pl0000775000177100017500000000072212671044616023020 0ustar 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.916/test_regress/t/t_mem_file.v0000664000177100017500000001136412473477707021012 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.916/test_regress/t/t_lint_unused.v0000664000177100017500000000241112671044616021544 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.916/test_regress/t/t_inst_tree_inl0_pub0.pl0000775000177100017500000000113113205574202023217 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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|.*t\.ps): Clocked ', ); ok(1); 1; verilator-3.916/test_regress/t/t_lint_setout_bad.v0000664000177100017500000000107512473477707022412 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.916/test_regress/t/t_var_const_bad.pl0000775000177100017500000000116312473477707022206 0ustar 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.916/test_regress/t/t_order_comboloop.v0000664000177100017500000000241212473477707022413 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.916/test_regress/t/t_clk_vecgen1.v0000664000177100017500000000537712473477707021425 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.916/test_regress/t/t_cover_line_cc.pl0000775000177100017500000000157413205574202022160 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. top_filename("t/t_cover_line.v"); compile ( verilator_flags2 => ['--cc --coverage-line'], ); execute ( check_finished=>1, ); # Read the input .v file and do any CHECK_COVER requests inline_checks(); $Self->run(cmd=>["../bin/verilator_coverage", "--annotate", "$Self->{obj_dir}/annotated", "$Self->{obj_dir}/coverage.dat", ], ); ok(files_identical("$Self->{obj_dir}/annotated/t_cover_line.v", "t/t_cover_line.out")); 1; verilator-3.916/test_regress/t/t_interface_gen10.pl0000775000177100017500000000072713205574202022317 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_flag_bboxsys.pl0000775000177100017500000000104712473477707022065 0ustar 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.916/test_regress/t/t_math_cond_huge.v0000664000177100017500000005001612473477707022176 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.916/test_regress/t/t_unopt_array_csplit.pl0000775000177100017500000000117713205574202023306 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/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_unopt_array.v"); compile ( v_flags2 => ["--trace --output-split 1 --output-split-cfuncs 1 -Wno-UNOPTFLAT"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_func_wide_out_bad.v0000664000177100017500000000146213205574202022651 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.916/test_regress/t/t_dpi_qw_c.cpp0000664000177100017500000000217212713417237021321 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.916/test_regress/t/t_func_plog.v0000664000177100017500000000446012473477707021210 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.916/test_regress/t/t_sys_readmem_bad_addr.mem0000664000177100017500000000045212473477707023652 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.916/test_regress/t/t_param_first_a.v0000664000177100017500000000125412671044616022026 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_param_first_a (/*AUTOARG*/ // Outputs varwidth, par ); parameter X = 1; parameter FIVE = 0; // Overridden parameter TWO = 2; /*AUTOOUTPUT*/ // Beginning of automatic outputs (from unused autoinst outputs) output [4:0] par; // From b of t_param_first_b.v output [X:0] varwidth; // From b of t_param_first_b.v // End of automatics t_param_first_b #(X,FIVE,TWO) b (/*AUTOINST*/ // Outputs .par (par[4:0]), .varwidth (varwidth[X:0])); endmodule verilator-3.916/test_regress/t/t_array_interface.pl0000775000177100017500000000072213205574202022516 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_a_first_cc.pl0000775000177100017500000000145413205574202021457 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # show-config: This test runs 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. $DEBUG_QUIET = "--debug --debugi 0 --gdbbt --no-dump-tree"; $Self->run(cmd=>["perl", "../bin/verilator", $DEBUG_QUIET, "-V"]); compile ( verilator_flags2 => [$DEBUG_QUIET, "--trace"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_repeat.pl0000775000177100017500000000071712473477707020666 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_select_little_pack.v0000664000177100017500000000113612671044616023050 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.916/test_regress/t/t_case_auto1.v0000664000177100017500000000451712473477707021263 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.916/test_regress/t/t_interface_top_bad.pl0000775000177100017500000000122713151152521023005 0ustar wsnyderwsnyder#!/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.916/test_regress/t/t_package_enum.pl0000775000177100017500000000072212671044616022006 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_interface_twod_noinl.pl0000775000177100017500000000102613205574202023552 0ustar wsnyderwsnyder#!/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_twod.v"); compile ( v_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_gen_for_shuffle.v0000664000177100017500000000344712473477707022373 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.916/test_regress/t/t_select_runtime_range.pl0000775000177100017500000000072012473477707023576 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.916/test_regress/t/t_trace_scstruct.pl0000775000177100017500000000104213205574202022404 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. compile ( verilator_flags2 => ['--sc --trace --trace-structs --pins-bv 2'], ); #execute (); # didn't bother with top shell ok(1); 1; verilator-3.916/test_regress/t/t_inst_tree.v0000664000177100017500000000465012473477707021231 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.916/test_regress/t/t_inst_notunsized.pl0000775000177100017500000000077012473477707022644 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or 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.916/verilator.pdf0000664000177100017500000121402313206353162016226 0ustar wsnyderwsnyder%PDF-1.5 %ÐÔÅØ 113 0 obj << /Length 173 /Filter /FlateDecode >> stream xÚ-ÎM Â0 àû~EŽë¡Y“6MëQЃçâE<~Â`2†ûû®ÎKH yònKÓí))2I€r)3Ä0:†r…S{4šÚÛøê/Ó0ëÉ·3Es.‡P Â,°äP³‚ S+ð4¬í4½7]7Ï3~ê¸xoc—fXkÃø¨"xA©‚_¢è °#µD–åÿS cŽ™&J`ÅE$ëÕÅfWš/ML5Õ endstream endobj 140 0 obj << /Length 621 /Filter /FlateDecode >> stream xÚ}T]oÛ }÷¯àiªârcxt’Ñų¨Yׇií¤Iíªu•ö÷w ®—.hO 8÷œÃáÂrL.דſà<“¤à*ÓFñŽÜÐ}ª½þþð%ú’.€>áä9]!©È ¨ôv¼º\ vÂ#€eŠa£j›Ñ6ãà‘‰“Ÿ‰ßbfA‘+È×Çäæ–‘;ܺ",F“ßGà#ªÈ8ÎÈ|L–Þ9×d&¤â­+­3)ŠIöéG*Ðô=Œ¾ü F¹91Êž#ÓS¤ ÃsÚ”µÅó¨‚r_4à àxÀ ‡¦í7¤ nð8VìÊUïºÑµ ÂUnÄ?ð€–]ö©àt³«15t‚70ìêW¢¬Èó¸\~Nàý ÷ÎUÀÛë²î¶6hUab¯mµ –¡0”CL³ˆp ‡a´uuÎ# S”‹ˆh–¶©ÞãY?¸fÊß…¡Åôj÷©ô!LdBúeÌ” lk·µ€`F!REdávΨmöî˜ZÛ„ØyLS^ÄØBvvc«q¶:¶'r`3Ó1Qþÿú9>ÐL`^&jB’•ë‘#v᛾¬ë™Õáóë×)ð‚–~»Â|¼'I?³œ­:‡ƒo~Ð9,ª%ƒÖÞöníª“K8Q­ìj×—ÛÀ<‹êItê ¯¸UTB±n€|J(PÃl[wn{"Ïñ)p*ò¨i5§¼v´öÖõÔœI†_Y´7Š@°-›ÍîxŠÍkž«lV~±ìWáÌîëÚã+}«ç8EøvÞþ³2²:3~%|>Óïøø2A, endstream endobj 157 0 obj << /Length 421 /Filter /FlateDecode >> stream xÚu“MoÔ0†ïù>Ú‡z=³4»MYmìð¡ªDABj…¨øûŒã,‚n–=ï3ï;¶÷¹ÙÀ²(£ÓŽå/ ´–†yídˆÈò»ãoE@þùùëãGü‡¸þÏâ Ñp”œ¸Ï·»ª?8J: LUÆ«qÈÝS©lºÜ|oÊ‘bð»!JPž}zjîî{ £[¦$ÆÀ~.…O —šV,5çf_œëøs‚4èkWdÒ*~j‡ãÜ ÔüØÑÅéÞ“ÔC¢<ÑjäŠ7âS,.€ø?À©ÓgoE´<Ó@ú2™ˆ*rcÿB%jU‰Ý4Ü8¥Êk‡ëºx'@{ÞNC?–Q[½É‚Ê:$ðÅÞyw˜ºóL£>sVxzÝ-xÃé,å57x´ÜáFn­+y?”Æ!wqÓÖÊ›>åqZ{jz;–{µE6µ~q;ç›e:­_Ö_Ø*(/hê÷s® ãhÏÃVW×ähPZXc©Åö}U¤n½Üö”ÆâÊ®’—¿$€ Dú'+åò¶Èß½ endstream endobj 161 0 obj << /Length 1461 /Filter /FlateDecode >> stream xÚÅËnÛF𮯠r)[_¢È££*ƒØI#¥pàÁš\[Û\†»´¢ý÷Îì,õ°å&@=qgvÞ¯¾\Ư‚‰“yY&ÎòÎ ÂЋi˜xi9˹v¦‘Ë[Q²aàêá(p%Úá(Šb7ò² Þ,ߌ_Eþžœ0šxéÄñID \¾ï»g†aê¾þx1¿\"ä.>^\4|B)ƒùrðmŸï[c"/ð§N^ ®o|§€«7ŽïEYê¬ aåDÉÔ áT:‹Áoƒ—èU˜:AìEqîÜJÒÔ‹£)Ù€M`”{yv1'á;`Ÿ7Æ?„ù2“5º÷0 §.§[C‹wÀ~yO<ùEŒ€¾àD¢%ÝÌNNƋҼš‘]‡®€aq Ù±n„ÖŧËwïç ›‹`?>&éПã‹–`ã$œ¸£ÑŠ£µeƒü¨#¼l2y†øÁ·J€Ç?CŸçtº–È×hàS7¥d׿üË(¹òðþÆó¼ž¾Ñ_r{—7Í8#AžÙXŽ•¼ù)íêÕ^ dªõHÖåîgªEä¾j£öHºG}öLÒSRÙ¤ÿ:_Ì>œ¿_ž¿»ü/%<§¶µ›Vˆõ]µ©±˜õŠ+ñ'»-9¡?û¿–š€[SÄ|Å ¿-+á> Ë­NSö€È±æ§Pó§§¾Û”]¯KVVübcl1ZÕé± S{ ìþšL]VxH\FU±²¤+ÕÝ*® -ïè{h Î.VR¬45 ]AVI¢ƒ.%:Ì4"öZö±¹yßèPXq»çv(E_Š%´>#8—USrmç‚*îLUî¶{ÊuÔz½úóò†dBöΙô˯f€t±zE§†µ¬«ZËvÌ– ~_Ïf§tš±‚×9'`/Ì£«·ãËÙh/qGSlšL±d£6êŒU’‚$0q¶ðèÖD¾-g…¢£ÆI†”ª1¥ÆsñÙbô¯ˆmr0´Ó‰[ ªy+Nh‹§Â¹ÒLVB±¡ŠоïD²Mü®©Ø=£—„‡5^0ÔF$w²­èF·,õ=ñaùÀLy….`|ÒÔáÔ¾ /ŠdK8LÑ"‘n:ômÇ2@Cqy+úbqV©±¥ ú$°4Ep™Ñ&öÜ¢—:oóO³Q¬5B|LamÙ©® ÂS-"¼Æ`dÉNsíJ§u+4WÄÂU ­Á¬#^RÇPè-kše('î}ÁôCÏ®W"GóWD-j¥ ÁH`©ö€Uˆ0%§Ô–V6••Ù(ÇØ^0p¶r„= œ¼†Þ;Ú'©8j<@È*#4†C1cÕ¤ðæ@ ”%™ÑÇæ“|dÙ…ÑŠ‡0â‹f Fûˆo÷ ïß½t·C´CGÁn‡ÆI;tÒýÌõ‘4¥únÿÅ ¡aW²Õ„Q”P»!À¼”¡oÇôf¯½‡¼ux¨LunG&RJúî’ -nž>xÛ9$®àšÙ7Ê[A;Ú±}hûdÖü»} ωÍàïÌTC%[K*jš†}¢Ÿ_“Ó>Závæ=üÿ/q¯Oÿràn×°ü+ õS‚*Y˜KaÓ'x0³ÀRloQ.¶´:ÖÓ¤5ãÚ¸c˜Ï`@’Bó½ëß#dv‚÷'À¤7{¦égÒJ_ÛΈúyu¸Ó¢%AÙ"ðDÙÉÎôGJ`Ì|Ý×ðø§2ñ½ ‹¡žÏÏ’~‡µÿ{ÿ|MÍ endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 798 /Length 1786 /Filter /FlateDecode >> stream xÚµYÛnÛF}×WÌc‚äÞf/@P€–(‡¨n%¥4n’‡6Š …U8þ}ÏPë¤n*ZmL ÊšÔÌì™Ëîœ]iRÄdy²‰ùDZQ4¤-iÁ‘6‘t Íä¯DF“Qib cÉ0þaðdä»kò! ƒÖ’…IëÈ)G6³˜-’sLN“ ~â ¹d /Ø@Ì;ˆ%â‰Ká KÞÊäåe €'°'¯)Ä0ñ†"€{¦»ÞSÄ3Ç$Ò”àC°”8Qp”¢£”f(c„JÔƒ™ˆë J‘Åÿ;½ƒ!Œ‰))˜Y€J À… Ä1ìùRÁ 5n¢•Ó‰Y˜´A¾‚M›dBu£tí¬L…·N’ gÌ«Q{ŽÙð.Š*²`Ò8H§€×’Þê1%I ‘±¡Ç†ìÈ<’&ïä$JÜ6Ù’<ÃM«œ8€Téh'ºOŸ†–ÕH pC–³¤4@>!“^œCJ“øœhhI­ñA|BÆÅ9ɹe3OH¾“ ËÆà®ÔDBòŽ2ÑN2 -e Å ÷vX£ D 1K²Pt„e‡š`×*'Ép{%SxTFQÀõFÊ, ’+TŒ•èCÞ¢†5ÊÄ#/“gϨ쨼¯¾/çmýýŸ¸¢ªû®žžº‡¦Î‘ÂÖ±œ+/k´†çM·]휗2ºGµÛ>‡C²yé¢Á ÅÛ¶¹Øm|^©hD3é‹ÈçBF×éꚪE·þBø•´NE-•ów·oDüÙ³I¹ýó=•›Ÿ~ÝOÊéáúv}ûÛ½ÉIÙîß>ܼݿï›kÿj¹ÿåÝO‡ôJ‘4 ôˆdÞL`âºBz¹lþïÓ¾¼úQqja=ê×Ðõ‡ßsZÔ@Ô§ˆÿï Î“Ĺ¹î©GvJ>ùAÈIì Unno»ý-½‚«³9•ÛýÇ[údðßcàÔ1°ñ?Å ¬®¯0õJQExÈq4y´ytyä<ú<†<Æ<¦ãh³=›íÙlÏf{6Û³Ùž=Úû‡Ë=¾IÙ}øù¶^¼»þmR^n~Ùßô®é7åó²)§ùA‚ñQì³âÙbÑ€k¹Â #ðȘ«h˜<. €H\D„Ç›ˆ? Â>>«~z0 Yãä ŸÂ 7 Ö…pxƒ”È*f¯kCÇBňh¸"ààÀÆ–„ᆋ¦ˆrÔREPý) ¨xE+ôÍ€ó‚*¼Ð|N`Ã0â0´/uÖ!'†a rƒ(Ò㣰H‰—ƒX@0¼œ©ñ> ÃÈÄõqq¸XìŽÆ¤B)9ºà²Ã8ô84¶PœôŒO£;Xcë#l¢8™ Gu“Rá°§›˜ œ]‡qŒ°T§ïÎȺša®5¼sè6R£±gxÎ5X4d$èaf„òÐ!6ÊÝ‘Ck%# zÆYÑŽ Í1]NnºÐðèó#tÐÃÂ;¬U‹5"—BF¬Ò0Ž{mE8¦MgÓÑû¢BGƒòVë)>ú™u–s+7V&?È ¡swr•Ã_EN9|AN™ÿ/9µ™dºL:ÝÝs&.“NΤ“3éäL:9“Nv£LìÎiìHØäê2!dÝŽ°2Ù5ÑcCÐg‘]ëÆb»t3ÄóØ.Á3£-úëkDÁ`»f°o“†Ûóx|÷ŽNœÅwýx„W'ÌüY„—ÇàšX$F~„@>ˆ÷9”—ãxœ×`«fÎ⼜Æ#½l—ƒ>‹õz5"íűPÅóh¯×ÿl]ìÏj]g5¤¯ïA^ÙƒÒÿ½$òêì®|_ôÄ%Ñ A ù­ê QLè|gˆ§ ÌW²ùYÈÛ32ò´éê endstream endobj 166 0 obj << /Length 1666 /Filter /FlateDecode >> stream xÚ­XYoÛ8~ϯÐCd¤ruÚàhgS$ÛnãXÅB–(‡]%¥ÿ~‡CR–ÉIº}ItŒ¾¹¾9èãåÁ»…á8œ¸c™ŽëŽ}cêNƳÐ3–‰ñÝü6šy&a4‹FŽY,Ç,á‚,ÏóMo:“ÑåÇw Ïîà¸^0ž†-!|øÊ¶móב;3Ï¿^ý¹ß{æõ׫+x þ(g˃Ÿ|gNkŒ7vì©çߨF¯>öØ gÆ= æ†7™Ž]¸ÊŒëƒ¿Ž…WžÓõÊŸ?0&³ÙØ÷¦Ò¨CÇ›ø–†ð‰<Ô‡søs4²|xf~åddn`~®—ky#¥ÅÕ=­oäUJ3w¾øç˜5)8- ) aÁ;°Ðrœq] \Ûv^n”þí¯²à·Æ`fÛÏ[pýÈk’ ;„Øs¶¨Ès6LvlцðذÇý5Äw¯¶Á Æ®nbY焉B·ýpfžÑJEY¦.P“÷ù0M]¦YÃ…˜4 ]×\ M®Lä5#QÎfZ¶£çMBy•E*V«òÁâðÖ }fgQ|»Âõ ¿oŠÛ¢¼W~¿á*¢ì‘Ó4ÆÙ­Š§k´DZDÙŸøUÄ”¯HLSª“)å5ӕ欣úm…q£ò‘¥ô9v`›Ë¦ ;±ÝQÜF 1bÛK ¸,€$k¤†•ÑœÖJ}V–•Hµ ·£R˱zÀI]뺮iN†|ƒ¯ÓXaÛÍ[L”tZÉ>ƒ„ »&3×Û‚”¥¹wX/Ä«ËõA¦S@”‰nQÛ—÷¥˜ )}bãõ·KÕ¸Nù ó“~à"!ŒÇ%ƒ[Ø\ü-ø-Çeõ¤òÿ?’–|°êOçw;úþ~ŽÖDYCŽ~`vBóš(zTŒT¬Œ çš‚ w±¯¸²jDqìHà‹µ¨ÆÞ`âk+¾AwDAOgÓ!€ÍPÒb°ð= TSÜaD3ÝÙvÁ±Ÿu¨ D½Å'в}Z- ,g±è†G2]áûœS:Ë]ŒÕª”Š›vPoè›r§Úµj²±*𬯾&æÏföÌÅ­0*˜æ©ÛÌ©\]*VDŒ“!^J†Α˜À°÷sI.`¯³Ë-œT¯äW“WV͈Z qO8ÃÅ¢LiC9a²Ùq†˜Ò…¥2 ˜@1\¬¶26¬A¸Á)Y·×Š:(‘½Äkþb ƒ°™­¥º1ªÞò¾ŸÙÀ²ø9¡ ßûÒ"š¨0ósÛ1ުݣQ8‰bOQÖÝ>ˆ“ïi¾[ÚÂjS2˜(ÛŽ­–R¢!~X•¬~²Ö7T ã¢ÉW²Kv[¤:xøN¢KŠS{†.„‹s³ÂÀqScF†µèìqGjL~Æz’¦U²›É\0¡-òhz½•O¥°ëQHÏc¯éïRÙ‹¾¸Ø†‡‚ôÌEÙŠ±Üâ“¥ºV*&ýàçs܈º3JMíOjîÝ3Z·í©’$ÕM >­ÕBÔÏ­u²Ò þÒíáU6ÙÍúŒX^žŸk·:Š÷„] ¯j= »øÏa·ûÞ 5šÅ;È\,îÚª`Ÿ©mö\·YxKYYä¤P@ˆF+tLÁ=:¬‚jN ÔÄ ÉD×v Ñ©/ÿP‡áˆz?é›l`8ÇcU¡~­8γ~'Ú(Ó↮¨œÕœæjêž–Ò¦ˆëöŒ®u²ÐU–êÓIÞŸIZˆýÙ“C;ð·ëæ<—I“µI7öÄʺ<:TbùB?½•íWR°’}Ì*WÿB,ÛæþÓ¥ýDçåÅqW%žÉõ¶‡*™>9¬C&M-VÏèÛýí3ðá:0,o6†%Dÿt©~–ü‹÷ª) endstream endobj 171 0 obj << /Length 1798 /Filter /FlateDecode >> stream xÚ•X[oÛ6~ϯÐ[ddTuóE¨ ]’mE“fS`(ŠB–h‡‹n#%ÅÞ¯ßá!)ËŽ•¦O¦%žûwnz¿8yså­È‰&þÄZ¬,Ï÷КúgÖ"µ¾Ú_F³À¦œeñȳëñì|D‚ ´'ò&£o‹o®·ÇÇÆÎll¹ŠET®ëÚï>ü™ýûýõåÍBÒöÝýõ5< K.'—‹“O< s-¯S&p%4GÈ#-n›/ËÌ€!q€ ¬b…˜Hf¡Æø…ÂË©6¯Zf›5“ð{}z˜YA@&¡N Vwf{X<²Š`†5K¤Â)DjÏJy«êÜ*¯"ÔõƒÜ:V) Yô‰${ É#è=ñ£™ýçºP†Sñ“k2iOŸ²BPÏÿŽ8µ# ñlý ÑIùJIÌã"Ù±û«¹¾Ód´®) úЈì;šA:íi¨X¢žCa×)3§š4’]q®só,™¡p# F…WOrÉSŠ6„;À:‹·:ƒÀ¯hÓNsy¹‹µÊ%±Ø]‚´…dBè#òÂK‚ ÿ*3pœ/·5&ïv/œ¤ªºÒŠœ5º즶0šÐWJ#ɪ)aêG uXg©gƒto< ¤7ˆîd GdÕ<6hú±,yqa¼,5݉ë‡Ñ Ev”À“E¡ŸÐÍôÐäKì[\¨J«Ú¿.EKhöÚO¬Ö¹@._€¬FdÙš˜1²0мÃÊjºÖ¶Ú…+´Wª/Œ.j ݪäCA©"ÁŠ$‹ÜˆLƒð¹8zX÷úbP—LéR)]^#nÉÖJ"ŽKwÚŸúZã@fí Š|ý¤i¯RQ¢¨6}vm ê]zŽ“Yh_¼³Ì¤Z7,Ô¼lLٌ͸ÊY50BÉiAM ON zyy<9fNÖñRÎ]0“ßµr?}÷}©ÈeÚ pg-ŽkQ„ó²Y¯1G=û­Â“À£½ ®L†Tm–“i_Çì­ö$¥f`MÄPß$l =›w¾üuŽOÎõ„ý©¥ü‰³z·'ôAs ©UUx!Ó9tƒšµx°"ÉšT‚§€ÏT”YK 8Ì;ùO’©) =˜“†ón(“áyP4V–võ:ô"lKÊòI19­T›"ç§Fõ»¦…ÁÊŒxû…Ô}nªÌ‚}³€½BñËH.+<6£q c‰€ñæ?÷7ŸnW’úã»Åq"nU}F ]öz&ŒÔ&4p q ˜Á6:‘[#î¶BånþÛà^³c­H^÷\\û\ä Ö7‘ í•È‚´±i.XµnyÙÂxœW©cÓÆœ™™f¸³‰ÖXÙwX‰À ¹Ü™»}Y.¤é{&€„æ­št$‰ZNa153Ú¶(‹m~Ó3oæºÄw=Ÿnбšf8a Íä~„(Êèkv£—ª”\ìvõW|=d¨hö½õ· Ò¦%2ÎL-/0")¦|eÆ9*ÕMf´{Ó©djï^OiÅWíasoÍÆ*¹©Qhl_Ç–7ùÁžòÄR#p×ü¤Ä¡r½/­G>ÇóQi=Òò$ÃeV*â\è¥ £sW„Õ‚ÍV¼ÄSá7‰LX\4Ÿ1Õ®×I'¯6¼÷õèEöª+Âh/’RÉ¢7¤¶‰øwµ3w¨{hHr R]î¾Ha03©üÀKD¬-„q±¾øö?ŽC8-ÌX•€±ù†÷? ~– endstream endobj 175 0 obj << /Length 1702 /Filter /FlateDecode >> stream xÚµXYoÛF~÷¯ òRiîÁ 08‰]4pƒ¶VìiÐâJfC‘*KjÑÿÞ™%M*t§ÉƒÅåœß»ôóÙÁñ9ó­ØX³…Å8w¥òÀbaÍRë­}u [UYž2»9t˜]¢:t„¶pc¾›½:>Þ@WHay¤Ã1ÏóìÓßydÿøæç³×³K;8›üuÀ€Ï³Xo]¸Ì ­ùêàí;ÏJáÕ+ËsEY͸²DºV¹uyðëÁs C°aR¸‚VE®!9á8mQ•yîÌumÁøÜ·Oò²\×Ï &c{ÖŠöWÉ6[!k»Â içZ®\Óë¬QUÒdeQc àŒÃ˜ûþž±…šUSc5®mì¦Lw´ª³¿ÕCÛZ¥N…‚j©¶Fô¤Ò˜äƒÉ7¯ß\ž½¤užuhÔÙ²HrŠÉw9÷Ì\z‰²¯TuSÖFתj€‚ˆ¤@RŠc^"Q,²åÈëÀ¨»3N.²\ÉJ›¡d®°âÊeçÝM•T»©°îˆ‘Åh&öÕ¶9:ŸáË]AìV¤kQV´8b"‹‡2Ÿ0À=Tã±ÇàÞP 8S°:wë Ôp/äöY‘ Æ›Ü€{õËO´˜—«5àôpr®“ë†ù2´Ï´WI¯E¿ÒnvÝÞ&©Š¬XNW𵪪²rNtYªºN–˜Èil¿( €¥ÙS¢©¦¤§®'s~½h›¶RÎ *^õšeåò2«ï]n‹E¹1U¥Qb©¨²6H|2€¢ïAL3jAÄÅØzïA˃J¨;b)##«!/M䃦í[ió9çL&¢˜œÒnþ|ÆEÒ CÓÍKmfœìšv¤zºD·NRãx0-»ÒuŸê¢CaŸÂKŸ‚Àа–…“Y“u†ß+“æ63;wIÞªÉzäc€4Ue™š’ŒìS¤î}µUÒª£R¬»€ÇöçÞ4% £™sžyÝ(Lû-f O—&M•-—ªz¸ÍÈ?I³ ÂŒã“Z©ySV»q@µJªùíÞZ•©>QÌÄ8>県p.INy&}Ë‘Nûðþ¤ftR 6<©A:œ°€÷ÝÈ“$öÏž¹rïþ%ÞÑ¥‚K7öˆÍwcà ‡ÜÔÉ:D» Ê(ÄJO;ÝÛ;¸l‰ØTp_ï÷уªVù2#!3—ʼƒ›o¹7‹œç§ú³å’F 5êç‡E0ɱ[»5fðë‡d8œ ½„9àöŸp(˜×=»|h¢oR$ô i‚„z†ã "LŸ Ýtˆ½»5¬÷ãBYÒ^?AžN5Y¢»+ÀVÅG}[VÐXHêó ÎÅË!Ô°óĵÿmÇeWƒ'P†n(û"5ósB´5ïûúÙzâŽá‰nbš:]¯;"îñÅ78uœ]þ§¬‚øBƒ O‚¸ê† jt E‡… šx¯ÂG–nz4^EºÉˆDBûɈTE"Hé‚cQSðíX$º6Ì÷qá}ûV´ê»Ó°O øDt=O~ÑTq:æQœ£ñ)¥´g„´$ í<ßIÛИE·Á,ÚÜt>¹­wéÞ®¿ME?XÆÝî€]Z>²ÏÇß“1Š n=~:4Sš Óèº1þü.š¿Ï=‘ç}[Íþžæø{ifüqšGŇPNðäœ8ƒî_]ÿ~iúg endstream endobj 183 0 obj << /Length 2507 /Filter /FlateDecode >> stream xÚ­YKsã6¾ûW¨R9Ðe C|Öž<ÎLjSÙÉlÆIIj—"!™5©%H{”_¿ýHIfvgªr±&ÐèþúøõÃÕ«·2^å"OT²zØ®¤R"Z¥*Y®WÕê×àçëL¦¯›âZÃõZýõZë(Ð"—Éõïß½z«Ã“uT–éUÈkÄðY†ÁÝ×* ¾ýéoÞ=|ÀÏ®Þ<\ýçJ‚\¸’ÓîZÈ0]•û«_WL}· …γÕ3 îW:I…ªY}¸úçÕë—LjR¡Ãd•d™ˆtÊJ|8\¯awSÖ¿…:2NæÁðhÈ‚¦hwc±3̶CÑVE_9¡Ž7¼FkÜôs=<2UðZöl«’çlL[ìÝ÷æÓ`Z[wí­3 :9A¸ZK)ò8fÝA–….¼%b)½‘JÀgÌ\ËXäϼEvà2¥TPvûC1Ô›º©ôÆ‘Ù|¤:0‰“µèîܽ¿Vi06ÅÐõöæ¢(°Æ°PÑØŽ)²%}wl»?9î­;œ‘ÎÏÀc†äê/.Æ*žØ˜†o­“ï ß:~ñ·64ÔÁ¡7%¬c*Óz:\剄z:ÏEŒLºcb¢lÕ¢!w@ŒH ‡Â¦IÕtÊs7ÓšÎøÒcRK¥±·ëz]™m16Ã7˜¬ñÒ9>š\ÖõKK+¡B9¯ü?V‹c‘ÌÎufô>Αêóøp6ÏóÙæÒ±·9O0…6åÀsuË\ö5~ÙWˆLúîÑ™Yô†Yèô¶ìFŠúÁô¦×ëìøðˆ[Œöd5”ßvMÓáÌsÝî–¼ùŒ“ÝØT쎑R‘ᔤ(à€e†Ìó˜]¸]¶­ÌD¬¦„Sˆ§¥ÉEÎ2m5m¦Ï6Sa(™ZÞ,—"Ñ“¯7Ë{ç(–ò”‚2˜ë pdèŠ1¥)ÌÂ×ëXÅ‚‰©4P´FS`Þxâ <ê$­Qwƒ‚³Ä²‚ ¥==ßÝá(’)惸ØY èÚæÈTOY ÛïM[ax!ÍEDcvEé÷õ'??g“H&Ael½k±ÚD: ·• ËK´@ºØš¾Ø4ÖL:˜3][þÅ"Ž¿¦‚ÂÇ´Ä£û¤ì(%TæTZÁAEÍ [óÌó9G†i_QUÌ'R˜.ªÊ‡Cßúº–òÉÅ1þ½1»ºý×G /<㺠¾I¹©9ÊO½çDÎý»nQèõ’0÷«}žY(’) ’}±àŸTÅ0hÎ"‡[ÖýX®…x~¬K´Ÿk<ìeƒö²ôÉ,)4‚>õ!Þ^ª§¤s™žw¡©!@lžóRCWƒùtë¶Ì˜ýœ’Ÿy¶¶4µë/(Èpwm,:XC…à@Ž›ÒîZĴé1‘Zp,1uß–¥ðÖ¶€k')ö%肳pÓ¥OÑ” LÕÉèÒ…S@ x¼ACÊhÐB·ÆT«1t¬?¸^º¯+súŠ È½Ç,¿¸r¡b~Ó<«¬i¶nƒ_8žýƒnË.¦2 -¾R¹ Œu[TX³ýupÕÙºj]Î@I+Â;Ä£çŸê‹cNyH¹”Wv~ªàÿD‡teæ÷7D­t2G<ìíbÉçbŽ+|Év†&!xÍi‹œÂTÁë¶èç½€†Oæ—:æì§‡&õf3ÖMå3/{6Ägd7‡ÙõýÛïï0±}ûa…±©LNPH/KÌDvþrv‡jÓU>I.ï§Ž{Ï?øZ ¼nèíÓ ¨Èá/…1;Óš¾ü"Þ@ÓÁÁ£ÊÁP%1ÏÓ•¥±Æ¸…û±e¢k—<<½ÈŸîÃóýüë½Ç UË 87Ýx}Àˆ[h¸|ú¿¿¹™ÿÏଡ…Å®,_ínn^í-a£DIì5cÉo—2N„ £œ\ìþk“úýIÞÐ endstream endobj 187 0 obj << /Length 2430 /Filter /FlateDecode >> stream xÚ•YYsä6~÷¯èGu²Òè ®ÊÖV%ž£&•™lìÎìC’JÑífYGG‡íÙ­ýïPG[Þͼ´x€|øª¿;\¼zÄ»ÜË“0ÙnwAzb—†‰—åÑîPî~q>í³ÈQ®ä>p†½8-4º½E‰¼®qÙÅ›ÃÅÈù»`z{ä~º+ê‹_~ów%L}¿ó½(ÏvF°ÞEIê…Ъv×?]|‡ÇógÇH²ÌQJ*¸nQ¢«‡ÂËýdç1âZÙ5°gOæüÕýË×—Wׇ~|÷þºM˜ÑhÃNd†Ô“¾¡¦DÞRóùž-,a¸GÙ°7__®åÝ-y“$ EF©R•Ԯ影&‹à#G Mkô…n764°¡–ëVš¼â¶Mõã œƒs¾ÅѲԃnYñºù@4 pÞ¦ºµÄ…t@ݯá'íô0(žÚÉœÔ@¨WŠ$ÿsêöŸþûûï€:ox¼é} œ]Ž]Çø‚c€·3ÇZù>² k™£!jxœ2ðbò6Ì,a²­Xºh©ü.rßÑ·ô®Ïø’v$‰£ÄÞyfi¥Ä:Õh¬:Õs¬jF”Ó+›øíØ2C'Ybg}Ä¿Ñì©R²ç¥EËÑW €–F ‘®ÿ’ð¯î™h£eøÇ^š†–g{}Zº¬ÕU¸¾—%ç\€%к1ºŸ¹AöÿÁQ4Tb*’b¬X pHbsŽìú–õuÔý‘&ž± Œ‘Þ=ïÚµõºmçSÊAR‹WBü$AêüX²7žBâ<ç¯],fC *eBFÆ= £ùm8øxÔ´ uKx¬u£z’Õ·4~;vtj쨇} 4Sæ8¦yјA„±s8ÚáG]U$xT,³¡n©îæêŒlÁl!›‚G[¦ZI]p¾`çb„“üRØ´ÚäfñÖA°€ªÈ½ µ¨þû–S/Ù˰_î^ü@£VìHŸI8tNr8¢­ýÔy‹6Dëá¸z’5$@0o(XǸj3ŽïFvÞ–Qß#¥ä¹¥Ø|¶MNÉh5©*³q¬µÏ“kƒi4 ˆ žW”ºSÅ@Iá…· Í0ˆ`Òæ3ÊŠ …ÑŠTâÅ&iâ³ÔszÄ¾Ñ žKYz54ÀRËo“)Ánµ˜ˆÿ’ÕÂÐ÷b1ÑÚ«¯fÇ ¼ñªVÜ«î«Wœ‘'æõšépæå¹Xö ]ŒˆXŠsI”³*p–àž¬o*Ý £ÁCñŒUÌXçÀÚÃfO‘Q5Ž“²Ç÷8CÏÔŠÂÖ~Ø¢g±ÆJ,èÕˆbÒêhìÌRº)õƒ.GCRÄa"ÎØbƒÝ˜; |€U}â”@¬4V´5Åak*ÄLÌ™`Ö™wh8¿@ Ù(•¥8ÞÃ*<‡{£mæy–vÄTsleü•S\ñJuƒñÜp+fµbŽ©nŒGNÒ–þ› aè—”·`]©n£Æ$ðÀ"µØCÈÂncØ»Ú s/ñã³›q#o*{£ÆÅ-qº`šLÑžãpÖŽMÉâ¦Ú]QûFA0(€ëÑ|´mðGxYñ¹*I•äù|2n€ßZØwtÚØ˜Ê\Ø2\ÐàËÌÏØ—8ZsÚ3N•caÖ!©b„R’¢Gìð((-y º@•gÍg„a¶ƒ0érnÇ)Ÿg 44|lÊleW¶:âéJ×zà]°(ǧ=3~jàº×ÌÕX*îÝt6êåýK÷|f*¥NìÛ¡‹aœVZ˜œƒ¡îð½Ý§/  "k®ã¢Û¡a}{Y*H·»íïVKTˆsTDAÈBóîãÏÔ`rÝ#+ü„uw$É;Õ€[\MV§Ù‰ ‚ElPÅÆU–¬êÖ\¥Aje°Æfá„áPi¹$íP.ŠÏ¿-¬¨¥Tô½ü9â¢á/½…NñÅqå [Šô?…µ·u? º©HñPXGDæÆÈÉÓ9 ±cÃÛx˜' 3 M,£ß/y'ˆÆ óª™ÚÖ±i^`5NNðœ?šp9ÛhÄæy4â˜FlÓ”Øùpý ·0&ØÐ‘LJ ÇËe|¥ªÊÑÐÃp4*¤Üp{‚(ŒÏÉç¨zýo†ã>:ÕOCÛL/›ŠkèõãÍ& ðjMËBNi¡xfš«€Î€š—ïçWp[¢$ƒ‹c„«àø*Gó{´‰z0ËØƒQb£ÂX\>ŒJé|ù°*EF¥$ØŒ ‘xY(Ö‰soƒQaBCuwÊ5®Ý¸Jg¡ÅÁÙ½|õ¼JçV 2GrÚS¿±Wa%ÿëZîæçGë~ž7_ãdþæ‘ÁïùG{¡ûj чäÿd‘Q£åÆš·A[B~™¢;Zƒß9P?á"~tÍ›éù’€‚¼ì?n€a˜RŒ<û€kä[ M¹¬¥„ý|È¡|§Žf–|=3!F6 !r¶²pˆR<qâ…¾0ÅQ–12ûO̟ܱΥ endstream endobj 191 0 obj << /Length 2543 /Filter /FlateDecode >> stream xÚ­Yëoä¶ÿî¿b¨6¸]ë­ p‚»6ÁåÚÆN¿¤A@Kô.k­ä©3.}çE=ÖºËí/5r†óøÍþæîêúM”mÊ}™ÇùæîaÅñ>Ýq¾?”Éæ®Þüüs{HÝ›Fm£ÀmwQÐÁ ßî’$ ’}åÛ_~“„³}âC¾OÒdò, Ã0¸ùq‚¿üôÃëww·¸ìêõÝÕû«øÂM4JOöQXlªóÕÏ¿„›¦¾ß„û¤æÂ<»ñœ@CÒºX¡/²ÒíÓv‡r+ó¯0IÑ\I’÷ÊšJ†MGª÷È4>/Žª Ã1UµªùhypƒZ&í©šZ6gáüaZ8¶Óõ~´Ñ¤æ·3“sG:Â×– ‰e¨º¶L·N9}Ö-®vB“tÀ¡Vt¬q Œºl’‘ägÞØsG´I‹ƒ™lÊΰ4ˆ¡4,‚ç“™ËP½^ w¢=Šà¾Wm…Ç<‘/€‚aŠ¿ß½Áßµf·7·¯y4²€S¢àÉsƒx¸ßYíx ¿e É hÑ™ðVbèRÕO»b‚SÀ :>l‡s×øhð•pÔ…!猊9†Ö¼4“ªnheãÈ F:ùÛª=AôB¶1*EŒ æ”|Bá°k‹>L²DVf3%tbS„ˆ®=òä³q'&Žü˜SnÕY 7I† É Ñ~Ãí‚Ù€âeõ½¶SmmH nÞ­yefhJ¹ƒ6K8ìhðÜçÀJ’q£E;Éìîh¯/ñh_+·–”SqˆŽqŽ\wV΀*ÀÜL­,ƯKød*Æ$þJ8âNÊñè¤&ÅDÿüÁºî‰‡p&Y¥Ï¯Ö,…ˆžÀèä—¾!­κf¢lˆÃ¥BH©:¶›BY´´å Ý÷hâá#j‰ìLgÁ¯aÜvB¨­†~¿¦ú fv\-¾ñ–Gâ¥Ó~]÷¯Äbòõµg>ûTa³Á‰#X(™¢øÇš3È#iPñ,C[‘§Á+ÊvèÂ+”ó‘?fµ?ðˆ‹atYnFÁ…s¬ZÈŒ¹fã$¥ £€J‘eùÒ.]{ý’&ÆYA¶ æ†DñTø–AÌi‰WOER* á-4]túN¿–Mï:‡»ä9æU:ó.’ÎJŒˆsÑ».âx¿îM‹‹ ¡{žeaë[@ì0E—ÆÆ kàŒxÍÒ–÷>xÀÈ:»Z ^®K³ ×•6>s“4‡p:BÍ–Ùy‘„¹ež#ÃIÕ<ÅÐ ”ŸÞýíïwoÞÞ ÝÉ.xÕ·fªÍDÇÕB`¨•[QûÜY'^ÄTN| <4Ô;€kÁIÎØË p'#|Ϩ;ªB¨¸{ò ;X!¦/bó÷[¾ì“-Ÿ´™¿ÓôEŸëúØ%réZ?ëÿ÷&ïµXÃ<…rH >§ô‚žÏ瓺0EH 4Å?gÑfh´(ËŒÂ0+ä~¯×.…ì»;éO0>¾4k´hA$ó[öô\u ëÚ[‘Ã^µü Tø–ƒ »Ò UÍjM¾õi—Ù«×ÿ¸Lƒ'Õ ‰ .2)û(üŒ™Ùè1È Ó^S»DäËÄžíœaU´¦Ö½®Y’gFáü‡mþH¢N`­0r¾Y)b_“e¢“²<™ÎŠ,N*kìµ?ruN|_3€ÍиE56ÉÉa&ÊH¿t¤ÖÒ"zKpEÙ¹K}˜;òÞø @Ä•lŒfÙ˜öeYúëõŸWòµØéÈgùènë3Óq’¦Ð÷w³|¬úÎ šjÄ£5àÁõ©LË^ÂÙ"Õ}–‚±A§Ã"Îþj zm)ME*Í"Ûù ¬luMVL¹õg€‡iï,XðÀ¿Š–‰;ÛòÓq'á @s-ìÔ<7Πä^ÆtõÇh ‡{#wH¼«x»ÇÍÛ·R‹„Dr ÂW¤-?cc Ð[xïè…J1´À`À8£‡I+‚½ÀµË°tùo*yãNƒ[í=%ý| fCTE(ž™‹7‚f>Ó \f÷¥ÿ[éÿ¥÷:¼tJ endstream endobj 195 0 obj << /Length 2397 /Filter /FlateDecode >> stream xÚÍ]“Û¶ñý~…枨±‰$Á¸îÔ±Ïi2ÓÎ4wu’LK‰Žs©ðãÎú÷ÝÅ‚©ƒÛíC_ÄÅXì.ö «ïyÏãUƲD$«»ÝŠ ÁÔ* Ó™\Ý«Ÿƒk-Ó–U¾æA¿yÐЮC)U YÆ“õ¯w?~ó^F3:B'L*¹ŠˆF Û¢( Þü´:øþï¹ùëÝ-n»º¹»úíŠÃºhŧÓ%ãQºÚ®~þ5Z0õã*b2Ó«'»ð°’IÊ@ÕêöêoWß¡"{&F¢5S2%ÂpÛ¬¥ñÇ´ùÞ„CgZâ}¡¡X%«Ç,Q í¾©óMeºu¨¤ì>€Ò ¬ìMAøÝPoûµSç¡àLøì™l¦q¼ÚÖÔk‘}uZk¼„å‰ òª"ÂŽÔ'é Û È9Ëâ˜x<®C˜nÊWõÀ«@±5ÄAGÓf ì•¿DR!×81te½§Å·Öœóà žîË-²xOÃ’ºžvm€ZŒ´Í1oóÞ€,v©±Ú*™²¿§ea˜w¨/6q?Óð{4³ÍJEù˜Ž•y‰#AFwohj×T•UƱ­xÐõpöÁÜ´ê©DMâd^„ÊiüL“{´âXÝÁ¸sç0ݧo›CèÓýìt)ƒëwf—Uÿ8E¥oqîáú[ç(|n© ­W!Mõ¼{‹’?|»cPß¶yD»CðØ6GPä‰F¿Dqô'ü96)P$»¼zwƒ“%õúµDÜ+bdá2¡ŠXœ)lj»”ðcY.œ‹%‘]û1o=Ô8øg6­yí¡¢Áɲ3‘j0W ¹„@”.-åAó­­7FînØ—t«5 ­5‘þMסi!º;ðŽÉ~› k{ÕÍÐÓ’|faà°‰ÒÁmy€èHô }_Ž“W>“˜fѵ£ Dvìò²E?An]ämA3ù¶mºŽf¦ Ûì Ñ“$Må€sV†öÁ%ÍNC¯½ªÌjg¥Ü÷oßúx³>æ}¹)«²GÉOx<óYÉ3&Ï¡µ0›aÿ™¡ôÖTf šIJw‡@a ,m´Ñ=b”•[U¬Ÿ"Øìèûƒ¦MJ=І(t€ÒMçäãqäe”1¡á¿D%¢† ZGŠàCÓ:ÈEPÓbøõh‹¢DgÔ.ÄK<Ùü6€ùÅ h} 8÷æqz &@{ÑBáµêÁ£IHxYªÇN%£ÀnÝÛX¨x¨ë@[_ËYÈÓŒ 8y!°c°¤X¢<ìÅü_²e¤j™©³R¦(!^ ó€ Šáp$z͵4ðK€s^ „€Ð«™npØ·Æê¶´÷ ®Ÿ±X]H)}r1!²¹X^§„ÌØëáë{c?Ÿé"?AÖ¶¹lµ6¦0„¡XÇ® ¡‰…•ZÌÌp8™) mBF0u˜â2qŽ{çymIxìž¼Üf¸ÇµÍþ¶äc0í0x¤-h€a¥&†yPP½˜}s€H³ÅJ‡'Â>ÝcÐFºc(±ƒ©dqõÊ—¤Ò©{nJ±4šêÒ?x(¦,UÓ•W†êÅÊC jÌxZøGoiÌ"%oÉ’·ð¿g®k·ä+>æ2Æ?s,½‘7ž|­¼Ëli§ÒoËJsgˇø3Œ 3ÙTÕ¸‹wSPoƒ9iBîè µ4~ÚŽƒ@·rä*î«f&çø ÀqiÞTäAü¿´;ÂŽ†™h"®-qé2‡•[¸ÀÖ±H ù•c¢Ã™3í5ÎäõeF³k›¡Ýšñ {ÑD¬¡y$ê‘ã9ûáŒgÚ¸ÊöÌAµbBë‹äT†ÐÓå?Ê‹bÌ™Ç2(…ZL[`ý¹Üßã}N¬àÝt4Ë´b@iãr1@…é!…ƒ6nó^t\\ÖÞ”ò¾(<Ø ;¬ Ø î9uQŸf|Qünšh–fŸªpRí*¦£`DWˆØ ] À΋m‹0 ;^i@‘!¼Û¶shÒ`j ]ëˆ49t-*Ê‘€ ÍÌgDw¶ªŽÕŒoKWS¡.ìäùMˆ£I\y jÏâk,À¸ #¢ˆ/0À"gËtyYã*ûIJ«“]Â:Íl‚‹kï;óM=êVˆù¥À«ex 8Ub‘RÐ=íüÈž»Ãû"@ô蛽©;›vi*Ž:ãæÈ„pzlËfèñ™ ˜—äÊ6BÆØœ×¾›k–d“»Âé/ÈW¤LG5Ns´u+E* ÊMÎ*G›éÑ^v¦5õv”¨!L’-Uê w¸~3»…çþè½¹;r%îó_‹úq¾'CømêêDPkà•ïô‚œŒSêA 2û|ëVm](r$‡ÑøèÉ` ùÁwÏÌÈ,¶zïmé 0Eó,KÜ—T‰ça)Id (Ù•z0¦[stÇÅ }¡šîÛ“[> stream xÚÝYmÜ6þ¾¿bШËòkq= iwƒ¹¤Mæ8´ÅÁkkf ØÖÄ/»YýïGŠ”g¼ëm¦¸oý²#‘M‘)JûrsñüJD«ÌËâ ^m¶+^¸J‚ØK3¹Ú”«_œëu*ÕUu¾ΰv…£aЭ])CGz™ˆ×¿m~|~%ý=A{2”+ŸtD°Ì÷}çÅûu:¯þý¯Ë·›¸ìârsññB€œ¿Ó×¥'üdU4¿üæ¯J`ý¸ò=™¥«;#جdœxŒêÕ‡‹Ÿ/^â6‚ìÑ6â4õB™ ®[ŽÍÁ:¥ÈÞÙ¾ƒÐËüxåŠÈËBZð>ïT}¿vC8­R¥*½µ§Â¹ló›Z!C:w]5TàŽvGsÏè7kJu3îhø«/ÃZõ4¹«†=K€A•]Y«[ôª‰'ŸÁ¯é}U }FÃŽ]!¼,ŠÈDTÐc gØ+ôCÞ–yWÒ¬@ûмžx;ÕÃ6Â(r®0®º#N©†¼ªY—nèÜê®ÉÖ¡Ô.$$€  nÁÌ×-î`P]›ã'ÂP:Mnhc^ƒ5I"gá1K*ò¶pJšçã ÁÜ”‰Ø£¡Ñ‚^Gß%¾Ók¢~áº3³bö(_¸n«|ÄlDïIâ~ :Ä{µkbT[¢w ÕÐh ;òMD­ónÇz RDkõ@”RõU‡H3aÚ0 ´ z„êŠa-NÖı—ÄÂfá?´&^fV1˜ >VM‚ÿ\²/K<ñ´uîÿo^ßäÒ%ó2OâhŸ+ÝKÁ> ©îŽÅƒ-Ϫ†+ß‹¥X¬ÒOË%‚Ë’2Ç%ÎÖdÌK›÷ú@ëH0†‰*c烈TAÎ$œGD¡tÁÑTKPçI-AÞ®Ö7”-È4Qó¥œèÙˆ¢BO ''ºãÔ©q7·hˆQl³àôÆÎØV̵€Ü¼^ÐR=v/â“&Mü§5.”¢“†ä²§¿ú‘¯¼gš< ¼¡ç‡üÅ&š•{-ßu%Æ) "'[À…8øáø”0e.sÞœTy0Ð'[ʪ¿¡óî;ÜPí§r¾=S40X!ññõM«Ûu;y­¨àžÆ;Ã*8+rŒ®7s¬d¬ÓT]þÀ [zK‚ìMlXæt9¿r]žw ÿÔ©C§MÔ Õ£$ã8!žu$U*,ÿqèÜŒ •š~M•ÅA¡aCµ•ËY)#0úzW¤Ó½üÚ#Ú»q8X…U¿”;Ø ÏΈ‘ÍŽc˜équ‘ˆ—êÝžwT!ˆ»¥_ã|rx”Ð1µ›¦ 8Oñg˜Òo¾·W÷4º«êz)-àìE›¤tvükl„&î´edãÙÇê:ݹuÕTÃR‡þ0Œ?WàS+p»ÆpÔãb<èþ´'P°ãy1~±LAÅÝîMÂÀ~©õhðïͱæâÖ·ôk6Åšy®ÑÅœè(¢ÚÒ@¶<«òëùTa¼1ÅPÛ|¬‡~îùÈÿ¼«ãÉÕŸÎì\_©Vuù`¬‹ ^Ð/,/ÆÓÚ4€¾óÓŽÄ5¨!yÆIdº^ L9ä}ÏRe‰ÈÅÞw¨4HPM<˜‡M¦þh6Sw’ U6p€_Ù Qß:Uªµj¹ÙòY°É«–SКnmïq” šõ•‰ÿ‡˜>à¯ø¼§å>ôÒã]gÖ¢ÌNßóc9ïTŽ[†~Ÿ6"ÄÒ™9Ý Àˆ,(ä*`äÅÀƒžÖc?jæ&ž@Ô'©Ú¾*â¬{".}[L\¢…ÒLj.oÐPȃÂåóEËÍ4 Aƒày>C€ÂÊaߟ2‹I*µR‰"²þ‚ãúå‰{âšà‘›[UMñ$ê6 Ø gsâ~PŒ°cýt·ÕoõÀLÀ…ù­8Á·¸u¼0Wé»UÙ¼ètÏÂÓ [ïŽå!\÷çs»Lá ˜Jëß —Ñ —iЏ´!ib/ó äˆË4[À¥YI¸>áh.')ƒK!¡»î؇çTˆ¶ùºoÀµN'P»òh`¡b¤çPË-Æä cᙃs¢ZKŽ8ØPŸåOM9ާ{1NL¾¥˜o-ž?·Œ¦áý÷D¡§ŒÄÙÓÔ8Õ®Õ'ƒæ_ûeÕ2ç§6)noXÞRü§èÐu½ñ÷ÏèÒý^, {t¦ãaä·Ì?ˆAgäƒ×€Àp¨óÂ\òˆ@$Êñ£@|D0– bd‹n«N·Ö]KÆËbÇ7~è/œW¯z)irö½ûÉK7|Iýù 9öR0†@%H_žLß%»j‹z,Í$¢( ~NA‚õ6“çñý7ßÐ`¼Ü\Èp:Uï²ðE]“¾÷DO¬§ùSÝ3Ô(Õá#MˆEÄü|9Ž34)äáRÁDªM$3Š CaB>Á‚¦Ž†ü!ór{Ùœõ‰…M4ÕnÏ)ˆ²SgøÞPÒÈTø¥6J…ª[^·².TÐ÷ÇácWL¹jTŒý _¿ùïõOï_¿Ý\Ñ|;¶ö^p“Yº­´üZ0Uœ´ŠÓÌ< ðãzÈ#V‚’ß ¨e0o ªÔ½·'Qsd˜ S=r|mH©¢—ÝÍŸA/%6JFI{bEi©µ˜÷ÇžÛî¿Z:ÏH¦Ðæ[‹ÖcuA‚oòVè»5)|nJîÛ“ûVôÀª$ fÇÁ;v+ÞtU?kàV‰¥ŽÄ–XÔ Ò ¦z;[}8}©JÃWø‘Ú/¸€o¬0U@´•úþ¼¹yÚn±‰›¼¯ C™¹½b€]pÎ~kVˆZ ½yˆÿøhö?ÿö`qj endstream endobj 203 0 obj << /Length 1949 /Filter /FlateDecode >> stream xÚ­XYsÛ6~÷¯ÐèÅTc2$šNÛIœiêÖV‡$ÓDH˜‡B‚>þ}w± MÅœTéôE `oèÍâèåÛ šÌ½yÆ“Åz„¡Ç'I{éœMÙä³s3K™#k•‹Yàè™8Lê™Ëw˜7âÙ×Ň—o™?8'Lcq6ñ錶ù¾ï¼¾š…©óî¯ç¿/®qÛÑùâèÛQ|þ$èog^à'“Uqôù«?É`éÃÄ÷Ø<ÜÆbÂâÄ a–O®þ]œ-Þ¿J-ø 1ÌYÜ» ÷æiÐ1o<âÙ©Î!ÌXZF*â=ý ya,Ÿ¢%Í;+œ%Ž…WÓ¨%yYÑØ6–pj7q‹„²ÒB+ ÿ!yÒ±­ò6ÏÒçV>ˆL®T!r" wýÏCÿ޳2"­4m`´ø }UM KUŠú‘2aZ¹¬t席;#=™ú¬jÉ?oÞ~+l5_h æ¬*2£è¡ICVé'Mj@*yÙ)L(æŽ|@·%NUJÂó“¡$î÷Xxpþ˜Né8BEB’"Ä^OÁPpÚÄ ó¶o’`z< é'ä=PÌ×ÝdË1|€DPP‡`ºjK,9óA‡ «šHm™Éº”Boé[PÎÀéhFÆ…wgoh‚èéº9¿ºøíõ,åÎâòêïžEš˜ºSîêª,ˆÁÆ ÍZ‰>hû2Ú(r"f…×Òrv™“‘i–z<Ö:ó I½)—ú0c^¬ñÞ6erÙnè³7Ž…ðJ}ñ§¾ NÚ8ÖoÐ>iÏð-h Â₲.hm90iIuÆ£#&^вÜjð"ºE›h”J} Ñf$LTQ(d¦„–š`ú„ÏOJo«Ö²?Ù¯¨íÖõÓY#Âe¤šlÊc“O"ð­ÉkL­ƒÑ´7U}‹é á ©©”À ŽÄ†˜:šÚ”Umz¡ˆ‡Î…-‹`a›ÀÖ&2QŠæ‘H«ZšbDôjMÔÎl£°5¶´ed‰l¶ÒAY®›_‰^Ië{ÕtML‡RÛaq¿¶: &?W Jaßqg;z6ÌHÜ Ã¾ç¹ë¢é9¸ñPHnÏÀÚ>‡þw‰K6ã㚇\˜ŒoJÚb÷}èwQ¹áŽwÚ‘€ GXâRQìoÄ—©Ol>œc:nh¶lU®-‘©èë»xD’)Õ¦æÄ,î³3YÍ<Š./Ô {:Tw›VzDF*¡Éܪ†³gª¹Qî)Ãæ{1Ž› ¥¼·µiæìÔ;œµwüb;Þ²¯º6|ðN`èu›ûuîöí€ .—ͲðÍ í ùž°ÿ”æ«ÖFÑ/^qÛÇ{p0Àó`wXê>SÍǰ ‰f³ ¶ƒ^ŦS¢“’ï¦E'5>ÞꆒŠ€ÈÖÖîÅHÔ¦^÷F¦ê‚ØK8ßo;³»Oáq˜ÕÔòõŠÎsQ ÉM ³ìß±ìF^Ê÷ÓÇd|ñÁ» *3z•† äÔHM ¸L—›©Ð4Þo•Iº–ܳ^¼=;ÿcñÞ2!‡¨KÓï‚Ês:¡ScÜ„ôL®E›ëQ°k‹PŸ@0¸×´ûªÁl×t˜írî§›võ xr3_Œ¥iðfÿØãØðAwI&þ£Ë£ÞååV-•vUØ7ZwrÈ-½;Ó4vN±fJZÀ~% œ©=ýZ˜A—ô ¢'lŽùrJìë¶\Q¹Å]è ¤ÊÒ<ÐTX´Ž}G@‰±-´ïH7Ž|Êm.÷˜ïмÎnž{;z¡™¿x`-—ÔÚæôiR¦ùG“²ìÀa–+;Ù̱陵5H¡TÌÕõ¨eeÖ9dêþo$Ñ×D¤—4 6¶·Tt!ÈÖæFÿª•÷};è/#øARsx¢Ásn§Hnz­ãH Šr³/ªÍ}Ö¾~l´,Nm¨Œu¬ÎHÁÆ $ËYM°eT²ƒž<ð²‚ûà cñ„Ý?‹ÿ)ÝV endstream endobj 209 0 obj << /Length 2384 /Filter /FlateDecode >> stream xÚ•Ûrã¶õÝ_¡ñ´S*k"$Þ&íÃޜٌ&µÛN’Z„$v)R%({õ÷=€›ÓÝ}±€Ãƒs¿~sñýu¯r‘'Q²ºß®Â(j•F‰Èr¹º/W¿yÿZgÒÓ]UëÐë×~èµ°èÖ¾”Ê“"“õ÷?}-ƒ (K„Tr0ŽAà½þÇ:ʼÿyûþçû;kòʉ’ÞT¿Riã$(,ÓÑBZTtóÃPäqÌr3)3¯ÑO¼h-Á®è«¶1̽¨Q¬£Ô;3Òãð¦(K]ò¸>YNQ]»ƒ°³DÈ!`š+تÀ«¶îHgƒ[UfIþÉø×Š©k¨@±6éD>!~{ªKÆí´{ƒ* ­ï:q*ÿMÛ[T‰þ‹•wSt;Ç}𚹚I°Ô-fOEéÇbƒ‰‡x 'ñ¦R‘g™‹Ê¿.Dd*R•;„¿1ÑžªºæKËký¸&[Á®d¤ˆ "XìZ%¯È¥iÒ×›öp¬jK¬¯¨'Ñx8Q^­ü8)¤ÞÌYXm¯Ék}UÔõ½“yÛÂôH;Js¯;ÙÏJ aj íñ£Ñ}OÉ„§°Ú52¥%ÕZ:NE›C†ÀäØÔ+±”Pem~Hž¢ïÏKQf(%x‰b‡SÁ0l’ CL\ÙÝÖ«[{kc =Ì@¶kŒ‚Ê*45Q³rX%·Üצ‚¡4é—iáˆ÷½qc5(If@¨šFöŸ$W3¬®:PŠ&Ø6šbÜB©Äc½"_5 ´moTŒÁÜšœ‰ÂìÛ5F,w“ dsH‹¯­x~ùg/Ë]~öÅñ †× ˆfÅîCý…Ä.Žø{2”a¸d‡ÀbÖô0†üÓž£4ôÌž‹ùp|‘[ 07w`|ä0ýŒ“Óñ¹ß¬JJw –Ó]ªœ‡l%Э-2ðXWÞbŒœY& ¯%Ácà!G}=–ìà¦Æ¦¨kK@ºß[sø‹ êV<¾BÅ{7L­AÎu< ¼¢á½ó)E¿Aö<¹›—¡¡Ù2ñƒ¥Ïã1|šŒÇÁ,µ"RŠ,S“Ü· _[.Ç0£—Ãé1h®Ñn4ªÉÀÓŸ °3¹S:/¼µëŠã\Σ ýŒc.Ž;¼ùSY™cM¥ðŒUåòχKL‹«›rBç’ QÏZð EVk®åh&Ü\ö—K*ö>VýÞÂ^Ú€g{Æ = —C{ðñR|C:ÍîTìó9Q ¿˜Ï20œ=^ &KÏœ.Ôç Ìg:@§Èbåøø¾5_cÆÌÄ›1Ε£áVߨޗÈG`¸S4m÷Ð3”/Zžúã© òßÔ)OXÕðF7”C|Õ0-¯¸ÿ:•LlׇOþÇu¦<ºŸã¶=¢à¼îíiÝØ hc b‹Á/]È«³0½ŸðI`©er¹®+ÓW§qÉfìÁüJwÁwmuxœ›[!´S&=Î9ÅBœ¦LµkÈ#Qb_à#©€q‡ v•Z÷ã÷“ÙÆxmq­m§ }ÿÉÑTðÙ7gË•4dŒ%›ÌOƒ¯†äsò…ù†~{ûîëBüýàÒÃÏ:tü%ÿ–ÚVú¦äêFÁq"Ðû 5çÄVm›Élò¾ß´d· ˆ´Ê ¾¡ÎÜþòu–ç×™$ÖîÔÒ’˜ìP¶R:Z cÕÍO‘p†~ÅÐÑÖøå¸o‡B‚Eø<Úc«ŒUäÝY«.Ýàç6ó€^3ûâ¡0–05¨4^‘å ¥ûŸÂÿÝ•X˜ endstream endobj 213 0 obj << /Length 2238 /Filter /FlateDecode >> stream xÚ•XÝsÜ6÷_±ãkÇ•*‰úœ»¹™ÄI:í\.mí¦mÇ#KÜ]žµÒ)Åvÿúéզjb¿ì’  ð¨×7gß¾‹ÒU”Yœ­n6«(Žƒd•ÇYP”buÓ¬~ó>® áI­ÚjyÃÚ¼zí ‘x"(£lýÇÍß¾áLN\dHÄ*d)l ÃÐ{õó:.¼ï~yÿö?7׸íìíÍÙÿÎ"à WÑtº¢0_Õû³ßþW ,ý° Q«bܯD–1ŒÚÕõÙOg¯ÑŒ¸ü‹YQ‰ÈYßß(mU3^‘iéE–´ô$þÔC¯ŸxÉü( ²"ÿ4(ë¥ëÃÚÓd­~E"ÍÚORá ;Ƀ®ÚÛQ¿qKèJK|_Ý£cËÝÚO3￲˜ZIÖ¦H¼`íaê½j[^ÜÊNêj OñøÖÿ ×«‡æ€­hB™¦¬ú¡­jÜ-ÊÒS°ÃE ;e˜2;[àÙY{ßo˜«ëf2§Ö7ßÀz”zçÎ’[rnO0¼w4²±ânÈK@£³¦(ƒ#ÝŽ­k-ÙhežÚØÔnzÖÇ0™õ„|TÆ«®a^: 5ÀɡҲ[ǹçYë•Eþã8öz¸^ý ŒÝ»¯hçXÏ#ïéï•ÆÔ±±ŠKÊ&¼¤Ü“›^K&Ô˜sm«º-Ï?bP.‚NÇæIàûq”a§–A."úû5öÿ %ÞÐãBd) S—C ˜]ÿ$ BȘ¯„¿(Bk" 8ü‰Ôó?(b·Ð=ÌVÐ}4h{̉J mIòM-GÝVÆHa”©÷Fnª±Ì©¸IcÍùüN*Ã×àOÎùºc_»Þ¯Û{ë¤hÆž D8_þsA^äÉ„:Fm»ªõgŸËJË ,¦‹ù×Ò•"ÈÂâôJ~ÔÖYS<σîóŒµTR„ÇÝïyd±ÃF¡€@×÷(SBp6˜Î‰uË™WãÉ÷p1I’x×Òš%æfÅ€á"Ï]þÌ“é [%“õ‹W#"Àù¸ø<èárY÷€ªï–$»9í׸ˀ¯”ªlr˜xý8ÆWþZ#pÛßÈoBo¯:µWJS÷û=ÞGáa˜FžezØ©AšÀ°%˜§=2±ãûv)l1X Ã,Axè,ÿäê Ðà½Ah°g`W¨7–D þ·è†2šëÉÔ‘êÑdÕTwªà…slXÐö†êIœC*æ¤ ¤/r åöêå_òuP­d®Aí)É“¨œ âÚ†#‚wÜ5`T>T]¡Ú­=„bqWu['ngjx¼ ðÞÝc{aCÛ&Œt¤ç«Âä—Ö0Ìçw<4ýÞæ\]X=µ!€ª3YòµàyÇëŠÓŽ ³Ò65Ñ•w­Õ¢j•ËV0…ç>äßáÎO¶µç/ÓUË– ôëÍØÕæ™Y÷F™Šô‹aïöþB£–_ÂÁP½`qZn$Ôô×0 ›üŸuN8E*0Eâ4æ´ŠEüf€8g®…vX3› HL¬ ½ â´8 -:“;ˆêÎôíèf“ª†çf¨´… ˜mð,Æd˜]|jo>üxXòS ‡¥Iö5GMåé‚`:²©…³ÒÁP…Ôâ N‡ »SçŒCÄerjŸ-tDRoYÿ,9º—×f\xæâB(èðjº2¤ &á?×/î(@®ËÔ±¥”ÌcÏð#…V©#þºê–Ò|«m“A!?UGT@¤®-Œ Ýþm³àe·%YFIo‡þ¥Ø¼ä÷<«t?T¥ûÖRäÁ%“Øç'¡÷ƽ¸º‹xëpä^ƒàÆâ×½DÌ«Nñ{Š€úexÊýl¸â¹ƒ” »>·Q2'Ѽ†pŸSè$X0nj?œÀaÎ×Ñæ¿šJ/àÐ:2 ÷e<üO¯P⃭%àÛò!ǨµÍ`í™]ô}ÕµÐ+/ö^®ëµŸ"î)¢Ty” LC!*˜5JܧòÿÈü(ê endstream endobj 217 0 obj << /Length 2350 /Filter /FlateDecode >> stream xÚYÝsä4Ï_1µ/çìØ’?‹««º]–å¨:àH€ÚóØJâŠÇl9“ð×_ÉãI̱ð2nµZR«Õýë–æõõÅå—Q²)‚"Uéæúf)Ä›L¥A^èÍu½ùÉûa›kÏ M[n#ÏnýÈë¶¾Ö±§ƒ"J·¿\}ù¥ó¨< t¬7!Ï‘À°0 ½~¿U¹÷îý¿ß~s}…Ã.Þ^_üz\¸‰æÕu…Ù¦Ú_üôK¸©¡ëëMè"ßIp¿Ñi( ÚÍÕÅ.^ã6Tñbiž±ÎXÿ[QSŸÉ±RNËþ`›}ó[i›¾óq£­±Ö <î™™‚87~”ióèïËÁ´O[?ί3¦6u°õ Øôۮܵfäž~àoÝŒ nÉŸñ°õÁ>¦j~u\Ɉ…Vãg[?QÚ;6öŽ{í9‰ù¨*ìÆ¢ HÖ˱–0­©¬©¹µ+G&SÏ ð„@Èæ©óPŽ#í'Ëá™×öx–Gü1C½¶Ø$ô”ÝšzËíÁîbE‚~fÞt{°¿!KÖj^hC©‘ÛUÓ4ñ®ïÇrß¶¦«iãÀ¹¡# A[³›no›îvMÍ ×ÕqvjŸ>2IÁ–Â#›é¸ðÆ~*aV=(ŸÁ¬ÜEË ÿ-6¢“ÕFvê°b,³/Pdä¡ý,½ô„3%SVÒö•}¢“lb)fɆ#RûóY¼ø*Š0…ÙŠ@gJ"¦Ï–ž¯Îqý÷•¹² ‹ '`M5Y:—s%*ȣ̉þc%Îü¸B¥ÏíjŽ’7gb ºr/Ôͨòü$‚‘Õ•-7êQ{75­åÍ ³¦=‚Hßyô,p–/ÌM9µv”Ùû“"+Îãû‡ÁàÂ|>47œO×[fœ4FAwdõŸ–vkt½ßµüªEu”Wmáçœ  ¨§Ï3­Y¤O@–BøâÎÐUòb† Ù’R@>d?jÝð—ôƒíVèñ÷Ì3Ýbj7 Hwz¢ ©×Œ ÐÔÜv{‰Ÿ1`°áÈGÛ‚^Iy+v¾ë§¶f™aGj¸1"¢Àñæäa€ f´®c·ñ'¦Ù¯4jÊÝör–Ãø'ήŸìa²þxh»’§²0H!ýI¤ìž¬W£% ²BŸæœ}´|Äù-;´ EyàóòLÂ.vã‰ÎC8{ní±þßÚ³)Øü¡÷#Ûø%ÏõæÓO¹Í“®¤y¬ÀÛ`9•¬šJCÌåD<ä’2i±só8ô1èeØ0çM•Ũ 6G–eˆ>6mËݳ?`£Li)¹]Úg væÑ®mçfê*λ:Ñ¢e?uu9Qä\dYEØ <;4 æ2l4¤dYY'Ï_‡F€Éû²«(A-ñ#B슎ïÞ¼?I ¨ì5äÁYH Mõî«ß˜úö{l–¿ØQPó‡,,~š¢ýlj’,ÐMÇß%.Á¸Ùc×àþpè¼›=øaûäÐÜø{Û¿B£#cTç“!Ðèîÿ*0ûÆô¸v“ Žç‹ÄhA3ÈHv¥ó0Htú;(DéÒI”Ì@"½h3ü’Cc¿od2x#×Uè5æ4T[玜y¥U÷LOÓásk:‚š› ÀƒÖŒæØàD“FÏn8näŒæ™C±;¨òůóâÍuš;5Íÿ/þÆq$þ‡Ô)´¡ÁèN7›4ã  þéàц4bcRR,% Ï&•ÑBH ¡i‘~¿z3sî ¦+¡ºp[P§•–™%Æ}I¡dÛ#ËPàè—ÑÍ\{çæ¸5T¢uDëöÃ("\b!U4‚T¹Zj„5œ}Ø&p7CSL®<Å ‘Àåó›ÞRº¥‰¢ , ÿÉ-€v¼ÑtÜÒ9ó(é#yÈ›Í]¹‚ƒM7.×[-¹ŸÍ£ç\ ”Þ±·èmº±©¥˜+ùã\è/ã… ¯âE¤yöqx‘A–G‚ú^¨L-ñBe˜pQêY@ö !‘͵KvªûÉÐÔœeŒ`vcÆÙÁšÏ,®IX,÷bu¾¦aemì£ÕElu?þÚúÝGÞs8ÚU{þ[¬ íêæ ¼‘ëb'•–Àÿo žYûr¸çMMz€@>U(»kËîžy­T%ò÷õP[ÜA¶Y Rç»5Sò=æãÍàÀ£Óø#ñš‹—{zÏ)‡ZÒ&äP°ßñ„ÚÆ¿gñŠWòw\±Ð¸4yEØ!Ý”Jû·q_(öÙY<ΗÆ"ädu@Ň•P‹3ˆžù=âØÔ\÷<2¥‚<ÿ݇JV#ßñ¯ž«÷o¸Ñtxé¹”Ë?ôòrpK¹ep/Œp9½ÒÛï“{†°òÒ¢Õò”2À•ÿ‘æ ÷—ÌWÃÆŠšG3t#t¸îÒçø8›€øô¶…õìX} »íž2À²Ö”"F×wHÐêò¡u4þ§‹yTgpa k×Ȥ ‡ÉøÈžƒ7¸¥xŤ÷ēฑ”í$M¤ÑrkqÂBÊ–Él|HÆONÆ–¹|ÅœÒÂÝd7YF—§òú,ƒž¿yUÌgv? #/ǺºmÅÒóúœƒ¢DYCPÔ9ËD‰û¿áè—u endstream endobj 221 0 obj << /Length 2339 /Filter /FlateDecode >> stream xÚµYëã¶ÿ¾…±@°2rÒI"õB‹½ë]Ñ 4»I?¤ÁB–h›8=QºÝÍ_ßÎP–½¾ì]‹~±FÃáp8ü̓ò›»«×ï£dUE§«»í*Šã@®²8 òB¬îêÕ/ÞÏë\xjÐM¹Ž¼qíG^İö…žŠ(]ÿz÷Íë÷"\è‰ó4R¬BÒ‘À´0 ½¿þ¸Žsïï?}÷îû»[œvõîîê·«äÂU4¯.‚(ÌVU{õ˯᪆¡oVa Š|õ`Û•H³ ªYÝ^ýóê n#.žm#Íó@ŠŒLðýƒîŒo*ÒÝZİköÉöcaºò£$È£œ&ÞÖ>­*ýïPHeàM†Þ-:âÉŒª}K ݦѼÈGmé¹T9ª^Æ}ÙÓÌvòºVD™}?55Ñ“qÌêmc¬í°?Š‚"IÉÐ Ù9¢Àþ( ‰<Ç…D^xeWÓ{*ƒµŸ†…÷¯½©ú§lt§j’~ÐãžÆÆ½"âúèÄÞ9[®2ÔPŽÒw¯N¬LÈJ H™©Á‹GÌå-ƒ÷¤» ‚/ê“‘óÝÖ­(J»…÷TÒsf˜ ̻DŽ]9!‰&w¸‘¦Ÿ®ÑÊöó ;„ðÒ„b„ÖFÅî¬þŒº"Hóø®ìéÿ ±qìÝÎh…—ghžE+˜ü~$,>ª’Å0^—R"¾ÜY!½oõ{8Ú©B»çil…X¶˜‡ƒ+|(é–zÐM3#€Xn±(½‰3Û„rhÓRŒlúÀ‰”Ú`¢ÞB,æ¦aE©k-ªuRx}Û¢³Ÿ£ÆFMA3~„ož(Ò;¥jÅ™dN4ê‘q5èVÑ>Ê†ÓÆ±ñ)[X/eˆ°ÒGG,ª<¶À*/U-†C˜+gÓæ0ôVGE¨¦õj}…x ½±gL7MOIï¿XøxE‚8Ë»ýnû¡eÉÉŒ}K£ª&à»_DÄ›gïô;ÂA…g^­Ž¹%ó,Ã Í ‚’S¡ÛöÄÈ8ñs0¯µ8Æ7¬ÍéµÍVÖ\T•y{z#EÕTå­q¸‹1ë:Qœ,N¥ƒµþ)qI—¤ÉDweË9t!Çæ_òÔò,opËÆÚ–¹ÌÜÚýÇ5Á‘ýy׌õhÙô&Q ³ÂÆŸ/„Cd2w´kûse7E:‹þå%]×7"Pxwï`áÀv­ Š'©ô{àÄÍ€òã0 ¸9œxëèlîb‘xÚ²ãUdÎPÿgϧ®GzÖÊh¨Ç9³Ö-dCæ°éÔÃ1!=¥ÎŒ ïÃ¥3Gpi!)—9XWBfˆëòÀ½yÛ» M}õSþ·ªÛ{ëú<ó~à‡3ÜR O ¼·F8jIæÞ2Ëž[ËŽyòC?íìm %ÕÀtƒ…¹14>o!w}zË“é*‘,áoêÑf$ݵ#õº¾óW/gÆr„Fè’»²(n±SÆÂRz·Šë€ÄëñþàRCé~ ZÔb¸'Ú:Å%w;ê±lº˜˜îд:Kd›iG$W‚Äs½ˆ¥·gƒÎ‚Wì¯á‰ø“¡nl)ë¿c%l5‘æÓžQ,tÔœk`§n.ßcȪ/©ÕƒBc/ThQ1_þÇþ°H2'ÕÜçÙKMv´´é0å\‹”õ]è0…2ý8¢„ÙÐkÕØôdé’wÒmùC cŠbñ"ïoj[ºN ÏŸé.¥BÖÕgÎL‘.Ú$44\!€e»6lr÷Ìð}°Ûo¹PN ³ •DÌPIF=£­Œöqf-ןéÆ= bšÈi§¿Ø­.Ê…8Ö<×ö[t yŒ×·Ø—nN_œžÖò«íÔUæ3›ýïĵÞbH$De/¬h ´·oñt¿þšFP?Ć;tC"üËÒf²I€\Ù#Ís&BÌ! ŠœëLØ¢8¨uÃèS‡¡yÜ &óç‰KŽ†Ì¤[ý»=4™Ð¡Éd®'%6Èè;EÄõ¦4ºº¦̃ʵ¥ è"wªSô|O$R²$X߰вy@œS6ÄÛ4.-ÀÏÅ‚å ÷ ‡ÊåêxÙ²$ü¾•ƒ¼6n–mŸæØÂ[M/Ã*5û¢U5åÆÁ†ê9e˜e{Q 2s+Š 0‚ìÏýPòU–Fdó{ÌÑÓàsÏQ¤A"åY @‡‰™Xº,SS¶`K—Žä| ó%™^ÌHJ-2Ï=ûÎ^ÊâÀN›å”l+{¼i6÷V@Ú/¸Á‹Ž„hý‰Û%Ô?Ò¯ ™ÇKЇ8èX@ßhûùnjJçÜìL(çÎ`¬N’)á nd"È"‰ &ÈsFý_‚|üOa Ž endstream endobj 225 0 obj << /Length 1992 /Filter /FlateDecode >> stream xÚµÙrã6òÝ_¡GÊRÁssT%5㩤v3I¬x’” &! »É =3©ü{ú%Z¡“™ªÝèn4úÚ^l®D²*‚"ÒÕv·QÄ«,Jƒ¼«mµúÉ»YçÒÓ½©ÕZxví ¯…E¿ö¥Œ="]ÿ²ýfs%ß(OËUÈ<8†¡÷åë(÷^ÿø¯Wßn¯ñØÅ«íůè•8Þ.f«òpñÓ/áªÔ7«0E¾z$ÂÃJ¦YÁª^]_|ñÕŸÕˆ³@†é*Íó – ñR—µêõ’ƒª®y1˜ûFÕ´©xqh×>|ª±žtã]mÊ`íÇqäm÷ÆÍÄÈŽ}ƒ«Âk¥œsçuÛYs0ïÁzÊš¶Р„/DP$ ©€m”žÙá׉‰€£˜¸Ù«Ê¡y¿¹|@Ã’—lÛ3¾Üð®lpñA7ë(óìàŽ7•»®©Mcš{T/Jzˆ`õX’¡]’˜ÕŽ£hR;Žä‘#P)ü¢RˆÅHB¶¸&Cg“¡BÊÑ1þr*‡ÇX?¤cýng .7/Ð=‰76ÀmѾv¯1råÜÁ :èÒ€q †Çݨ»ZW¼1–¿Æî9þd{"Cýõíüá]nN•¨˜ÅªÅA±ê €!Åô»µŒ¼‡uƒÝGý‰K19;ÇAÇS†5ê ˜G&èDôù›./&‚¼Œ‰žä“Ÿ¤AœJ1 Š˜iß8µ{cÑuQž±uqqoÛð¶S=Èguÿs˜„ü†·åyz:gÛ®Ö|´fÈÌ„œ¹w­±ÿš¿;ŠxX(æVi« zlÁÿ•ÊÞt˜ï wÆ÷{ ¾•À'Ú7MYÀgÁNÇÓh&Á§ÿ½G+ÈD xøÁð¢ KB¯×;Ý릤"ƒ$ŽÔÝñä€ð^à>…CC[³‘˜€ƒØ1%Å!&¹g¤í“#\¼`(t F²K˜˜DåÂ/<\4%å7¢øÚSèV+—.—3Aà râ/½rì{¬N¹g™¢2=ÞSBR½ÃôQþê°äzmoý±º &ÊþÇøø«·¶GW ˆ:,9ê¾ij|¸+FQÐI‘y?~ûæ»íÕ?¿D· zÄz¥z,€­,¦†ÈcøÐ᳨uß3¸æ¨o;4j’•œ$Bà.°JC‹éBÑ€Q½Á¢50Ú4Œ"[#`Î>Ž÷D)ˆ39êÙ©¦Ñެ?첹Ȯ²¯Ãd vRtòÀQ¦J€-R¯±L¥¨ºàžl…CWk¹½ÜpÔ´¼;àf¬­éjÇç\HMÄw½Vÿe¦äáe3Ïdž°§pùõÍ NW•Á²‚;hNýT·(·‰€?¯{Õí×yìÝÀ(@—o¶|hª ÄÌÁ/{”sÔ¼ èÛ·Í=ö)$([pPi—ë´îomã’ ¥Ê52rYîŠBœ‡ìŽvìË5{pjX£Ò(Kqàó꾸«¹'““s(Ìýˆ™¾sû, l [ò¼†\T½ö$îèûÕxè|ÛkÍXÊ7@ Ú‚ DäõX¢ýöŒ¿G?8šƒBöïx³×uçX4 Q0y½{ñöW¨vpeðnte¬¤šŽV†7®yºæÒ{WMS¡§uõ4ÖÄl‡PnGª úõiB»ÔÓo ¦+.]aI¼£¹R”ç[€Â!ÓX”'E!.8 ¹påÞÞ8ñÒoÕÓê3ðtÍñ4È`þvãEÕ.•`³º<Ž N!°U!ØvQ‘í2´nÆA;<¦1B ôўΨ–ŠiH/\LÙ…8>(˜&ò¾{yÅ{%Òõ®ª¸¡X†GK ò¾Œƒ0KŸšÀYçÎbÞfB˜Ã2hWàËPž¬q™xþ¶«vnù†¿7ö–úæá¼t;d}ÝÊ1ï,b‚e£úK7º·J‘x÷ºÑ=ä1î¨2!¬€‹évîšçwOp¼9à Eñ‘Ñ®‡W±x¦aqÉ©Ô}DKÔi"¾«õ¶rݧ¹û®›Y v*¬§‰DºÜ ae€™Ãåãnl ü´T|}jTÌìlz™ Z=}]èz1·ThS¡ÜóªœNð–»õ^DB›²ƒm$ gÏr¸ôª6ïIëxÞ`›™h^ꨎDSIâýªë3ùŒ]A`Ö5÷Z!Ni.æáÉ ;½">ûl)Ë‹ )ŽÏN£3." ŠìX,¾øâ9.Ç¿Z×z|x ,`Ûœ¥ÅÌ3¸=y†÷nô¡Ñ›{q¡ÆB™. ƒòLž=#”Ugó1w´Ì+ñåIFc%¯ÜnP§Um\ŒU?X¯ÐS­ûSO½Å`SødÿˆŠòКŠëÇ ðõ‰ÑÝ_]P"Woʽê/y¹3ü\èøM† ßHmbVßnŽáFÂ=h>П.> † ítƒwï ‰qºé™Ì‡¾eš[kúSü÷^7› #8iHÒˆÇI;°3\ÆÂÅÇ©ŽPÈl°P¤_ð^ÛriD=ä^¥‹ì/Ùå÷%mN¾p®¾=ÐP÷¿vÇ4<»šõÿð¤â¹GþÂlõ™í<¿ed„5|‹ØUq‘Mþ[Ioâ endstream endobj 229 0 obj << /Length 2088 /Filter /FlateDecode >> stream xÚÉrìDòî¯èà‚šg ©´ÇœÛðˆ€ˆÁ@¼(KÕÝ5hiT’íf‚'—*µºŸf°çâÎÊJeå¾ø³û›O¿ŠÒM”™È6÷»M$Dlr‘EoîëÍÏÞÛ"öÔ ¹¼qëG^À°õã8ñâ Œ²í¯÷ß|úU.øˆ" â$Þ„Ì#…ÏÂ0ôÞ~¿…÷Ͼýò»û;üìæËû›ßo"  7ÑüzDa¾©Ú›Ÿ 75\}³ ƒ¸,6ODØnâ,@Íæîæ_7Ÿ¡¢ü@¬(‚$ÎYß7 z¡°H‚2Ì6~”e”wÇ­RªJÿƉ2¨iìÝ̨ÚÏùÐOãqÙmä¹W«ðQŠ/dczFù~Uüø…˜þü:àD: :ÊÑü¬S>(9:%ÿÔ褩/YÔ£Q|ù¤ÇƒžÑfÔ•ýºï˜z¯ÕÏÜf`£Á¼Ì)³ž"`òA!„"ŽRƒ¢ª±T IuW5S­»=%S5ð‰FññÐïì]Ó0@À›ÇmšˆZ>4îé‡-øúİÑ(†~ ÓðØH0(qéGQP¦W%ûý{26nöú“áÊwU?uøÄ,£`ë'IâÝ)åâˆ8ÝZOt…¤ÖÚ2Òí±Ñh<<à'çWmþÞK™Ú<þßÙ’•6[¶Er.ýž¯Ùí'¹G•²ÂÛ[§Á}fýÔÔ ?0_>¨}^£ØÆL+2Oý> Ó<‡Wl7¦{fÿ‘ﯹd)CäEEŸ‡¾Ãô#°y |îdO¸í£¦ÔÈBÏáŒjT5’‘ëbáZíäÔŒ·ü¼«ž!Úì·»~` êÛ#몀ºoïÎY›x=Dç`X·H25rìóâ|cØ9±€‡?ìõ<¾±…<^VÒ0 ÂR¸BT+aáçYW•é­òÔõä™SËԟ߉,  Yážy.ADݽM,>Éã@„Åÿ–,AEŽfÕDQ]šÝU‘û£¥ TO_š&+‚4Ëo ïd«Ö¬“ÄAv™4?F”(¹¡RÁ…ƒî¸«x™6€¨ÐŠÓc'Öå{h‹!ñ:ÈŽq}çPý‘1âjÓ0žšVAšÝ2ù0‰¥Z OÒÔóœŠgœ¶i‚_ÌòEÀ_*ˆ…îKþÐ&~JöüÌ%{¸(=ÙÕŒ2ŠRkIe³pMt›~¹§wüëû®¥Y¼áß®˜Œª±*$Ù\V¨:¥j.¹ËV€ ^wµj.ÔP©RÍ5mß5§ ‰m)fgBæ€î¯è²ã +õ²þU× QfÞf«D;,Öò ²¤VЇÊúOÙ»Þþ,ÂùW5`¼,‹1$Gô=¥±ç"´W ÃóIֵƪ+›5.g{ +Ôô“ :Bä%iiÇÔJ/$ÅÈ} ô“’ÔTÂm³Áf}î6 ~!bï]Ç·N6>±‰ý_Ú ôˆ÷DRÕïMÅ"Џ¤"Q$áy´Är›ÁîÏg"‚_÷Ð%ÏU–±kžÐ+ÎŒZt+N+!6«/ŠÒ©_ó‰Ò Fw¿‘ ö¬;O F¼Û1b2h-œÆhÚ*C;Håµëån¹}+™¹õÝ-2 „6–yo­SÎcBB¾¡DpË) é§¡²£ö\/àÀµ€¾ÝO¨P–zïàÓÝ|‰9}L%ŒÈé“¡D –Ëû¼)Žq‹bü†LΚ­(aßçšâDËUÎ~;(ÖÁÆ¡ÑÎÞY>v> ›Î/3®•ÔF&vO(n0‹s._sò³‚0^Íi§É":ðDk´Ò +€„q‹/]0A> RŽF .'4o#í<ÙaÝW|ÑôÆP,Ð øGÒguÊ~â–Š³ÒJýrCö`ÍÀ~DËMCç,Ü[õ4°ºËí®á;õ¬ª Óÿå“4Wb¿VG¨ô+cDDIîÆ蚪1«SD˜­Ögï͉Âín‚‡á‰æC—!viç…iæmø\+u\Æšpc7³æ(¸å§DÂÂaiœ®ËÞèhÍaôFbÛ@…Ýœe3ª°Ã`f†K ›)æVc0i‹Üû‚[¾q^p¢ Áí@ö|ÑX&~p ]Ð*$¦•ë%‡3hi[´ür‡‰‰o +¥'¥’Ñ‹‰Òî–Ç«÷ oë-Ù°Á ½ßܳ<†‰ç?ÝZÏ?ˆ¢FOàœé¢ íôÕAÚÊg_ƒÄ½à´¬edbÖEH_Æj–¹¸ŒÕï!÷PÁöêƒÇ%l­™¸Šc¤à)W}ùl·œ–oH:®5xÏ"Ð †uÂ;>)BFÙ! Ï…*¡ež3c-:Ñ55„b‹;OÞX¢9Ø„ ¶È‹Å-#¤aĹp¡ÁÎà ë+‘¥;WO8œC¦¡@x:óãþ-–¿ÕÑK”yí´HîÒõj*cSçúÕ•ëË LËËUÐù>ÝœŒ†Ó뺄àÂñˆx e:ÌíÓf\Éœ2~œË™‘'g]ä2 HC™c^°fÂEE™Kbâ‰>Èní¿øÜåìh88GDZK`ØõqC·E.öú³³qUvÕãgOgÖ®A-þWº·ë­‡rí ÿçö…6®ü_©È$ñˆ›mo dCFiäQ²#ƒ9s‹ ÷ß¿á‡×ú endstream endobj 234 0 obj << /Length 1943 /Filter /FlateDecode >> stream xÚ­ÙrÛ6ðÝ_¡ñ•”,ïã©“ÃiÓ¦NËÉCÛéÀ",cÊCHÙþûîb—4iÓ{¦/°ÜÅÞôzsôã» Y^‘†éjs¹ ÂЋWY˜zy­6åêOçË:©U%ÖÓ­ÝÀia£×nÅNäAºþ{óëï"rO˜§^G+ŸîH€Ì÷}çÕçu˜;?Ÿÿ~rº9C²£“ÍÑ·£ðüU0r¼ÀÏVÛúèÏ¿ýU Ÿ~]ù^Tä«k‹X¯¢4óBØU«³£?Ž^£añ@4Ͻ8ÊH×í´ØJ×tºßv†džéÆ^á§+7H¼$dª“F\Tt±‘^5;>´´š«Uºfèã6¢æ]{Ië^lñ_ü‘%[Yz-ÀsáôjÞ‹¦|œPh-ÖaæÜ¢`7¼"IHæ¿ü(–Uià¢l®HîŠÓä í.™cT½«À’ŽÛ¶F6ªANˆwÇ=sØEo¼µ›Ç‘ó¶Çx|yKë$xó–nDa& .[]‹nIêmÛ€9„jüãFYò*ÞÕá·tÐÒôUG{ °«Q»F!·­ +*F6{5àÈÅ«1x«jÉlÈê°©„ÞÉê#–®$ÃÓ,Ý1š Ï/Šy öM)µÙ¶Z>3 Ã"´Ò€6ñŒ†+À :3µ2Œ~ö&„Nh» œkÕ]ã!w"kã(pNÑSºî F%„’‘#¿Fàw³d¡Ñ¸Qä4mG¥¢í»}ß°ì5eì9­m;g’éDeZ"tÝ­õàÁf€»©Ÿnûs.SѬNxéX¤B/¸PÂìž;Î=ú¾±aƒ:\±Ô;u°qÖÐq¯å^ƒ øVÓj›[J3û¡­ž?}£ÛªƒôÍ:ç.è”AéËóA)þ¤pÚýRÁsãÌKòp®ÛgðœMÄw)KY¢gŠÔ9Ûƒ¸ ÚÖf™Õ< XsÀ­Å²Zõ5£!ú‰¢6àƒ­ˆ°Vd˜vOGÕo;(€†Î¸Èã.÷Ìw-Ň^¥×~ûðñã§÷§ï7ôézm«icð¹^0]m`–¼reÅàH½NÖ²ésƒŸE¸Á&n‰­ò™üÁ ~pÏ Ḣ¹àƒu¬,›­౎o´u2^Ðqê,8^¶z`¼\Χø˜ -­ƒ÷ìaÙ_±ÃUÅNñsº«7²tµÜÉ›ý‚ßò|0úMcòHü¹CŸû.ɽ4|ÌwEqç»4^ô `+CC+µ÷¨öÐ0±{“ ‘ª6B_0¥íV°ù‰î§”Au9Þ‹5¦‚[mɶvBYp´gÛñ¯¨¶¥Àº€Ý™~Í0œk^ꜟžŸ¼eä©cÜ8A^ hÖQKëñ‹žœñâØ¢†]‡maA*ÕMã(v޹‘(ƒ‘Ëð(û³ââË›ðz ȳn¸/q57s¨¡‰.†ÌRͶêKÛ÷Œ‚]OUˆC«Þ«ÊN^pâé¨]2Ñݜ޵šSê/?ñÏT 0=ÏCD]ÑÑýâj@‡ÇóÐuw²“V†ÃÓí{Xj¼‘—æÁf4G y¿^&÷2L ; 6“;ìY^q‰Ñ:±µN»#x¥.´Ðv¶±Æ œWÍÐfàsMõ«ì)¸b âCŽŒ>¶(àuA’áL¸è6H¨¶¢`Á¹ fp,ŘrxP0ó<«†æB3V }·Â  ÃJ‹›J†I—ï°ªd ÊXZì0æ¨ SÃ(³µ˜F¿Žáà;ƒÙ^ ¥«ÅGŠY ]rÇÝê–êÄ}Ës Ú¹çéƒóËVnº$(ŠDÞt ÇË¥ú Û< ñX0Ò£,BßžÍbÞÒÄó!Àçä¶i)Æj¶ ¶QbLˆS˜Jƒ19^Q»¨µ}kÝtƒLát܈¼ÐÏ¿/SzL²Œƒ½ã!k°¼­ç¬Ñÿ+kù¡vŠBŸ‚êA(ä©—'áý>~Ø«ç>ßqÚ0¼±ƒæ§÷­ ‡m¥šÇw‰Ø Ì>Â|.ëXeeùHâm÷<ã<ù5˜³"_×RøÆzî#0·T°) ?Pb8È‹ñEhÅ´›ôÉ´ ôÓߣ'Ãs² ‚z)ÎËBJ2s.éÉxAÿYØ}Is¿6O¾õC$Pá7«­E䃱 ŒØG<ÈãVjŠ…ï†BwTâx¸ýu–ü"6íòä3¥U7”óù°iá <¬¯¶o$Îûß?|~wòfsöæ—§wEë|©u«Ý…CLÂ!ajºàÙ»Tg‚ÜËâ{ò†ª õ|òÇwŠ8H'jÚ!´¤Ï% 0ð´‡qî°'ûR‘ô3lœs‹ÄÙØ¿m,!¯;ÙHRôÁÊ1Í&@ 1ï[m™#Wút©Ûš€ÕB R²ÂQÕ¤U«‡vI^•îµ*ù*íDZÀç' å¨÷•\¨†÷Du¿’¿N?b9> stream xÚXÛrã8}ÏW¸úI®jk$Q7×>9¶ºã)GñÚN2]3S[ŠÅĪ•¥Œ$·ÿ~‚¢.V'éy‰I„@8<Ìõîê—/¦3šêS×rG»ç‘iYº=ò,W÷§l´‹G¿kcŸi¼HÒhljÕxbj9 Šñ„1[cúÔtÇî~ýå 3Z~,ßÕ™ÍFùp`™aÚl3¶|íëýmì*Ø]ýue‚12Õ×™nÞh¼úýOcƒêב¡³©?: Ã㈹žnÁ(m¯þ}uÛ°¦Ûp}_·™G!LŸOÕ©à-k™;†nÂH{äe½p²ëdgb9ºe&¦£3‹Œ7QÁÓïã‰íZÆyÌ!7±>žxS[Ûž^_ pZ{ª²ÿfùØò´sF‚&±U^hŸ<ÃU%ùø=£0*²${!Se‰aBäÓÔ§ŽCA“ê€çnSí%ù=€s!¯÷(tû|<¸bqÛ®¡íIIfô ±—<–s’Diš£Ã3‰… \Ðô\$UEßš¶¢y-¢—cÔ Ù¥ŸÅF]G‹ðÇÖ )¼ áߘ4^”Iž‘ &SH ÝN ˆ0<4)N NY\û‘žóTJR"<ÿkùÃ`6V0J;„ù),~Ë’Å/ “4¥‘¨tY†EK÷‘(€ï4I*‡ÿ`îP'ßW²ëO$É:GÁ´R€ë©Øc5|¦T':N06Ûi,;{«8›JÕy1í‰ò@“×B†Êã÷ÏÍín“YPž—ç¢Ö5àØ‹g bÐ@¤J”8Î>¡ÕcšÔûÂD$ØxDž©Àî3n„AæãžÏ²’gaj)¬ã´¬•¦R/«”ôkhü¯œ’ƒÈcjƒížÊV{(„ <}‚¤þ@Rf«±išÚ#Íïn¯ï6‹`CFÊæz»]#ÞÏ„Q@®P‹Ç4™Ï¶Á2„µëU° †bè˜Þ¡“‡`³š­ýÖ“Á¶æ˜˜ ¶Á#—0ÜÝô ç·ëù]¸Ý½ýý»Õ]¸^Ýoa±c6ò \¬f×Áª‹}/aKËùr׳^-w°`9 ¥|èJ¨mט™0 æ»àv½ûUìû§5î%¼]n·ËðkO·ýBBàOì¤jhoµù}¸Ø,ˆ‰ÓÆË}¸]~ ƒÅ…ø~{!|\.v7Ÿ@hÚkz*I};TWI)´<(f€Sq™à v+Ë;åºòÓtÙ (‚(h`eUäÙ ’” R‹õwüR~¢É>åc',‹Weá#‘ƒÖ­…JøŠ 8qA4¬QF£SIà*„uXùkËç¡“N0Ù’p'e"z”H¨’áƒD´Ø<‰ ˆÓø iÏd8 !ô/«É>*yIJdøÛÞ®á{.;¦…ÏE~”ß=$Et“?x¦¨‡Wß©$5 è"¯€òðøsh1¢9JÍÓ©jf‡Yòÿ%UŸ%GP‚åáßM$èq!¯OŽ<«Uã8´Ëà 졸¤i"Õeš¹…i†zu  —„w;…²L X´€eF‡¯ÝW´U \ЬihâS“uIüIŽÒ —IË\:Q+TÁè:nÇ· Í™‰ãuAªåùìÈj˜ÂB®ä‘IPÿIì;#îÁ ½löÁ§8¸UOq A†8S±jz®´^½R&z ü³í|”wÂ…1-"²´sªzÅ »qÒ©kˆW£ØžH’£¼AqœÕ(Žc…â8!ÇŠ¦0~ˆâu± —$v±íÉ.FA„åP@bE^HYw#Ô¢Ïqº PA¿¬EÈ›«À–7?ÚIâ]ŸÞ Ôþ’×øY'ó-b®lzô|Èd(ˆ7¨zÇõo?Ô<.{,½Ñ¾ËÕÓc¿tÔâí—Ê{¿T6~áz¶pC*Š>àjÌVó‡áÏ4ô{@I|ûŸ6ì‡X·as©asºÿùrÛÅŽSÕÀhÚÃ§Ý ¶c©ÿ»¹Zý;ÄŠPNÿ…skV¤žÍ1Ûbú+´ûÖfªz„jȠçʤfPL1¨÷˲Kš»ø,0¤ÎÓU½ãØ@HÚôþgÕ³±¾jˆPL‡éžiC=Muß÷ɧeÔÿ¼þ?ãüñÎ endstream endobj 243 0 obj << /Length 2121 /Filter /FlateDecode >> stream xÚ¥X[ã¶~Ÿ_á·•±Bê®ûЛb4@²“vŠlhlÚ&"KQŠwö×çÜ(KÍfмHä!yxx®ùõÝÍWßètU†ee«»ýJGQ˜¬ò( ‹2^ÝíV?ÿYq`:[WkôëZhtëM'A–:[ÿ|÷íWßÄjÂ'*²0Nâ•b),SJÿøaÁ¿~ü÷»ïî>ಛww7¿Ýh˜§VzÜ=µÊWÛÓÍO?«Õ†¾]©0.‹Õ™&žVq–‡´êÕ‡›ïo¾ÆcDå³cdE&qÎ"l6Ÿ6•söЀäp"…Û‹†eQºªTí̾êšóÅÙò⡱¿ †58³D”„¥Ê`q– ¯ýgÛ úú®­¬.ã ?lD`—(Î8Ún\_õ†Ç_§YPÕƒñÓ«žç[aЙǺښSÏGÓ0½j˜Â¢ž€ üemßòœû9+ÓlÆë°LE[Ûv`©Mgváz“ªh¢„·¨¼[`r˜4 D…BÞò©ÇézÜ-ëš'ß ¤Jñ pz™Ì#Vf<¬7pCÆ‚î¾í–ä}„Y¸†OU³5 rRS‘®×¹òQ.íåÒ"—åRŽÎ“‚jwL±ã×r •ñ|?½¬ÖgZ)sÙ÷B`[eÆÝ.ÀöÊÄnyИª«Ÿd½ÐÄ¥a–§(Yÿ0ÈÀ©í ÕöW’Â3ñ{~TqBgZgœégçxx¸CóNøßö–Åý£=¹U·»åæÙÒI“˜véÈJy2ÕšÖÕìmUCò’NÅ¿=æ´¡Ùúôf¡Ñ6<&ùŽÚ;‹>¾}² nû˜Œ# ¾”‚ï–û¢ú˜œ·Åž¥ßO´'ûøW½¥½ÚîÇÙÌà^¦“‚¡?*Y‚©)*… •…—Ä>ŠÈNÄYs|Üz>ÂÐU{ŽHø5DäÍmsxqÿ$°r’mKAE GI.‰í=œ4ÊT08â‡Íiž¤!2ç-†pžCi±>Ee ÚzÉ#ª“,ò:jµ£ïR`TÐË3lÍ%ŽBF3p3ïÚÞ„ ø!ŽBhÀî$÷ÀÖ>ÀZkkh ‡”G Èœ_ I`Eà÷€ÇÆÜi„ÏùhG÷FVT  a>Ï­í=3bÖB~ɧо'ÕmDЙ)q( T~¡í ˜¥ ¶$Ä òæþ–ïÛÛªæ9#rܧä |¶5«Îò« òapÊiJTÅÝ¡©!–¹™ÊÊV/Ô³;Ü%¡¢ÁQœÀŒ-ÆzBÀ(þ(2Î뇬A‘‘Õl´ žNø1æCê±­9-c‡ &Ÿv²¼“‰[®sX€(k0ÑBÖ8ÛþÈî89ç’WnFÀz•íh†/¡îÙ,‚¯™8ùeðý%H­—0u’iö¹+‡ÔÄ ¦Æñ ¦¦Y”ïq³ƒð:|"åÿ"¶ý,ËÆØbÃL9)66šv1¿áÏÖI¢¸ðÞ-U׉ÖÞªÛë%n2âkÞ á w&]‰~A$qðÙt퟉0Vò8Í–1v%^]û1’,‚fНDÂdš¡h‡/a7:Hê!Q6»9!½eòà„0)î@FÓ7;²äT¨1¬A>Ÿ}Óà ÐÖñ:€àWŒ­R„T©ùdlm{Á4HÆŠµ™× rÈ’k@F ! >±ëÇ Xù'¦ò—³¢äÛB>â"ºŒ q}m’eRmKÖÐÔ¨°†}./žyT. çðãoÁ|—׉žÐK&8½÷ÅÀ[G¬ü±ž0AÒõÖAúJN@:w÷C'é6›Ú ?1¹#Œšz^W®"`Ùµ vDI ãlF'˜í8ÅØˆàè£Õ} ž¬sslþW DÆQt%àˆ#”ȧP"¡Džf¼dm Îjq.µ˜éàü¸Ä¡D0úþŠEza‘# ,ê,Pž—xTn7"´~®:埔øyéÛp-—K-¤ZžOkùÿ_™í«^Þ5>LCº¬ µ¿ ˆGm–àXü2A™É?Þ€ºåá†ÉΞ°;P9¦qþÌ)ÇA—ï@5ßòØwöp '–²”ç¢"ð§xV°Ïñ ~=Ü"œ‘¡¿ïð†-|SRé&B[ó–wyhÔ³—¾$Œ³Ì;çcë^Ðdœ…™Jü<¾¾ _¾êÈΙ½Œ^úÒ®iê¬ôÌsxõ¦„MS"²›“Mæ‚"ZŸt0xÉ££T…y_¿þH6À4 )ì ™É,É™„Ÿüþëi–œ¬ c=ªÜZÏ*¿ö`h¨©[ò¤smTé1]@òyŦ ö%Û†*µ§ß<¼êT‘ûIô‚ùœS”†Eš¿JùµèIð(ÒP—W f,´½Üñð!Ðß–$Qa {€Y!°#¯¢¾§J”µI£4xË?8µúû‚¬®My ŒÒ(,ä‰;ÒþIýÄ'Eì endstream endobj 248 0 obj << /Length 1864 /Filter /FlateDecode >> stream xÚXëÜ4ÿ~EtTj–^LçÉ¢TWhÅS½ÒJ€7ñe-²Éâ$w=øç™‡³k*ú)³ã™ñ<¶÷›ë³ÏžG©WŠ2‹3ïúÆ‹âX$^g¢(¥w]{¿ù¿® ékkZµŠüqD~„]R&¾e”­þ¸~ùÙsÙ‰£Pdaâ…l#µ0 ý«·Oøùû+Ô•þ³'O˜¸z{õìõõ‹Ÿ~DCgW×gŸE zÑÞ)¢0÷ªíÙo„^ K/½PȲðîHpëÉ,1P­÷êì—³o00–"Ž¥—…HdÎn©öNÝ« SÿëßÃ4ìt£k ±ÑÈM0ÌÈÆ?;XXp­Ó¡§^”Š¬È½ ŠD™¦lÒܰZ³¨È?¿ü’¿Ñãuø±¦¬fõ/êÑ%)Kº«³“ÅâJ¢q"²9//`Û$ʱô —~ìíðdá¯Wqáßóz­oÔÔŽneêLgF£Zó†©Y¦jûU*êý50SYÍDcn‘¯Ý†Š?·«4ƒâLN¨¿áï?Úö´Wî=³Æ¦ˆÃÓD¨5íÙ£mÞÀõèqKÄØÑÜ¢®ÞτĔé,¶> ‡û÷é~jkž‰®™?ZÓ4Ú ®Iã¬Pmò¸dko6¦Å ËÒ7£ûü%+H4¸!$¶­™·³ªM¥!ib¬3£fbè·Žªõ`šÎ™7ÊÙµº½gªïøûÖ%)9ŽPrÿ÷PF 9ŠQÊ}*CXÊ\È(9íB—Ó5OBÅß/L‹0+gk4“^ªLvŒ1‹8Ëü²RZ°šZe1JÜ &¾0VzdrÐOº«ô °›2ÿõ°÷+Þ®Úž¸wfÜpp#Y.O»î€”0.ÐI m‹T ÛîZS©QóÏqƒ…FjMåÕµ‚Ï­é-:“—þ‹‘×ï0’ÙŠj±ó‘ÒÝ0Ù½1å„—Jç¥aù%”€§Ù,9Ã\-çéR­‚¸ŒE¦§™ØõÃGÕL°ŒÃ‘E'r2(?ö£Kæ`S¹÷úõ¼Œb°†ÈùHú˜_È5Ë@E%술,¨.¨¹ƒµ&î$]Å@ªßg¹•꘩ ¯RWN¯‚õ=öØ›ìÂM{| WAǾ2#8@ÎV9¼E¦kþÑihÜAÙ{§ÚówŽœ~ÁCG‚ÖlgÛ¬{u•ÕjгŽ Åi‹s[–<>Æ\7Ù !ƒx‰¡h«0c8fàâ5g²Ì¢+9ºÂwJ ðoC¢…®ÆÑᤗä}w¶_·z;ð/N¢>p*l†ê¶¥‚ƒ+Œ®]ò¥?lh~”óÄWu ð½½Ø¸p„–!–¶iènOÁ½y:kY±‡ËÚØ¥yŒàtJO§à)f«FÇÒØÕ Ї¾ë©ß?XoÍ02Ey;Ò0z˜e•Ù‡ô¡ ¸ •¥Co£Ýò Ð?íT륦€¡HZÚ%s†@±‡ÖVáæˆteý Y`ÜX­YSÕ8EH" ëïö¶Ã”‘Oм`†ƒÑ•s8Ã|l˜-Kk7¬—h2Û›\ºIà‰,ý'÷|Ëá7ÊÐÙ‚ô0‚œ²µ©l? ¼²?ú†Gn¾uwî K²è €v:þ 7*å¤)ç¸öí³gKîVývƒ²6- 9l/ö’G½ôà°Jà°r×9Ü*at@.õ2ªÉZM3>2£6ü` u-ˆ xù=ÜqÎ^´ÅÙÄ£¤›¯‘À¥ íxÎ*ƒ-£Xüu¹XŠt„FmhÞÉEB¯RÎ10R±˜¤²¡À4Pÿ"ëfd€Iîà°,;ðq䮦¢&ß×àvN¸¶0ªmé&zGíù15îmç0S;Z«1KçY‚f?gZÍRøÖÀµúvâ›EäF®S[»Ð…+v–¢.OoâI´l™ú ,¥|P Ù„4Ý0jå@”`Ðn”Ð{ûÙƒ•#_fÄ,ð²(“,>Ì$y”‹ÑÉc®uüXÌòÓÇâÌ ñÒ)òÜaïjñÇtw’’fƒfÁÞ¸Pô;µÝÍlÃýÝs@°©Xz8„|“—±("7NÛ¿“ð‘6jx÷õÓ"œTõ² ™*œ b1½ú¾¸úé9“_¬¸å§b(’´xx²ÕS«Y$/oÊâ´Ý•öøùIä£Úð¶êž¦÷;MKkozÛÖ4Ä—NøÌøÆqNžÅ{¯Rç‹,øq~l&³ýî ê¨v»&å“ù\"½ó_û‰º\lΗ†ôô­¦™@x„ÓþÊüÖïœ{[eð‚pÏP¶©Pý‚ÿE z£ì§Ÿî—o/˜¬ŽØº»=ü7ð/í8¿ÎOžŒÚºþüs´ m½\}j›}À­/Û°ÁÈ¿\ºbÄ™pÀ^…ËyÏÿÂü“[¦¸ endstream endobj 253 0 obj << /Length 1490 /Filter /FlateDecode >> stream xÚ•WmoÛ6þî_¡e*¯‘¬wK): Í4ESg‰—´èŠB‘è˜$ze'ößwÇ£ü6có>$<÷Â{îN~;é ÎÝÐHì$ò"c25\ϳcèEvœøÆ$7¾˜·ýØ7YÍ‹´ïš²o¹¦¢î[¾˜¾¸QÿëäýàÜw6ôx®cGN`8¤#‚kŽã˜£O§—WFx×7Ï^½"bôitöÛäbüõF“Þ=n:†»òÇ·]ghdeïËWÇÈáè½áØ~K%X~4´=  ã¦÷kï-æ»› ;J\#Šc;ð‡:4ÑÖ?õ­Ð M)æD¼¡¥bK"Pæ5:Ê-×µ“0¤ËË/Éüî„ηôFð>’å''BžóŠ73<„?ÿHüÏ•Iëg¶ÀiÑI½¦³¿öYÌYÁ$[]Þë{âuie(aydi¨å"’#;ãm£ñ9et ¤%2,ßµ£îo¸ãG±)gš¸þr9"šW;‡ ¼e¦éG.‰˜ŠšˆE? Í´æ¢mˆ±ì{±™â¿gÅI êNs#Ó¢ Mwè MVaÑÊ» â€@,A|Ï»Ýó L³Æî[™èºë˜÷À›#˜|J¼gôH´´IkFDÝV¯`ã$5#•wp.g©¤Ã,-õi-Jâ=£Ïð:´C,‚ V§’T‚lóÜHVîsÓâ…‘™V´^_]"Ži§|€ÇÍy®Åh9*ÓG †ÑV¿êíÔÓÁ:/Ò ^ËìF¦®¡ŽN\¿Ž>ËÙ4m ©5¥r†Eîê ÷¡îЬ„D"†Rd9±ReéYÎÔ«àYCIgO â èPvír™º¹àµ¨J¢å1fðUåZÕL´E¾c{¦à·Ð„G·£ë‹§Ö>Ï'ãëo×(:cQO0jÐË$€*tóÀC…jF*kõ!A d×Ð “ëWj(œk,§ƒm0«‹IpH5Ö[‡•Nr”¯q»Kt@×­¤Î-¦´.gLÕœ­C~&Ê9'¿a·…câm‰S¦Q‹ò8TB=EWÖÀ³ñˆòÎÕ=‘6À¾öõ#õRÕÅHïł霋ê¥ìHÝsg¼! ó…kÛ($ª»­ã ]Èy#k~ßJŒHÍ‘ë>ìi.jm6A%ˆ§ñxòf€•3b°œ!Þz°èÔ –i3@л¦ª^°÷®N'ïÞ¼¸ÅdJ›@¢>DÁ¥,4‚ØSZÎðÌ>0‹µv кÃfƒÛÀTù°²ŒÁ¤½Ðr{Ò™oxù­Lyegóù¡‘ß©¸ +8.ôôŠˆ†iŽ‚¦âè¡§Ä„jW¹Þ¶UÎêñ#q.Eæ÷o9¯ˆË ¼g´Í$ †Ú­›çF7™ä¢Ú;èh´›i›vyÉY“Õ|Žw]êºÂQ²íš×µÀüñÈXÕµK“Žà€MN_Ìj–B9šÔBךUèÄÝ«'ù¿ÙÑ®jÀ©Á¼Ô€±¾ëõlÛ;bN×ߎv‰ð{$(ª¢CÐŽöòñœqYÑæØY¼ ÁaŽËjÔ¢Ä*<<©[¢ô<@VÁ«Çõ!ôb/Â"¨2}e©'ÒmÓYÒ³¥iž6Íþžƒ~Å¡©J ¨¨ŠâbÀU¡w†² ˆ’ì€ xÌðã üúŒ/‚3ù*£( Ö²æR›YW)£ óÕJûœ«±J{|ˆæxo Í&œ_ªïNÀ9|0lÔ¯vÊâæ3(¿Q£K Ïô-*M[ýÐÆ<üå’±ÓJOËj­=Xåc«± [ ÎÁ­@w‡ßÊ—µùÀ|`ºº»g¯y{¨+ïXQèqz'êb/p¬N}âlÌOåÿÕÒ‹©šùøkO> stream xÚWmoÛF þž_¡¹&±,Y¯NÚbiæ -šºK¼¬C[él"é\é×úßGOvì©C¿X<É#yÏ‘ô«ÙÑð ­±3ŽF‘5›[ÞhäV<Šœdì[³Ìúdßôßæ•ÈYß³UàÙˆª?ðýÀö±õ¿ÌÞ/|÷±$p‚0±\²ƒšëºöäãÙå‡wÔõí뿯g“ËsZL>NÎÿœ½™¾GcG“ÙÑ×#´]ËÛúä;žqôé‹ke°õÖrœXk-XX~;# rëúè£W?.J'ðcr슳<ß`„ÇàGØ›þ(¶eókÅaö]0Jl®¯ˆ!?»¾dh¯+¡D¹ >#Þ%»ï£H¹±¡$íeÒˆæ91ÔRÔĚˊXÔ–Ó„QbÏ–¼ÔŽÁa@î‰T˜)ˆvàyÎ8 )žø)›¸vŠrKV.8’x¶P´±Ú X£dÁ”Hu´PÕ”f¯’sÚQK^Óµâ«ú´?\Ê‹¬•ÓQk¥ãC§XÙåwZq¦8AѧÀLÆ6°a2x9М€—ñÜ l—/Ó 1MÒ=Ò¡}ÍIpþ«\'V™¨x ®uš%‘[…LÔªw²tè£ÄòÇ¢‚  x-ÉéÞÒ£èÒ£xéc¾ïıyz3Ê$¸Ñ~™ñÏÄAÌZâÊ„*Bfa‰hxÐ=¦ Šˆ¦&ã›ÜÔ˜h…I,ÎMÀ¾÷ÈÅ‘‹O^û™´~÷I@ì Íku‹à+·uÚy×Ù¾è#±ÇFS¦HîùóÉô‚È— î ñÙ Ý4¿‡wJš¡5`ß'Q®sÈžb¹ ]{8$Öy.Ó{"ñ"ð[ñ¯  § EÒwÁQ GÁrb°T‰†(êJ Ë×lc,ÿ¶s{%kž-øÖ/4‰qìˆ÷íÜñ…(Iü) w•³Ñq{¯yž7ÿ’Užõ(#$<‡ë¥YÁ›Ò' |Ï‚³lš4k‘½k0"x]?{¡uz[0«ÒIW«^íQ¦y“™\ôndƒ:•³ìuåS”æ(2_bèÍ×Õ´é±Éí’´<{ƪŃN²^ÿ£ÍkÐäú† ÏNNÐX*‹‚•ÙYµ¨ñ4¶3¾3èÙ§E;½MwÓ÷Ü" gn½wì¹Æœë„†òÍWU ßÁûÀ8dªzÖ¢tÕ)|xAŸ’¯‰@]íHôºCˆ¶&/é•ÁcC±ûz´^Šö‘¢ø/”H*;Ì…T¸‰F_F{©µbºÄ(òL®Ïoß_?Bõ÷®Ó3žsÅÿ?!ü›Ð†Ý] ƒ.|ïxÑÞ8¨ïƒ®êI] º=•l ®&g¿_NˆÆ÷¼·¹mñ@ßë–ÍVø'dScuŸáÏFsÆÔ!´eÈ¢nò°hõ©«J8>Æx«í<صóŽ¼Ý‰Žæ5¶_?²ß ëžkßoŽMǃ;'žbhÁô´ %õ"wüŸéXzü\bÁUÊ £7¯dA<3¿y6Nc3ƒÈÖ˜^Š.÷õ»Å$…5Zø^}¸DÓJû Îô¬ƒbôéf죥ÉlV:}ð…jœšV‡Ñi5´ÑŠoÇ<½Êøœ5¹2–˜Z¢G‘·ÍcÒÁPàÅv) ¼kìWÈbú¤ Lj˜Ü«Í8•ꎅÊîü@.ך¢’eA´:ÆÛŒ•™1µ”Mžœ½dfþÐI­›ÉÕ›wgƒ.ÏgÓ«Û+NñÂg5Øå Çbol¿ÖÃŒF6'“•NGHðÙ¼Â1Íu4×0!sžÑÆ> µ¢AlÒ;«‰­ƒC‚žNrt_‰œ»êo{Ïp0;üû$ÛLÏØð…)¿2s›A2- »¬ù «=ìoÅ“­8Ý´éDMÓc4æšçÝ51êŽ#Ú{'?9>1E˜›âÊîä7•8“寪%Mí]¶£Þ~ͪuÍ3½  Û!¼·n:«PÔVÌi²ALM§³C|=C%‡ë%²!ßÇÖÜpÍê!ß³õ æYw{ØðálöúÅÓÔ £Ì1C¨…'O‘­À c'vø÷–ƒ€,‚öïï¿~V \ endstream endobj 262 0 obj << /Length 1193 /Filter /FlateDecode >> stream xÚ¥Vms7þί¸I=­hzâÞïðŒ?`ÇŽI±ÆNšdÁ ¸ø^È0ðï«Õê Ø×©3ý¤Õjµ»Ú}ôH§£VçÂö.íN`Œf†í8Ô3B' Q×5F±ñ…ܵ#—ð2IYÛ&¢mÚ¤BÙ6]×#.íÚAûÛèCçµöý„õƒÐ°ÐG$·Y–ENϯÏ.¯z·ö¯ßƒ—üŠÃÍÇQÿªÿwbú7×à²u>jýhÙÒ‡eØO™¹Ô¶Bcšµ¾|³ŒX.}0,êv#c­ 3à BêH)5†­¿Z§ÿrÄ Š¨ç†˜ÞuÑv"²ÆTÖm'$år•£°+‚(JTz©XiEš‘r¬ ß°l™Ê:qª«cï¥àXP6CZÒ(Ôe~Üy÷Ÿ˜÷,…Z§0õˆ ²YMqQ†¤è÷àhf“ã{•:¦(\g=eµPdË$Õë‰xe¶ÓXg2ù>Ž“vÉ’›¶M»¾&{àú,ßõ8ÃñòÏv“1œnÜ (ûž(í@¤§Œ%9-P«ëÊc©xeÅzy å°dGó”Ö‰X 4ÜV‚ggg×…à(mB Y²Ú^ß”¼v,¡1)a‰áe² ¨x…ënqòØöÂÊ-ôñPÙ$æË¶ 0Íã$Ÿ£âƒ4±€‘Ä0z‹K*u–×"”o–E)°ªÃÏÃÑùÕ™ªö ú®{Ò3wDÑY/@ÍKÞI“ †˜RÖá›ô•¨šÒÛw>x>oÁºwûyü±7º<9ÒÇP«ˆÇGÚ@?º<ð ï_ÐíU2_è§œó˜k('SºÁ8q(¸u©õ_9ïäìÓ§ñÅ ÷~xb.Å¢ä,®wï—sþö­óàèe9÷ }çƒëò{È•â«íz*¨ïP§kæmîùÒ)¤ºOMW$t©#)·éЏ$ßQ§Ô½ ÎŸæJñ‹LÓ¹+àô«ò'/³»—œGæ\<¢¾ ,ã5Ÿ‹åJ «ž™AÓ@@‚çǯ<Û%OS]õû¢L㦚{ä~ìëAgÕ‘çøÍYäIµxm n9KÓš><Ï«¹ê·RžÊs2Aj‚—¨(¾Z® ¢¬´º´Š2`ÊÐàŠ=¨gRÚy)Ç%QàZ¬G±H*”f…°…ÝðPîå% m‹Œäë¤3\«‡J["¯6T¬’ú)‡ä-2 –ÏCA!q'G[R7ä¶E&éoªÊ¡JÕIªž¡B¶¼â¨’7cYQH'$C4z… @·QdžIi‰ï6²9,KØò©|Ù·Mä”äÏ '•(“ÉJ$E®©Ù‰ Û£®8ÐcéÀóäÿ,Üý­ì—« P« Üý­ºÎÓßêlšÂÐC—€õÏñ-ÙéJà´~Fd+3–O9¼H¾§¯»×}ñSòŸO¿~¥ÕóÆE•inLVUÉ> stream xÚ}YmsÛ6þî_¡ñL﨩©ðÔÝäCâÄ©{Žžtîz ,BÎédm÷×wß@Q6Ó/Öb,‹Ýgwé·7G¯ÎÂt¶\,³(›Ý¬ga-’Ye‹bÏnÊÙ/Þ—y{º5•š‡^7÷C¯¢ûqœxñbfó_o~|uc9y²H³|°Œ¶Aà½}yúÃÇ7ÿþ×ùå{㟫O7çÏÿûϺ9¿ºD‘GïoŽ~; AF0 ÍâEä³Õîè—_ƒY S?΂E¼,f´p7‹³|UÍ®~:zû+fE±HâœÕóýGßÔ¦3ªz½V.§‰·Só(÷žx`êU«•Õ<ê¶D¤^k쳚µp´Õ"à¶ßXfšZöµª”ë¦eÞýÜ 000vª^é;K=«Gg5àF~.–iÊ:«[Ú×ÌáÏïøG³%ˆø«~§kdwª3MͯÅgÂ"ieýÿ‚8U»pgDø¤|ÄGSã†(‹Ð r‚fÃŒƒ·¡!µUõF[d„ÞJÕ<£*Û0µ1NOÝ‘ô`j8ÝO¢Àû>Ó3ßn›¾*™®›ŽÅnéMÆrÝò‰Ÿ/Á‘üse|—³ ö-8(€3qjkSã !gÝ6;¦öþÞ5-(–¥wfa)Ï‹íDL~(†®¸A_uLámñÔ~#›Íî¾½ž?õÈî -:E¯]ã­—™×[/³Lñý’G]2t3–’Mö×ǹÑõyÍ­³!Ð;u'üÔS̲ k¥™µi9²™ôNv®U%Þˆ›î˜veì“p“Rœ²áßêôÔvËT]ºu¦v{å¼,øŽ‰çAÅܱÉsO;ëNùþ[ý„s –Døêª;2‰9ø‘‡‡ä‡  ‰BT ‡CäÀ­JžÙ¹Ø©x Qè4®KËÌ]c»ê‰7`ü"Uê[æž~ÿý”éWÍîÞTZ"}°–5ˆ©À{iÈ=ýôùïVÌ®VhðóCË8Ó £ÀþR¯ø8X%rÅ©W™ÛWìÒréÅîŽ7 «’½U–—7÷Ù™?¥pªë[zW¤Ø#:„‘w³5–¹FöžÑ–­ˆ½+j<«›2Ý>ʼZ? ‘S(Ù¦Q)ü5/zæ0–¹ba€öޝ:ÞÍÙZa¹SÛž]7ᵸžH(KYÏV¿P“À ˜®E*.%ãg‰1t)›ð€ˆµÛÐjaý>OáìÖ¨ÛJ“)–9fäžêëÙ< Cï͵ãQ"½¯°€ùë‹+¼×ÏSºN9Ü=ÍAtKòè€È3¹þ)b˜âÃ53À“_ѱ8yñŽf ™eƒ‘I`ÖýŠ,—/Ò¿3;ŠæÊÔшHø{¯¬À‰!m2·4­^q´ŽvÉÚh‘8jÚá˜;Ö‹’LÆ@c"È„Kïÿ½•ì±vð'2¸Ô‰€©s<ì$Øë!ãKp»«ÓUiž ;¢!bÿÂ.UOQ€ß Ö-Š\*DXRÒ(eW/yÒŽý«ˆÙþºn|Û©ÕñÔ­è´öØMóï# 7øúõÍÅÅB±Eœ?¥Ç£"6'žX]*N€;Æa1”ä)ªA_DèºiÕNV``Jµš×Þ«VXT¼HörÉ‹ºíÉdrw”S8ä³2–Iý¨W='1$q)zNΜȈJ£g!fˆPZ÷Ò.È¡Ž˜¹ë阱!ツ•E&oÝ î«žF9V¾¨TÀOø¶Æ•¸C.ȃ¦&ÛÕ‚½´¡m’¸×p¶CgECÐHñOÕPµV0< ÕüE¶Ä%1”¢|“äYV"N Æ,–äãÌÙÛ.†WG»ky/ܱO­ª*>â¥`ƘR˜ë 6d;nù¶ÂÓtUõ¥lÉà½ËäE4,å¨h‰íê:v šf°ÍÃÜGÞÙ\°§%·’_Ã+\§ø„¶ ÄkÄc\ª0ò)£Qlt¤Ž#:³:¦ÓSïR«ç¿€°j'”(À*¼‘-y°UåóCvT„s3§²¿ë´´¸ûlÀ*ÙH?³4^7d¾¿¶hæ®5dS_UFYx*º_’{?˜ÍÖràSÑÖE3´A”ô3‚ØøÉ`Ô­Â`««{´xV@ÚñÚÍjÅ“û ×]H”P°„Ì@Q…ý¸ÒÖí²úº$Õ¼Šù—R Èß#S=ÝÓ”¦Çì”T”â ¥K€>k6Ô ¦þÞT`ÿ¬Á²*‚5FjŽrP©vCŠìEðD«9<›¶cÆáÃãE0¡lo)´0+‚­íñdAü¹]êîq*΃as&µ@œ ñ϶‹œÁÄõ“íôî”âvmພ™FxäCð8$8yÊ´ÔBªâvng¨ صóˆÛ7[éö­p…`±¡,ºL©w'ÂöÍ8-ï:×5šºâf ë¾^¹Ô»L]bªlå½'KÞQ3jpX}Š3»ÀÜ2ÑÌQ‰Ât cqÙE\ºr¸ÔÀ ¹*…=NOy5ô"¡3íÖ÷ëɎų=ÓŒ° ¡ÍЀ;X’à eïá€âˆ˜ô=iªÙn›ÞUtâôüªÝÐ ò0Ö”ºc”‡780Ûgbî¥l\»gùŠ=þU]5Ö~£q<_s-' ¥Fh„äF6Tµüy{¿Â‘5ŒáÕP¤$\ç¢åÖÔ›JD±¿À}5ÖÖ—hרÎð÷\¹Öº¼Uò±bÂÐìŸØ_b€‡"™Ô@ÜJsïgŽg8žÿ„W9Ò_CMÉÁí«vE~VèÚµ[!VóS`­|«n ÄÅΓµ&4{2ºrŸBê¦Ûº‡Óï$¿Ã6“_ú\ùÙ’ •f–9ü)Ûß¡8•a' ½;üM͇Õr].°ª¸ÁåWR Æy|à‚¨’˜Ë˜Ò®â‚&?ò­ Mˆ>P$¬È¡Æœ \u …ÎŒËÞ}:gÆPcø¶åXÂÑœ®±3fš•¿â}²ˆRyl”Ç=òŽ}ì»æøð@ùl‹nÂÇ.4Ú£NíŽÊ†Ä»l:©F]p°OßÀ½ûÀûãKÅ _Áò᱇P.™!ÁJßRÝ·AFË—Ù`˜ß=Ì‹EA¿ }w±QæþMó'„uò endstream endobj 270 0 obj << /Length 1564 /Filter /FlateDecode >> stream xÚX_oÛ6ϧú2I”%{okÚ)Z [²C[²DÛ\$Q©¤YÑï¾;iËŽ›f}±ŽÔñþþîŽò³«“ÓóxêÍÃy–dÞÕÊ‹“$L½<ÉÂÙœyW•÷Á7™1Ÿ÷¢.&±¯'AìK úIÀXê³pg“OW¯NÏY4’ÃfIêE$cÇ¢(òÏ/^¿¸Dö“W'ŸObxyñV+ ã(÷ÊæäçȫàÕ+/ Ù|æÝÆÆcY&@ÕÞåÉ'Ͼc~6›…)ËIõßh¾ÀÜ$ò›b’Ìü;\ÄþЖ—7øÃ{Ú\ ½ÞÐ"òõ€î¶üm×ô¾›À-•KQ -¸"ÖåHp×ËKkA‡@ΆÓKXK+Œ@‘'AšFþ_ŠÓ)Ç`ÀÀé ŽÃùtJnÕ…–ý/¨ŽSɃr~©_ñEŒŠ[byyv¶å^Ûg·F•Y:Šl—…=b³¹ßShÁ… °È­^»¶ûkØ_3[ƒ³é4õçDÜ‚,C2_´´e¢…ÄÙÓ§D˜å~…VXæ-“¥„²²;à ÆÃ¯gQæÿ9´ö ÙX)d§9%Ý ÚYÐËa½9怋0ñ_àqppÄmE„ÐøïD©¦…æ£ÅÊ1!öÛM¡‰Ú›Alˆ8Q-žü]Äð^ÑÙ:1¢Ä×Z6RY3r‘Ù\T2fCˆ†ËzI$³û!µÒ,öÞ€%a™_É–ü’éÔïj^ šq»æš£‰bÐ Ò×­)Å[Ëâr”°)vÌzì+ƒBŒ¡VH!xãØ¿°òŵI• ­\4˜óÎîKE”´ÆnÆj)øÔÜbß)fù JÙtEÏM1—x °Áä¦À¦ɲ,knIO5¬×ܤ_WtÙ5E\4€­]wj¸I¿V!5ÛdæÅiÈÒ,Á¶Æ¥)tì|×mãq·=è’ÀÎX˜ç)±ÿ^ׇ%À|ªj[QEoK¬«‹’Wß)×qU¢ç%ÄîŽxÛ©¢ÊKœ¬[è)Ò‚7 ãXèe‡q²7 žO${šùÿ,àÔ æ=[©G(FÝY«~Êñ#&^ÙóB›®ÏØ®„V²® J¶f(‚°ÜÖ•hι˜!½Ùov Æ£œ%NZ“¸Yn'ó×®ç+ñå[Ø žkøa1 ”ÓSE2õß×¶aNPmZxY§×+Q; £ˆ¢Z˜±u$îNÛ¢4^Jq6 b6OØX©•*Ž+£Tm(ƒHÀ‡1UAkpÌõs3±lòƒ²<(Ã@•ðÆNnñ",ŠZÙ*´ùüß17QèQq2ç[ÿ¯dGDÍo ßÒ̱mm¸ÁféÃâ6¼@Ýï’õ•#SQn74O¬†š q¿4–Oót«éµ¼å½Ó…,[}¢Õ¼7éž3êç-W¸!ר›êÈàxc€RTŽykÆc`saë¯ä½.\1bCiÄ¿¶ÛÅÝ•LíÁ†ma“þ,l 4ÿy'Lªã(I¶xþöÂúÜt²×DD#Á¿tÒ‹ÔÞ… „zc÷ƒ‰ ¥-Þ%*Þ«XÚ'Z ÝN7Þk´i‡ò³cò/ky\ÍÓt¶‡u?`cS>‰vÕóσIk•ÂÅK£™?öçò®QGô½¬åÒaUÝ5KiiMØAøqâ1IQ:*o#}„Fu‡‹£Z6Ò*ºêa¦’#{yy_ÜÜkžkÞòÞ•¶k°£i ¸@£> stream xÚ¥XÛRÛH}ç+T¼D®¬„.#ÉÚ} )»±“J*IQcilÏ"[Ž.*•ßîé‘-9b!»Ošk_¦ÏénûdzptîFlǡӹázžÍŒÈ íaìÓÔød¾ }S2ã׬–kæ0(–ï3Ó·c7|™¾9:÷–/Œm×3á:pÍqóìêýÅÛ74¯¯.Ï®¦xñàlzðõÀ…£Žánõû¶ëDF²:øôÅ1RØzc8¶;upeøad£ü̘üup‚ŽønÛæÛ¾áph3?";¾o 1—÷?nnÐo¢8—™(픃[‘φæÑÑÀ ¼ÀœÊ•À#eÅW›’ÖæyAƒòVn,™Šu%ž¡`‡åºv]=ßW(D–É;Å`q´UqÉoR±QÊÖ 2‘B«ûìŽuyy _÷¹:rð#f-?NŬ^,äzAÓEÁ7Kí zÞÒd¥b†‚êÅ/(¬ –cÏLc¼=Û©Ù å9)Ðe# Áãy%à|³¨×k%Ñw @ä·/2Åo´]- F/_Ò ÉW0B_/Qû2¯3¸™’M‘,€dZ'bOÈ<ϲáz*×0o£¬ÏØæ@ [?—k@‹Š{‘ÔŸeb÷4wGhšeÁ-òbQ¯dOŃÀ|<Û®ãy[•c9+xñ@“|®åfÚŠ÷@j¼šñJ¤úÌìo‘TeG]øhøó}L_¬Uœ\s%R Rztî š¶ÏB¯mÆ áD­lán³…ï¶²ˆ[ï6z=tÝŸÞŒ/NÞ¿Ä¡ùñæOübà3„ûuÚ*/iƒÓ'á z¼T‘ÄÌÿøMeYrV£8Z©uE“*׋DŽž—–æE®^±ÒçZaÖ[Eàe(,T=Qb•ÝÔ@g79s!Ç`­F;qOÜCñÊ03z!3›à4~ ’iY…à)ݰ¬»BVâP]iEæa’ xŒÓRÚ}Æ^Ì1à̬KÊÎSï”$˜˜Á(YÑâên€§iF1ÁéLs&„ ’ •± ¡ ò˜Ùq(Ráµ\o'[Gÿ€…ÈŪÇòm¶O©$˜uU”8E˜*nxªe^êó:êå³1;ù8™ž]Žž×S 7ÁÔ ±ÀŸw%ÒŒ1ðp­0 #9§¯–|sq5¿;=ÓÇŠî&¤ÆSȧt±ì{Šu®¢ÂSU˜D@+Å5¤Â‰$©T@‡DŸhKÅwP<ß$»š&9±œK¡ xûx+çD‚)3|4ãQ{™»Ïåmdt̃ò5B7 h\\Ñ.§…TÌyiy+Yà™=oÓæ¦J©8qgQZ¾Jh½9:p4ÌTJ»»Êu§¢ˆÂËN“bâÿU¸Ý@9Tyò?à.ˆ;? 4î0\rN+ûÐÂ5*:ÁÏ`rÌI7Lú v<:ãZ½<<Ñëb]á*Ž ³Öæa±Ü(-Óé³[©,’º«Íw{cËJ×>Ýv¶wS^.›š¹Ûê17“3ë»mÛÐzдø€S²GI¬¢ ç3ä‰>Åéób…M.¼Û š£füR9€ÁÖIÒÔaƒþ I¬´BHzL…©öÙý‡nÃUŠÌ8Èé+)MÖŠf~óH0€Ì¨#­…€† H¯µ4¢ëRì]ÜqÐïp°Ïè=ÊQš®¢KGìéÕ/:!ÕobôS$ŒËKÊþÿ‹‡£nÎǪiy5y{ãXÒTÒÓÐö¾Ð›•ê7}øÀ•c°Tˆ¯µ¤&ÍÓуmí?M6¼,»\óÕhD›wK±¦¥Y-³³÷¿ÕÑåàÅV¹R“Š ±È˜9Á·W'è´gû¶CÃo ì›’+uéhæô=´6Õû—ç£t£Ñ”Ê'âà¶Ú›€5T â}ü•´O°Ný Õ?l)¤.~í³¥zŽÄ^Òt þ(âLwô˜´œhkeV¼ØØÐ›0[µ0Œ©†ÛZzM-„‘®…!ÕBøìx“N- {k!Þ¬©mæÁ‚fŒöK_Í¿RõOþ¦3ƒ­þ©SWb÷û^;ço¡#ýk‡úX7ðíÈe†ŒŽýÔ6Mý¡ endstream endobj 278 0 obj << /Length 1932 /Filter /FlateDecode >> stream xÚXYsÛ6~÷¯Ð¸¡šŠ&HˆGÒvÆvœÄ©¥q'“f<Y¨y(<¬øßw Д¬6NŸ¸X,‹Ýoéhºw𖉛„~8˜.Ì÷]>ˆüГ`0MŸëa8²R™2§Ž˜SQ GAÀÀMX8ü2ýpð6ðzzü p½8x¤ƒ18çyžs|yqqr<=½x‡çgzIßã—/QËÞÉtïëƒcÞ€uÆ.ó¢Á<ßûüŤ°õaà¹AÖZ0aäú@eƒÉÞ{Gø*?yòª0Ž]DdÑäÓdzr~|svzôæôŠ^°á Ÿ»‰Flì&œÎœ.Àؘ9µl~*ñz5ù±#çê//à²Æ}Ïi–’SUÉySVÄŸ—ŤµÑ™ªPÅ-IvG2äÏꔩ™Ïaí ³§f•ew8ÇagQQ6tÅ£A#|ødĘ›ŒÇômeª¥ÏŒµÊ2¢æe®Íà΢*sâ b¤hc¢ÍÌÁrÕ¨²Yö@k{9H‡¤FGcõȾm+sM£èÂ1X6öft|QÂöã.Ñ rÖC?rD‹­‡›Wh¨"“)(eðX9tB ­Ú Ã=)ƒ‡ðñÈbãð ÃuüÞ%xl@jÔáxÈ" ß9žÜ¼¿E·óJoéT^!\d£Sž“ó*sÐÌ8 ×kË&×áד߯¸>sÃ(±¿žàÊ1#ÿ>…Cà¹~'éæwt…Žä9Ʋf‰¥@›/°e?äµõ%ed:D#L63z­Ä÷`Ò¸RãŠÊ±ç¬*럹ÙÙõ@æÅ®‡Ï{ s½ ¶¢77‡ggú¨îðÊYÏ0B•üÚB'JI „×BBÿ 9ZGä¨ß`â™~ãa¿Ñ>`Aâ>ßDf³´L¡4§(cD|бªv„×rý Ò|SBtºn(€Ò®Ì\%šnœ}ìh» ;íßÝf,íìP©f;¹þͶrñŸö˜_ïæö•ÂJ•ws I´W ¬^ÎÜ8tM‹#ó—ÃOØw[l¸cìüzåMÿh†Är—¿#ºýÁí¿‘ ø1PÓr0G/!]•0UàÎŽê²u…*a Ñø9èc?èô_H /Ru“¾z…M²¥ù¾Öýkpª«‹ÇþpÁó:ou¯Gêš–nrúž¹ß·Úûn¹Ö1B¡ŸzÝc Óéä0RÂME݈¢Q+(‹Äo^ÚÛÖ{ŸµªhB~ÓI™Áœõ}¼×º3ñîÇ-4½Âœƒˆw(Å5§’²c2° (å²_AŸfÊ(ëä-BYk-Mt%ÔÓ˜ñùk=ã¡òÞÊ«ºn-:°3í›5*G¹îy«Å)Á„ä|*[ƒ/QXÙÚ¢çïžåiÙÎ4\qÜÔ,ÈBý§ŽU´VõÒÝQîXº¡Ä6y?±ÿŽýyF endstream endobj 282 0 obj << /Length 1365 /Filter /FlateDecode >> stream xÚ­WmoÛ6þî_¡&·3#Š2%gm5/Ê5Ù­CÑ"3–½x/ößwÇ£d)q²nØCä‘w¼{îáñü:žœò¹³` éK'¾v¸ï³À }É¢…pâ¥óÑ}?„«š¼H¦ÜÕÓwk4Ó™+Ø‚Ëé§øÍÁ©ðv|O²…ˆlpô<ÏsÎÏÎNŽâξG}áÆçô½øpŸ¼=BK““xòû„ƒªçðÞ!Á¸:i9ùøÉs–°ôÆñ˜XDÎÖl,!CæÃ¨p.&?O^cd‚#“ó…pd±@„äײÞ\j:›ûs·M/u^ªKŒ°ÕI¹&ñoÞ܃§ÙŸà® ÷à€æGIQ¨%¯îèû%š¡a^Ñ÷=âW¯0<€1sfœ³Å|N~4Jo»·Lò ;¬´¸ñÃUŠ®?œ¹ê²“uzó¹ÁÈÿ#ùŸƒJþ;Ôu›èYG5¼-þ"ê9õM_ÊziÂ(öÙKëåÁ‹]…ƒHUµ,ìÿN%¶H'ôM¸Aû0œ»ÏŸßw:î©¿Fz¶ ·16ÀG>U%‡ø\çÕ€ÂhPìëª{›òr…/¯VûÐÁý><¯½"Œ³z³Ê,XYn_ õþSàd+&ž†;i %È04꘺mRÚÑ:¯L¹ÇqrÛˆK(è#¤Fî!0HO¶¹Îh‹UŽÜ뺰ÿ‘úª ×TNˆž&c¡KùhZdô¤!Ì~‚Æ(iÊKhžœ¶`½°êW¹¶2ššÎn' î×xÅ£÷6ç®u³7aÏÙæKõКiúÃX à/XEŒðº?Yó«ˆA endstream endobj 287 0 obj << /Length 1551 /Filter /FlateDecode >> stream xÚkoÛ6ð»…­¨ŒXª(Ò’¼bÚ<ŠK›%^‡¡-Z¢m¢zxzÄ1†ý÷Ýñ(ÛqØëx¼÷“~;¼ºdcgâO¢0r¦s‡…¡/œ8ŒüdÂiæ|v? îªZçrÈÜvè1· zœ —û ¿Nß¿ºäÁ¾Îüˆ ' Œ_îùÕíÅÙy¹{s; ÷ã»Û7××WÞòêÃôâörÈsß ÃØ=» ü—`œß\Á‡¡ºÁÅtð÷€üÀa[«¹Ï‚ØI‹Á篓ÁÕ{'ðù$qÖ†°pxû!@¹s7ø}ðö÷£$ñÉôN—hfËÃûöeã½q„i/l$xÄòGòcjèT +gþdì=vì6›õÛ ÚÑ6ƒn© è¿AcïgÛÁÕ¤ÒN²Ì§M'><+½pâ'IBÚøöoßµÈp endstream endobj 294 0 obj << /Length 1358 /Filter /FlateDecode >> stream xÚµWÛnÛ8}÷WÞ.*£±"в%'èÍ)¶i71úÒ"Ñ1QYT%*iþ¾3Ò—@² ìC`r8÷97Üß§(Ê>_ZÕã¿èéE?¯AÅ¥2üáÀ3l9 [.œÄÑÌ¢Ä2-7­¤ß-tÀ.ËaJ¹h[ÑZAeXƒ6¸—-Meí!ñ+¬AÐ Ê‘dõ,ƒ+d¹ùß{´¾Þn“¥XK{<ñçò§y?$}1C[pŒLÈáõËÕ†Í@LJ·ž>¶B#š'©C3wísÍBU‚Ä]Kï9w  øÌš‚Ä®k-mmÉ=£o Ä>ùðÝåÞ‚ÙÄ:†ÅJ™$Š®´“ål lˆ1±ýð-£Ea}ÐÅ=›üB5â™Kš2}Ì´æ»Îˆ¡€}eû6*=Ég½[È*¢œN„ߦ[ô‹Nãž¶_Ùª6$ÇSƒB”š´ÌÇ…‹R< ‹’¶;@vÀü>ëJcû¾íx®²•] ‹NIÏð‰S멎Œ8‹× ш*7 g|ƒ`8s_[°¤và‚86ö—R8hfMމ.%~k/ØÚB‹v`€1­7ûL›ð­Åq®ÉÔ ƒã•î¹)¦“8ÓÉÔtÒ°¢2ߎØÉ½ÍÓf wó4n_®êÊ]æµzÂ2¸Éô?±*¢ßpå ŒAÿ¥J¼†4­Òttnågðâ_šù¹s;xú¿ÞÙ$ ’0Ï‚4M)Ü¿=¿¥\”Ô endstream endobj 298 0 obj << /Length 1481 /Filter /FlateDecode >> stream xÚ­WYoÛF~ׯ „$ ‹æ)Q)úȲ£IS[ÈK¤4¹²å¡p);Bÿ|çØ•I™´/ÒìÌìÌìß.߬g^dÍœÙÄŸX«µåù¾ZSâijÀZeÖgûÓ(lQË<yv3{vD=AhÎÌ›Œ¾®Þ]nÛNà9/´\¶á°Ïu]û|yµ˜¯po`¼ù±ýÇåÕë÷ï—.™¹ü°Z\]Œ<ϳ_ü©=_0ÿ‹¹ç—ðç¡»Áb5ø>ðÀ¾ky‡¨Çs§VZ >u­ Dï,× f±uOŠ…L¦ŽTn]þ¼yâø“8vÂ`Ê¡£ã+Qˆƒ½áWÔS³I¦rÔTZ˜d™â%Ì~êm•Ù. cËšÕúHRTä0Ûåš±‘¢NêcÙàÏ;&+p²±%áЯS4ŒÃæØµÓ¤d"ÉUÅÔM[®'öìu]̺—ÍFš],„*ðZh}jWu#2–ÍY²Þ•i#+½O§ Ä›DuÜŠÒ–ç`BŸÀóœYñ8?ö1Å!¥¸ºeÆ ŸŸèï;Qïe©%”>$T+>øÇü²F„”‰ÔC8ʵÇ&É•6P2—r€Ä8`¿?šNøÿË£]€‰pêÙI™!¡m ç­H2l)d.U=D©C‘ÎS^¡“{V9 Q+­ŠBpŠE¦l(¥‘5ªê.ÛJgÓ—êÛlmº¸¨jÁ½)K` '‹>²x¿£Ö‚™‡lŒ›dÙçRm9KLCHɬ•2ÔA´Cþ ú@ÛpfG{_ˆºÏ2v eÝ3'—t·ãê‚ËÚVŒ—HÝšI”Z®öœáäÇ+}|¯ ‘3‰§zàÄS:ÌŒÆhù‘=„„ŒçC^¬É—äÜU’Û`²Ö-Ì/ŸûoúÒë€jðX©uihóÛDiŠAƒ”á·S®¦fO!Ø-Ó|—ñðGÝ(zšk€{ÖeR½À7`Oä%¬s€³­·ö‘.pdj Œ¹BßÞÂéëGJ—ÁYñ#)¶9E+ºqÛÏŠêö?ƒ Ã•`j#,5î‡ôÑå€ÇÁË6Éy Ï$šOö¸k¸¢™&³úŸ³ˆÔó씉ä6‘åéc1Â]9Ô‚¿rIp,Nò2\Gø$jõ%ˆcóC|Ûä9SØ-@3{þ¼äÅ¡~Z#õË–…!\@éK¦vJXL¨»KÑœ0ݺtH§âÿî^¦Z×ìiâõ­NÇ Û?Qt¹»N'R½=‹Ä+¶£5;ï+z*4×ÊŒr¢)Il‚ýŠá7;ŠáÐG½Ï:†ŸîêÞîÄRÑÓ—Zãrä»ðüv½éÛíRh+‰¾üÄ+ü2‰°Jø\- “¿kñ=¢èÑl´ƒpRÚQºIê“–IêeÀ˜ícÛ€}¯Ýkc_µœ ¡FANQ7¤Kc‚¶ýÅÈÖ·w í!2‡O@ó0ºeÕ9Û¿c}xc¸tâ9¾úkt±„¦Gö ÂÐãÿ‚¬Óe­bOºn¶ðjÖCåÄ´!›¿4øÜômqTîç° .ö!º6]ÚyaP‰¹¼ž­+çäè)˜‚ösB/€RùŽklùÌý¹Þ endstream endobj 168 0 obj << /Type /ObjStm /N 100 /First 875 /Length 1316 /Filter /FlateDecode >> stream xÚÕ™M7 †ïó+tl{˜I‰”€E€|`Û-$9´]ä&F4°‹Ý þû¾œdÓµµÛNd;ÙlkfHJ|HQ™4‡H-ÔŒŸHJ ‹©â—ƒîi ’ ×)¤ù¹†, ’Ñ$“ T* ö¨¤PV …!V ÙÐ%ÂW)ÁĸxƒÑµ+è7yçg’*îj„V… Í.ìc@/½sasŒ;þIó|CƒÐ(ð&˜ î.¤ðÀ‰3î@!g<‡·¬YЀ–¢g&|ŠaÜ\ý6A¡fr ÍÎ šÀØÀœ‚ˆÀ*kÄèþKr°\‚(°°@]«Ê‚X‚e0•¢ÞÈAjF§0!µÂ2ÉÏéþz½©³ù ÌDzÓåü|˜ž¾ýýr¾þéõúÏaz°9µ:ŸMÓóé‡éÇéᇠÌKxÁ…GÉ~ „l?ÔI£Ìç>u,T!v†õ4LßožmHsÅ×›õwc’oɵ$>ú޽;m®¥î\K¶ô0cGÔ3DiÌœý3ü„3Çÿ²×ÎíBjÚÍgùBjíBŠÍJB¸öÛ[lçÏ-¯<½°J[MËÂjZÒ.¬²¼š–¦šrÌc,òå«iûg/ü3à&$Ë×ÜÒ®¹ÄãîŸJ7KæH#ínÙn%ìîJÜ{!÷àãáò°¶E­r/ô*wi «m=ªú©®ýfÖîï endstream endobj 305 0 obj << /Length 1912 /Filter /FlateDecode >> stream xÚXYoÜ6~÷¯ÐCj¯¢[Z(&6²E¤Î6}H‹‚–h¯]%;AÑÿÞ¹¸’jÒ/9çøæ:\<»gçíÒ0uwN†^ìdaêå»È9”ÎG÷Ã&\=TµÚî¸Ùn‹a³¢Ø¼]nþ8üüì:ò—rüÔóÃÀñYFÃ=ß÷ÝW7ûëý‹ç›R"^÷jP£<[µ[ŠŒÿ4\E=•ÈV—Õ ‹±¾ ì/!Òê‡z4cÉç„i1÷5š{À OßÓŽ z‰°÷˜üÛQ·¼*º¦¯‘÷¼m:3òJõ}]¸‚\nÖ´ü3òõs|áðöæONÄ·‡gUKú?³jFiê>âa7Õ²½ÝlÃÌÕ¼?Ñ/ã*EljÚ«ñÈdUw¨'‰«˜È—Vtkm5b/û–žè“$s_uH'=õý.ñ>ÐÈ[¸o[ZÕ=Ëÿ€¡!´ºdƦ#KÈá5íÈ€pv`ÃÀKS5x2¨n0L{÷nÁôãŽ@>èï ³ªÚt¼šËÜHv½Õ ÖwV'‘²¾¤¨6Ÿ©«û#9±þ²æ­; s2Dîí4rɯ! ´1¼™Ý)¾ s'ˆÁæÔú.Ža,È-=X¶ô](-K$´ôÈ_´t¤Ù–†ÐÒ£[:j^’Ä næí¢¥ŸuùóÖf¯@k˲ø›ý"„Jß÷G‰aÕò@’ŒÄ‹ ™éÖè‘0ÆH“fº Ç¤Ã±2ö{rµ®;L§GÃûª5¬¦x^®IVMÕ*>§H=l¬™`È„ Ъ½·{xìVqÖ¹IµÃZj£©FN) dY>tµzÒ‚JÌhAX›ê¾¼ò¦k_àhÏêâH(pRnÝ*€“(òˆ5—J>>dçñÿ ÿ@ÚnúŠÙ T0¶öéƒü·IàóTQ0’yÖ«l¥˜ƒŸ ¨y)«¹êÓã@âÚws CÕ8$|V&m–) \Oçü”>§VàJôÙ]"¬âX`5{"Ùµâ´ÉH$ƒÜy!9‹b?¨ûF$$Š©‘Êkc$=] »æóÿN³ L^¨–«æ”vÊÖx¤Ï ¨ ˜ºwC×<½{Öt« %g=í²?`û߉ëù|ì•8Š SŽ. 4™’ªdÂ-ÊÿÂkN{XÄct¢¹®yC=«¦Ñe3D-û¡ëÕ=ÏŠ,‡Ú<,%µAÁK ø+õ”hpqÖíz\@åFï`¤xkGÜè4âR§-ï`E¥rJ<2Þa†=ìfØÃ¦ØP5c`F‰û†Æ2B?Mß•¼ôˆ ÉàÇOeÀ¼<®Fu(I¨,pyƒÍiU⯢¡)•‡3_Øù¯éϨ>„½¨;zœ+¢*ï5Ú™Ÿ2¥ D Ÿ“†D™uÒL8A‰é3P¼5“$o¡ä7êÅüG”ÐÆ1p¥ ôAE9€Tz~¹ŽÿÐMP³µÈûÝhö|@-Ù¨s”ÃØ¢:a?åOF£8V”~:³ž …j¥ÑtíÝd¤à˜®±“ÚŒ[‰w˵P[ž0°R+PÏF9y¥šd-(ÚV,Nû¹yÞmÞtüÙ¦Kvå”»°®¸ãC3Y¼Œõ'æFï÷µnpbg ÖðòcE9îãÈFß 9¾ûŒ`7ìÁù‹¬ß#Ó òˆhU¬7B ê&9[Bi;ëTHZönÜ[›ñÏçLô-´x„ÙcÆa*ÆiÐ[™®–ÿûãÖ¹ýßÍ+XæeñÎ24œlåT¯Š‹/ˆ¾)íÄ@5¼±©fe(Úa¿Á[¹·Ë#ýLŒQlÿô/9uó endstream endobj 311 0 obj << /Length 1535 /Filter /FlateDecode >> stream xÚ¥WëoÛ6ÿž¿BóÖAjEO?’nX›Ú˜‹,ÉR×ÀЂ,Q½J=¼bèÿ¾;åGªÅö‰äñîÇ»ãïŽÒ«ÕÙÅÂò´™1Ûcmk–m®6±ÇÆtæh«H{¯¯‡SGg‚§ÁÐÒëáÈÒ ˜ˆáÈq\Ý1fÖxøqõæbá˜Ç8æØ0mK3 ÃrÁÎ4M}=X.–×/‡SW_-ïn åþahOõ»ëùëw/oPæèËÛÕüa1´,K‰»×sÒý`zæú~ ƒ…çžÍWgŸÎð S³öî;†eN´0;{ÿÑÔ"Øz£™†3›j;©˜iÎxbØ0Kµ·gž½úFÆÓ©á:•‡û%xà¹:æ! YU¢"I9‡LÄ…ÈPâèi!EÅcS’ Ïi#n0ƒyˆ¹äE®‚šFÑäkÍ3¦ìSÃÏ·dÝémè@©®¦Ým›<(ÃÍHÁ1¦ ÂY–1ó< ˆçU-šPºñášw Oñ䉫׉œ8zÄ kš 3Árž”¡”X;ôÆz6AÍ"ÚÛ 7Ÿi[¹zXd%OÁ5&BuÐU“Ö$„dõø[äégâF@CX4¥tב!JÙqPF‡b#M-BY 8ݳm½âÛ_ÑúKo°ýÈ—å`é~˜°ðñé h.949uîáw0ìümë$K°í'ˆ*uüÍg?‡§C›÷7KÿîþµšOÏñ¸ÁêîÞÀn,i.ã<'¨Ûw77‡öú´ŇÄüN|•œ6õã RTQú‹åÍÜ÷¸ïß,oËÁqt n¡’£€ã>?ä×i¦k%ºuEˆsšæÁNa¶¶L¶m¸m¾‚èÔžïÓûÍ”ðÑ\Çh3ø£7¹´ð Kš>«>XŽ»IÝ:RI÷¦Ø»o9=ª°ý¿È”‡½¾µþ(tíæí2¯×’i¿™ÌGø2IÈrþçö{’±îŒÕÓ+×¢ð’æÏp$¦5dPÀ°-ß‘#Ç>O£¾bùÒó²Y.ü—¹Ð™]è±êÇËñº½Ö ÑÞ endstream endobj 316 0 obj << /Length 1866 /Filter /FlateDecode >> stream xÚ…XÝoÛ6Ï_¡=MncEõ™bZ¯ÁZ´Í6gÝC[ŒÄØDdÉ¥¤Á°ÿ}wß÷ÝÕ‹0s/×kÜÎÜÕåûßÞ¼{‰®Þ\~@A'¯¯N¾°Ów‚Áæ~껓O_|§Ö[Ç÷Xž9÷záÎaIê…0ªœõÉï'¯Ð1Œ‹™—¦‘“d™±”Ì’5ø‡±»ã²þìÇþ@àí¦@WOq¹z¼åí³gûň,ê;ÐäoôÆ }ˆPê,ƒÀËãØDTG³åù9Ê-šÝŽ×åËv£ÐT}zPC÷…çIjúÖèîš= ~¢O-îi€kæ7OÍßE[óJýÒïöhj~y‹}÷쌄­… *š½PV5}·¢26”âºG™›‰Þ„ôÞoee¤ šÈ\®mÙ4Ý…¬¥ÚZfCšL}ï—?‹;^á&EÆÿ—×qÙ^žŸ¼ª>òª«kõ”ßMkü–ˆ‘I½6ºª®yq«ætµ‚—_!µ_©~Dq{Ë—s®ü3'©•èÄésqße‡ò)Hç€^gSÖëË jæ0s‚ÈcQbó vFàB:êé€z𦧓tèé<zúdÀnFÝø?2Wõ{¨)ÀŒ¦í’B·h¥pÙr¡›g/+Yoh9ÈŠ\›a"Pa ô`à^m¥"Ž47¢-ÁMuå*¬oü¶}M+ŒÅ˹L¡j,änƒëƒÌå4}'kD¿þ;MÕƒêÄŽÆP$4Ø·v·ì A›WÏŸ«0AÓnË;Z¡ýÐQÛ¥QNÍøKÖe³€XÜ+Ïš"‚dúŠæ6¬¼“¸7„T’éwøÓTú#qú=mÁ(éï¶Åbü­(ågŸ1Ñ -££e—k¡0# 3"ˆvÝ˪¤¡ ŽÖmŒºß‚ > M?—€¢(gѦoÉÿÄ7™„%Õ$ì3ëc‰¹mTG£CšR´€JSû†Ü‘ž&T °nT†ƒèÁ Ô1cwh/::pį‘|PƘu†&d7cc§´ŸŒMê¦d³å †ÍJîtRâ§5bJ¤om¡]@:ùF-Æf¨–þ}ëe‹…‚3£&³iFš1&³ñf£¶À-¨éÀlÖÍ¬ë ‘DÃf¾ƤnÛô›íl¤qu”æCÈ£ÌÔj:V—V›¢dï¸6…øƒnäPucµëȤnee€~“ÆH'KƈÒ á1áj–4踽{»Ð†Ì`þÓØ›¾màa`Û({x¢„Ø€5F-‰MQÀ‚IwQòMßí{SòÍ ã¤uˆ…±O1ö8åEÔGÍðxtµ?ê³¹B·ÉcÁô "ŠI¶zÝÔ‚ˆÚƒÀª‡¦´ÒÕ¯©Ül>Ž,&¨à‡Tè|YUÄoÅÍx·.Œ ^ÛÐlŒ|sѦcŽ`!J¨–ºyTlº(u•é·£´Úø‚NÇXÎFtK¸¢o2Œ žaá}î{ãÕú´‰hÖÒk"Nc3×»ØPvëëWíªCªåôëóÓ¬¼éâ]$“<¦™¥T¼¼[ıŽ$ÔßfS‹Ô×ñ=¤‰[Wb9:·3Ý)ë¢êKqFç¥åFéà@“ï0w½n!˜)QÝ,K¸å†ÐÑ¥‘&Jw¦”1†€ºäRÛ‘ˆ*¶¸SÛ“˜180!ñpŽÌ£!7}QÒ÷(SÙU7Û'Ôkɨ­FG&KÀ‰ x]442þÐD”R{„bÚÖY¹ïù­ŽÞ¨Çl8²öÕüR"BÎfïiX ¥…ká üD A¨~w|Ð>u\KÓ¿“s•Û4FÝ3^=|‚÷l졽Dç^Ùƒ™—‚P!Ý«åZï\Ñü½2|D¨'®ãð˜ŽÌ{-wà}K;u:ÒdrÍòãcÇ^—am)ð‘¤hå½ì¶DÞø¬eYòè’~¼çP2À9à=p¼Ÿ»x×Jê;N }¡‹ŽžÜÕð&5ºa·é¼*b¡ek\ÀmG@º|£Ä–¾‡¸‚€½YUx•ãȽ¬…5`ΫyXÓ ˜g6?šé!‘§DØsmŒtëçúê#[¾© ©$ Qlž4›Û<Ò×½ìð=”ÀÝ !úW¹Ùêçð†v‡`Ïv`P)JBÓÇ€ð'HšŠÆøÎ©KCýæ7݉Ném†ÇÞÞÂ(9ì½iªŠ-˜DÛÿLh “8²ˆƒò˜’„ᅧæ=XoÏÒG€Œsàýau®ÉAšyð Æ'kæÄc‰ý«ê_&D' endstream endobj 322 0 obj << /Length 1846 /Filter /FlateDecode >> stream xÚíXmoÛ6þž_!ôKä!f$R¯C±!í’-EÑb«×HG‘hG«^àDùÞ^!ÛȇÛ7WyŠZ¯H~µ¦µP‡¤¡*)e;¶ùzœkI È_Hé5d# ¦u¹Ê HiIãyE㋦.w4[‰»žø°Ã&O.µNn/e%t<±FU} ñ l•g‡o1÷1¤i‘´­lYùQ|xd¹^À1@°-Ïc‘ jÈݪ¡˜› ÂM íÄÙQCÔœ‚IÂv’ey—ךC_¨Ü)à”2©2bÐ9y%14~„ÑŽ`ÛD°ÕºŒ` ó"2éÖÔe‚Á¼%œL¿åMS…ÌŒŒÜŽÅ¤1†Ë58™ŒÂdpZi•§ š]ÜR‡ÁlÉHà&ï®´¨Ú-ìºèHN~ìdÕ‚j6ï{ö‘^C~LÊU!¿×­n«¹8Ìó£í:ºÐˆ¥äÚs0{‘/Ç6TäU7¯ ªçiÙ.‰zwúΜýò9“ž½ÁIÇ`·õb{ºÈ‘/$~öì'ªßäEq;¿–UVCÖ™d×OƺÃÖ®t#š©úEwdy«³90 UþÛIø¸,êËÖÄ΢CDùŒÆ"¹¨5¢$Ä·X²PjiŽáM‡‘fÆ'чL{~'1gSî"pÁ(I£«¤iU.,:•°@R2€`U7%äŽì±R©^Ò÷U#WM­¬K±k´-ú5²ZP-¶„’JÅE¾Èä¢Õ_.29 )šZõ9Ü;ËPšÆêÚÚ¥XM‘ª&AÕ¤Z2kÚºQËæ ýßé쟨Ú—º2Ìvá#m?æ…Ú.|OkU®Ù¨Ûg¦‚–M £!¦^˜©#Õª;‹1Oÿ“¹¤ªÚ­¼iu¹ñøN?ësòâz"¸mªmn–Iiî±ØAÔöYqm?n¸oêBà„q…NÈvЈZ¯ôÈ•Ü!ª^ŒAM½÷»¤DÉ´h Í'E™+âu AYý’È\ÿ“K[áèÍÝcȱx›xrÚ{$f‘ëš‹þÔNM–r®4—ΦTNÄ™ž1l„q‡ÆÀœùžŽ¬²Ð‹©ÃÆ<¢ '>çFô‡{tEFà‰±Z# võyÌÙè{ú)}¨fD‹²8 ² bã½Ä™5Så±@<ÞYÿÌ ~óós•E“1sýPÇþ¾ÐCˆÄ££3îúöðˆ~üyÑw¿ˆ³ƒÿ^ôÃèïB=<Š·;ãq…¨žN~ кtƒ¡QBn ôá1ÚÁnÄ“Œ> ‚®yß1³oò"K“&3œ:¤µÿÝ>FpÏÁ®ýãþÁØeIIq@v¼0 ±9£Ðþë2ïà”ë»Z\5b š¤RC!-¬¼¯(…Äë5ì6­YEïd¸4¥ã} «¦c¿†#H5ÖÚ –ëÓ9‚åÀZÃvb¦t:È ÄpÖ…Ü:X ½p;zꨑ·­áÕº¡ØÕx1¹3¶ûl{F7€ <’ÞÍ×3è;Îz¸ßµhçH=ÃõÿáJÜRtþØ&"&Dü5lØÃ|¸Üý߯À„ÏYìù÷$â¸îÍÅÀ ¿ñ\ôþ-8ýj©øg—o$ãO ©à8u²B4chŠE/¹^†=^f4Z¨+%öìŽäwëœàÑûÒFÓäÍht»¨Ù€Âîi†;/0Üf˜àÀ„×àì­»·B¿€Ž·ïå y0È‹r Ò¦‘7pïC^µF^ÔU›‰›µÇ ‡8l¾öNmÝs"ÕT0¦©à˜~¾ôœ˜<ƒcàÈ‚(sJ‚ˆ6MŽW?¥÷Ñ[š¥”F2q OÍû:žæ·47×R*Î8ÐÖë&Å9¤r¶¹›÷Ø?o G¿Ò([Õ3KדUݼ(¬mªÌh×,tœ ñFúqR„æõþoyç endstream endobj 326 0 obj << /Length 1913 /Filter /FlateDecode >> stream xÚÕXmoÛ6þž_á*·“"ŠzÅÖmíš)Š®kÒíC¤ŠDÛBeÉ¥¤¦ù÷»Ò±S%Ͱؾؼãñx¼;>wÔÓ“ýCM2/‹ƒxr2›ˆ ðÂIÄ^šÉÉI99uþ˜¦ÒQºªó©pú©+œzêJ:ÒËD<=;y±(ýM=Iâ¥"ø¬C$°Î÷}çå“WÏß>™©óü5Hçøõ?yõ ™OÞ<3Ü·¯_ÿögNPûÎÁÉÎÇêü‰X)=á'“b¹szæOJ˜z1ñ=™¥“K\NdœxŒêÉñÎï;O¿‰—„™`mM¾T#ªBáEA`EºE×:Ãw­‰à7pˈ¾ÐóqoÛP͈‘xY’Üed@¯%NÙ,wLUèÅ2þ&Å÷7èììŒr²,n‰8„Fþ GIúŽzð5ÛÒÿeÔ¿nP|#ê7à× ¢ØË¤„ˆ¼$,{@Èb¡ C ü$NŽÄØ€³Ä™Àf ‹ , gè­˜ÙUó&¯;ž(UQœ–L!ö’¶…Ù°CÔF K60lc7’É ýˆ°À1 nY亴T¿àу‡xÀ‚±¤Âùù”Ë‹Q@§`­¸KÇD53«¹qu ñÆl¥ófnìig¼EMHŠÌ°Äß mÝ1šÛÃl—Êt¢%TT®-¹.DÑ€w8ĂƇJ·¯88q U×Oêí¹d^N&^!‘9Ë–¢RµbÆŽ/Œ·öÉ Fí—õ¹\i‹ºkGÓšhìbÏ`Š.¤}Š—J†xÚB7? åFû#®ÛH0jâÛŸ, öGú¦ý‰cÛþd‚Ûh®¢ ›E›€‘ý›Ø- ©Ckñ$‘ø¾à†ðèàà€)!ãÐÅINd+pĦ2^÷#×wƒ¾*üj?˜ùNGêÀS­î1KR v88¹^ òd*ðŒ© WC¸†ù3•ãÍí¼© i{™Ã]ÔCI)ˆûÁ¦K 3&‘ݱ8®33.ŠœÝ¼æ–†2 “\ðËÃ]3=WÒÐ 1¿ëa¸Tܱ†Ø¡ 3Ô}UV0ÕA_“c.As­sÄ«+»YÝÒî;¯W¹Î—FÞØcuÁchWmòÁ*ïas5+ØÑvok‡Û Úõw[Úd^œÆ·§MtWÚDÿJÚ`K|#m°Åå´ÁÑz%.˜ó6•èuÚ µ‘6¡Ÿ˜´áîÚ¦ÍVoÿÞ$ƼjÎ?Pi¹¢ZÓê²Û ña,zù½jJ\õ¬ºÂóPBÑB’(Ú媪m;]VZ}Åå ™{ø>0„Q½ÑD„•6$ïve·¹Oˆ¯:È\Œ3[Þ/Ø©ïßìè0Io:Lçñ㟧nšÄ¦~ç;Ëi jCê·tu#€‚GXʈ§Žë2ƒ üw-Uc-ßYõ¹·«÷.*ܺ½¢X¼m(Ba;{ðLjµ%à3dÀ’Á¸¼¹õ*§#~˜`œX®nçŒ×¨°[€¼;† †áë·×ƒ óàVC™0Ó î&·K53lH„¶1ãOd†^ShjUr¥«VW=EÑ`MÞ©ýj¶$¤ñã ¶DÖ Z€ŸnÌÞöxÐñn”q°ßã&wK¿÷Ð4‚6pá„9óÈ¿±Ïíœêbo?•@³yÅÜ›†t©‹Ake¿µ /ï:¥í˜¬#Aó`Ô4›lWò™9ô-gxQŠ^+z`–éµ~B(j\0Ϊë·?‹ÈÏ"Wœ‹ùgóYeQñÅ2~4¾†ó›þ—2äN¤Oîô"¸éEðÍ‘^ÇåªfoÑ)zÐñßl ÷ŒŒái¸Qçç¦ pãh3XW\ê±×ÞÐÝÌ.×jhÔážæÐîmO"éªçÃf{ˆâïÏÏ^œŸ_Ó/^Í lç'’Ôƒ‡ƒd^šš 2µŸ<ÿUæ~Ö endstream endobj 334 0 obj << /Length 1714 /Filter /FlateDecode >> stream xÚXÝsÓH ï_áË ÎиþŒí¹'¸+ ôæ&n˜²‰7éþª×¦ä¿?i¥u’âxid­V«•~úØ>__\½'÷òe¸tÖ;'C/vÒpéeyä¬ ç£û~žE®ìT)æÛÏÛÑÍQ»‘—Ëùçõë«‘¢' }/ˆsÇ'Aû|ßwß<»yùîÙ<Ìܗר!r¯ÿ]_߬^ý}³B5×ë‹û‹öùN0ZyŸ:Ûêâãgß)`éµã{Qž9F°r¢eê…@•Îê⟋çÿs­e–yq”’I_†ºŸü(®¥(K‹oô³‹û‰»ºNÖx‘¾< +vï„&B7•djhÛù„š®'ήéˆXt/+Q`âcôœÁÕÐâŸeB|Uµ%šY¡OS·×Èñ¦øó ¯#»}é Çä°Ñ²'ÍŽxgAC†±‰O~âŸÁŬÖb¤E]ñV}—Å$2VjЇ‰{ý½—µV.Ð oé>¨þŽ(ˆ;‰Y#‘¹møQºM]@X¸!Yã—»FóÖ÷ÆÕ@|E¯ÈÉkWèóȱè¦Ì•÷ƒú6O–®(žÅø«š~ÙÊÇyŒÐ÷¢.W6éâIᜨRÔûÀ¯§ŠA¤ZÑi¾|Ę„ ÕbSP£ñn‘;[,¬Rkj¨kvjß„`ùþÓ£ô¹EÖ$“Ã(ï»-ĆÝDŒK¢§C|BjÅ©¯‰·•ª¼Dòì{ËdrÒP ;f•µ%šý%Iµ=ð¢¾ïzKöx‰E :‘ûÐAÑ…dù…ä]A1„c1„¬ýSurÛ*¢Ð•œÑZËÎ@O™–Ƨ¹ü_Èï°Ð"ˆÅB°æÜ !¤[¼èÝ%1޼ ;àfÜ@ ãâ‰Î®® ®7­>ðên(ËÛ-”Í}[§‚ù¸ƒâ!Ç­a–º…uÓ!ÂÜ]ãÂ,sµ¨$ɉ¶-•ÔÄÆ„5Lk%2ápQá÷Fõ¼û´ÍàÞan.ÑÛŠBÖ[0bÂÌÑWWm'ö•`¤M…j:8q°ô%3tÌj÷îËš '‰Ô öYÿDö¹‡ˆgšY m¨PzkðËUZ—èÂð^0”"Œâ ‹7jÙfB`ôÕvV!^sª?ãEcð™eÈ Ldpic2‹å ûK4+!¤ k'Œe¦ ‘;ѳÛLU~I€O tMÛ)ѳö­ƒ[<² =7e?ž=–?„"WeÑS@»b l9÷¡pBA+VŒð# P SúbØáY0jd×Ù^1jàVI®!¿:ºÅÐKõÕ8ûAÐdàŽR7´FÙ®™m3WfC­îÌ8\jX× Ô¶¨¿SsäBÖ@Ä,u6ã[:n$NÚáÄ „®ˆAÝÖÌV1Hê^ ÂÀåo¢ uUÓ²Ñ&MäaÕrO,7=›~qÃ_ãJT{:»@ 7€ûUubÎ sbàÎ Št[rQÈ'¨Éºõx`Æ7õÏm‰Ãݾn ÿ¸/„™ÄPŸ—¶/Ä1¼KÒ“7Ep|SlÍ›b™>zSLýÈKSî/¦LF¹ \–t_Â5°`ÊUˆH3.Á÷q çõŽ÷öV‰*ú~Ü €uú&`)ƒyTÓ´ÌØM¹¢_¢Ã Rü|L–”ÃÐ $6€ wßÑ|‚K\ ‘<>ð«z­ ^2ó§QTŒ!Wüý¢v…©4sŸðR%lû€I„’ø:Ù¨^šJO§)µ vþC²”;ó—ÛÛ¯Þ\ßÞNÄ3Œ½Ü_Â9‰—ŸÆ›×¸Ú$¿÷h æp§¦%²&£@"ÃÂÕ RÈ gMͽ43ÙeÚ'·I;ç„ù’* ~#ñÇÓ§O&óÛZñJ`À[ß™'I(ã¨Fn‹ÈÓ²M€pêNxúN"0pp\ðL ü#tð Ÿ©ÍÐóòÐN¾F Ú™vc'š(þq´„Œc%­ÂÙKÀÁoæañc€cØ€&c˜ß¼º™sfÔEœ{¾•rû?ƒÿ=kn endstream endobj 340 0 obj << /Length 2427 /Filter /FlateDecode >> stream xÚíY[sÛÆ~ׯ`Sy :",OGÎ(ãºéHí´ãxè%°”0Â…ÁÅ’òë{n ‚,ê¸Ïí ±{öv.ß¹ìòû۳˷~´HÝt­Ö‹ÛÝÂWÊ ±Z»I,nóÅçïË$pL[”zé;ýrå; 4Úå*B'pS½üxûÓåÛÀ›ì£”çúaºðx?užç9ï¾{ÿãß¾[ªÄùñ wœ«Ü^½¿¹þËûÜæìêöì×3Öy ä&p}/^dÕÙ‡Þ"‡¡Ÿž¤Éâ‘&V‹`» Zåâæì¯gßÿ»XaìÞz±N7 bfêöÞ,W*NÍæÝõû«Íz‰çäæ/k3O{]çwú†§ôve6´­©QœžGpi ê1µ® “´,Öüéú¶¨ï. “zNY<,UìÈno¾ýöe‡ZIV¾ï¦QÄœZÝå*Lb`¼€=ƒ0vñhMÄ)ê NnÚ=ž _ݛ܎‹ /¿(û‰ç­”ç¥LïzX·9÷~ñ"o;ô<³ö«9í‘|"Xu‹>3F@!¨oZî€WãpîØþœã3T:±ÜJ…n –[ù@SrÜ'Ó¶°Ã.˜Ì”ë«Ä¢ŽUÍÓŽà°´({Fnú ¤T`î±(KnµfŒ ºf¦ù|ž}ojn™:kÖ´iM~ÁS £•q[™š¤}ܯûÃÈÆHhÝk¤^ §@‘¼¹ ÒþšÏË€_ê“æÀõ‹º3˜Tл AÞÞzºãýÈ–sl#$%r 60í;üµÕopúâDýð",´(䡹;BVÉnÎ^¦œ—v#ë_2ÑŠ ªƒQRàŒÏOMú¾ó³(z© ð4ZŽÍ#ã`Y1R?EÇ­¹u9}e·%"•Ñz[¦`éÒÙsì&2vÈ-§Ú>Ñ£uˆ<­}4eo4€W…¤u×q‹w‰hÂP´L!þá;ö¿h9ÒZÈb.IUåYY6¨¼GìúÂÐ9B`‹ª>ø>’ç·ÜyŠ\æ% $b ¯äŒs´ÿ(/`ˆE†ÑB@é¾75$Ëî>¶ É9èhÄb×HyR³qF#‰›û¾¨Šß4q6œ®wh+LZXô ØI¬ª€<Æ#ì´`LÑ:f\Â÷±-ú‘¨k)q—±ldtjïŽI£J×RœbƒÜwuz1ç.ìZcDÃ1Öšwµ.¥âª8€ô¬§C€…¡Üd¥nm+¹Z—¯8¸°ûa[Ù«Ë9-þ9°Ú›Øg;ñ-е´çÓ %iF-ß’f«[Y8›8q —Î3ô´Äwî6- WŠ&Ñ9Ê„M ‚»“aÕ|m?ô˜% Û~`UnµÖ:ŽŸ²a4Pä…PO’¾þˆ¥h–8ô⃳ÉâêXF.·ê{A ’Ù Øbϰ×lS2 ª’Çû"C"JK˯CAÈNÉ ð±ÀP ʉ“ô•røË¹ùó»kž}”: ×;Ì*„}h}8ó°ÿ¬J•€wè^Í)À–úýk@ÿ*¡[é{9JðÒVipD¾ÂÀ<õ<@7i¤4Ü— d™¢œO£ìTÛ$>ßÚqÄrÙnxÕäî•H0¥Ë%Å›©p#Î\Ú/5=Ñ…àW=?sHÝB¢®ddò°8^ãÂÃõÚî=ÒË(Æ”—r}cEÒÍ.Ô!Y¢(w˜ ¾½C—_:CºÙÁÇÊ8”fNH]ÕËÈPŒ¢„^äÚû#ª±­%L.¹4ã}œÓch¦à·ûÁtû¢—@&Í—ê[Ín8gx¬tÖ6RË÷ã $”«RÉÓ/Ü9dÀF¸ý 7Qû¢ÈÉñ¿…uÖ7ÿC VjÚ@aA­Ž@­BûDŠ–¡ׄ®“&\Gúv@åÉ YM/СƒsnkY¬ùóÅ ? ÜØ À­âCÏþ[ô/jôñ÷ endstream endobj 344 0 obj << /Length 1846 /Filter /FlateDecode >> stream xÚíXKsÓH¾çWø(‡XÑû±{ l  €ÔÆ&µ[@…±4vT‘%¯$üï·_’¥D,ÚÓ²«§g¦§§ûëÇøéâèô¹íOb3œ`²XMlÇ1½Ièf»“E:yo\M#×ÐU–«©m4Ó™m”@TÓ™ëz†kÆv0ý¸xuúܵzrÇ2m/žX,ÃŽ`ŸeYÆë³·/ÞMÈxqŽ\ãüÅùÛùË‹·sst¾8úëȆ}ÖÄî´qMÛ 'ÉæèýGk’ÂÔ«‰eºq4¹£…›‰„¦T>™ý~ô¯åÄ®D‘é¹!«ô©Þ×Þ$×iSV|ƒ%ÏŒ­`2³}Óó<Þ³@S¨[T_ƒö˜AoTVdŇŽÑè/ Oì¶Â)yÜÜÈŽB–8ƧÏ$,[®y®¬d¦ÕÍ4ÍéÌ"cb`q*BjtÃ]Ö:$AA7<¥ŠoƘٶû>«¾ÍU‚›ýØÈþÊñKÕd™)E*ÈUâÙ“'L$¹ªk&S]7Õ.Û¡†Žm¼ÙÕ"wIªÊ^:7eZÉ^źSh¤»\4Xã ,pÂwÒæOñÁY¥“&ß?´Aß:#“BCÇØLŸd+{ª‹tsòÊ­Ê*÷›®·poåû‚Bm„*Wümn²z̪•Tå ™Ö¥òºäð¸C{–Õ­L€}é»ÝUè6Í#6/Iëd“ñ8€ð¬ddÆ®{Ä ÙEøU+tó7ÐìÿWÐìY‘!Ûš&;@㈴ö¬-Žto)[ô ‚P0³¦q{‹iœP²]ñTl#zÿéÀ´wÓ›íõV©þyÒ³szÆ/ÐL3šqD*#!6š¹P_ѹÈSyÎÄËõr]ó`…7ཨ*Xó>òÎHDÐq›m®7š-ÊÂS]‚Äs{Aƒ.H€¦ ñ< Ћ /´$,ÂЇ°à616¤A!m€à»è¿„+(ë+ö€%^€¢xÄÂ!B<äŠaЉ; ¯$ÿn€ ƒà|Èþ6úHpÓOÔÍDÒÍDº™hÐÍDÜt„F ·Ëe+ÇÓäe?j›ž¨mz F€^mßÅÌ·£®ÿ9ÔŠ‘ž¦ 'ð)(œ @Åp8 dHP8a,Aá9N[+@¥=ïn£$2«ÿµ—µøq-þGL̆‰o4¾·Vh^ð•0 ezP}‰i òsb¹ãÁ]FI¨.ñ8A 먔PŒcÊy¸¼ÊšŽ©È{žé^8嚟§>X³ÊÔ’S'°PuürÖ ÈYíŠqP£³$6Fì98ÄõõÙºKáK<¨Ã‚Ñ¡ƒ†AJé/WµÑÀ¸Ë0S!uzÜj(Ü€¹Ý-ó,9>E±1×"G¼âµM¨°Åpƒå˜6’Q¨ú–ý³Òª¯ý*~mmI$ÑuMj4ĸ¾Òõ.o† Hr­ ]ýpœÿ9_œ¿¹:¿|ùúâÅcSƒÚ1›O„wuýìvu=‡Üèg—è³Ïb&"¢+I`sr ¨_70­*Y‘jÌ,…®eg5š j-Yâ™{¦S½R¥în´Øj6ËU±Þ©µDb&uÅŽ,kv º<þÅ@w>›Æ±¸¸ìôêö3>%:LõW¸c+Üï±=<¿ ÑM{qy¼{8FüÁœË¼ž‰im%²É¨H,}¼XŒJ+Jþî)5íÆ<3€î' Žˆ_•»"mA»Ùfy ázËQ›d¨ZÒ.)ø\?ÞCë^ƒ”·þ±¢îƒ¢C)ê@QQGξGÝš{UÝ µ†5d£®`ÃX„U1˜ÌäKïø^apÌÙ˜ñÛLÆÆ£«ï**´Ñ7pÈØ³|¬çýKy±T4ºåuðÝVl Ìzl^/¸ŸæÎl!Û †jÕ`<*üø¶G^äv\¶ôMŒ‘kЦoU'rûÇ;&bÈâEÍsô’À/Õ4  Íix–„.ã cÓ—ãr˶%–žÚ˜áê„[0r¤’­³âš1¹¿£^¥P.G¼ßº~N6ÁË Š¹Oúñ¢,t¯ÙV’Û0Ä¢)Š=*XOû¹ZP¬Sèoú@ø¹½Övǧ„Ò»šA¶ßzÞ³ùj,ñ‚sdП°(+Ò,QøF!.%Ñ{{± o'g6¯»r$]1Kxuç]xÊß%Ê­„%™¥æ!”u¶6d¹l™QÑH5Ãyzo"½}A˜ÙU*ü€­äÕE)’¡Oîi -î‘ù¬}‹~°|kAÉ{ FËñÉèDqWa‘V©´†ý‰Ïñ…\±p¢ÚE·¸Æv?aÞ!à‡}Õ&ncm±Œç˜à¨ï„yýEá›áÒ×ö]3´=€_lFQÄZ{vû×÷ß«õ)$ endstream endobj 348 0 obj << /Length 2041 /Filter /FlateDecode >> stream xÚ­]ã¶ñ}…‘‡V¾ÄZIÔ'Ò½\÷’ Ò½´ëk $AK´—XItDiÛ_ßÎÈ–½:ä‚«^DÎ ‡Ãù&¿]_]¿ “Eái”.Ö»EE~¼È¢ÔÏ ±XW‹Ÿ½-sá©N×rzýrzÝr%Dì ¿Óå¯ë®ßŠ`Â'Š?Œ‹E@<ÂÖAàýøúö»¯—Qî}wƒ„wóŸõÍíÝ»÷·wÈæêf}õÛUë‚Ex”Føa-Êæêç_ƒE¨/Š|ñä›…H3?‚Q½¸»úÇÕ·x,N•F~QÄ‹4ÏýXd$T§öËU%žjå¶V›ŽfׯU‡Ç„÷†emʇ ¾ºþE…íVaèIBìžt§ˆx/{UmÊú¦ßŒ,xþ§é®¸Ñ¦›e(ë'ùl7»Ñÿ•~¿Ip0VU¸rïvŒ½'õàBÇ)Lü4ÏÎÙŸò/ßL¤ÀÕj£dW?MÆCá‘r뎣î%îø¨MçØ‡žl™ÉþÙžI›’´º9t†–£°"N¼qí@ŽF¶¥ò—«8+¼wœ¶D#kkxD¿=IG ®¦+ÅØÞÇGt°{¼ûûO7ÿ|{óf}÷æûY·Gñdׂ€_QD;vtk „I´<.­Œ0Ú×2%-‰=8ù nI зÙÃA[ý_Uùä©Q1õÔ(MAB€E,!ôRD”Â\@‹œåh‰¨¿º>ð÷–·fóqás” ¢'‰éÀZh×cº‰ÈXø³zßʚƕ*kÙÉ^›–¨\üë¶Ò¥‹Žh´ÖåZmé?œöbÈ¥fXˆÖôèRa®íœÅuë|dŠƒÌm„Ú(Rp}°Û3OõÃi ñøod÷@Dý½ËA4$’y_˜ ¦hyÓƒËÚæ ÑEP53²;EÅEq©æ—@‰š$-$”Coð°%¸ð3P|¤¬àTniEÜ‚þŠXxwJqeœ–¢(‹ü4MÇʸZa]xé4rÃh$r97h Ϲc­D ü,O?j™ÏŒƒ0FȽÚlÏœ}c~ „ødg¿ãœUjXc ÇiʦH!¾[ÔaïÊ'"8oîu{­œmvᱸÎÞ›¡®ÎÖBõ1¤;€–”HÉÔrÏ›I0سwôÃБäPníÿY¡Ÿ¨Á)PîïeO£©kwº'*‚êFt‘gv*)‚*EàQ}ˆâµ$"ö¥¶®ÒSu…òñ{È]-a\ìÏœ¡´N6áßR:Ÿá ×§¡f€³«£4ÙQLJmçfÐZé²Vû9¦Ê¦*^šª8™ª`SådªœMULL•;SeSA*[bgtŽÖ* \®VKg2a÷¨w4–(±«YÇï´+-"˜ ^ºÀáx‰Ü£ÜiÄE iÁ\Jˆ]O‰n @Á‘J§ŠÑ¥‹=¨V¡ž4–£•Üöl¥™/¥#ìó)j0ieCú‰hâwiêgp9æNø'!yÔK/?ùH½Ùüíýz³™áš?S®Ü“ÍpŒý GJj×rïÍ—_â ð*:­+ú0…î’ä˜iú…ÿ€“ºþ& <óâòÆ¡ý£>À‚m‰¶(ïß÷®²ïd‰~ÒºK2…²èêG'k!¹ º\Ð:—™Ú™¡çÔ (2‹ƒ«C-ËqÅÅ53=׬«sœÇÄÝX¬ø§ÙèŸÓahk`¦6€áàp:Ì@ÕÛOMWt'q•î$nÈhÔ|ŸßIéRгÝx'qPwV4µµ,^ËÇŠhF*m/·((³áfÂä¼#äŒx,”‘8EË}¤óLÈO iÕ¯:»g`+ÇáèY”Ÿ»#OΤôì¹7Øêí£eýûÀ…Ç–Fš|‡²CÝ“["¦¥¿Û6ð>ܾÿiýöÇ×xËZæâJŽ"ö½$ï?²aÅãÈŒE,O±~éÖønC›4#¾²³îðÞŽÓS]r(\4gÑà®úÐ4þqË“S¾»áW…A_ôR3W­À/ÂìüÙêøègï5¾ùÑÿ‘Þ9W¨~(›Äy1Ì?^_Ó** 8â÷­ÄsI×ÓÔì.ðV5îÕ±4µi $·æQ}üißYö-Þ˜èõ/ðã$¿¸îNχ>|Ô¢­›y ¢€«&¤ŠñÍ4ŽÆWÚÿkÓ@ endstream endobj 353 0 obj << /Length 1491 /Filter /FlateDecode >> stream xÚÅXëoÛ6ÿî¿Bè'9¨eIÔ‹,Å’"E—l÷Ú" m:ªG&Êq»¿~w¼“,»Z›næ/<Ç»ŸîAúùb2?bGz2 g±q‚0ô"' /“ÂY¬7îoÓL¸ºÉ 5 Üv: ܈f:"r…'ƒdúnñr~.üž0ô½ ’ŽO:‚ öù¾ï¾:½|ñëé4ÌÜg¨A¸g,Î.¯/®.¯QÍäl1ùsÀ>ß zk„ø©³*'oÞùΖ^:¾'dæì¬`éˆ$õB  çzòËä9º%‚¡[2òD’9I–y‘HÉ(s_äm©§³8ŒÝïiðà÷ÊfAàÉ8&áº½Ó É(còÛªD$tÕ+= b/ÉÒÃ=ºZó¢ïEq6ºx„ÿ p“èŸýX¶Â8qwyQ•Wˆf«›JÅGâYψ³‰X5™»Bñ÷Ý¢²b)ûd˜]Óø„zrp/¶8ÙMÃÔ­Ç0Ïzc/Jò‹–>úeêm±¦(#+Z8öyËF«÷$˜·b5ÍÞú±oê¦%™z3¥)2ƒg™ÃPx>§/{Š >±ý¼–¡?àç^Ûu^Ý«½« ‚cQ#ñ£ŠúÈÊ~8¡q©oÁ |CRè†%:ôɾ‘¨ûªHM©Ç}´,hÂÿÍç3þ_#3?å0‡£ØËBqb'S²X@N`+0Û›ú­/«¨’ÒKeÜUÑÒÜŽøQ's2«*rê9å"{öcnÔ²Àê — D6‰õ*“"½&®ÍsÕT6ø‘QjcÔ-oÞØª„²iù‘&6Çi¡M›º€šv½>W¸«º„ȱYíaFžôð ódš> Ójж @ƒ4>,n¯õLW©’\ƒ&5).à!F)î±"·‡ôh!Cš1¤ƒs%B z6–rßêF`ê8n ­^á¬ÓM‹U*à"™=aêÀµ‚+ýQ8>`ôè“ùSXM"—€­ïIÖ:ŽšL«V(øž¦«št¨œÀê¥Y=ïnµ7†ÚØÌ}ª½Ë ·$Cœ­Ñ›mA´j;)MBK0eÛÂ'é›52ì)ºëc"*´ùFƒ‘$N¾øY¸(ü¼5w 'å‹«mÓè-dX€ˆ´nÀ¸³ ¤öÀâŒ54S ok·MeóUT<6#k¶,»f†­¦·o:K2é¾R\A ´jf‹ g…QÝÉ®(Î,œÐ $ ¢}ÄÕ-Õ¬i¿@V!ï0µW¤¡súéX ÑAa’¹FW‰¶—ª„CZ5EŽ>àd_l“¬CÉeWmÞª© ä“DÂõÞú.Wç€U ÷|šEè㈭úƒ*ï ýµ·¨‡ýÉ8…“ÛìÿF=èÏ]$þi_½áv}õÓÙÍ璘//._Œ)‚NŽÏŒØïU®ê5wûJëýÕ¡rRF׎<¤ñÌ‘@û’© îc/öl~’í™Aà²w–MåÞÐÃÇ%Eܱ n¡ò(@¡D ?±7f«‹ @UÔ/´Ñ„­_³Þº;x4Uµæ¶áBHÏC${Ãq½Kb¼Ém?(ÇÉewk:R.¡ˆsEÁÿV*«ú&¯àd}Sbu Ýõ¶À2ñèjy}ØÙmaI¹·ô ²ZW·b¨{VÇ«Æ3¯h4wôTBºª[ÒÕ9’D7`ïºßÉï#«œï#=0ã 7Ñ›0”ØÑˆ f‡‹q,¾t¼&Ýnì!Êë}ä×)þŒõcG¢O=¾øäÀNv,!h·+”HV „Éÿu<ÁNu°Ú¿47ªÛ¹*à óýÀSùšëò>/ö Û¼dÊúƒ#[*›j©Ï÷8¢nJU­F«_Qêøðb^DÀÒ˲Œ–#Ñý-ò7#!„ endstream endobj 357 0 obj << /Length 2210 /Filter /FlateDecode >> stream xÚÍXK“Û6¾Ï¯Ð-”3âàCR\{˜8cÇ©]ÛO^븦0$¡L‘Zœñl*ÿ}û”FqÖU9ìEh4@ Ñøºûƒ¾¾>»x.òÉ2^²˜\¯'BÊ8›Ìe/–éäz5yý8]¤‘nM¥¦"rÓ™ˆÚé,M³(—¢˜¾¿þîâyšŒÖ‘2‰E¶œ$¼†XÀwI’D¿|õâ‡Ë©\D/®p…4ºúùúêÕÛ—¯_½Åeή®Ïþ}&à»d"zkÒX$óI¹;{÷>™¬`è»I§ËÅäž&î&i1%HÕäíÙ?ϾÆcÉå£c‹Eœ¥s6éâÉÝ4•|0×àqà˜uscêÊÔúÆ)ûáÉŸìÀC2‹—I1™‰<^f¼ÔV¯ø0¦f·(î®»ºt¦ñJÚ´¸4kî¦y©Ö¨ÛJóØJÿš¤Ym†¯¬î—€On-^Ã~:“óH—fýÀSÝV?Þ7Å}áà™ñ2ÏÙhoÅRFvÛtÕŠåºq(ˆè_Dšµì“Àa„,¡û­nÃ,ÿ©±ÜïÀ-ñtVÈ$ºÞåNá×Ü/E´êð0%H~>fþ£yÉf}ò4QùLUÜÑuÙ9ïR胅5KŠrÈ(h;¾ÀaÊÝ=Û>p¯RíÆ/Fgïvøë=ÔòXÈ‹›¶pê,“ÑóéÂß:à)·ŽiÎRðYà¹ÚÀÔ¹`ßB{Û4í‡sgâ‹ã|T½T–EoWÕà×÷¬£«– ï¬;˜‰$Úw­~ŠÞ¦xF©jFÈ­^ÃU×¥>uª×zkë1Ø9kVž§Y 8Îêjs¼„î¬8ÐÉüÁ»ïn+SBÐRï×$OöªU;ít ñY± ˜UkÇ—+ࢰwWºd(h  {ƒÖÔ+S*§½–QŠð† 0Îñ"zÆãeC×°òÓûhyKÁÂ`üDY&üTy†ïŒ5pË$ú¦ –q2'ùÙ—_²P©zÓ©ŸÒjëZCÉÄ" %Þ‡Å2Ìlêêá°Á5w}¦ é­ÈÀ+³[´Äp}§ÊZµ­Ç1ù ¯;> éMKaSµMÍ7b=–R1¾ïÊÕ ÷H¶oäº\æÑ;ùU‚ƼÇn½¹ÄÎ÷—ÿàQÀÝ€9T ˜ÃÞ߸‘_Ü&OOA9Ëã…LýþégAÙᤇ=ú:Ò+½æ84ô»Ýÿ‚oqð,ëŽbÍmp"÷]ïž/÷Ì D¡Gð*ÆèÇÙ ·#ôg¡&áÒcôCÿ7côC×£ÿÖba–&¡N€€K×8@†ƒâÿØðØaüã ·Œ}FØOä#ì'‹€ýd\Ç óûùÿ9ö=öÜÞïQ«ktJU³1e´î«ä=wã¨ø*¯¾=B=PATòYù;+÷¨ìnoÜŸÄÏ_.wÓ" %賓?x4ÄŠupû¾sç}9:­Þ ÓÏ{ºEí½i}™[GKšõLn-Ce‚g6HhN`*Ô ¡ØãKÛàr¤ýmXë¶Ê±æ7ps 8ìö8ÆN«ÕŠ?ÃC æ¾5ÎÏ$Ûp ¢+§èòS×ãÁv 6‘1ó;qŒ{SyðªÊ6üÒ ‚+(ÔÀU;oqWyòuƒOÏ}ÄÀÖí½±C ±€X!ŠÖc”‘|nÊ¢]îÉEÜÛ8 áe ·JY>%´5õEÌ õå³$Ð×"8OË3Ìxµúà—!rÍ7o^úÚÇË#¡Ÿª® ¨L,ýE£¤Ð5¥¶ÓiÆVÂýÌá™9†¶&×¢Ù´Xõ‹ï9'ÝÁÁüˆ"€¨Þbžº3MgY¡)'»ödjäªÒø\®\ùhì16Êf·‡ðéJªlkC°0¯¥[¦§Ñ_M$‘¨^„WÕgç”ÐÓ_!|‹c Šá­zQ@«ø«Ñ›[n=ƒ†qZŒ‹`ÊaAáÉþ=!F¼ô¨d¼ýQÛ‡tÆ™(÷P#‚,üßBÿ 0˜A¥?úœÏUàšÙÉâPéÆþ#%Í£o|I?ç”vϧLŸT%Q·dl~âyÜÃÊ>eCü?I‚öø£½²œËAV'¡×cÊþUè#°y5 :ÊîЦrvk|Õ;ñç’=EL^è˜~o(OH6æs~‚@dCTõ<ÍòQÐ[(tD Âñ;1Ù jö– Í l³9;H ®ýîÊí½ Ïºê™1[F¯^_³P3ižD„ê-¼ÅÈ—0È¥%ò*L9þ‹ †è¿×ŒØŽõ õéq´ä|úVíüZT`ýAx*ýPqN•60zfª"Z)i¨Áq0þ‚7Õt\@†§#tÔj`Asœy ±sf†(ôÔRŒ‚Æ“J* _Ñ@ë¾ðÒ!k‚݌۲Dœ™Å@ŸN†"s*F¡ÈÓx.²É¬ñ"õÿŸdYøßþ¿‰qk™ endstream endobj 361 0 obj << /Length 2363 /Filter /FlateDecode >> stream xÚåkÛÆñûý !P*°x|?Т¨ã8ƒÔi{—"@¨{äJbM‘gryÊõ×w^KRgžÏ†ý¥èqwvvvvÞ;úúúâò[?^ånžÉêz·òƒÀVi¸Y®®ËÕ/Î?×Yè讪ÕÚwÌzã;- ºõ& #'ts?Yÿvýýå·¡7£žëGùÊc~û<Ïs~xþú»Ÿž¯ƒÌùî%R—?_¿|}õêÇ×WHæâåõÅÛ öy+ä&t}/]Ç‹_~óV%,}¿òÜ0ÏV'B<®Â$uÕ««‹¿_|× òw®•d™…)³tùÕÝ: øb¦ÅëÀ5o‡›º*¶¿za¬ÌW— üÕ‹½»u9ª«ÔM­aîó•ÏDDnî%«»Iñ!?õºäkªÑ –]ÕÜæÃÚÁL“Nï«Ðíšì;Uæ¥ µê”©Z¡fZƪš²*”Ñ<3ôÕ¾Q5² bÚø¾›Ç1óØÚ¡.#PÏÍzªÑ<)5¡e©oñ pP†!/øS´´©”]G…Ú½çI§UÉÛð9u•Lâ wë8vT=È´Ý=XgÞÝ%æ¯UL3N]ó¨i F1iž›ù(<µ,‘âežåÎéPë u¸œ:G­šÞ‘-:Ê>[ê‘Ôcò¶ê¼Uæð@u†¿£q±ÀñA5{Qämj¸¥[°Ìt}~;²‰ºjªf/v4»nSoðÝ [µ*´Ëö}æC›ÑÀs7LÃõ¢mWþŸ9iÉ:N&G"Ï¥ÃG¢`z-ØŠ÷¶¨”;Ò ÊI®p3È–9Wå¦mê{ ПUc'†þùùóhnê'6¸ÿiáèÔM§è¯Ë½ÞÖ ‰Zdš0¶˜~Š™Ì&† ð‘F2ÀŒþ›•?7+?˜›•oUçn1E¾Ç¨“ùï30?…Ë =`ÆwzN÷D#7 XOÝéiÂÇ{]"›»DI£é«R‹Sd" tW²r@ìëQ"YÆìaL]TpçH‡Ùš[gξbÂìÖÀƒ©î ìZäŒlué&h¾ŸÅÇ08Ãg0á‰~‘ŸY3PS 9 öï X×. R1 Bé"îd{¥üºH–¾dSLµ`PF¦$…¶64µî1¡x fÎRm“tT¨º¾çµN¿4¸RÉ~Mè(/•:!/øCuFJuN§$ Uãy¬n 0»– \‡ –²Ñ¤•ÞÕ`Ú#8­e1ÉÁJLÏ#)`¤Œé*Åš§à EÐy <òkTÕX"½LÄ{ùD çþ”LµCxοú{4}Ü#Í¡¾SB*Œyw<çyÅMpÆÛY2 K&„E¶ÀnϾ" =ùézÛl,ÃDøT.Sžöà=ÒÛ¢f÷(põÍ;È? ÖTs‚ÁjMñ·$If Â:Là Šñ âp*×Èk¼3¯ñ¬× ¡rÄ& 8Ì‚Æfµ?+H¥*®þ^Ý£*_ðDqàå!}¬`€ÉùÝ »T9¯šÇ-6Æ£ZÛE¥R-ãò É(™Ä„ p´à#a–:¾ëó€sB€c7à1$Ä IïzhÏ‹ë=Ø ê§¼›%NÙ2ˆëw`tàœ “‡@Øme ƒ®Ø>«ÂÞboÓ½”ô¶=T,}*£‘Ô]·P…K²g™}ZFŽnz÷±‰ÀK&[æDy t†§3s&GˆœW²Â GbË©ÝËïzzåÓrËß™ 'bg)3O¹úÝ¢.HG Ä0x¬ª;U%¤ù:¡›éƒâð¼_á»i>bp"—|óŒ,‚‰Gþ3Ã='Ècº~'—ßË/tîê¡âÈ[#:þÊX_m å_|,ÈC³Âåû9}Í“¡×»¡æq% px…ÁL•Hè„6Y’bKfNNð¢ìðM h¤EÜõ²X#+(I@¡òâ[ñ*)¾ýÀqœQgI¬gˆ\Ww;x$2HñNƒçoÑåÄy |¤L˜Ž €,†#úòÇtðæVx  Å!'1„ØdØiÕC¬AMx¹ó X8{Ýè#u@º@É<±uŸj ϶Í|È ju©`˜* NlÖ„± †h¦±4QÝ=Ãé’ˆYaa‹£ª)o> æC¯öBŽ,3žûÙNbëò ¶;ª¦X”³·Ï{ÌZR…±|ŽçcO ˜cÔ4F±öÉ`Ò€ÃM*UMN±©?fj’µÂÅÓÝÐ’µSi4!Õ¿a´/f[{PW³ÿBPZKZü‚ø˜™ tvèRp’m‚¢wÑ™AÄg¡= c`£KS„R½… N•tdÞír\v¯^¨ºvØåK‘ñÎ]ª2$±çTÒÑÃî„ó êNP¾'—" ßüí¬ì›­¾,«¼ÙöòRWoäY†³~u(ÀÝUmN—óñ _™H ·$O(÷·ð€îÀ).Í¥Ù–·Õv~ãÛ*ê¿–'õ®={‡Žþ]A¸ÑŸVqµ_H;iê†ïd¯Ç{Fÿn\×]Ê_ùïÉæÆ¢ÿlrÀñâ§(‘KMdÅÐ,“Î*7FÒ 8ÂP˜¡ð HÑjÇôLË‹SLnÕÛAÆÄ-Öô? Ù †Š²BƒŽmâóä+³‰t]ZôÑbvÜ ¶Î;?ÿõ`Ÿ†UN¡¿²Aí!¯GQÆö„ HÄ̆´ l¶d‚šœéÈö¨no±A‚r©(å|Jü„TW@0ض˜šŸŽ¢BꛪŸôÊýÔ<ÁhÁ+B'6k¢ÐÓ»ÁZA:¾^±’-³gä³Çž¯ÔýÑuÝŸu…$hÙ–WÞùœ &õ8w~Dí‚7稙c¿Ô¿–.п‡Þ0¡±½G®Ax]u¬ìcù²ù‰šej­ÀÉÒý£~ö÷¸_1ïé âØœÝFŒˆBþ†Š;Ü0Ê%\Ëôÿÿ¡A风å5²òãÐMýÌ/w³,cΣØþ»ö_ñ/W™ endstream endobj 365 0 obj << /Length 1807 /Filter /FlateDecode >> stream xÚX[7~ß_1B¨LÐfv<÷)ªÄB-ªv/€VÎÄI,æ’Î…lö×÷Ü&›lSúÛÇÇÇçîoòbvvñZÅNîåI8³¥£‚À‹œ4H¼,ÙÂùì~šd¡kZ[ê‰rûÉT¹ LÚÉ4 #7ôr•L¾ÎÞ^¼ý9ʼ$HŸe¨Îù¾ï¾»üðæãå$ÈÜ7¯PBè¾»z5Ã+.'YäήþøpòÎ^ÍÎþ>S ÀwÔ^­ÐS~êÕÙ篾³€­·Žï…yæl‰±rÂ$õ˜•ÎõÙŸg/о ÿ—}I–yQ˜²nO¿O€-ì´ ”é[]ØzuÓÔO/ؼ#7‘—û‰3U±—G,æ/35µž—†ÍÚ¢z¤îwœ™eÓV¼#¢y±lÄ‘º§–<_ýЊœÎ®j]v¼`æÐ-LɤÈí׺g¢,LQÂbá±âAæ¨È £$@ͧ£êQ!N£îÃ*O’JxòÂ?ûð<ð‡ïÀÍ^šŠ/fkCÊd‰h“®©dVÚÊöº·MÝ O½] ³¾ñªYò¸4ý!Ì­0Yv*SúFÄðP4UeÚÂêR.¶2ÝsTÕUÊËã˜ÕãþŽýi! 5†­75’{o®ŠÜçÏ'S¼›Üo”`-(–xÕ#SèÚŽÇ®o›zUîp`í(P^±ªõÂ,˜k‡"›Cgx¢y(-ëÃ+´™K–(:A6É¡v¨kJ2b^zlÚfÕê mï+óþ„clW? #?†¤ÂLDM#Ÿ]ŽT£;‹V!m¨‹5äдL,ÀJ0²©yYÙ®×߈¡I”¿(K3ëÀr˜.:óîÖJàâ‹Fõ‚¹–§-—J)„±Ã›Á˜´¹—IÎ^ïjÌû~ †bª¥±{=À]óÎôÿ‘ñÐz¢Ÿ5É ŽÜnØl8\mß1©©)b,`ÃT, ðAºæ[Û¯qÆ „%¤ M*[7r“^,¬rvCŽωÔÇ]ßlNÂcò¨íð@æs]™r/l·Ó¨LÀPÊŸÊ\÷Ì`»s˜äê0…_×õè á•Äöݵ5­n©â×¶Ð%o·f Í£.Ì( å;š!Ùñi2ø¡¼ÁëÇÁOØœûÆ…1µÉá8ù„ƬY1¡ÔõjÐ+(éiåTÄH†öÛðì •ŒRµŒ½fÓí:4ö h,äß©lxþ²©6¶4'ótË~+ϸÉÔº2¥´$-}§ÄšO] é7y–ò¦¬ÍÁ{¢Ü 4øUr^dm¤¼, ©Yg©¤®.·õŽƒØ}ÎÃ?öoáG¬ aÇäßx¸åáŽé©‹fÔ†Â8Æ*.yÖ蛡7¼ÜÉþbM3*¥µáZR®°r ÷áÕ¥.lñ3‹›Sh˜|Ü2°¡†¢–…‡!Â;æÃvAXu'×¶{°ÁÛÙÞnÝâQ[‘"É ³ºéOuaDà§snP%â3(€–sj)߃„°«»BFvÔ. ˜””A×VøQ3ÊÍÁ_º=Dþ!. Î€àƒ®0?Eô=ƒ1Ρƒ¨ˆPk¬[à[†~ÛCÀK&t;2~¾yH¬éösfd_íx!= >,zB©ÀL™0(F£,ÇðLZ²‹&coÄfÍ7€­¡å€¹‘K°#ô ‘àóá™áåȶí ¤È%]v®2¹5Ô"K\ÍÇ4„ùÍ¿^ó‰­|Qu$‘ÊþøöamnOé^ŒÝ†„a@$‚»’äØy„lÔ>€¸ÿ €tä0€(t‹I‡ÙG 8Ž õáXkZ RÄ™ OšSpÉ È³hüª> stream xÚ¥ËrÛF쮯à¤j1|‰öä´Iê4uÓDéÅñhVäJâ˜äªKÒŽ›É¿X`)É•ëL{1±X‹7 ¿XLž¿ æNîåI˜8‹µ„¡;i˜xY9‹Ò¹tÿ˜f‘+uU‹iàöÓYà*ôtE±yyL¯ož¿Šü9ayI˜:>Éràó}ß}{vñúãÙ4ÌÜ×/QBä¾=ÿõ|OœM³Ø]œÿvñåM^.&Nà;Á¨Vä~êÍäòÊwJ¸zãø^”gέ!lœ(I½ Úù0ù}òí‹æNxù|î L²Ì‹£””ûIõ½,A›tîZuÝl[I-t1w‹îð2F›W®¥–m!;²úÈ{¾3‹@Ÿø1ÏÅyàvÃn7#”î;B•¬HœûüÏ’^Ñ÷f:O\¡+±ªe÷l:›G¾»Ú¢¯Tˤ¢eQ½èPØuGǪåתO~¡t Gæ ä+2 QFÃr€G<àŠ}÷g…Ô·øGÞ˜¿žBðŽõ (Ý!*À§Œhc9`|·q5\®j’^ Í5s¥°ÆÌ Uꢦ‹#Ë™IKZuÒŒCWË w±•(8sÇ+x0+ƒ‘k¥™¤·´!TzèÌ)w·äºô) ½/¤.3’úõ €sžºð]ÈÏ¢ÙÕ–ý2¼òV§l©:*Qr×£žâv[!·¹»üŒÜ&ú]ãYy!Vm@òÞïóyj2E§ ÄR¶P T ¨zk­ÕwÆêÒr£¹£°¡CæsJ-,Ñ`F0y·3¡–ff¼—yÊ&$t*2ª+È8jµ¡+|¦ºWGAÀ§ûþ‘Æp¤Tò÷‰ àYȺ¾Ô×Ë/–ãb0IÀÉ¢¿^Y§Ô[v€ †,Î1d&ù·xL¬¤B‘Câ¹ûŸEM¾.—/ÞŸ-—>¾\þòr±\’ ªJù°× -6Q…ãOŸRšTm¥<™,ÀZ‚ÀŽ&‹Žu4oe¡ûd#MA¬êë'„¹Ýư B0˦j¿‡ÖG&DQqwÁ7°èvì9¸Û§ŠÓjh-|ÊÇ=Cà[ïÍb?G}e½E'ˆ@/n›ÐM ÐM:æMOϺ#Ɔ Ælû¥[Üï›+ºoÄL“ä®2R‡Ù)SjÑ+£ Žcw5ôØå x†º˜pCˆ8­Ôñ²$·˜©Ã}ÕàE]sÿ7x¨ocܘÁ_SòürÇo›7šA¬˜®:Ý©·j¨9')¼“ h(úÞD}œšÄx¾±Àdj[ t0ÅŒ÷çªÝй‡¼XÕæl•½ÔMÕŽ·Ž–QÐgÌ@¾ÔÌè´9p²jÕbuÇó õçú­8¶6ù†Í궪krÄNs4"ð¾®:F¨5}¯[ŠMK]¡¸Ÿò0M½!ëAì-~±”«a5·ñx¡;Zœp·É½,&Õ_Õ Ò=†[Ó;\’h‰Æ>¾0ƒïŒ•’ˆúäÏ}è&5|N†“E…ZSÇ’ûSþQÞŠžV¼ÿµËEYNC6ƒ—w}ÕTQûÉh¶# Ë$¨“Ð]úê a õ7Çháy%:Y²åp,eWmZ\¿èç=a9;‚ÊÍŽÑ&ÄȤìþqˆ]^kY˜š†Ù¼¥Ì¼Q]ƒ“‰ë¼> Í=]7ªcˆ›ˆΆf:bÙÂn£¡Mg|ãG‡²êp‡)O©;vo¬X\ ™iúoû¯1æÆð¡×CÑÚ¤*í/|lrÿ=ðaž»ª­ï‚-^à‘`Q÷6|C%xÒðbÈ@C‹˜èrÒò!†ÁhîQÇy?’Ž€¨8±1‹¨¥o#F4ßRIg‡Ö Iû°ÙžÓÄ=3é‡$‡þE^ã_HË{µ<ð“dJa©NNHΚw2Z° ˜s¸@ùéÑå`hy3-×@<»©ÝÀYµÒRÙηkÞ‰f´Ž°k­‚އ ›þ© ¶é+ZãxXc´I’síleä`Z_QtXúvÓèŽú¡åüJ]eV߇ã·ô½EÕÈÇóþÌŽŸRÖ´·ðÃØ¯¾Ûwæ±ÿr‚<³º…{w¯QW-7ì»ýÏÃ-ÿj¤ ¾£¤øOg–„ÞÜú8µÿø´sm[ endstream endobj 381 0 obj << /Length 2317 /Filter /FlateDecode >> stream xÚ¥kã¶ñûþ '_*k­¨·l‚½â’n^Zœ/= ­EÛìÉ¢«Çúv}çEÙÚ¨wòE$‡äÌpÞ£Wë«›ïT²(ü" ÓÅz»PaèÇ‹,Lý¼ˆëjñ‹÷ó2<Ýšº\*¯_®”gaÒ.WQ{‘_¨tùÛú‡›ï¢àO¨r? ³EÀ8T÷‚ ð~¼{óý»»e˜{ß¿F ‘÷ãýßï×Hân™ÇÞúþ§7oßÕëõÕ® jd+òU-6‡«_~ lý°ü¨È':xXDiæ‡0«o¯þyõ ß% ¥ü"IÂóÓ<÷ã(cæÞ5»Œ”wj€¥,ñº¾ìuǯšH'X¬" V2¡òLÇãÁv}ýÄó’‡ßÂe”©9àÆP—½m¯yí'÷·vh?}Ñ_®â8ðþfGJú‘¾Œ2ö a ¼}IïÄ—±øeCxåV—ýЂPhuÚ› nîqzC³B™'$ˆïæÓ¦1½)kó\öÆ6¼û0ìׯA˜fS•ivrµlÓè÷¥ *y›Ÿ~þ ÿa°L]³Í–¨ÎÊÊ]Ñ_¾¯4ÑïMïØHocDz5m: ã···¼@*8~q{KhiQ¶ÚÝ%„($Ýöºbpoy„g4UÙ ôööæ ‡ö´× Ïmú½&óš}o¤â,$³Ã±Ä!BʈžF‘§Ê[ïùLr–÷á…CùÔÇ[H‹ÀúãÔÞ‘âp ‹¡îùPe~ ¢xB#`ÛÚÃy§*ÜúÿT…v ººÃG…Gâ‚KáóIÆ÷<°nqVÖdµ%Jú©cØ > Û²î4:Az` ƒÙèÑvÇ€ Ù¿WÉí³áϼ„w4 :¶µ­3¿¡ÝÕ Ø&Æé|=B¿ˆâVûe:w Ž]CÞ¥)…/ykʇZó wJ^¾çÕ²µé‡²¦ð„˜1ï ð%ÞLð¦o‹#`ƒ“ Càá’¥z{è0žA*ñ†¨å…·Z}\lÀº;™~ƒÊÜû€—]+U1Mǧ̖Ç PNeÜ—sÏ…ÕÐé ,!¢óÅ<m8*‚ ûÈÊÞu5«øP¡™ø|`öN×êòÀ0ݶ¶íÐûß=û¢Þé¶ãm0H‹3%ÄÁ@€«$ˆ]Ìnx·ú»=ß÷Th°ñh°ƒ¥f=íÈŽ°A·7ÑÖ:¯ù[¯3YÀø¬DʇCϺµ³ÆIžQúÒnºktY€Øœƒ½Ë¨y¡Ç€N÷=œ¢«¡ÄR÷äÚG³aE"ˆåæV¦+ÉPÚ&‚€ìŒhД„+Èd( C™÷ê‰ÁíЈ»)dKÒòI»ÎdpóÌX¸|»ãÙ%Ô›Rö+Ýëö`ÍKFtQƒæ¼…Ì9s ºýÀ¼`cÛVo°Ü€0HöSÃ{lâYÆs3B¹ëK߯ÎQKˆNô*¨-lŽê\YA4ð% ‰ Ⱦ<'GÞ¦êÇ‘8¯Ù­Ï´“B‚$àF#é0ä§Á™X¿7˜[ªbØÖÖ5GG§'Øœ04ó b/ §ìE¨:}`ï-¼“j±Ø»ßŽÞŧ9“v¼8”æ®ÇM-TN-w‚ÃèÛ4 0â¾'6 ægŽý=”œ%[²¹Ø¥ˆ«µ8>¼²\"/ä·xl!ˆš ¥P•yÿÈ’‡¸+Ÿ*¾—i .X¶x8Üó%BÛGÞE+mªÙâ”+K|ê±µ€÷йŒ ùJI©(¦OHÖ·V²-&ˆ¿|ÅP|!;ùjov{‚?W(^&+*zŽG ;Zj°ÞòøÂe¨¬‚c1&ñ¡ ¸Ë2#ºm;QrP‡û½Ïëw“úb.IÕ\ÊŒåIKTÅÉ”j,¼Çç1I¦TüÔrœô‹Ûïñ\˜ÒiIpsokŽó¸xa ÿ“ú\Ø@^°¸Ã´ŒAcŽ1@ýµK™¨f>^µæœGáʤàìø ;îîtƒ¡´¥akv;*o‘~çuµÓ ±ãlŽm`´3J‹Dªcœa)VHKÅÚ¯´Òê²% ¥ ×JmGôÿØF©Ÿ‘;Ç®‹x©ý#Õà“T“ÌOUî5P¯|‚h|I4‘F½gFÖ!½š’  $Ç$Î Tz[B ”s¢ÞpðËý ùŒ1Ga"þ “i¥ z2ŒÏb§Ü¨S+œ]tñÜ+Â9‰‡0“Ö;Cpí}J¶ ´°ù§ª….°¤|6ì·ö > stream xÚ•XYsÛ6~÷¯àä¡¥’ˆâ}4O¶'Î8“£Õ¼$™ $AÆ$¡€ þúîb—í*G_ÌÅXìùíÊgó“ÙE”yUPåqîÍ×^ÇAêq”UâÍWÞ'ÿã¤L|iT-&‘o'ÓÈ×@˜É4IR? ª(Ÿ|™¿ž]$áHN•A^H2¢ î…aè¿9}÷êïÓI\ú¯^¢„ÄsùörŽOœNÊÔŸ_¾w…òN^ÎO¾D ô¢½ZI……·lN>} ½l½ö ©JïÖl¼$/‚¨Ú»:ùëä íK¢±}i$Qîåe¤IAÚéÞîz°,‹3eÔ4_Ñ̯²}j§•?Ãõ O€ŠH›^ÒyµÝk‰^Ýe·ª#ªÑ«¾–hh7¢ Ê²¿üÄÍèûQÔó ©ÚÍÿ}ùQ¬§qˆÑó AYp´_ÞYiZQSpj½QK"oUÍÌÅd ñ“´h¥\É%ƒÕÄ[‚pb¡Z>d·²c²SÞ 2í–®ŠoÜ[>ÐaeÐ rîf‰]0¸1Æô#½] ÕYaá¥4O_ø22_Þiµ%N×ïvÎm,<ÕvjÅ×}»´J·ƒ€–ÏXÑ]wœ$BÍÝYÕêžÅ‚¹ôTF^='u÷>L£üåÞ4NX úXtÉ-š ‰1äÍ$ËÁ %5sìVàóXÐÇH1l™¸5ÊZL\€¥vD¯é2¿½Ö½?z$oY…!8¨IÀHyt0Æ4ƒkI”)ݺ˜T©pkRdþoô™ã:öHª¢ (ô”“ôSµ(Ê;9@Ä»Eåè|>v;Fº† åŸÃ,¤ÇeÈáÂdèFïÁ£(†¾çȈèÈ|Ëoè¶¾?æ¼qæÁ7ýÑïåÊ)Î*GÜYkCD§š†7]XéÊÆrÇ—Z:Ë@Ò™¶…:†£[b50̬{º%>‡I"—¬Ê¦Ö ¬>Ü(gC¢uhà±âû —½é°ÜÊb줤äÈ ŸõBÒÕ#n:o#ça=“i¦lÜU-àäcy„ž%ŠÞê鱺k„UËçp(L ×à­*wŽ_(Û{¢¶XÌ"bß±÷mˆ‡aDÔ|ω~BŒkç‰{*^ÃÂvF¢u€HíÊY—&± Î%+p·tO‹•n·ÇRçºÕ Ó$¯ü[WöHâ#ÕHÑvhdQ¢â)uo‹iä®’µÒ…ìUÀ¤äâ~O+y·ãbà³ÓéãÛç±hæ¨Çú»ÚpÀ.×¢¯íƒ¦²Tšç „%Ü&ÿÓÜAx­‰Ž(n&+å’ØpMP5þ^ÉVáÐAè¼F—Dþr~о;Åeè Ûf‡Ù•kø]IW\EÅýOnjà†Ko$d‹…Ç‹%*¶¹J¾f©Km „¢Š<ÇÜ ý­Þ·yè›t¾C;–¥èä RôØ®‘ĨeÃ\Ð’-ow*& 78Ýë†6³mØÆò jðÕ;«õªÇÖÌá›” h—28VÈ„°ˆb-;K4 Õ-Ñ® "àhúrf1D!G8´â?~u»üÝÕsÏB‚Æ‚í ICi¿’õsœ¼r Â[edwÌç+Å¡ƒ{%f‹üIʘò .H„xâË›‡Çôà;b)*d“½ÛKðòÊ Æó?¡T”…Q¼"¿ G`R§ûß™¿a*w¥§h?üá_ؽ«¡ÞÓ ½¸fª˜¸Î Lm™Ú³î†ÝʿӆçÇÃO•ì€G½Ö À„1á|ÿ ¾6Ø|p_~ëMw5·L•<‹Ø'p$Ùû4\ñöý›ýÞnð:¾ØñyÛ˜> stream xÚ•XKoÛ8¾ûW=É@­êýÀž )Üz“nãÝÚ"U$Ú&*S^ŠªëþúáPJ“½˜Ã™áp‡”/׳7×^deNû±µÞXžï;¡•ø±“fµ.­Ïö?ó4°™äU>÷l5_xv „œ/‚ ´'óâù×õ»7×;²ã{©û‰å’ /ƒu®ëÚ«‹›·_ÌýÔ~{…{µüs¹Æ-.æih¯—·7whovµžý;óÀ€ky½[㹉UìgŸ¿ºV ¢w–ëYjµâÞ âÄñª¬»Ù_³KŒ/ˆ,Ïs²(ò‡ã4u !çîà‰g³‚oN@%‘ýPÕšUÌáç{Cñåɵìš]TEÓ€-®³m X ¶43%åOñ=‡lŠ-MµÒŽëJFB¾5О]b“õ³èЭÌICã•”9F`¢Z ®x^ñ_¹âµx>¨O;&`eœØ\ð®öH  ®]YŽClW¹Ü2ÃÁm!€Võ5í}BFÝ’‚`& œ¨šÆ¶adIÔbQ²Ê˜ð›•$È›R°§@¢g¾ˆÂáP 0q3û)TQdE±¼¬ÆIh_c†uõAD×hîˆ?L.êÍÂŸŠ£á¿ô!Gyhðd…á#ükB|úöë9áV/ï4Jµ3$Js)è@£Š0[é¨5§,%kðÀ…q†A„6måëÃ:ÈTþ#éûÚ8ìo¢d?IæÒ`Á.ÚeX³)ÃN·…·íð’MøM2ß$í+¬sàÃÔ4p3W‹Iɸ ™nbÎöhav\˜RH¨ºå¦0ãDÅ=pƒ4ëË„$ÚèË *S 9—ùÁ°$úG4ˆ§`¦…XĦçÊ ü§Ë:Zˆu ÝÀæêé¶‹å’LµR˜¢S©[¡Ó—ŒÓG÷4Ñ`§QyW&\§{Œh懃¬’çªæê%—bÓ0‰­õñɧŸF„ 4·\Pq§jáäÑ´ ¸–Š8„Ô馆]U§S´²ë^Õ‰Xµè¨¢Ö’T$ÕLvÂ!jˆ:WàÂÍÅ÷‡ŠïßñÅ\Çq`ðÀ£ ¤Ëë )ï/a<ºnbÀÒ¢FLWò-›ZC;“Ø! 9œÉ ×MÉ»âÂPà÷QŒÊq dM!y×,è¡;Ëzífj£qo¬èïܾ¯xϽ‚“Ø.ksCSQ›ØT=¥ª#çîêãU3z1…ϘÄ5/Èd3Õ™M¢©Ìâ3 ¼=NÚf2™Cõ£¡ø@³Ÿìñ!À ÆˆTQ£š2Š:—>âÏ0ŠSQa á:@ä\Èm›? 8QÚ $=d}í ¼÷è­kŒmºM'ïq“DNa¾6WBÛõazB8USå:ë hê=¢á¸ÃºiÌ0B÷³Ýb• ˆ¦Ëö{v:âK«–º(¡½‚ç»Ê_ØMÖúu9Úf›ÇŸØ‹ÿÃfš¡[ÆÇ”fugT·aö]ƒæ¤ozpÝ4I?{äjउqõÛýýõruu¹àÃ|µ¼éæ¡ý ö{À’é¾wÿ}ŽæÆÇ °+Dp´¿ý^ÅO½gT ~èdn|އÿe?¯°îçš‚A¹d˜gÁº9«š1Í7ýD”OøùèGÍÑ2l Ý„oJÄàf˜ÃÃg˜‰¢jË~wlzÝœà1¹/î 5kÀ’a—š=q|ú…;x196«Q`Bh$ôdÂǸßï·à¤Éä&/X‡øÊç†Ý!¨5Ak…:¥Ð]ëíô9ò"'3GR?¢Ûª2ß×ãËÛ–Nâ…€éØO}Z¹Ýÿ ÿYR endstream endobj 404 0 obj << /Length 1867 /Filter /FlateDecode >> stream xÚX[¯ã¶~?¿BXˆŒ]{u³.úpÒ$‹¤i‹=íK´Dû«‹CQ{Ö-úß;7ÊöY1öŇÃá7Ù¡¿y¼{û}¼ ªM•'yð¸â$ÙdA‘䛲JƒÇ&ø9üתLCmM«VqèVë8€°«ušfaº©â|õëão¿O£ =I\nò¤"ÖW°.Š¢ðÇûŸÞýó~•”á»ïPCþøðׇGÜâ~UfáãÃß~zúî¾{¼ûý.QÏf¥›8*‚º»ûù×(h`ê‡ Ú¤U<“`¤y±I€jƒ÷wÿ¸ûÏ—TŸ//ËM–l›jŸWi*ü9oÀ*0æšù[=tHí–g‰Ò”f2˜lüd “0ü­U®FÖmÕ7@å[Gsèe°I¨ffLû7ˆEd›*ʃuoªí–ÍÞÑæNƒl–Äa­ÆKòÓýo¡½WSëΣ£²ªóÃaýüdZ¯C·³:MÖ µ&{¢kSüÞEŽ"û©¯zâl‘sн¶Ê]Ètµ™xC @mö§U•‡gq§Æ2¬³E#zÕ¢H”„ûÁz П0bÁ" Å(˜¸´ˆ‡ˆæÇUô‹ÍžXÖgfí¦&7ÓG¡Q Uœgh¤¯MÍÙÔƒÆ=’²1ZŠZµÞ41LMtt8kÇÙNÕv c!±¯PÅ¥=‡Nöú Áo±#Äò$ʵ g—O‰²Q;mEŠ]† adíĵú ò#œKYÝøáÓ`Ý|–Kð:°t *§ã±=E üŠËH¢"/£Ð™N{®5ž¢"Aµ¢ˆ—™³£yDQç²sÁ(1ðê?ëÉO ‘ƒå$x•LQÍvSe¬åÅ\Ûž8ïáYÐ3´Ó͆—_åªõ|í—Hì¼~-[®×üä€΃¬˜µœMyèk«;zØÞ½môÅLÊ ˆÆ‰<z´Y;2V3{o3[Ì„š‚PÕ̇±›•Š €Ds¦çïžáŒÄqÜ,áÿø¤Ñˆ"E» B™>1(2¾£idNc~ÿòh`Ô=^Ä3ýYºƒ0Í†îØšÎ!z>­†„=ôã’•¿DÛè•bçþ™«ãîõë¯_?þc÷Š’¯þóß·þ‘Wc^|OÕ䓎ÊÁmíñ iÑ래?ØF[fî }S–Ø^ÖÕpTðë…:ÃÈ%–xje­Bö Ê:™ît·˜­Åy(µ-CŸõLïÌ­HõèìT»·S¨‹vÿ°JŠPŸF)r,xy¥ÖY\…ß*§XÎáªÓqVTzEÖå%ýpýk”{Z:mŽ.Çh™F!ŽöŸ9”Ÿ¾„9çpA¯‰"üKRĹ»/¢¿ÀjÓ°âg¡ñûÒžãÔ€:ð"|Ÿ Qp'¯Ãâk ÷ÂMÒ,ÌiGQ#ÁÖ+Ër),@AESï+ÃbùÀ8 l»I+HR·CHíìVß”Q©ƒµZq@?ƒi(…~Eñð•qtÿ«¯WÐr1n"ɧÙAè˜Kx*Û‹V¾7P’y–’YA¦´DL÷¤D‡°Fõp§ùŽ5‹Á,¸™¶Õheiàã“ïa2Þ\®3ªÝ­ ~+°]þYIShpÀ~v0ËÌ%\âÈDÊìùëž4kص :æƒðfl(î‘%f‹>3òWÉ®R®Î:xƒ@ýñ›òâD¥S`7êv/4¦›¬’bDÙ+‡ÒÇìRAd ÙtRšaJŠ_VúçÑG;à’\Ù`‘b†;׋Q€—.ÍÌYœ•é3!„YB»Ôø„ S­qÞ%0+`"ãýi$«ßoÉüž,¡šFËŽì'TCÆỎ¯Ì)МÛ%¡?£”¸ÛUZ€Û'nðfá±>áù ™cŒäèïâ:uJq/n¸éëvò¦þ¨$”ÐöFò†¯©r§yô‘DìHw³àŽ þIÍIž<¢ýèûÿ_†‡©§j™e˜ý¥ ùžˆJS/e­ž§;|ÓbBУϽ^¸õ8 <¹ûË ™DÙ½ªõåëAZƒÕ+*¥ŠÑñÅmfc¨æ$¹8„ËÈq›„”(Š‚†š ¤®K—ìƒ ±pÞ—È¿ÅX ééûÇàœYØEÿ0Ýñ¾8€—EbŸUl|3ÐëÎ^ɧ¬›(š’dnî»å‡¢÷iïÀ†=n(Ü0«ÉÒ›=|´f°†jܲЫ hù~§”CÌÛ.æßEß›¤Š¥¥«C«BQ†_"c…ï|'®Ì‘;ˆŽ/Ôòk„ÄGmçÅnàïùRaâlÛYçÒÿlãÍà]ý_B8Íz¦ß†Ù}+uÞ÷¢8×…Îßó^¼on©—©ôúZÐ'hÜðiÍ× Þ¦›"΂u†1&lôõò—ßÿ=öaæ endstream endobj 408 0 obj << /Length 1787 /Filter /FlateDecode >> stream xÚ¥XKsÛ8 ¾çWèÎÊ3µª·­ÙSúœtúÚÖÝKÛƒ,Q6'’è%©xÒ_¿AÊVÖÝ8ÓC"Iøð Ÿ¯.ž½Ž2¯Š<νUãEq¤Þ"΃e‘x«Úûæÿ=[&>“¼-g‘¯góÈ@ÈÙrÉNxÿâ¥:ÙîN2x¦¯Ú¡f6·Œ˜í„9³fÿã&Ô­'†Õtl;Lx Þ6eçãzêeF9$¢µÍë"Ícß¾"صNóõƒP£æ,)‹ 1M¦f +<¡F õŸ4ŽÀÕŽ–ޏµý‚ ÜíÉÏÉö‘ñË©Fâ‘)|4ÐP¹Aô³½3ÓV´cKÒ =JlË~3Æ*ÉI vÁïÓ‘Ýš=¥‹)ÓŠÁœdÝQ§#+Œ…·u3Šéa÷ô—MÍkyÿØ”Ýçíy õ¡®j|¸tZñÆvXë– L-¼{ŒP®J§¯™ã^újIŸÁ$œ!º3û*+L…OŒAÇ–®tâhªœ&c#¸¹i¤1qãì¤)"yawb÷7Pl,†_•å¹7  ’'›[˜ñýŒ …¾/èƒâ·¬ðÝšjaø[Ž9+C5!¾_°BÒ¬yݘý}ég¢ì”³šYkZN“7×öYwJ×i¿ÍËÝ‹]¡í§RÚ×d»ÑöלÎ>㇖Qgx6¦ƒhËÛžÏ É>ƒWI‡‰ÔÐ`KL­¦Z侂.²µRö™wC#l<è2²µ9xž&™ÿÁX%ÜsïÖ.°#ÅG˜Ù‚p$׊ÍÉD6ÆÖ§ª$<ÄYvÎМaÊÖÜÃ6pL¾FÂYÑ ‚áKoŒVóy i£W¶_Á©RJj•ñ”eI°ˆR2q°,bÒ8‹ÝÏiÿÒ(1x endstream endobj 412 0 obj << /Length 1760 /Filter /FlateDecode >> stream xÚXKsÛF ¾ûWðà5‰h’˧ÓœØNqìÆR’™&•¢VÒ6©rIküï ,@It8iNÄîX<¾ ½žžœ]{¡•:iäGÖtiy¾ïVìGN’ kº°¾ØŸF‰°e­ŠläÙÍhìÙõh,D` 'õ¢Ñ·é»³káéñ}× ÒÐrI‡ï‚œëºöÕÃÃÈOìû‡ Ê ûâî’}yžg_<ÜÝ€ò»·Ôyr5=ù÷Ä%®åíMŽçÆV¾9ùò͵pôÎr‘&ÖÎ0n,ÅŽTaMN>œ¼Fýô£$q“}§ÔÍé¶huV¯ôK0 |>}E­ìNÀ4MÎö‚æNêFÖØ 8 Iã¤ÝnGcpµª¹xIÞÎÛ†ˆf-ÉmUê&+1$ÊU®èüÍ‹g“'ÝÈÍûæFŸ,sd_“üéV³Ú<+ N†wlŸ YŠ­1Ø™°yŸLBÁ²ósÌh^m6Y¹¸ç¿º¡ ®æ`rè‡6°å!׫ßÇ=åio*²§–+NÔìê ÇEw#- Uò6û¸¬jypi–~šh¯bí­0ìeK;do/ùã}²R'Œƒ.ýjƒwn²æÓ{WaÈCÀC/Ï´—iú^Nc¬„­RÊŸš Áw!!BŠ C Aö0&ð€o„ÈmUÁÜh¸qð>ö<' ÙÀ·²”5èzã|ß~BœT-. ¦€c¡ÿ1àAµ\È%‘Ï QU˧KôÊŠÙÑN$äWW™7Îh¸1FFÒAVhæýt;›Þ¼¿š½ÿx‹!™Þüy{õ0duŽf‰Èëp@‹^”&¼"2G¶ˆ*DÁܦ*ún*ôþqäÇFzF5Hæj“´æ\*z’´·[K¶j¡ôÊ =QZ"Ê×€'h…æg¿©ŒÖ…,h½S Ùa3±¼ÀAä÷ÀNÄGµÓãÚ)<®Q̵3аvB±vrá|`0M'޹ Ædu .hÒ´É06O¸HLè9P zœÍ Š|ÕŠø›uQÇØ1߃BZàÙà ±¯U­Œ@íC˜t‘ï$Œ¬œÙÖ}¸„nmÕ°„zêˆüQe^´ €@ŸžvÜÈ» L=ßž¨ÍÖ<8Óm]W-#\ ‘¨ °ËÅ^•)£^5k¤¢ç÷ÍŒÐÙaYc›©ú| Pž“Ùò4eïÎΨ? .Á–ffšñrI;ï&7oï®.‡.T̃ÅýïË«ëÙô‹éìå'³«³¿®î‰ã·ßé+¨è#yª›jûjHíÿÚVâF`ÄÅ‘yÏ{Èß™W%6N?Ž1¼ñ²~$ d„¬=z_-ðäYr¼`?®î¸r @U× Ó¨A VP¼ ºD±·G@Ú…ÝÐûHà";8í`†YL5ô­%ö¸ áox%Ÿ›) ºVšÏwF çu¥™•áµO«U©»›ÊA0êè"‚<ê€Ò[’IåZ¹¬¡›óç­˜ ‰’nî`Ù}¦%æÎ ¸ø^/w,ÚÁÚt§•ʉԒ¹«åñŒ'ž qÖ’> stream xÚÍXËn7¼ÏWð ¸ì'I@ð!1öÀp|H"ø Ø‹ €!’ 8Ÿê‰gE  fW‰­†3SlvU7=Ü{*IJI*¸Pjž¸{"î¸ÕÄ= 5\k'\[R¼3KªxT$i/‹PIŽŸ§Z WIU£[Oµ£Yj-ž×Ô[IÖ•0ÓT<ÆÐD´0ÁòEðš„(y\Mñ¦ Ñ1(["£hÔDŽ!=®pIæ¼c\P ªXЩ6ôØm\a#µ _†{†%.á@‚ ‘ŠF¥„?fpa4 ~JO,pI`œÕÛ[¡E "[‡…=Ê^U { EѽM ­“į@•"Å? ½‚ç:^ÑEÖaz`Â:¬ŠÃºÁ]ñ¸7 ^ÑÝñ« OBÖV=Utê´¾FcíA,¶ˆ÷ˆf hD ÀX™¢'kôaSÃo•Žî°© ѤÖÈ‚ã%5Ž^H&s¸Œ «Ciœ´j ±Ðh?m–1zƒ/‚ÄÓn¶–¬DlZOF!¼]^¼xÊ€zá\¯ ¨jÉ@÷7×÷éâ"íö˜‹„y·vÚÇü€˜Ÿo,²óïL¤EÜÀÄîÕíÍ»÷é2í^½Ü§Ý›Ã§ûôõ7ü~À‹«_Ëî{Œt¸¾¿‹¼ŽîËîõáîæãí»Ãݺ`¬~8¼ÿíê»›Oé2Æ‹I\;¿Å0W·è‹Ù¢+î ÏX‘&Õ{ I¬•Ü0±& *-w,PqËYñt¡¿hû@õXÁôó@{¤¯“BCúÖP™Á1ôÑþ?²’|„tJ,˃$6/‰ YÉ=w,ÓPìB°*'¦ÚQvýK×­R2RrÙ*%Ó´”ÇÐUJLE¯tN}â ¡v¾©ÈcÞñæ¼ãù¼ã1ïÌ2Î_SÐ"9öÕ (öƌ͊“[Ö:åiÏMýé},|矢C`…·Vd:°ÇÐu%ÍI5…ü¹Ñ ’;çÂtâÂýØÔÚ*º–Qô¶Yô>%ú“Ó.JŒÚOã9&—nN.•ç๙Z©ù5+µz6jÇ[ÂQ<ñ¬'‘6Hm%mü_>=‰­Ž¤m3i¦ÉzúÑÒÇÓ¶õ­<½<Ï£½ð íc•ç²™ô|•çC=æ8×Ø×ª¼j¥e²:åªÙÚ”¼eÃ6tZ€;Ÿœ%Eëxd¯ek´êü‘½GöŠ‚0>âL@×/Ôg `“áÄ ”«g×)_ V­ËIg ­kã¢R'•±„oó%|+Ó¡Ü`ÕÎW쟥kã6Ôl³’>¯¤åjËíkeÕUöÜÛ”UÁ¢Ök›2*…Öô|Ÿ®¶Æ¤»G—­1éó»G×éì¡.œ¹LYÅv€Z»Í@A(³ô(+|e=µ&;ù ¯e(OâÓ÷¶ðiù–Ê-m¤æ›©Õo‰ ‡¥²•M@ÿšŠ%ëŒG÷‡Ç'5ëO‰ð¥Ó endstream endobj 417 0 obj << /Length 1668 /Filter /FlateDecode >> stream xÚ½X_oÛ8 ï§0pç.žåÿ¾mÀmX7t:¬)nºâàÄj"Ô¶2ÛY—o¤H%vk`½n/EI4I‘?Ryyyò䵈ÜË“ q.o^ä¤Aâeyè\–Εû×, ]Ùªª˜ ·ŸÍ…«hgó0ŒÜÐËE2»¾|ûäuèäïEyìø$#ðáœïûîéÅÅ,ÈÜ <º/Î_‘ O3!„ûââü „Ÿ¿Y Ì“ÓË“¯'„øŽ8¨zÂOU}ruí;%,½u|/Ì3çÎl¬0I½¨ÊYœ|b·x:¥ùˆwÐðœñëR<¸…ùÔwÎÖn3ƒ$ÐHÝ¡þEÛ–îTU¥/êvÛm+»Î–H·R :¦'6y‚r ¾ ÒÄUý}¡ªqî*zÉçtÛÂ)μ¼=f;póC€/ˆ‡ñøêý,OÜÏ? JAg>áÀj°(ŒSŽL¤ö¨œÞáŒ)pö $-cÈ™ñ^àânˆ“^Y)˜Ýoø ¥¬ŒÌ½ ¨’¿®j¯XüM«‡bôÍT`¨žòF3ÀHðÝwt"¢O½­ä BŽ«gX¿üµüaH÷Žƒsù"3ôcŽÌÐÆ‘‰K5»Ž'·ö^`¸îöÆÀšÒ Ë,Õ? %o7×Diˆé–¶Ïͧlùñ»ïn4n4jJ ä® &uƒêÁÂÖ`™V‡K…E6(2”' ˜º®uCS@,4½’<Õ4–ª+–•‰#X^bPí‰.åM±«øSGÙS°§r®LÃ/ÁôeÒ%<:!_¾¥ê†GfãàÀ<Ì2ƒÕa–S¶eèWSCäLÍÈQfgœ€‚ ý@ +¸TáJ–Áw ;ù@­¾Ó d•a,+ò—¹ÇÒ~¿œòX£›ùøƒgv:¨BQ¸od#[Su3q@`²ÇU±ëðËA’®ÒÈ$V+×PŠ0ÄY¶ŠB®¡ù’Sƒhm=“×m›÷pÁÒkµâª×”ƒò¹.±ÞNáH(¼0ïáHuWì;€?iøâÇþVƒakIŒUu‹|}NW¤õ²üë! EXá{“4üÐo4¢q=!Ïó¦PhJõ…Àä÷0r‚E#¶ÃÚñ>FlŠ#r~’çþFÖM¥·[Y^=x°ÿ±ÞóÇÞCé7¦&[éOÎ]œqÝ38€é]À)d¥;VOM› mAW\Ú-vÀŽ»äúJÀL••÷KþÔ8‡z`yîTi;)WlwËÊfR_t·GïbnIÀZÒPžǫ̂LëH\ì¹ØC”ÕXß ½‰@ÛåŽOtæ›ÒTÖ!{­m¶#ÐÏÂ>õ×°yÛ«^­ä8b’ûïS_£,€øÇ˶è¦( Ùé¸Vر¡Ñ\è‹ÜöõíhUœ¥ŒdšPW>u÷Ô5uíA;ÌA;€9L¥’ضãsPùÿM \œ~|܉#"‚v¹)á!ÑKžòƒ (¼ßÊvÇ ®Ø¸…uÛ“ã9ÄçF> ¦BC_äó4íä×Ǿ2¼q©›”c›& ' ä“AïK%·>È7d¢Öìº!nŠ<õb‘Øwò³ ï¦^åvn>ÓJ"¸Är~áxßdä‘ò)*Ÿº·Ðï¡ÍмÆ^ÄãÌ0Q-·}*hUË€ ÔR•êmÊÉPỨ¿¸³i+•ûˆ$M .â©•É+qx#óNYtº! 4ŸgÍJmÕ1×;Õä{‚0žuks›½é‚Žoj }BÂĺ©çï1Ù>Ó _u-‘Ê„¢!’»¢fjØPCã2ÝP'Vu#Áz^Š“Ù¯8»×Ǩ¤dïVz×k£:dyÁûWt{Ζ ز…‡˜ôþïþˆ:‰ÿÄaõ2ÉéƒqdÿùùœÛÁI endstream endobj 423 0 obj << /Length 2286 /Filter /FlateDecode >> stream xÚåksÛÆñ»~'Óƒ“︙VVdG©+»’7u<Ê 8‰¨A€Åb”ýíÝ×1Sûkó…¸ÛÛÝÛÛ÷_\¿ “Iá©J'×w“P)?žd*õó"š\W“÷ÞÓ<òL_7zzÃtz úé,Šb/ò‹0~¸þþøelñQ*ðã"™ÌC@wvy9U¹÷æò é#ïäâ[fôn†¡wryqÌ/^]!Ï£³ë£…À$˜„£h‘Ù¤\½ÿL*Xú~øQ‘OÖ„¸˜Diæ+5“«£¿½xzÆ8ó£ ¤yîÇQÆ~[[}Û˜ŠÅºE!Y²ÊÜéU3ð‚¶üæµååä•¡æµ²›Î€¼2<µ1kdºžªÌÓ}[·÷ÏR ïuÝ4BR/fÕèÁ8ž}oÊ¡yDcø¬pUlj¦b¿€CÍB€©„õâõ_^¿yóöüâüšIvô0R$~3Á5+‡cµU]Âö2æzp#ã0ê¡ÖMý«ê®eXwÇ_-sÝ÷ÏûÈÓÖ˜Ê1ìø»²Â®íÚYeÀÉHó@C¶@v†ÂƒAgaèIÊ¢Úú¾]˜ÑëOgiœ‰ø1øC¯êZÃ#´SËC:Á˜ÜôŒD<ÒÛ%Ùä#Åhæ;a¸1'¨íŽ4 \Fov„ÃÀ©«¯q"„ɶѻžAÄ¢[5¸M{sÒåñeÔ"®”ÝR<¡îï +–熩{Á,ËÆ òòÜû)H‚óVdYè¦1ý!ÑöîniáQnh®À[µ}×4àÝ<ÕÍ”P@ðµe{PVˆ.³.‰`G—BÑñ—õÑ”‡y·ºŸóR=<öš?·VÄ·(KîŒÃq ÎÝJxóç°/Røo çƒÊBPX{ß¡ŸIn`f±g~Ñ‹ec$;†[‘‡~E³y¤Yݬ5Z)Q‰÷gþ E–¸ Zeƒé÷#m‹gƒ$[„ÙîÑQñÀ±ÍpÓ°œ½5÷5òh7ôé.ý:ŸcP<çYýÇŸO./OöÇ›«óž9ø—_îroS2ôÅÇ÷õÆý†?È?‹Â;>fÀé÷iô#ê£PTˆ0@p—ÙÎ6’L[Hv³<òÓ4«tÞÂp‡ÚŽTA9¿]Û<2–5¦u0†H¨¨gPÙÕ)wËJÐÆ aÜ[Î.¥æôM•¥èGнif>ÓCp¢D‰‹6ËŠZn6„è†Bìý8Åô¼âÕŘ” *=†["á†ßžP$w–½Ñ–ãÖf3ØÚ5M3+»U‹L…:fCìG KV–À¬kù$qœ3C8ËÌ N£.º o=¯K„ÍeJ…‰z]£Èy`¢„‘2JM8½Õ½àvŒJþ€bwuÅ *ì¤6}ßõŸ^x¯®ÞN‹Ô;™FÊ;=û_Å7dªwèР9ƒÌÕÜ §´€[MZøhmç¼R îhn+±U¼:¶1€¡d—º4Ž?yóf­5kHÜX°0½®?RêCû>2gn p…SL~@_ìUXuTÈúVŠ X¾)`°¢ùC'ËÆ“!¨ª¥á¡ÙÓó™¸ñ'9OÐ Ê@ú5á ý‘™éHÿse~ ¢¸5ìƒQ”zèÍ4%¸\в¬+)•…ÎI4XÃHÊã˜Qô½â (ï|9—º…=ÔÀƒ]±°Ó€îÈ®îï¹ÑŒÞ,¨(?ˆ"¤±ÃÁž›!¨n#Þá•]•LÙØ µ³8·¦gKÂýnÕ–Ø?úãâ¦=¿o»žäS©’–Gì[ÔB €Ž8WãÈ®–K(Ö„¨_ISæ¬bø¼_áqR’—én;NtÔŽ»û¶8ŸØ˜K ?=¹:;¿8}ó×·¯Ï®Ï>­7ßÎqಌêÖÖtÙˆ) ÉÕðÈ ôV7E”Ø•z-Ì´Cv']YFXêÚã–—© ã`+#3ü ¿ŒòMß܉ˆÃ\§]Öq¦Ân4 Æ›ˆ”a@¼ÕÆ úuQǃš—Ý&ù¸}½à=:èÞn…L#WcHtxÒC§ r˜F{Ù !¸#xÃrEüzçv¼%/qð_0)¾ÿZ!Ž€–7äñ6º•ÅÖ´#önR¼aëÊ`C*kÖ®KºŒ8ÅCÝ5tS³û·MiFxRÕ¶ìÆ²v•ηnŸ\MŸDmø¶É&lß`IÿáìòõÉÛÏ[ B¶%ö—.nû®}ûq ‹|äÉž3îÐ>L¸ù5+#[n‡+ ê^ð*3@‰% +jŠ¸ÍÆ9¸ïæþÙ7z¹Kb­‚ እÂ2.‡+Ö­pTÊO(_°›qG©")s°ÐõÝÌ”¼'`©™â%[Öw7z2¢Q?} e®0¹DàÍ£>7~/𬱽ƒ³$Þ+ÓR‹Mî!D‰ÙVx÷÷l„¸ð^^“w£ÎÝ0Eˆ=•þNÊàV<ýã³£(]õÃQí¾²R.©k„±˜„;/nÞâˆKÇ_º…ácèW¬&î¹suWqäIæ6ÿt@zr¼ÐaP묗 µƒ8¯~Ê8 ý8ùþr€oâ+P© <£7¯,ñ®Œ{aȶÕ™Šwƒy> ˯×ëµoWííª·ÃŒ+ˆ·Ö㥟ííñéj±Ç²W³¾‚zñ¢³C×Þ¼DÇY5Í[r?üÁ`1Í)èî¦7áMè3ŸêîÀ)~WÅâÝùõwŸïà*MÄÁUJ¯ÊàôŽ£½Ò@‹ôúµ£×L €¾QG Gæå€{G0.ÒOvCŸ/Q{¯ȽvomÝŒ$——›ù${s”Õæ]¬;0ȮƆ ËCí¾ÍztÈGÝéÆÒm*޽‹ŽßÒ?ò…øN³àgÅ·{a-´ƒÈÂ/4DöT]Q˜ùa¦œ6™:÷“(ÝN#/8{‡€;5(A¥’Äý÷ñ_&“§£ endstream endobj 428 0 obj << /Length 2353 /Filter /FlateDecode >> stream xÚåÙrÛFò]_ÁÒ>,îéÚ-Y‡K^Yr$z“­$åCrJ8 hZùútO÷€¤Œ­Øyܼˆžžž¾»gôzvtr$“Â+Ò0Ì“ ½x’…©—ÑdVN~vþ3Í#GvªÓÀé§nà´tS7Šb'òŠ þ:{{rù{|ÂÐ÷â"™øÄ#ôaŸïûÎÅÝÝ4ÌÛ»{Ü9§7çÄèÇiÎéÝÍ0¿ys<.fG¿ÀÄŸƒh‘øÙd^ýü«?)aéíÄ÷¢"Ÿl a=‰ÒÌ ª&÷G?½þRÇ8ó"?¤yîÅQFÎ…– I Úuô‹˜ß Ô½èe-½GTè(@|`–8í¢‡%C¸]‰ž ~Åì6Z2CÕè^Š’÷3Ù”²äeÍ;Ûa#mú¸AàI²“÷w²áVõ+vA°§fœ{A‘Yü‹( ‘xaXXÏœâ&‘ê$^ÓÊÕ²i;Õ,§n‚÷+¡-j ºfXÚªª"¨mª'‚ôf½î¤Öv³D p*Ô?Cc"zŽœVÒü<¾\–‚Ÿ3ÕªF‚MÎà}m×Á.Ë €' VtÝvººaì>*8D¡fg·×·7ï¯?Üg ßâGd ££«»ès|”ÇšŸW/hÝ8¾µ”7u“"q®Õ#ª-IT³JÀ6ÊG&f>&0€/ ^¼®q xP%ç=±,h–’0íb,ŽT¯A¸8Œ«Zž% ³è ‰pq?Ññ!ö&pÍD `äçu¥æª7ßkøÉV«^}B^ý'(Ë¥Ô¼Y”%EUÑ! ÜZ §|D é-Q‰8fã@V¿BDâ¼8ö†‹˜>?»»Ÿ]ß¾¹:ûʨÆòá†Iâ¸î¼œ#“²p¬ÜÌ¢‰½ ÐO iÚµM»áõ_ü(i×Ä %™¸—]­ ;okIÈE×Ö|&X²hÆü¼îT-º'ò°jÖ›^Sû0Ept2Ř)¬€k7=¾¤¯y'EoÜ‹_”}À·d ‚$*QÁÂrf=\Vªg÷ê?÷ ‹~výïói:§Ó"uføçôÏü|Qvb?fã#4¯Z£(Åá´Z6({ì'&W«Ïh !=®q"˜¢½ =´’)M2g†Ö1'í³1Ò¢mFœÄÙT6Ù.› êqø+ñP¡$ašq‚r >Ô‚(¨m"f%ì¦ýJß Sö3jŠ)X±F@˜vc>B6Ø ñ¨=ÄÄi-$HpŽ–vÝ+à×6‡Ñ§W·›nÎ%¨–hUËfWØaÇ/~âC_iÛayQ4ômÈÉêq,PR/ˆSKìnàa^xq¤¸ñc”ø‡AÄ\  Ià<˜ø—ôQ*Íþ1› R ‡hI@†E»ú„V ^vä ¦¨e¦¨ V‚uÈ MÕc†àM }SqBcÄP éJr25Á:éADŠ q?»˜c "RB Í}”rÙ‰R>ãÂE¤ƒ(‡˜3¶]ìÈFäÝ Ë½-?5ð‡üú2þîýÙíÍýìÛ'“ÌÖç:ÎÚ§ÝЇè$­ƒMׂÚ~ Zþ4M€¦ÚHúTÍÁ*µüóć ÿù „[š¡¯,)˜z [ÚÓaTg½1#^¢66§ägQ¯+ÛÔb{ìgLzi2\5þ9b1`î§¹¥ŽíÜ\q‘7"g¬&ÜNdl݆¡íJrÒÿÄ9ÏôœéX:¬´г}«JÉé™G\aþ6óõ»×çרëþûíqì§6Ž}ÇÅ1|¬Œ£hzDLfŒ ¥¬8Bmû¤@ãP¥Z6µ´vÁ%¸‘©RŒ‰mȉã»’)cª=8ÈL@ðpÐE°œE‰óA»c‘L)VŒIVÉ‹AÒ¤ÝP«s˜yH ˜H Gü Ë3Æ’nŽáFMÍ põ>‡Šî¡…¹;Œ¶pSÊ£ý˜0 ¨¦5;Ž<q7ê'Ûã 2`½,wŒÄÌ)Y»›$.B±ÄŸÐvÙÆ·,q~ƒ™d¯Â¶Ýèe Raœ’Lj¤΀Ð_mÌÇÆ„»XêzBÒÅN‘üaœQÓ‰MlàOÓ6î5ë5‡Aò¯™‰h?àµD‚ÕáÄË)TµK…3yÂ5k.5è óË#3€ÐCG–æJççÎý0bdûå0н|÷4°êûõ«““ívëéMó°étê¡&4Š“µàNˆ¯>ÆO'mª1IÀýúþæÃ›Ð÷ýû·o^Ÿ~ìä§àcèÑÆr1’ü®b¼Fþ~|X qiÌæãq( ÆG<Ä¡ö‚Xµ ó,•™d˜„n!±I#3KÛ}£É ü¿~ü?¿8»¾¼º¾¸9}wñ^B[ ó€®öá0WlL»Éùá*‚ÁÒTïJtFóï˜U#jÉë-}ºù®g®6©í©L ÆŠ+ ³y$PÍ+úÎZd‹ äg¸Xie&AøÔ}§ö/i€²êñ@˜ó{|ƒ €¥Sæ)%Ox¦ IfuòÉ<™'sÊQ×Íô‰}Þè˜X'ë®…1°6 =_à°Â§ƒâ%!h,‚à€™¸* &£eÆhö*£±‘&3Fì{oìA£Ÿ£ž!Ô¯Ö>(ÒÓ¢ï¸O„)Õ^sæ7YzV"-E·_ñq’支óm÷ÈGÌVöíñ0цGI/Þl-~­¤{1¬˜Q䶺’ÇæI¨VúYÛØ›7vp26Æ™ª±i[—ü^ÔìØVò¥%äaÛýDÄ•z膇"µsZgÁb#˱סóÝýÇL‚;!J¹¦bVÚ>"(~†àžàpó³Ó?‡½afÝ»©|ÏRõχÓñŒxâXÖWß6Œ_\¾7Ïw§ïþ­bˆÀÌVŽÁp“õ1‘<(Ͻ'Ì ë4ó9ß²€“)ÜívIè%‘k%À #qFŠ=1$%8 iñäíÈ4¿w¿ÞþžÃK¹çyx™¦·Csõc‡˜GV<‚ëÖ\-8¼Œ$ÔýK“ ;JO\èÐ…ýÿH’ÚÿÈüîMÑ* endstream endobj 432 0 obj << /Length 2424 /Filter /FlateDecode >> stream xÚÝY[sÛ¶~÷¯Ðô%TQ¼Jâ9OŽ#7îqÔVš9Óv: I˜@¤BVýïÏÞ ‹ÃLÓ>ž'-€ÝÅb±ûí‚z½¸_‡é ó³I4,Vƒ0Šüd0&þ,‹‹rð«÷Ëp{ªÑ&†^;…^ D3ÅqâÅ~N†¿/~_ÇÁ‰ž( ü$Këˆ ‚À›ßߣ™÷îþåcïòî +ú8 Ãл¼¿»åw?< Î‹ùââóEJ‚Ax0-öÃ`:(¶¿þ JXúqøq6ì‰q;ˆ'S?Ê .~¾xgŒ²/Î8™Íü$ž²}oæ‹ùÕb˜MÀ‚ûKüý/êÌ9QâgÁd0 SÎXrÞ45ù"óöU1utYëÛF++d ¿Ià•*7"©Û S9ÿõÝ´ÔjÐŽÏ€$L×;Q´É[Çß™’ɪnYýx§žÂs€3Faègé„þ-ˆÓ¼mU¥ÊWÃQ¤^^¡xÀ!t[ox¨«!(yÄ™ÚÐVÐÒ,ôʼ#`þiG¶©5!:$9upyŦÂò¶7ŠLI<Û‰ä©á)žÓæ30—»j—÷'4S•?œÏYz–Þ£CšfþdJšÞ½¹½|=¿ý«¬–CÑ=åME÷¹D*ç“;ïÈtÛr,m8#>÷Qà;U•ßl½UíF“óaÒBê¨-Ür„aES%»DÉÆ’!‘·ÍÛ¯gÅÑ¡§f¡CÏÍ:¹ŽƒÈR.A2o²Í›¶÷²oÖÀÚMÐ-xËHIxU‡¥½6†©ºÂ4AÊv»]£¬u ‰Ð3Œ1-O‹¹lÎ+ ‰§ÛçJ­&|ìO”ÈÕMRR¡ ’¾ß ?Ìï®nÿóÂ#]x¤‰¸¦¬ a¡kò>ÎêuEX¬Z„׀ ‘8N3oÙµ¼À ÕÆÖ<#—ËñcÁäe9 #„Žýä÷ÅÌó•.)U¢žDÂ~Õã0…â`:ò32Yt/‚Óg$:¤øú¸H ú¾^üÓHî©Õ;£D·Þ*ÙFW2Åè ”Õ-ì(¸›ÀÕßôâ(æÑ^œ¡[s5úñPp:·´ÂóGq•q.@Äž'©ª˜hTÙŠi¹ái›WÅW0”êÈ(žBY1ÛÚ¢ÉS®F0µÊ ö>ÐØT­˜¤zºGkpC: ¼k¼-×v‘ m+ËÀ( ¶¯¸®ºãðF—··LœËÊž]k¹z‡®úZ…«ï¿?<ÁnÛ+GLÁN‰-à9üˆeËÔ®ÑÛ¼yâ®v°‡°ÔüûDÝD×ðèˆõZôbü­¥2Ðb™z[‹[f–xÑMŸËëªhÃx´“²);ó¤šQ\Q¥‚Õ•’ºTÖÕ‹–5XÞŸû.pFYjŒÖÜd¬¥ò HÎÁ—¶¹ 87ãèy#S'X–ˆÎq'V²j Ÿ$ª†{j˜å(7ê-*ucÿ=#9Úõ›ùûÅÛ¿ŸIâª+Rz5Ö+&•±Š©³*)"çw—$IpÝxá¬R„KµÃÖšô|É8Ë­7R£‘^õz‚t`)še´ÑtŠ`„c*7Š Ä=ͽ$U<äªy‰3”çópÎJcÅ#HˆVîgTU0ˆ— /b”DïC¥?w²ç!(<í1='é~Ä92>N Ä‚ñžÝKÜ€çAš:á×Ua: PuÖ}M %J®y« r¸È|͛岚[ubZ¯ï½’‰µ<;s20a4ò¢^óÒ‹N|…ìèðÔ iž¥“|qîtêZ‘qæ½èm~Þh›/Ô´SúÊé‚]lì·ÿØ3à p®á"eF†ý ÿ»D7w@$rÖ±Nì€Zó}ËÜŸÞÏï¯áñûpõöŸ¼gé;9¤ïÔeÝÔ³®éì ²Õ«3¦‰·=€<µeêy‘È—ô¤ lB†CÁ…Sâ[q*ÏV\ÃŽ 7~rŠŸŽzrŒHŽs˜‚¨·¼z^˜?äµ<áÞÙ¨m_ªÂ s?ï°pßÀ|Žò0!AcYr£¯˜!Š#ôàSœ GøHì Kg }‹¿ü¾„‡)Ø*R6bSèEÂ} AÛ5•¶ºâ_õçÎèB· e™ë=áxNhãüA;È…v¦÷£Ãó×ÎÉ#q׸æõˆ˜šÐ GŽ˜º#ÂsDŽxxY §8Ù‘¹;¼,,Ÿ†B8™Åô&F–/¸«¨¾³|;üþINÞYÉñÑÄ‹º×ÅtUÀxv¿O‡ËÅròn@:çŸBƒ†¦‘ Q$ï$ŒÊe k_e^ õR@f+ÕbmŸÂÂ¥ÛÌm Xú:2êË&ùÒDœD<|©òÂ`üò=ôañ-þxs?9æ•4¯•}EàÀß“¸ýtR›`‰?¼1ÇÆ> stream xÚÝY[së6~ϯðÛʳ±ª»¬íSÒätÝ9Mº‰ÛN'=3ËHtÌ9åŠRÓì¯_€e9Q/yíK ‚7øøP.·g_|ÓEáY”-¶»EE~²È£Ì_ñb[-¼–ëØ“ªÅ2ôúå*ôZºå*Ž/ö‹0[~Ú~óŇ8˜¬EŸé" 5¢æAà]ßÝ-£µw{wócïâæŠúq†¡wqw³Åo¾¾Ç5Ï®·g¿œ…°H°GÓb? òEÙœ=| t}³ü¸X/žíÀfg¹T/îÏþsvùöŒIîÇA¶ÈÖk?‰s²pó¤ÛNé'°&H½~¯ J‰÷ŒæŠN]@Í‹k|Æ–¤x*!OõmG*£0€Jµš×¬ÔÏAK²ëÚ†¤¶ß“2™Ì[¡'à4«0ô‹4%ka}ã“Û£br´U”øm‚.âÁ››¯..ï¿[™w¶ÿ¦™'N'¦~‘„4ñGŒ<œÌŽ’‚b¿=µ„†ß4ðþ«tY•$-,©¥¤^s€_tPè•xêDêpÓÅ£ië¡çéÑïýå* sokC€ÊF ͳÀA$”-üæl;ãgU׸mèé¶'Á†±í>S«Õô FP,­’¼¢y1½lx¦ê÷<š~\ô¤ÌëÓ¹ßή-¸ûÐãÑÀꆢâmwsG .Œ'ŠÃÄzÈœ£œ{DXýêcm/ ü9HƒC'w²õ uãYÀ ^ìÏ=î©T'K@7]Ø8fÕ¬— ’6ï`³Öy6¨+”Sï‘coƒ‘ØÄìÌþ ØHÂðàZ6Ú¨(Û¦'ÕJ³ºoyσX»{™½-¸²M߈màQ#œK½¨6íЕ<ÖyDIºivQ¼´æ•2àW´?:N€E*¹CÝS‡0¼3 oÍ¢ >‹åµWñƦ·‹ÕÜ|Æ(}IÅkÌí”#ËH·f‡æCàá ÿ9SdŽ)6ÛÍÅÇ«H?ýK¼!‰,í-AÄGГz/ð#TñH4ªBj¨A{+î6F=éf¼d8Vi£*ž׆Æi×§z%jîìèÁ«I¹ökòs‰+~Æ«˜DÞf7-à™F#ž$5œÒ ¸Y†§Éä‰$â‡1¤ª¥%œñø]Oúã&ˆcüô£[½ªä„9¬O°ßúdöAp޲ÇJ½{ô*ƒZÔ¦u dt|uûí%Œþi™{åNÁþí_Ç›íõÍÕæâæÝpO‚5Ã%A?Qb¨?»¸¡Žâ^Úcc[ÙÉ`¿¬!N¢£¿58¤V} €²Ô•B˜£ü¨x;î¡Á½‰ý(>؇ԯ|éÏùæ!øWþ é’¹w©žÃn”í.(Ð.H”Öá';ÅiÊ7ƵØýL ‚íôÏ{Y7<Ø‹ŽîOAêùØS»™šÆó®Ý³ÂV !2Ÿ­°`·3¸«ÝõR3±ãkÀì‰çCZn5ß»[wnïHùÛ=Þ8Õ²Z@·o¼„oß‹ { £l=ÞCMBJ‚~Ji³—Œp‚¿ˆ‰O Iv Ê.|(wB?±z„$Ÿ:‹øû@h` t5î<ƒ²Õ`LÍ´…Ääw³zfv†žµ%£À»ÆMi5MÙ\__ó", ÌR1u‚T+ºG6Á1„?nbrög5k2ÓR=LÁãÃjù›KuøUx,I8¨>½~vÙ´êˆ&{tN ÜSýp³ yºMIq±3à ù5GÞ²ˆy¥Þµ JyAj5z %÷L¹É!æOx/{R[î%¹òý›ÙãtÑÓÃγ †«‘ÆÞ—j|{{uõýws¯»Ž^ôpL/‡º†“§¡fXìÈ-îÝjÐTÒ&Ê>6 ί¥† ¹vã§ +¸P%ל€Üåjèø¸I´Ôz1çӵ޽Fé¹÷JŸô×ê±Ý 5Ær<Í—ó¾’žÈ ¶…t‡N”½*yRß’ö4ïBM«Yh0/™8Ï.ÂÔ:w¶Ñ¦”—‡_Á< §Uwí¥áQʘA®ç> <¬O Ç´ y"DTs1QSS˾—jUává°wg==1'™¸dXò˜¶ØdžË*(ÏÿëÀþÞfÏÛÍÕÝæ‡ë÷gQ:¾ V²ç,&5Wd¶Û‘ ްyfC*˜øpÌé=@¨‰?øÌ¶Aýi†L+\!žò{kãcj ¨¹ÂU#í<;z*²ë#*5A6/Ä?€‰Œ^œPÛÊ6Ë9Z@VnP-æþݸ àcµ„ùL”y›žôÌÒ0”óߌŠ=eæœÝu o&£¡\ÕÁydļIÀž¡tE`{èU£þ'˜^þˆÍ§@<)ñ^?1Äæö]©ÙMò:s>ÿÃÊ0ÿÊ0ñÞêííûH›(àlÉ.nx¼Á¯ñQ™>C ôºÂO²'K6“AÄi†v¢@8DcÞiC«D?ÿUÃUòI¿`ƒË'vêrȸ_Õ6v¼JÓ axeîˆÛ,_<4 ã¡ñkIAÝ‘~L[°¡å¼ùMÛICÙÉ1è‚Póšò †./zîÄ)FüíNJÇÄ}B‰Oü<ö[θÃéa> stream xÚåXÝoÛF ÷_!ôIbE§/[-ö¦ná¢q:Çh7´Åz‘.ñaúpõQ'ûëG)$ÚÐlÀ^öwäñÈÉ“_®F§¯Ed%nû±µº±„ﻡ5ñcwšÖ*³>Ùœi`«ZçÒv댅]Q;ã íÀMDì|Y½=}xz|ßsÃ$²<Òá{ çyž=[.j_.¯P>°Ï¯HÑGGaŸ-sP¾xs…:G³ÕèÛH€Ï;ÓWx+-FŸ¾xVKo-Ï ’©µ5 +ˆ'®Tn]~½Ä;úÉ£;ÆÓ©²ïý|q~¹XÌÎW³‹÷«_éBGŽñC7ñbk,"7 Iè#:FÖe7˜&v»–à ñlIŒTå9QºlZY:þÄnµluU{-›#æ…íZ§¸{Íâ|BZ•¥J[•‘T[Û¹ßJY¨Ï^äÁŸ8AûÁc!Ü$ŠÈZåÞºÎxZË ì @­U“©ÝèÛRæàü˜G¾îZZØêvÝï'ŽºÛä:ÕdªÄ¨ÒÍpguC  ž`"Ÿ>çà ‰7¼§Éµ3F½CvgªÑµ¼În™˜Kã˜éfÏ|¾äNmô®Yk¦t™éT¶j75V+Ž ÜíGÑþ”µÄßGÆÅdœ$—Õ˜cãîvíqòŠLÍhï5*»'ÐgêFvyK  0’¹¸Œ1É¥Æ.£iÓe9O·x¤.o_G³î­6PD] L—ƒzu –ç÷g— ”/ãöçG»Œ¹˜_]Íožž,Q@udÍ%ˆè‚0|Á‘¨ˆGiÒï 8M`Ni25iSͺ ¾²=,÷qOI{ø8Nш|ÆA’¥L¦ºC˜œ¼ƒò2cŒd…nˆ¯2³YW]ž1ÝRd€ìs‚’ØÍ†f©þì¡âÝŸcÒ ¶¨L¥¹¬ûâ J[²r¹ªØ´HL øÁ à„x›y†¥åQÁ¿gCˆŸß–Um„ýØïó¨-žHe†¹=RU 4TÓm6µjš^s<v®)M‰MqWføó}ÿ+=»‘3`ï‚ìɰ_\r­y2ðC:ìa(<á.„H t dø´!qÐ%B_؃÷´ srÅj¸ê€‚zÀÿ¦†-ggïÎ?<=Ž~ 8ŽHIj%s¢Lù茉œÓ5-h–e.eò ÓO[‚#°|»®º2Cw›³*>©äýÜ·nUЇfMÉŽkT7*(;ØjW^5$lÒ— e„núr÷·¾‹{ß½š½¾8sÀÖó%þ¿ü¦>ºÇ;UMv}wb â$÷f K!Uòi_h "UÈ´®ˆäê7å·ÔG,¤ª¹%ó»ŶÌ;…/ñ훪¦u7ò„@©çü܇õà<OÁE=~7…ÌÐ%˜ù‘}qv¾¼$ØbHùé©ëv›¿RTò`}Àùã!£VÆk"ì1Ø´4mª¼ãÞ!¸“Šˆ^˜;KI;˜%ÅÄÈÀjûÓÅ(#ÚD ƒa0¥Fj6Ò‘û£±Š øâÞ'\t2.K\`0sÚæXCøá×W'5XŠtŸˆ;zôÕµÎv]p'¸‰ nþ;,pÚ}åËíõü+Àçy¹S?8¶üjöny¶x3{zv‡Éö 4ˆ(JЙjØà>w ü-‡­êÚãRE¨ÅÚØü¨ë·ºfO|Wé§ø¹÷åÅÏt©¡ëæì(<‰Ÿö’ƒoØÈƒàr©WÈÁ±¬hœüh>î?®ÛŠ?©Á >M¨g6M‡!+ø9 ¬?”)r@Ýô"ûv»CæIïÞ¦U2£IïÅ_\U«z(~ c¤ª‚×RÙÀÓ€ËèÔPÇïºPøw0Ù=lqr#ó 1àkUW’,š_>Àí6M mµ E¼,r3“žÛr¿æÓ÷¦  ªÛiªú®W(¹‡'_ÖÑ¿ ;ñì‚CØ=„j‰ÑALS³ª‰«îTÚõ妪µ0JjF.¢ÀˆÒÏ\ðQÒÿò'ÈÙˆ( endstream endobj 444 0 obj << /Length 1793 /Filter /FlateDecode >> stream xÚ­XmoÛF þž_¡a&¯µ"éôÚ`À²&Ú­)–-Š4.öÙ>T–<'ÿ~ä‘’¥TÀ2l_,äñxÉ;ÿ:;:~ÄNîåI˜8³¥„¡9i˜xY.œÙ¹v?N2áªZr¸Íd¸õd*Dä /’ÉÍìÝñá÷ì„¡ïEyìød#ôAÏ÷}÷üòrfî‡Ë+ÔîéÅú4 ‚À=½¼x Æ/~»B›Gç³£¿Ž0â;Açšð?u曣ëßYÀÔ;Ç÷Dž9{+¸qD’z!P…suôçѯ¸Gô÷˜d^ 'É2/)y¸×µšLã0vïÕü:yåßœ  `f^Ç$¦KÝhYäZéÒJÁn!CQ£îUI‚?Ó'5éyÞ€ðJKRúâÇ~ÏÔw­-àDV»f° n€5¶‘r÷ø˜f/`'jFîi]ðŽv¦„ô†6Ì{Á›&‰—ŠÜ™†±—漫ÙûÙÙ“'öòAõ A%ëÒL¦a’¸ÍZ6H¥î#£ÚÑ`-qt?Š8’>¦‘ÚÀa¦!{ݬ2 UXukQ-ˆÙè"y89ËYÖÕÁLêVKžn^‘ùiF=ÈͶPÏW ø>¨,RKF›ü Oáüa À1ë“‘èLšз«²ªu¹‚ÜðcˆŽ6Hái§¶njÃ[äÁWŽ o#ÊÛ·€,£7(°–®J¶¹Ð_|!‹@86DUÍš˜QOo:U°o¼1¬t'ŸC9a¨|~yõñl"BÀü|¸<û'È„CÈØ½‡aÞ‚(Ev0m‹°¢Î‰Rš @¥e (jÐ^ÕRÚzn˘ik—­0Í…IÙ–3:ò¶¸ê î1Ý)œ'ÄÑl{¯©ÚŠ~›ïJd]«ySX=·JÎðBwzõûÅÕÇIöN/ŸY+ϱÁÂ)¯5^CEJ‡Œ¹´^eK{Jµæi¾£Õ]ÚVÀäg†ªbk6Ç:mì¢Í¯Á8ÇW\‚ª4RlÖÑö”Œ º¬Ê)ÄqKm2ä¶­5uß–¦QÒvãÛO ±%1Ê^$ì‚Hµ®¡lSO²ÚpÉ­eýH"]­@ÕåÁê~åJÁ¶ÖtÌ6eÍú%Ò‚’™öNßïYþ¡Üm£€<5lhþ·æÕÃʃÑöPÀ4ÆB¨šÃë:µŠ(rß »,¤ûõØåZžHãᙌ—ëeUt/¡mû‚=2ÞW´$¾wèU´°Úc!-ö;'êýòÓ7Ï¼Ä ¢'Ï> stream xÚ­XYÛF~Ÿ_!ÌÃ.ŒÞGŒ}a{11“+Ƀ×X´ÈÖ¨aŠTxÌá ÿ}ëjŠÒлp’±ºº«ºººŽ¯õz}ñÝ;/šeË,öãÙz;ó|Î?^¦Y0[³ÎÏó4ptcJ5÷œn¾ðœˆf¾‚Ð –™Ï?­øî]àŽôø¾» ³hæ²ß9×u·wws?unï> |à¬nÞ°¢_æžç9«»›kP~óϨóâíúâ× ”¸3o0-Xzn2Ë÷?¹³¦~˜¹Ë Kg´p? âdéUÎ>\üëâ5žÑÏ^œ1NÓe$lßO7oî®~{Ã'9ñˆ.37ž-¼h™…¼úôˆjªv¾Áèn§:Ki&ÚÃ|ÇÔ¹ù·„º®¹¯TÉ´áJ?Ìýü+Kê¾Éu±œ/â$Eׇìú®¦¾cÀ=-“[ešò™åJ³áùjî Ò‰RüÙK¨õ¥ˆ8§k xDŽ"ðjf´ýf$ڢ˼ع®ZQ;áãÓõpò(tVWün èkþЕà·:ô“ªB¯F.Ÿ£Ã°6Q2÷öT°î;³"÷æ39üÑ´Úê•­OÍš0üõÚÑH¤oùcýš qÂb{™U0q-SgK C?¤ ž„j}à¡~2mמ©Ã‹KÉLâн(*ÖÚ5sâ ¶8¤N£[)G©c0±‚ÄY]óøoüYQoešã»îv<Ì9{Af‹;6õžG|?°à¾æoW¨mc*l>F‰œ— æeâpANÉ¥Õù¶ÿ7œÚ+. Zê3Ž<>šëcÍxfJQy‡©¾j4–ÆBø%»Êl˼3óðž Y×\µQêNµeÒ¦›mÝìU•O†’Š\õ†a⎷e`q’Qq ÏÙ©q½ÀèVœÃF1˜ÞS‰'Ž¢·ãuç‡Ø¾ŠcŠú8àgof@Pägt‰¸r?ã“D¥¢Ì€ÒLTÓ€®`Œj˜5ÀÚŒ\ˆ‚Ї£\=g­³`îÕ!ArO\æ¦#h1Uè,ÐÈüЀAŽj-Ö€1a øRpÀwŒ5‚í+aÒ¿b°}ÒØIæÚ“ýºß(þ¢ÈѲý×±÷ 4béºmÍÆBÙ1JÆye¹nx7•4Ÿ,?U¥ôwXgâ@H‹ lUe˜óð"’2Ëänò¾†Úò‰¬tWBæX)ðÆH 7½aSa0ˆ 2M% æR¥ŽZ”jA€˜pQà‘=ªÌ~ W25Ô‡2‚ú"ãÓ™£Ì1Äõ[y3zÅÌî«‚N¤u ˆ|ú3£%_ªÚ>Z‡ÑÃáÌÿ·à® C9–r‡V½‡W(±æz¥"âÇæW0ÏÞ>òËúÝly“Põ÷Žç!A8Í Ø™Ÿ— ”(~0xVj gú§²ê™Ó‚Œ«DÙÎP«ßñPAayþ"­eXB7®4©¬Öøì^l =c Òo³ÂœU~4G\¿ƒ³f4‰ÙÈ(jét l”tÜãÆ}û½üsâzKà-ƒ$‚¾WåbüE~ä|ô¿w?1ùÄŸðç·§L]Q+ß™m÷Sýþj¢w-¦6€ä¹ˆºñËX•–xd¯Bq$WÀ̱P‘M$Ȧ`–tãñ!a¢RE/dzƣg ~Økªº•„÷Ùʉ.§ÜÝè_{pª }çòé Çõ˜€j¾“}0 x…-žÀ‘Å[Nx˜#qœ@-K_•&™5»]åÚãî‰E_©0ˆSÆ'ä¥|> ¾7‡<²a]×êr+Å·žÒ8ö^´à¦³ð$ÓÎÿYUÞ©âñk=ÕPVÈ¥ZwÚ‰†^rìDbP{(Ë…#˜(™+gòe%¿í=ìùª=ôÔþ¹„ª±¼È)Üòê›sŠ›L|Õ0VW£ î4׿›'ð¥˜â ;æg½V¢‡—-Ò-¾Äײ8«Ü o5YÁ…Çüb ¦þH醸ù Ë‘©¨ ¡÷þ°ó&CY¬ÿë ¸Ãºn”G×ÿ´é¥„ãÚ‹‚eâ…3Èâešù¼{ìÙ¿Ÿÿ ÊAL endstream endobj 453 0 obj << /Length 2495 /Filter /FlateDecode >> stream xÚY[oÜÆ~ׯXè¡æZš—á­n”ÚœJj­›I ŒÈÑŠ0—ÜΖ”¢ÿ½ç2C.WT‚ôi‡gnçòÛì×Û³×ïÃdUøE¥«íÝ*Œ"_¬²(õó"^m«ÕOÞ¿Öyì)]7rzýzz ôzÇ‹ý"L׿l¿}ý>ŽÎ‰¢ÀE² øŒ(€}Axï>~\G¹÷ÝÇkÜ{—Woù Öaz—¯>ÀáWß\ã™gï¶gÿ> á`ެÅ~d«röÓ/Áª‚©oWùêîWqšùŒšÕõÙ?Ͼ~.£Èü8HWižû"ΘÃêþ8…×ß×G¹W"«÷²Ý©ÓiL½k÷ªÅ=϶JUvºï˜t»ÞÀ¼b¢ú²NRO6ƒìUÅó]Û<ñd×–Ê_oDxÛ{eì…¦Ó=*„Ù„¡_$ 3ÛÝÁ|1ˆ‡ÂÛK¤<ñ¬lLÇ#s`Fè^ø¼ü Wwƒfj¯eU÷u×ʆ Àq”y“@ªtý?H'˜zŸC#ûN_ -åðÚÚîy¨›fI ­ÌÐôŒƒºeÜ)0ÿ]«yF¹û ëP·BxåSÙ€òÜ ‰_¾4Égì;cï)»ý¡©Kk |ºúîûíû\®sám™t1#¯˜&E¢ódβÂG5Øy2=ü6N?ðÇmÝÛud9ø•3…¤Ìï퀫’€p×펿wªUìs¡7z!R*ž¿ÓÝž#[¦È†Ù#8ØSMbÏ1ÛßËž'Ë®5ÃÞó¾ÞYo°¬Ã bö¨%k¹ˆ(e1D”xÝîJe žL“ 8/ÛÓð*{j7ô‡]w0‘,™À ÌF]# —4Ý®.—¬,ñlàh+kgÕ’FØgPó‘€0Ðó2{qÇÛø—Ñ’§.täé³°…´SGÙA4Y8ËÓ‘µ±×³áí5 RÔ¦ƒ¤¥næ©ÜÌM/Ðô Mgž •2¥®ÓØù ƶlÇ×”–`Lé~µ ìÆÕYÍëâÅ^oáÛº)àñZ©iÛ+:¶— øÐ)þr ‰K¯ˆž[èsS%¡/ÂÜí0À Bî@ý‘©¢"…¢÷ÄTûN+é^ÖYÂì‡]Ûi!fB®]q4¦ 8væÅ*‡ëZÌŒGuЬZD_ÌSî´ŸÖe´N¹¬5ÈÇø}ÖATé` ¿€¢~-²ò}ºú~]¤ Ã8òþö÷wot7nCCÛ  —‚dƉ,-‡C{àþy}äú¦×Cé" dZ‹b$:5CÁc÷û¸¥,ù;ªÇ®bl?æÙ_d¨_v$Ò ¬ØËÏë©õ˜Z¸žü vôZ‘Tt®]Æ‚ Z¹&‡IæÜÉŒF4N®½[§bñ¹É\ =rƒÌÐslXXbÙ»VÀ•Rà\7ŽXqˆùиþðÍÕïCâ"DXDˆ4t“91•“TˆÎ,T»¤!•8°ph1çPÄ¢ë OR™Ö%D¦»Ëa%ö2ÊòT[Žj³Ùø>ëpT±"}”p„bžÿhuqœ= ö£-â©øã4ú—vÍÔ-¶üцã`'É„ |ÁW¢4²¾‚£™¯8Ç)pEhGÛŒÅ販]ÚG2ã]±3\ ç¦¤õù¡GxTvÅ.×¶!êŸNªŸ®ÿ ÆÈ9‡®È99Ü[@9UôH¥†Ç¤tXB=ç—±§U­øV!È•Åq`¹Ú^}'kMYÆ+–ôxG;±µ×ÁHztr´”MIA˜¡¸zo8—CŒãˆµ0þˆI †[èôòE¾4¿—=[t‚´€ü”ØôŽ'Û„èMP“»ÆJ(µã%|ªæ¸I'FõgÃC¶".²]™Vî<l©Zw.d–sÌÛÚ`MU9Çœw¥îäø@#Í<ÿ Škv8¶I¶2ry‘síÔQ½ðæ7þBâ·.sÂÿ%€Ö•3÷jWL+øI¡OPD¡‹p—±/)8ß*Lä8¢×û ƒßjgP=¸Àƒ¿Öt}Ù T;Ò#}¢ŸñýÇ*Zz†¨÷àIzþÄ&'Öÿ¼Té>4ÅC@9}¼} „$QâÝ -Bà¦C‘?sôWžúÓB$¾º .ˆ­0~Aÿ4ƒÜ@ùr3 ÂAòbY†“eOª¿¹½Àçß$ð^¿æ·ÿÞZæîêG0ØÂq!0õß7 ±o‚˜¢(æâò3P <­ªÁ•Á}fF:•gHÁ÷®^ºðŽ”_•î ¯Ú+i7öî@¬8÷ìu*8Jl¸Oľ#ŒuKÒñ‹RûŠåȵ¬ÑI-Ä´¾Þã 1´VJ ¡”m%]°@R£dÅO%ðÁÒâf ÕýHv’⊱_íêE˜'>]>b1ÕÊ,×ô"ˆåâš1´•.ÐÚŽ ÓÓ˜œv¦×4~Lô:³Çœ’¦öÙ h{¹Ç„2“¾Zz$ÀSÎ2¢ùü¥øü<’sŒaÄžBÈ ¤ÜíÚúWnÞ" ÕY0>Ém¸CÒdž£E8• Ü Îj ƒI*‰HG85P2 ïJb? tϾÝßiäþðøR…¬£ endstream endobj 457 0 obj << /Length 2072 /Filter /FlateDecode >> stream xÚµXKsÛF¾ëW°tX+¼×ËŽ•Ú’JYWjDŒH”ñ`𰬤òß·_‚ ²ÑöBÌôôôt÷tÝÃooO^½SÑ"s³Ø· åûn¸HüØM³`q›/îœ/ÓÀ1mQê¥rúåJ9 Úå*B'p3/?Ý~ÿê]àMäø¾ç†Y´ðX†ïÁ>Ïóœ·ëõÒOëÜ8×—,èãR)å\¬¯¯@øõw7(óäííɯ' „x 5ª¸ÊK›êäî“·Èaéû…çYºx$Æjĉëè\ÜœüxòíŸm 7ðâEœ¦n$¬aÓï ØäG‘S5êØó¬oà›:MÙà ñSX{£7È»›ðN÷“‹mÝ´†ÇLtÙá$tA$“O8;q†Îä§²©fòüÎð¤Ö•9G™+¥Ü,ŠÄ ¼—0röCƒØéq Rô~ß6û¶Ð½¬™¿Ð•þì0¶ÍPç<w?­q—«0UÎ{Û¾õ–—ó|´ '¨=ª!SãAfNë}©7x9•þŒâMÇÓÍðcئÝ¡€'^@ŸâôI[?ît/ÛdûA·s–£™7vZ“{ › òÈPáï=]!^4.4ü%§%à4vØœ-­ÞVƒ㛎aWÁì~Øv.g‹ŸM"rå‡n¹R@C úéæíúêúÝ2ð( ²IKçC¶€r-“L-ä]Ohïˆûb™ÅÎ-þ\ü‹O?ʇñðÈÍB>û‚õ½yêzSaþ Ј)¦Ôè¡"N÷ES¯ú¢2¼¤»ŽošP0£€QSsžCÚìBÞGãÅâšùj6Coò¿wQd¡‰ÝðþêòòíõËLûˆ–è¶Æ3c®žb&†ð‚î>£ãÄyê Ú&SÊ-`d»Í¶¨_ '¤• Q >3­#r³)uËASÍ«_–„#äã}i¬\ØûdÕ:N‰‰N£“C/&ÀQBÞCŠæé±\¤`"E9†ýžMhy^š/”s%óUŒ^ù`4-/HJŒ†­dnk8òÿìE¦R7—"»"goø™M½L”²—=÷PÚ¦â‘(‚qeåØF&‘à‚^ 4 gmØ R<1:>DÍ¨Ïø‡0Р9囹†®à8‡ÀÞ™ÚB€ÎGàÈ® 7îxÄ!F/‹•È5l\À¶Ü<è¡ìm¢Y¡…dê#CÍk¹LÉÍ®'a¥Ó/Ádý^3¥°‰Y”¥l)‡’+Él[³éË'L¥'ëÇ«ËÛ÷—£êOIê'Ô>LTœÝkª5~ªà÷Q.ÀfÇL-Do'Lü ð”§hAP#¬61 NÈîÝẠ‹Î Ä~Óš±M ò~×¹sñrh z‚Às¶¦†3Ê’nU9]ó@°qà[P6\€£©ªF˜†No©rÁ˜ê|§àÚ£¤ÖX2ÑÂ'Ý®ʼ>ëçT­É9‡1‹B‡CQˆhH®L‡Z~\³yi<¶7ÌÂíl e›u Ò¡;Ù¶º®bÛïFÍu9Üqìk©,§ûr©I°ªèzÛKH1žøar¯Œ( ïØFE~SˆÿÝ739z…žO]û³ŽG˜qIŒ@'s›À×±ÔXÞÀçï}Ñ …B˜!lIß4e‹žx¹4ÇúÒÉüÈ€X;WQIÌÙ ŒÁÁÑ7SSPß"7­€Éo¦ó HÁSRïVê>“‡9R¹Ÿ9êMSo:ê>Ê) âqÝ1dÊ5ã:àq¿«L_l°ý Cçª>BR„4\q8?EÔ_Bå¦A˜*yò¦Áv Ý]ô÷‰‡ûrè~iÐ_µ,þ?!j‘« ï?øŸåꈰÑmûtç}z=t«9Mn­R®:Á_ìk¿ž³;w…}eüb7ëF'ydƘC¿Õùs ‡¦\n–šìÄÆ½¶ ‡§Ïwðf˜ÜvÁyðßÜëÿŸÝû{t–{çÖɼØËWøò¢˜òc_` GÜ~Rýy GM©‡£Z“ÖtÝŒeÚ5û`2_á6ˆ^Š1%è±ÐãZJû¨–Ú—5â× «j<©ªo>\¿‘&ÿíý,–G¶´ÂJ+|%Çqhkj–pMÒqM <ê;pa3Íz’׊³/‹ ½˜°Ó¢@Ë ÖunzÓV…Hæ³JX'|Ÿáh\V‚ Òlè˜(Œ¾ ú¼cÆ ?k€ÐRÓË{µäÒ>¯"'à5Eƒ© m†Ô²ÕF8 ¨JîS:†ÔoýFÏÕ0Jû¹j¸¹ÚÂspÂÈ uú‚3ꎽ ;“Ǿçf*ùK˜Œƒ19ÙÒI C^ªsãw>#çD_Œ›¯Šœ+@+uÆö´c¿='×®?J焵d«K‹˜øêh†íNú~D¾{-`øÐ´¿þÐæ´ÝkhM0 ÙÜ.ÖGæ«×sî~¹÷HžrÎáûrråðBÛŽó„â‡ä8Oê8ÌíW8Æ ãQoÅ(+ òNaÿl§NÑY˜ØÊã<ÏŸí´mÒ9Óþ[…òÞjÎEìÒ Å‡ ý“SX$ÿ3HE¥Éà¿w—Žú À 7ë—ZýÒC›’Š~©E <K½õœ¦¤Ãï? ^\¬ùðsPñˆðÇ)÷?* ÜD…‹UÐkÿ`Œû—ææá‰o endstream endobj 461 0 obj << /Length 2012 /Filter /FlateDecode >> stream xÚ•X[sÛ6~÷¯àô¥Ô4bxéN¦ëÄv7ÝÔMb9;¶³‘„)I¨iU/ûÛ÷\@Yò2Û¬̃àà\?èõòâåm”yePæqî-×^ÇAê-â<(ÊÄ[ÖÞ/þ§Y‘øÒ¨FÌ"¿ŸÍ#_afó$Iý$(£|öÛò‡—·IxºOey!ïG †¡;‹¢È¿šÅ…ÿáåíÇ›7wËwxÂϸaâ_ÝÿãæšI˜»_¾ýéî÷¿¸Y^üq†^tT3 ¢páUíÅ/¿…^ S?xa”…·§…­—ä‹ ªñî/>\¼þÌ}ó¢ÒdÁº.·’Ï_ë¦Ñ¨é^u¾n-áêmP¡ Ôj6‡yiY ß⌓n¤ul½ÂM•C£½d³Åå‰:¡ ‚báLÿ¶›%±ßKÓ‰DÁJ7(Ê‚g÷ˆÓ  soeA™Ž÷Pp^š…|iéÛ­ššÙ|DŤ›Òt—ª Oÿ&©±ý - ¸›6[žiʦÅÔšùR˜F{ïgñ¦CZ'F·À GQPfëì4M²ÒoÁ~bC¦ÍCKG²¾Ì©´1î—5/ïÉk@ìŒÞѳy'þÛ5¯Æi Zö¬Ææ%Ö¸³÷xÎQ]šü¼ºö{Õ«Võ'‚Y«aÄ‘;2“6}0áöùÑ}ÀCnþÐÙab &ëK¸äNÿO$ 3šHÕÕª½t3ýVôLðÎzàˆÁrì#?Çr ¿ÝfOáÝÒÙžì‡ö€ç6r^­‡®²CpúÇQ¼E”ó»3 ënb$Ç€ä!òN‘|’oŽH,s†äÿòÂ5‹ñš×ÜH)wÀ¶ÊõPJo$ ÙpñKý–ÑØT÷ö»/CD?SBaɈ¡8là{sØÈÇ0ŒCL»ô¤½ã¼ÁìðƒcÑXÍT¥Û¢TÇ‘Ó.Äø#‚‘Êh«×=s>)l£îÀo¾™ÊS—ñViW%î aøÛIBÒÒ¼f?å SBV<%­«K‰?v¯1²‘b|Ñ`Ú|1z#œ?è‚|òÇ£ª%»‡ACÈ/uѳòÀ/)%M–û¦)a‰my™àáÇ÷?òxÍò™-WJt/V÷¡ý]ò~¸¿yÁKBÈZAs®@à.ŒÛ¥ˆh§²ëøj}{C·ö[£Gà©C_˜¯u'™Z¹÷ÒOÐÖ¸uÜÔOßY´{£6ÔäûÆqèA¾aÚ=¨Î¶‚ü '×#(&÷FM¶-"ˆ7þ‚ŸL%> ¼%%4Ë@HÁ“äÖ³VƒÂ%’dqœ?¶"\ƒ£ùìÖaîo5®ØóüXwÈÓKVöS‰Â¦„ˆvß1Ö¡lÓá•^Tý3ü/xÈ—"ë1­„µ £è*9Õ ï4b”4 Ç`Ð’‘€Ü¡ñ6Fþ1@¶ñÇ>O…†;^º˜G¯,d¹×-c`<‡›ŒÛ•ðÃÌÚJ…!žÅTN€ˆÆrD há_5‚ª4¥'uP€P¶&¿¢ØV6;žp %(±2îñ<%™”= q¼ðq@*OÚüŽW™êE¨'{ˆõ<¯Yh?eÆb5ÂH·ö™'!\vƒ{!êõékpâ§*WÙô'Á"J=-P*f¥òtüé? »ö¾ endstream endobj 465 0 obj << /Length 2984 /Filter /FlateDecode >> stream xÚkoÛFò»…Î8 TkÑ|?zÀb7ñ%uãäìæph ƒ&×k>.Çýõ7¯%)™AóE;;»Ü÷ŒÎnŽN_»á"µÓÈ‹7÷ ×óì`{‘¤þâ¦Xüj}\&¾¥º²Ê–®Õ/W®ÕÐ-W¾X¾ºÑò÷›·§¯}gzNèØiâ.>Ãsá;Çq¬×K×u­—K/±>œ¾þÏ«¿¼zws‰7üô­—×?½ú‘AX»¾ysõîÏ?zusôétî@¦o»N¼Èë£_w,½]8¶Ÿ&‹GÚX/ü(¶=€ªÅõч£3|¯—>{o”$vàÇLë¿Û¥ïY@P•g ec`ÝÁàYŠ‘÷™îUÇp¿1[sB§Éjµê7j•·u­º¼Ìª•.kâp _¹®†S7?±L™Ÿ 8Û]Ϙ²Áïú–g…ú¼ôbà¯kUí¶lÖ¼»ìíãáà [~n5ãyž5ò™çÈl8wW!§5ã6žý™èd ^‹ã=CƒÂ·ëál`pÆ„ó½ °j•5DnP|fƒÇ =EW ÒÞãHÈ„ßlí^ òêÆ¯毬×j„"ë¾3fWó’ÐËÀ<»«”|ÔòØ©¶+P7i{ÕÒ9^ñ ÇgMÁ@=–À¬Q}Uê~Œä“9·Ý®æÞÑ—uùg†Ê¤OX‚›’®Ùð4ë‹ðq£ô­š¤†©•ï‹j®uV6ZT¥­eÿ}×ÖöDüâ˜ÞµÍʈ&G2SßÒ›vWÍ ”BLäŠkyÖ‘ý€š¾ àv×Éê‹o£4‰PÛ®]wYÍG•ZNõŸéƒï€¾µsìyÂ-t…Ÿ¸û:)¨‘^œ¢†&–˜`6 X^‚“ÕŠG!î}ôp2™5ŒyÕjöQãaÌn¼þiÔº F¨$`æ9b«ª¥íIê"tݲøzRk2k3Ö­8 ü-ŒÐžA­ēµêûK¥í„.«2oÙ¢ùjðš‰Óûß’üðæã2ö„’ïÙ Ü©á]S0¿ÀÈÑ_?ÉvŠ °'„0d¨F«¿ðÞ¢§¤gŠì#FWöBî;2ƒ(‚ãŒÈa¶Óü`/ÎÏÅÿ6ŒxÂ}¬P0Õÿ0!Èør– ²cž€žS6j§•æÓP+f„~|ñî0'²¾»Tté;ž½ßݾd~ðD”QS„A„Ì#˜v¯²‚'hú8’.¸¡¶“ØólË9"ˆ„Ò ^ìŽÑ¸=ߺVä¸D×qƒÈLóŒ4× Ðä²Béx ÔD£6ྻ®T÷´:}Ï8OØÙeÍZîÛgñœõZUøø8´ˆÀ„rDl€?ªcø7Ç*¤wH×Ë&¯v)VI•øÞÎŽõ w’‡'ýÂÙp™EÊSÜnÌ‘,^) -`ÇšTY,eïLVXd]aä *‹œ@LI”b²5¤;zÎ3—FÜb‹I00åbÂdú%&EˆÊÅñ(̹Õ6L”ZÇÈH0àå±fÔp–(# ƒÔaï‹hô~øÕ(@RàCàÝÕÍO;õiWvÊøBq BJT¦%r‘äiðXè1ÑQC\äÙžvØs™’;t ÅŠvGb‹É*h·=ºò< Û+ŽÆ;%á¸õ=K®âÙË®‡å›DÞèýÒt/;@BÖâv#«`)='ߦ%Oé®ád¢ñ¼R Û"gw£‰I¶k^neaMYuÏ©³3j <û„½#GXØ*,ƒ]³Òêá®x ¢ŸMj9¸¼B+ ¿^SQ¶Ç®)ÃmCY-`vZ1€)z˾ XìîJp]’†Æé…ãͨºª`¤:hò–¡uv`VB÷Ö°”Ò1¦†.í¼Ë8£œêð$™Ë)c­‘?»¦d¯þ·9å¼js«±ÐBc*5£ ®êgÌ R \0~(Ä”nïöl—÷L ç™q cÙ0ñ«9%”‚ç˜ÈQCÄbfõ.ïøò¶“ ´lÎg;'yëç‚4¾å£YUýw=ë^b$”DGÝ“²ƒª³*º˜§á—ƒ]ñkTÃÓk¢ ƒcê²~Ä¢XðžQEpFÕIâ>cÝ‚¹š7Muq²­²ôvF&OóMeëÇÏò`%¼%ÅëÊõFr]D³apyñþòtâ²à”jQ¨×5WÁ°Ð+-Ÿç§Má3Rž@9HÞÉä×è_ Æ—Ì4 žä*ˆÞš€‰•d˹)Âi°n¥‚!*¨ñÛ½ëv²’BÕÆ­ ¸kUÖ­gß)ùûÀåÀpÙßgÙ‰ÙQ¾A' '˜ØÖ¢I>–Z}{Þ¾™$Þ\ÈP ¢l±5 v‡hŽd¥+Îпµ£r¨*^¥¯*4ƒœŒ¤~bXz<± iÒ)½«¤léa™(VnÞK ¹æEV&×ͺ“/É:8áNA¸Ò—«h„x=nà5P¡-¾Ñ,®bÁ$Qu Ÿ¹rýÔŽ"ï Ivð¸lþ5Q`é_>&1¨{‹¯¡—ØÜ){Mµ|Ç4 —£ÿ ¾d5Ôkò÷ÅÏó)"a”> á¸óÏiäÞÇúTlì6?…‹2´sp8ôðØ³½ÀÝ7wD¾ÒÌëÒ¶™éß-‰À7õuH´B\/ì·—tKà²%Ü’ äÅmNdòIärQÙ (˜LΛt`V•Ízëû©êþ+Y”QX»‡p”ãÂp—j33ƒlÚ”I…jò’:ްÎéG‰~üéöâòêìååíÕÙÛkv¥tNËãH%Î~–?i˜á/fÛóøÉÀw•/ð¼›ÍØÒçÿÒ$K/ÚFxر•ás·“2{=ü 7øêÃ>2¬­V¨ô_LZì“…Ùš»D¥ÔN’„éBóÏîÿ›ù endstream endobj 469 0 obj << /Length 1499 /Filter /FlateDecode >> stream xÚíÙnÛFð]_Á:EJ%!Å[¢Û&°]«ÍÑ©TA4¹²6áîRŠQôß;³³%—z<5è‹vv®s©Óù`4uC#¶ãÈ‹ŒùÒp=ÏŒ±Ù“Ø7æ™ñƼN|“5P¡c¸;3}ÛuÆFZ Þ¼sŒ HÏ Çö㉱QŒ…áGcÛ(7fƒWƒÓ?ß7Û¾Ñdbþ˜¬}YI6´¼È7o†ÞجZÚ¤II@’‹j‹Ês„Ó"'¸îžò8¶=7Þúà±æØ?~lƒÉ–A6IªÏ­JÒZ £Ú\ò:×”.’ešùjh…¡ùž¥R؆ËÑäJˉ¤`D¤cÀB)c\;C2ã­ãx†€/iÝù74 |¿’²@yIY"‚dEkž”1ñRSVZ9™„PÕʺպÔñ`ÌÖiµïQ²Ê{½ÐŽŸ÷x™æmªB/4ÖàLRå Å:Í©½:R÷u/jÛvš—’T /ß:¡³C$ÍuúˆÀt…g$̓;ÒzGêЬ\ƒ—6¿©ÓÔ¢Ï[éÊÛÆù;V;‡û](³dÓ2Tþmß%v¢—(šfgÚ ¹¬ øž–’m耹W¥¬êÚzŒF JånŒVèàôêëÇñF“õ¸ªYIœ({T¡ôÕûEÆ›‘\¨+.X™,Ô!éHðâ“ A<ºSéQܬxκsDº¼P†/„LŠ‘]h¾£NC6-wÿ>­_]võa8¾®ä”—\¬¶:zC<>Œ%&Óžî‡Úÿ÷îvTÖuw”Ç㕎ÎÖÁYZü÷;u¦y%ªÙš¾¯%êÑ2šzñ^ýYAhO<ÿ°ª†¾]Áò¡5e­Oq ÌkV²&ÁvŠÈ 2&ø³Æ¶¬šB‰2¢/È›ˆÃ‡04f7B²âìIOõ° {2G — ›Néf„¦eéöŠX 2E¶U³<4×@7תy„¸Ø¤þLªÓ Vm£E·±&jÎÖHg9mψ Òˆ›‡˜Èô ¤Ul­¾& {›çÁiÐ…_®»" Ã hqöÐ \Ïœ¯°¼[Ï&€fÆñ¶(3oõ’[J&fÚ0Œ^O>%ÈuºÁ,ê7°O³YJd5›"˜M@N%áAk7\a³!¯æmõ¹Ä ´*H–$'”ÎÚlç&€4»ô-¦hJÕh%eß%Ø'h9 S0Tãyzj }ˆ( šçï§Èáe| ®Õ‹šÈËkÔH§‚ÖuŸEûÓ·ZLÌÀ̸ ¿j%¯ÊGDÓãÕ7¯TR±¼BGnºž¸W¹dM™H®3ô$âp/ 1Î<¤)Jd¶Ø+KàìáC"m}Ž"ŒJ)–X*c";É¢ŒpÊ9qÔ骶æU+ú’þcËÄö’^l®èRÊl*¬>XÉ3ø®( ZzK^Ñx,Ά¥\p|V!vÃÕƒ ²’ðrQU=/›ª ®Ü{‚µKCõœaRBŒEŸë_«TÄ÷ÓîùˆPÉÔy‘~.ჲ*j5¸p£K´+ö‰.vÌRUfŸc½ÅÙWÅØ(u·™Þõ9Äæ¼ü Ëœ¹„¦~¥HW ƒ>ðÁ­2ÈXM©Pf¬L9‡åò5v Ëç‹_\œž¼X\œ>›©ÐûÁÒv÷lÃBÿ9ù ®Oµó ´˜ ¦U=!O ³qMÞ®YU2‚–•Ö§µk¾%­­PCP] ½ÆJ²ÐÃ-ö‰ÝQØar}˜îÿß_à÷†øï}p„ÿüƒ#êÿà˜¥ç‹c–~Ÿ0ÙáÓ¢‘xˆ«ÙMAôïžè‡ÿhøž=Ž!gÐó'жÿ¡üËJ¬( endstream endobj 474 0 obj << /Length 2372 /Filter /FlateDecode >> stream xÚXëÛ6ÿ¾…à°r±Òê-9.H÷‘n/M¬/EÑ+R®DÛ¼ÕÃGÊu|ýÍp†~쪗¢_ìág~ó ¾›Ÿ]ÞFÙdÌò8ŸÌ“(ŽƒtRÄyPΒɼžüâ}š–‰'µjÄ4ò†©y=zê'Iê%Á,ʧ¿Î¸¼MÂc9YÌÊh’Œ8‚}az·Ó(м×Ó¸ô>\Þ~¼ùðÏ›wó·xÂÏ(0ñ^ßÿãæšH˜»Ÿß½wòÏnægÿ9Cá$Ú«™QXLªöì—_ÃI S?L ™•“­]ØN’¼b šÉýÙ‡³ïð¾ñìÙ}ó² Ò¤ ]¿ï§IìmAЪîéÿÿRïw%yb‹‹þüŽ?rÑëÖÐÔ¿Â,´¨¤*zEÖ9±rœ³0ŸøQÌÒ§Vz°mšÆ^+ÑNÒà0ñÌ ºZèš&?áÔÕ5MበõD³‘ĺZ‰n)iíõ¦]£*nq’6ÒS¿(bo¾’;Z%4/ÇKú¨5ØÍ¢`–e¤£xhxÉV +¤+f­7ªˆY÷­Pñß xµŸ¬zÓ¸{á¥hײB@µ­ìjY;=cÏ™áZu½5'ÉÆ-\Šjg—ލ¹ÖýR‹Ö\Œz†ªèðà3ôoÕÇÙödºêA])Ñðr0ZÞé–`7ëÏù{‡Y_Ñ–õ/„,R£þË”Õþ¡—roà L›úDÕqd=¡õòŸDß­Òf@{ÍrOuf¢&EI“Ô«DÓÀíIöVemqWÕW>ŸGWe±ÏQ¦Štæôë©àèè1Ðál¡Ô{ é%Ü]uësPrP­äKÔÒ•õ'ÄÊ0ÈãS˜ì¯”‚Õ@ÿ‹‚A54$t#¢‰‚0l×DnWR3w‡Ûú óæ„';ôüNÚŸé˜îVªƒ˜ÌÓÔ{«Q‚Ü*#Ǿ?, g^ÆÑ¢1ˆ³°´—#ÊúçÈYÉ:+ ÁÍYpßò $y-Ä5ÖO8c‰—Åè•X¾MšU¯ö_ zö$ÌyŸê-QS¤ŠÅ 5‘3A|×r`©jàd@K(i…ÑR‰Aõñ¥Ö½N KD'¿“_0XR<®Æ|¥Þå7N–Ëà„¶Ær)*‹×åg›E¾¹¤ Öû°fŸwÉ2xÔô8ÜÒºFÒdCs-ßzÓൠ1(„AÇô„¶8…G¢YAúà?§Z Ñ;fSá¢q„¡ÿSŸ!§QZXÅ3@hy­€é2* ÃtÉâMW–ÞÆð1d@ø¾=ܯåÊˈÖýš]ÆVß$»¨ƒ×²qmÑ&k´=–)œ"èÅ./h [€-¿@P7¼›Õ¬‰åF§Ç)Yr×숅Ç(=`  ¨Ž<ˆ4j &¡z²GmyMqœå.ªpyfcc ØhÃ`«ÕpÊ×4bW"Éå€ù=É4lJ•-v06=zOÕ>¤:'¸Væ–ÇGõDX»’Èã«s ä(ëä@@ õú‘˜(1À’žB< 8e1y2o8¦5é¥ì¤ÆÌQ¡N½…à`7.X0qbúõ:}½N»aÕ:=-\Mà¿Q毵x 43f³ÆPB³ †XäñÞ‡Î;x»GâÙHu®Ú§²—çx'ýR, 5j| 8Oj(4Zlº #Êzþ f´ù³rÇÀêz‡8-< õÓãÌ{’ ‘E=#R6N‘ðýçŠ#ŸâÑeànALÆö¹æEc+éÑÔ[0±"®‰¦¸C)4{k…Ág\ñ‘p ÃǬþñ’7WWD€ðL .äŒk<ïÓŸ¯Þ[âæ£}í¼¹qK³P-h©»°ªt¯ÏÍŘlš¨oUÃm©…g‚ ’âP¡Œv(~ÏkgnNâ8qîH¨P#Ñ/èÿØ®p WȪÖÝõ¨ .>é ¯È¯/_rrÂkaœËŽíD+OOÝO=LjQj1p–!;b„Án­*[w,ûEÓ/ÍåS±ÈxA¥ê¹¡>¢!î… ÁÕ±®ñ‰… 8HƒaŒ¤êha­ìÓ^Ì‘MM®êâ²ZÁó\®ìƒ, ïæè’H‚ÀëXSÙ2 gYA‹ÿðvc¨'sVj¡P"ÄsÇ.‹§ãQxðå'áÿy,ÈÁBl)ùEV€ ‡ûI$¶rV·ýã`ÐP—PêŒ{x–ü£ØudÛé lcÀ™§ÁÐ`eC¢°ÍF¦èàE*lÅ¡T|ZÕÛt^»Ã•Ð~#ºBwk ½b ˆ1˜\Îq¯ÐÃ{™³:½„ïn1)Äô(Hö½Ís]|ä\œ»DICtæ9‘ŠåðS9~VÇ„±´zØ`Úæƒ¨Aâ}#øcµÌ%·dŸ«Kt𝨇…íqî½ÑÒÖÊ’’.Ã"hˆ½ŠªEé’5,9ÿÛ9±†ž¢^8³]= v ES?»iâ²Fq3g\‹#ùÒÒhÄ}º#ù‰Þ•Øb(óä#X«3˜bé5áÚ“¶ȾšúYDíÁ¾©ÁÏÔŤÔÔ€Ìe×;ù €¦Noªá•«_ogæh§ ¾†fÐ _²V8ZÃ¥[ûb€] ]‡¹lGA+°§DBÕRà!Ï=·[ çLIax›}°g%±M3­2£-L+Ê­ÖWPu×zÄk–r³”Ù§|Á½uȯëóF„ilV‚YRÁÊFTF*aJlöË QîÛÐÿÞÞ»Dknï$ÕÆ‘@!×ç%åÌY 5â¨?ÀÙ>§’¼ O´+<9¢×ߢógÈÎQ.æBÂ~^Ž}-ÌÝÛט–çï?¾-¼õ¤Ù?Gù;œ}ÒÀ?ßæ·Z¬O>Ã%‡;ÒPñ{œrYê)pÇï×Ù'Þ‚¸Z.!ï¼äÏÐ'ß4² /Kˆ2€mÈß³S Ø [3hùn îf¯f·§÷»ï[ =$)\ùi_®•iÔ£4ßòWŠ‘­¿ASýÞóˆòÇtû±7Ü䙵 +i\o·G ¼|¡]ssê„ûŸßÍ¿¿¹¿»÷IÀwM‚"J'~e“yá¾·ÿmM‘ endstream endobj 478 0 obj << /Length 2358 /Filter /FlateDecode >> stream xÚµXmoãFþž_a"c#Eï¶ZÙl¶õ6Mv7¾E¯p&Ò8žF–ÜÑh“àpÿýÈ!%Û©·M?Ü‹3œ_’~;;8y$ƒÌËÒ0̃ ½x0So’EƒY1øÅ¹M"GjUŠQà˜‘85zäFQìD^¤£_gNÞGþö9‰ïe“`àÓaû|ßwÞ‚ pNGáÄùtòþóù§_Î.ð†ŸñÀÈ9½þáü‘À»žM¯.¯ñüƒóÙÁïx ?z1#/ðǃ|uð˯þ Ö‡ïEÙdðh®Q:öB ÊÁõÁ§ƒ·øÞ0ûÃ{ÓÉÄ‹£1ÉúÓr…Î3ÈR5}§ø‰{ih¹qš8p€¥RGËÏiiZ]ñ@TpWeNm–Rùˆz¯uFlpjâ-‰WÕ£p +ìàú¹1r5‚÷Ö¯ï‰õ€gÈçî¨Æ¹ã4óÁâºÅW€ºÝ ð²$!™›eÝ–pg‡NŽÛ–¢º—4~¶Ç´š¹ m¢`¦©é[Õ†ˆ¶é8K¨ _£ª¦ÕÌU†xø¢Z?44ý¨Ì’•´,©·Î1J|LÄÎiéî{ˆ‘ºF}±(ŸQ3 ìȸ[×-j<ÌÒNºlìÜáÒç~–&oPUJq"ôýää+*ÇwVž‘×z¹N°-h`%l òþ¢¢W– ðÀ©x ¤X¢ï¿Öö“´X›„m–€ËN %M ± ø:,²Z$J¬¶b#–دn¥Ý@•"ùhûpLúà$ö%6ûoå5a—®Ëç89í‰×¥ý 2š¡¥P• åŠ' ﵞöÚ¢ª°¡PuÔ6RË*—44¼ñ¶ÉçF­ä¼1bµFë£á†¯ô¬©E”Ð9{ó†<¡ªy–ñ¹RÔU%[•D›’…6-eeƒo÷ž]ªÉB2p[å]¬îÖ¦î6ÓQ|F£V{Ë‘¢À–™ ÙAåPœÈMê¨13ŽkÙ¥+Z:ó«ËËó³Ùôò;š˜]Ñ ÐÖ(tÖ§ÎYWëR6íéÿÅn.æŸO/ßÍ?Ÿ_ŸÏæÓ#BTJgÀAõ¹…Ô×˳¥CÏóö{¿ã8?#¡éã$`Ó#eþ‹ˆÚ”µ8‚„µVe·zÓO™njËÃp(†_ò,•¼ÏË×kšæt¹Ç?T‘Æ!xbEèóav"Çn NtÈ,”†¥ÖÏ4¬´´ßÓ—Œäv8õ ÉƵf6Ýâ>ú¢gó¹FhkÚ—‚ìù#ñæ‡ùwWoO/æWo?\sf¾³TýÒèË(˜Ó  È¢€ôãRQ&§]ßô¦ ƒTa†(|c”mÛ gä‹öFéûˆ‹729Rº-)¨’í rÒW¶wAu]ù$»¨S|P÷-¬ÚZ¼hµù´W‡Ú”ó2E6/8КvMi z@%n^U%Fn2´ZÉG@*xp¤ÎTØ!cMŠÎê 3ë3z >7íDeXÂYäÄrU³dìhˆ<,T³.VCÛgZ`€ Ç{¨1õWBà"ÎY:qµ2¬ÊgpbNø plõ|0”!Ðío¡ïK ‘— ¥Ø+&Y¼Á\Ÿ‹Šï(- ÃN²;ÛaÄCµ"¡1À}"çÝÇé©°oãm8æhlË;,ÅW2È>ã‰-`‰#›ç)i Å5.¢êwM LŠ›MH3„Þ¾Jau¼Üõ`~:xl©VªËu˜3¸ñ¹ù8å•y.›f·]Z·w%D±¥u_‰²Ù\¼•ÂõÙ¦XÆÁn“–¾õSˆ1*E3(ëPX¤’K‰%w’àE6µ c m)¹RXˆÙó 4BÄ@ïØcÑ^éÖc“-H&ì!I†Y}Má)»/l­&Ù6 Áˆò:o$Ÿ„]ºn t? MsáTŽi™÷*FÚöL°±«n÷â›Z€P ˜‰´tâ°ë·xYÂM&ÜNLL„¤bìj+þËqp‰ýûM>¶V×ÀÞVT2‰I@˰~ÜmäkºÆö!Ÿ£[ÿÃ7Ïó7o°.„À‘t函û¾7ÿ¬)„=9}º*ƒ:Xì’j‹®E[ö¡/¸´Á:+0‰kA3Ð’@쥱ódâW¢ò€à±\â³­îÇCnn"׿C°(Þ²»šC¯‘Âмà•}€À)bçï`XFÿM4ÇýaQ‚°û0ßß¶Râ%»#%8åCô²“ÐÔEªà4¾›´QqPà“™Ó Al"HdæZÞCçÕœ˜3—OÿÊKac–PVo¾ò÷e×y“S ü$AhPsÂßYÙ!ZQor½ÇƒEÞ8ˆÐ…y“Œÿ@I'ÝßÜÿvA endstream endobj 482 0 obj << /Length 2727 /Filter /FlateDecode >> stream xÚ­YëÛÆÿ~… •D<>$Jt>öÙNì¶ŽÝ“[ŽaìQ{'öøPø8ùò×wf~³"Ϧ‹´èqvvwvvÞ³z²=;®f©Ÿ&Q2Û^ÏÂ(ò—³u”ø›4žmw³÷Þ?æ›Ø³M^˜yèuóEèÕ4óE/½ØOÃdþaûòüyŒé¬?Ý„³4¢öAà=Ÿ‡aè=žGïÍùó¿?{óöÙ«í_ù„wL0ö_þåÙS€4w¹}ñË«K¦öl{öÛ fá‰Í؃õ,+ÏÞf;šz9 ü8ÝÌŽ²°œÅÉÚ*f—goΞð}£ô‹û&›¿Œ×àõçzGÞ‘x ®v5¾/ø³ônl‡ñµi;Û¾êób°ËKÛþòx ×hé§A2[„+'8èmki×:ô "¯±™­X2ÐY]òÂ6þ|±Z¥Þ+{äI9•Vë,Tz-öt¶ÚÎiÝÕ|Á»€Û?0³¡wÌ»=Öt{¯j>âèø)Ì‚ïBò[„¡Ÿ®V`¼Ëï„“âFÀö  ø§‹ h/ö]í1–0GkÏæÕ &ö#›¢Ÿœ +† ¬b`$¹ ½ûb¹ ½¼Â÷`S¶À¨VliD¤÷n”ñhŸW¶ư¼è[¥—ÖÜüH˜tåµV§DN @W\×Í0=!®ÌQ´,ø òvyÛeIhËù ä™Íœ X«¦þ€Í·ó-¾±-YÃ2GD±ì˜CK¯½e,ŦD% 4}ÕRtsúÅ]Èòdw¾³ÕW”ž:!N¯­û&³€Åø[ºØ’üÚÂ.*L™¬©Ûð.ÿ5ˆcÛ NHyÃ÷IÈßÞq ¨{Ld¦:­ %Îyòòâ1³}ñó³)6qÀ]ÞÔUy:l¹Š½;`“›+±+ Ù6ù å¯ÄZc©1ê(*1'„J¢Æ7¬¢­±fÂT÷Jm±¨ûNvõÝ¢=¹DÐ ®ëC—×Õ¤­oE0ì‘yä®Á¬> °º ŠA€êk]Q˜¶µ­Ûg:@.Ÿ!ÐwvTYKôØõŽø¯Á*`ëôo$*­ÜÞ®>LÝëâõk’DÒ¾xYXÚb|Ïšauó 4ÎE#ŽJí('"öv; οƒ} ‹ât‡¬yUC1ûÝ9¶jºøž­†,Wg¦.Ô„ÙÒ7Ü-$ÙNƒ·Ýç,ÈÍZ=ŽWíà¹Öˆ@ ÝÀVSÖ}ÅGwØ&J¡©L¹µ@sm]ŸDo‹oõÀ‡ú™ 4¬gqÅ•øyhj>ù¡6Ýœ’† $Y¦ÒÔ;KFæUÛÑå¦S©HNæÇ²¢áÅ÷ßcA¦B³ÊŠØ[ÊÂó¬æÍIæa>‰½¶4"ZÊ,غí4Ï\cÞ~²Yσᮡ8LÑ>CÊø,Ï/N 8õÃPÏþçž3ýýÃLßÖHõœ8†YØo‹Ae­Ë÷º‰R÷I²4<î9®¨ÞѺAL˜gŒ’ßT¦ø£…‚”K»4¢^bãÔ0רßú¼NC$ÝÞ—LÅ@]è,ÅB«`uCµív’t’±²ûñšžËTD«,Jašc0±ÖäSkº&41š £x–nÒ]«¹IsTDF±ˆ•¼mu–c.Év„õm×ô[Š®‘TÍ'XÍžS¬ŸÄ¹&ÛÍ2:€cUGêû„.Í­X¬5',“ñŠW^FÿxT„qþì€EÎ#¸2tã ˺±0}èÇè Ó/’ØWr²ëöZl±CñµM%•Äô“ÿTC@Z÷„}Þ™öV‘l”Nÿ«²8JTª \Þ“ÀJ¶=2À¥`}ƒ©§dëYøuSß4¦,完xàE‘ÁpT ¸?ª3xÁ±É;=ÃàóÅ|§¯ÔCÐ2¹“Tä —^Œq•5ÇÐCßsÐw-PÝÞÕö•¦ScÄfMЗ±ÍKÌФðYšÉ-å´ÏÏ¿ð§xßÂHJp¦¹¤uANŸ,ògÈÝù«)îÃÅ2ø|YÿòÐ_y&"ÍШíKNJ¼–”)Û+õp•lñY]ŒÛ°/C&÷×Y­½5T‡Â„OdOcgÜKWÇ(Ìs‹H-;Å`¹ëP‹^‡¨ÉGó.+ HÕ!ãAʼôˆA1ixCmÏ‘‚¨j°(í¨4tHâ%Ñnyú æÒ©:âN¿±à‡üDÀ%¼ÄDñUø»Y\åŠÒÐдRú-½0æÈEš±GÃ)çÆmУˆ¢I²¤%ȧ<äþžN¶wL@_Ê4Í¢7íNXmtù94Ô6:^É i€×ÞO¶²¸En}Y”ÂÏx(ìNývèý«oõè^-'Ž>vßNÖÑR±Æ ±úÆ)„äÔ:òÜʻ‘M–;à¦ÉÄ$:ŒGd‚gxI|zˆZû^‚¨½t½]"y÷‡EVãA†cŽd}M_0µ6õؼËíg‘mõ™µ-ÈUÃ$%V€ø"üu† /¢ü&…(E3-… NY %åv›¦9½AÐ5Î_g{ ?T¿l¸#˜ÜN]åYê< 2ʲ8|°¸Ó`¨HÖ.~¾>¸¹Jw^»s ‘Äâèë4ÂlŸÄâ[$ØvúÉ@éQ}Æ/;j%Üǘò YˆfDŒ¥QgÝœ¬i‚Eâ-\7bH3ºí!zg¤<1ÎY‘é‰Éß·À ’¿Û¦–:“îõÔeFn7nt0Vï]jhC˜¥áƒMH±ðÎå¸V£QÛ7Ž”h6ÆÓìڻňÙk±uøèÌ~P‚ŒcvÚ©—2ÕÅ®/¼j5z!ãD.q¨Nbµ=±™Ap¡ÙS©=:¡¨ Î%²t´=}èÅØh¬ïÊxvÖmÔV6z@>YLª¦Š\…\é»§ì2úàôúA_U6ã°ÐJÑi‰¢¾˜ÇTS¨jáÌ»ÞÑþË-CÏþFàH&Ì…”ÞQCñ÷ƒ–èú¤4´Zü‡„Ñú,¯†?8z‘›OÐôO¯pÜ&~®©)‰ýåZY–Œ6¢¿¸@u þO[ð#g¤«c~œ’îù9½ª¹_eHD û jn©æÑCØýÌó£×óRÚe®ê;;Ñæ„qä¯S¾@êo6¤îï·ü> stream xÚ…XmÛ6þ¾¿ÂhˆÔZ½Zr[´H›¢E.i³¾à€¶Xh%Úâ--9•Ýý÷7o”å]åòÅÉáp^žúõöâòM˜.6þf­ÛÝ"Œ"?YdÑÚÏ7ñb[-þô>.óØS6Å2ôìrz-Ýrljû›p½ü{ûÛå›8˜È‰ÃŸé"`Qû‚ ð^ÿû—k\~qµ½øtÂ|°ÇSc? ²Ey¸øóï`QÁÔo‹À7ùâžñ:ó# Ìâúâ‹×ÏÕO2?Ö‹užûIœñáoð]{@cÏÖŠ‰¾¼9ºñËã‘qbÔw‡D´9 ‰Äß@Ž­ÂrS@âšn€vÙÕ±w€óãÈ«£˜qKc$žn˜ùq¹Yº´{f°·cïú±·êðÏŸg‚rT õÃÌ)ДÕE¡fWbR ‹Ôã>qòl]X^ôß¡JSpYÕ•mÓ¨Òö¼c[Ó#Ll0+æ× Ÿ—ãy)ž“yu«KÇîçœeA©Óe‡ßÌÁî;m•Ì[ù6<5‚3šh>\ æóytÅŠu²ÍžyÊôŠ÷Hèžf> …ùa k°ÊTë5k}äÉn‡ÒÐ Ó„  u˜Éh™p ±äÞ3Dɲ‚"öa¾!ƒˆJaºÁRHÝëM¾<#èq'Û-ïwÕZuEÇiÃù9co:ëó’| TSÈÝ Y%zžÉB¾è8üꧨñ(+:É%qÅ4 ““IÚ=ú(I¼-BøÅ•†TÆÔ}Å’ÖœVÀ¸×ˆ|$»1,ýìȉÖîF-æ^"Ía;G›hê$aÈêd¢2X¤ Y¡ÈæÈ8Y˜ $™QmˆÚH Žj“ØQm·‚ÔžˆñçÿW¯Ä§ÎÆ:t„òÓ´ˆ’øS?'žÓâ~e'–9ÙË!¶~B×XÒC (~ɽæçî 2ç^˜÷5*ò7ç¼äϽ¸ºd˜ó”ð!¶ÈÝ‘5Nk{á?K÷ûö“Bp:*ð)”FtŶ–â Ju´º•²À pZåñ´GHžamâJç/ÓÓPfÓ[n¬.,”ÓD;œzŠ ŠóÝÈÚpÝÂ)î} oËq©I<1d¯md’'qè–<‰$ž›$SÏ®/IòDy?WEøÎç¡­ªg0À¹c¬>:q¥3N\á\+žaXržóÈx‰ñ^P_òò hx°+`sç»È‡~"‡NÝ“utÖP$‰¹¦^ áäÅ𤀛DZŸ¹ìy£»Þ p3ô+*¼wOšþ‘pÝшíF´-0ÅH=ä>ŒF‰ð­Ã§½SÔßaëÐa+–‰_‘X1V•ºö<î!ƒY%zèµ·:8uOlx lT‘†x®*‡276##§è{Õ‘¶¢E Ζ½Ô#΄H­Œ> stream xÚ•XÝsÛ6÷_¡™»jjÑ Áñîå'NÝqŸ­$sÓv24 K¨)’H+îô¿ýiÉ¡&w/âîX,v¿]èõêäì"ˆg™Ÿ%a2[ÝÏ‚0ô£Y&þ2“³U9ûÅû4_JO]åóÀëæ‹Àk€0ó…”‘'ý,Hæ¿­~:»bOO˜¥¾Œf‚U„,Bx¯æáÒû¸úñÃÍ-.:y»:ùã$€ibŒ{K?鬨žüò›˜•0ôÓLø2[Îv4q;“Iê‡@U³Û“Ÿ¼ÆCÈ`ÿ‘ôeÌ’åÒdÊ6å|‡±÷÷Ooo.¯^­>Ü|Á³Ü|ø°Bã¢ÌûOx¯P®hzÄÞ(jŒ^ë:¯˜+µíŒ¾ë;ÝÔ,yÐ L[ŸÅñáֲݣÖFYÔj§ævgÝ—×ßùm…VÅb°ê¦w{ {}¢p<Ì÷4á‚Å¢¤ƒÝõk|GscN™osku½µ7Éxùx –ÏsT=¡ëñ‚ŠÔ3ªå…a¶á‘#'ÝT”ô„8­^óзs:“S¦<`80ÕP˜wÝÓ}ts’l@÷M×µÿ8;Ûívþ#¤Ž³…<ÖT>ƬÏ]V;q}‚Høi4– >ùB&@xtˆ&Ñ8`Ó‘Øi -Š8R€nNÛßUº¨ž˜{ÔVC¦ü¸Dxúž¥ÝF[¦†o_ýo©¶ÃÌ:Ei‚÷„¶æa@ ÌhÆA Hqã¼·_ž^äçÎÖO¥2ÿ‚/êDÚoÌzÂEYæËXxèì"\‚ë Ö&!›³ˆ"?–¡+¿Cýõ~¼¼…º7ÏBï?êÁ.)ý4ýnÝÀáFJãHÀ]® å¾d‘®ùdYÄÔxW`õ5­F8őϸԘƭÉ;þ: ÞycuÕ¬͈|gš¾=\ðªsõa¢½ý£×íV¢âl‘ Ö!Zù€i2vÉã#6k M/Ýx·¡}EŒÎHÙ­~†3Ó‘CpvÃÃçÌ,ƒÖ,†*·†(ÆÐI9Îùs—[Ü"Z‚êë,Ûòå+UÅ<¢Nà+‚WU»qjZç¢"Äm :mT—L@é£J×W9Æw4&>4fÂzvü£6M½@À lÎݲççW—S˜w‰Ûe”N1n•íegGö írö72‘‘ïí0’W¶aêžOšy?÷U§·ªÔ¹›R»¹ï¡P @Ï)MXx=ºÌÚé"Y*Õìç\ƒÛ¬¦üÚe+¤]@îöyíÞåÕf²ãšf‡ÊÀðŒ’¼èôX9ãøØÎ W:˜pPàO§® >L!=ËR9Ò:µ»/´®BÛQP‘@˜7È ;[¼RaBQåe#lÒŽPIWð!(`(‑n¾kW`!TÒêhš„¦É ;бÌN¬7,›ydÔ¯BJ@jË,]…¶žÓ¸7oϵ²N¶IXHh€ãIÁñrS¢9k“/&ߨ‘¢NÏJM 1ÜQ õQU*Ç^”„Gئ7…£G,/ƒÄûZÙ[<]®„0ÿ®ŠîPç¨fÆ­7ÑÅ€cWa›ª<£çžûíÚ(º-@霪pàÑÅæ׸I×v ñîýG&®©@3}¥ U[åÃq‚ƒøîÏT `ÿ¤Þgܲ¢úƒ·”}XG™ß»DQš ((ðµF ’é¥<è8§ïÉvj{Ϋ·ƒ÷–Â"™r §ŸG jà…xS¢Šv­çs÷Nƒ”ÌЪ¶C»†8°f•®ßq=)çѱ«f± bw#$¸‘}ˆâ}"_ÅàÌ ìE‘ôáyÏäPè‘6jg4ߦ# ïM³eÊP‡Ç§J–`™ðâù?¼pV4 ™AcSŽÝüVÿ™Ï$”=iU•®Sî¹{Wr‡‹ø«óç7H‡Ò5@,CIÙé`¤JâýN%à9ŸÐ‡-†t%ç¼¹¾d¢ÊëuÑu—¾Ýï09O\#‡A?LEû¼7Æòør—Ø¥`î~ …i¼·âù=½§+s…!þÁß-2ŠÕ$q€žPZOD¸&<”I†–Y…U$ŽåËäÁqŠ*øJ“séçˆ/¿òäûÜnX½[íTÔ,îAºtA©?ºrÌ´‰#¸ µÐ2¹ ó_ü÷Eò¹§jŒìåÅ‹.>r]ü«¹ öþD;ÒÅG¼êófx¬:›,=€\j¶®ÎŠ×pÊÜåŸáçMà¤[„O—kãÓfÿadK?Éÿ÷2œz ŠÔiøâ1„©ÄKÈìÌ_.—<–Ã?‰ÿ}êo‘ endstream endobj 494 0 obj << /Length 2932 /Filter /FlateDecode >> stream xÚuYÛrÛ8}÷WèQ®Š5âE”´µµµ¾ÅŽ;³–g3[³ó‹°ˆŒcýô a^ªOh »O7ೇ£_ÞG³Ñr²Ìâlôð4Šâx’Žæq6Y,“ÑC>úcüßãE2ÖÞXu›ã“h\Á‡?>I’tœL–QvüçÃê—÷É´7Oœ¥“4ÊFSž#žÁ¸ét:>ÿt÷pÿáì·‡O÷kvtùpôõ(½é(êVO&Ñt>Ú”Gü9å­FÓI²\ŒžI±%Ù|×­þstö“md‹Å$MælÂgcëÊ¡ÕÉxíŽãÅø÷’kÚ í ŠzSdÙdžEaÿþ"óÉ<]…çšç̵ÿ7}Ïé{RùíÀäËÙ$ɺ±ÿ˜ü$Ê–“Å|9:‰ñŒYñVŸÌfã/•œþ¦r½ojÞÕ£l ¿ETkù×gt¡ªaÿïXpÑ*§ùóJÙGßÊå<ïÊÀ¡hþþ½°yñb¥“$Íb´o::IS’EÏÁÑ€ƒØ K’É|ž„ ¹žÑûãø¡«½Û …Ûø†*"Ùû }3¹[ÑÔ=‰ŽT5 e'ɸj íewumêFÁ‰ñïgÓ¬ žr„7•§Ý¢tîrðÊ¢q‰ÈÄð{Sy¶ºòª­Aé|\¹ºòhS«'†ù«¡?²ºnN§øa‹Æmyhm¶Îüš¤>¯&,ο¼ylku É¢h²œÍx )Á¾qÿ'ã§Öå5‹ŒÛØ6×û‘ŒOi…R[ÆÎûû5Oñ<Ÿ³£L[²Ú·™¨*÷ê+O&£çdx+ úç0ûÂlM£pupÙå×ÖìKt4%XƒÒa›f \¢éS›ª.YûcCÑ2IDñÚlT¹çÖ/u£ËZÝJ´ÿÁµl¾5p°Ì¦Ñrü@^ß I…«lµ5ºfDÎ*‰c¸ñi¶”žoѽÙTç…Ù3p¡1*dŽ·›JbØHë¢9ë—úd0(`¯œ aø¼SM›V€;Ýà <Ó¦wWïXcn<ïð.úê;Ã8ä§¹•fÙÛôGÁsQñÇ[@É›ÐÇ3N³9'§Ð#*=¡ ­Û¼ 3eM#é†JÊË”g/ëNtæUn‘_аÏ0ÛJ{]2[ œä™vN7¸jeÄ}¿·$‰ÆUðèä7EЮÚU!Î:¯ŒÓ^ĤAÎ$-Îûì-~`w€Ù#0LjÞ€¹ë®ZM`ËàÛ>±Mcð$Q×´c„œ­4PQÂßmÓðºÓì馠"‹u.VM—ã{eŸ¹Q~«eÌ…²²òZ?óøYºxmªºb„C !¾%¥9ì¸d{Ê5£m-œZýÁ5$`©‡GºÃ³dƽµ~Tuc´ceªJ~œ«UŸqvƒ9%Œã·…– ¹Ò¡Ø’«ô#q û¹_¬Î-’|Rù¼§]Ù§Á´YWÈç³iB…e6MÇM¡ùƒ9V ”H¨ú6‘P²ÇÃ{STQ _XJq,Y‡²'à²GµÁ v"Á`A7”E2ÿ:¡Ó¢äê½_Ú“[ôaQVm²-I–½¸ =*CynB #„ª¼ùŠ?!e'¢X”*•;³;†˜VN æÀ¯ª6 æ•kE‚Q4`)Õjò}ŒÃ¹övþA(çM:ŸË º•Q^ÕÊ™½²ÊˆÂJ#o3XŠl]( –ž©­º§.÷ú9È}^Û@JC…G5¨NQ#l¶Œ!+NÙ g¦BhÕZƒT?K#@¾7:ŒéÑëÑ^ #þT?)áWÆ)ðTGQ†¦ CöÃ&èg'â i)Â(«hÅì eÄ*§E|åõv¤­ØèsAÏ -`õ6m3¶r/â –ÚUÄåðó΄˜güo%{g¡lÐ'– }ˆb”¼U÷úð9Øf©T¨¿ˆ|…ÿAE‚ènu3x¨\OÒYüC=I‘Ô“€añvVk.éâ@à¤ÑÖ…ˆ?’Ÿž½¦™Á†v‹:”é9ÃçÐ6 ÛY+kÇR;˜QçÀ'|xÈ Uë‘gÓ9Üà,„í¡ê€ºWˆi¥¼§5³àÌÒ¹t¯U‘ÝW†N'2­UlCüd-z,M±ß£Á| ^Qœá$rĤ!%ÅW-s†‚¥®ò¦yí4Në5Úî"MÕ«굨A:9…u€ÄZ僥†“]!öÄØ–¥é- ôL„8S èSü@ $®Ž…±Ød¦0@oº¼C4 LªŸVæ½oå´Ýp3¯_Qo p2¡ ‹à'Üuùðíš8r@ ùýÍlÞq£rh2î5ˆJíîF{]×nˆB@ýè@ú_´–õâå¬Kx‘:~«[(9#—¹1ä±Ë‰ÄP¼ õ½!Ž‚›ÃBR IŒ•0”Át˜ßßÄr¥í=•šP‡<îŽ2¯—íS«SÓ u%p{ä±Þ¼â†jÂ<7¢¤Â$ÂÀE- PiR½¡•…Q…‘`ëÀHÑëÜè–B=Rf—é]i‹äá4E,se‰!€¯Ì㣡\:.î^†*™8áE7•©kmáÎX7­U)ýIJAy$ÏÆ§¥¡Ù!¯+(~NÄÀ-Õu p$ÍfÐó3{L*‘ÝicYÿZ•ÆrDád+ÈSÈçf­Z÷ÅðMâZÕ…)+>h¸é=ÐËÖ# ßÇw‹@s TÑÎw5(Núu–áçp‘€dW¥~¹d{-е¬¢¾Ú¡™zו£üH¢¹tÞ,õ”ö-¥;býFäBØJÑý')zÒÊ (Â^žÂt”Û *ùöTnéÙ0#­¤«âÁFLë'ôTR…kZvñWѸñ¯/5\F:G™ÅA½3¢vý›¼1¢¤+&¸Y.2,öLù ‡ý³ª‰¬Ë&Æ‹ihcö½ÑÀŽ++œA0§˜rBϬôf4?×,¹.0!AÞ¨­SŸú†ë“çq7ª°Òê‰Æ‚ ´êÐá–ïª}99żŠ7>~µ¡WŠ/:ø1ëõÊIoèJq“›ƒ _v¬CÐWTa½UN4äf‰„›e”1 °nóz˜î~C£’ô¤‹¥bt8®S–†Z_Ä>Yô<Ë]¾õ: ZW‡!Ö…+%BWPΫF –C[Ñ g"q}µbðx×îEaK¬jùu‰â߀ñsÖ__ŒEá3ÆLÅ×þ‘·©nõú•HóýäùQ)àt;xÁár³•¶ù³ ës:âȶ®Úû*Êÿã¸BgÕaDSH‡ø¯âM脃J»7Ãì·Rô—&äÖÛÍmk™©0©/…‰Ò¹;ôÖˆÒãAo¯vo 7‘¹WÛ óÊÃÍF´(¥•a…u¦£Ú3Ä#𣦗;€§¼[FxY ¾„À¶°øhœ€´ù}Á¯ÒR|oº‹·hIh_‡É ð©Óß)û(×Àw´3š/&Y<æ˜,1;à ÿU«„e endstream endobj 499 0 obj << /Length 1903 /Filter /FlateDecode >> stream xÚXYsÛ6~÷¯Ð[©‹æ%‚lŸìÄq£ÚŽ+)=¦ít`ñp@ÒŠó뻋]Ò²Ët:~¸»ß.¾XŸœ½óç“ÔMã ž¬·?Üh"‚ØMÒp²Î&8¿L“ÐQFrê;ítæ;5,Ìt†‘º©OÿZ/ÎÞ…Þ‘ `!šxd# çyž³º¼DÅÐ9¿^}@½“ËõÉ罉?lº¾'&›ò俼I¬ÅÄsÃ4™¬`9 cá°*&«“ŸO.¾qŽ8IÜ(äÃE}?IàܪÃNšì¾ÒÐySW;¢ÃA#GVø:·»îi$Žª¬\àÜMáÈ®`ºý*Ÿ9 תžó¥®Øöµn$Sk¹A±=sn¤Ù÷üu2]©S jæûn:Ÿ“ÛçUf”lPÈs>õ¶iؾç,d©#Rv¯(4ä¦Á$?6K¾ÃÂFfDzàúm˜}#7Z}b­6(“×í~:É2o%Ru6ˆ™êyõlÌýRWz)O„sWtíÙ¶ y¾5˜Á0I(’ºPVÓ{ÜU±+òÀ2u³×lj©m€óc1ÓÚã!ûVY}ÂìZ¶‘÷9Zí˜ý±[.ÇNqg´EƒÌrišÎzsoÎyŒæÂ†lÙ!Â]W<FYØ´UÊŠûÀ5d#rÞäF7D]Ê*ƒ$2ã¼B‹mop)^B$&ï>d˜ØêFî*EË¥Ò­´8™{Î;D¶QTñ¦gîtÏ>/°2 ĦÅà©óÁSÐz©k”‹R@ŸÚ±zÚºªmY†Š5ëb«˜³€Ðör§QXgÙu¶$‹:Ç*±³’ÕüÀhæ]ÉBU¤±Röö+sV²(eÏÊ•Þç̰J@ÄÒÚëÍþ ; /åVªbÌUP4’41-{T„O8wêO/ z‚O¢=ËŠ)TÂɪ©«M!µaþªU“ŠÙ…l¶`øÂhÙ3JB’Ï õ…©Pã…'ÛŠ>d(þj»¹†2€š]Aïcú¹i‘æƒ?²¬TÓ0ra…G©!w‰=•´uÖà»Æ­zroÃv$™Ùæ4ÚïxCPaÒV O<}˜Â™mCÄ:j­šÙ—¥2¶ -·•u[3óJUªç@·|´ù¬˜¹TÕNö\¨D£ÁýÄ*žó;²kUÛt@ šqbo˦£F²J_à ]Ô*`<ª5nhT‹þŠ…«š±óBÖ> stream xÚ33Ñ3µP0P0WÐ52T2u ÍR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ(ª+¨ endstream endobj 502 0 obj << /Length 85 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3s…C®B.ˆMÎåròäÒW0çÒ÷ž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ €ËÕ“+ hz¯ endstream endobj 503 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 504 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3cs…C®B.ˆOÎåròäÒW0çÒ÷ ré{ú*”•¦ré;8+ré»(D*Äryº(üƒì*ËåêÉÈžã: endstream endobj 505 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 506 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 507 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 508 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 510 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 511 0 obj << /Length 132 /Filter /FlateDecode >> stream xÚ3¶Ô32T0P0VÐ5R06R0µPH1ä*ä2² (˜Ae’s¹œ<¹ôÃŒ,¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. Ñ@ƒb¹<]ø? },Âìq ÃÿÿŸÿoøÿŒìÿÿaàÿÿƒ(ÌÀåêÉÈÖZ endstream endobj 512 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 513 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 514 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 515 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 516 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 517 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 518 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 519 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 520 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 521 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 522 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 524 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bCSs…C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þC¨'p¹zrr4ö+³ endstream endobj 525 0 obj << /Length 89 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bC3…C®B.s ×ĉ'çr9yré‡+˜sé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þQ¸\=¹¹6VLÖ endstream endobj 526 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 527 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 528 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 529 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 530 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 531 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 532 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0TÐ5T0²P01WH1ä*ä22 (˜X@d’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒˆÁÿÿÿÇÀÄê¥ÿch`üÇØÀðŸýÐR®ÿÏÀ`””ÀÀåêÉÈ|Q  endstream endobj 533 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 534 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 535 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 537 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 539 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 543 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 545 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 546 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 547 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 548 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 552 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 553 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 554 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 555 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×36Q0P0T0´P06T02WH1ä*ä2² (XB$’s¹œ<¹ôÃŒ,¹ô=€„§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ÂÿÿÿÂ\®ž\\Ï5^ endstream endobj 556 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 557 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 558 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 561 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 562 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 563 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 564 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 565 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 566 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 567 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 568 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 569 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 570 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 571 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 572 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 573 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 574 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 575 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 577 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 578 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 579 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 581 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 582 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 583 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 584 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 585 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 586 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 587 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 588 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 589 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 590 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 591 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 592 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 593 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 594 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 595 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 596 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 597 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 598 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 599 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 600 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 601 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 602 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 603 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 604 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 605 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 606 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 607 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 608 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 612 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 617 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 618 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 619 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 620 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 621 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 623 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 624 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 625 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 626 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 627 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 628 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 629 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 630 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 631 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 632 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 633 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 634 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 636 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 637 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 638 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 639 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 640 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 641 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 642 0 obj << /Length 294 /Filter /FlateDecode >> stream xÚMÁJÃ@Eo˜E`Δf~@“Ú+UÁ,]¹WêÒ…¢à¢4óiù” Ë,BŸ÷M 3òÞ}™{ßâü¤Zùʯüñ©_ò,ýË̾ÛÅœÅÊ/Ïç7»ilùàs[Þ°lËæÖ~|½Úrswég¶¼ò3_=ÙæÊ^äÉB²5{ ´azH@Ѹm‡" îPO”»)êˆímÄx¤”ÙýSH4ýÒ™¸N\%~gÊ>“`~¢‘ Ÿ|QBÎ××p£Ú*Ôê^ÙªCŽYò¬6÷_ò×ÌÓ¼Kå"MÖ!I A8é#’ŒÈPŒH‹*`ŸÙ ÚÞ“"{Ôäˆ 'ÜÏΈôØB¸±-ý TÒñ¯ƒ.öº±÷ö* †ƒ endstream endobj 647 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 648 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 650 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 651 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 652 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 653 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 654 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 655 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 656 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 657 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 658 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 659 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 660 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 662 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 663 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 664 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 665 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 666 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 670 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 671 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 673 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 674 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0´TÐ5W02S0µPH1ä*ä2 (˜™Be’s¹œ<¹ôÃ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. (\®ž\\&Q# endstream endobj 675 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 676 0 obj << /Length 114 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04WÐ5W01T0µPH1ä*ä22Š(˜™B¥’s¹œ<¹ôÃŒŒ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ†þüa`üè?’›îçrõä ä—5ez endstream endobj 677 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0VÐ5W02W0µPH1ä*ä22 (˜™Bd’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ‚êÿÿc`¨ü¨æ`°›ÿp¹zrrléI endstream endobj 678 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 679 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 680 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 681 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UеP0¶TÐ5RH1ä*ä26 (˜A$’s¹œ<¹ôÃŒ¹ô≠ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿÏÄÿа—«'W *› endstream endobj 682 0 obj << /Length 113 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F ¦F )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêü€ÖÀ åPº‰õìä¸\=¹¹AQ@ endstream endobj 683 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 684 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 685 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 686 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 687 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F †† )†\…\@Ú$l‘IÎåròäÒ pé{€IO_…’¢ÒT.}§g ßE!¨'–ËÓEAžÁ¾¡þÀÿ0XÀ¾AžËÕ“+ ‰;“ endstream endobj 688 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 689 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F Æf )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêüƒõìäðì:¸\=¹¹{-= endstream endobj 690 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04UÐ54R06P06SH1ä*ä24 (˜XÀä’s¹œ<¹ôà M¸ô=€\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü òìÔ€Aûòøð Žöêá´ÿ#ÿ‡ÿÆ ?0`ÿ ÿ þÀÿ†ÿ@¡.WO®@.…8 endstream endobj 691 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V04S01T06QH1ä*ä26 (Z@d’s¹œ<¹ôÌ͹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿÿÿÄÿ °‘§\®ž\\ºâAŠ endstream endobj 692 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 693 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 694 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W01T06W05TH1ä*ä2 (Be’s¹œ<¹ôÃŒ,¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ? ˜ÿ1üàÿÏøCþûûÿç?ÔÏÿÿà?ÿÿØÿ7üJq¹zrr)}(Ë endstream endobj 695 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 696 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 697 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 698 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 699 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 700 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 701 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 702 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 703 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 704 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 705 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 706 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 707 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 708 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 710 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 711 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 712 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 713 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 714 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 715 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 716 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 717 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 718 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 719 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 720 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 721 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 722 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 723 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 724 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 725 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 726 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 727 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 728 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 729 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 730 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 731 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 732 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 733 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 734 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 735 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 736 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 737 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 738 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 739 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 740 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 741 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 742 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 743 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 744 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 745 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 747 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 748 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 749 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 750 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 751 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 752 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 753 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 754 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 755 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 756 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 757 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 758 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 759 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 760 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 761 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 762 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 766 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 767 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 768 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32Ó35V0P0WÐ52T02U03RH1ä*ä24Š(XC¥’s¹œ<¹ôà ͹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿ7@ц`þårõä ä.§á endstream endobj 769 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ó35V0P0RÐ52T02P03RH1ä*ä24Š(XC¥’s¹œ<¹ôà ͹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿ7@ãÈ@pÿr¹zrrßb”ß endstream endobj 770 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 771 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 773 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 774 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 775 0 obj << /Length 112 /Filter /FlateDecode >> stream xÚ37Ñ32W0P0UÐ54R0³T05VH1ä*ä23Š(˜™B¥’s¹œ<¹ôÃÌŒ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Ì `0¢èÿð©áÁåêÉÈÇ‚J# endstream endobj 776 0 obj << /Length 143 /Filter /FlateDecode >> stream xÚ32Ó35V0P0WÐ54S02R04VH1ä*ä24Š(YB¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü öê?Ôøÿÿ€`=ÚÿáŸÃ Ã`Ã`†  0>`>ÀÞÀÏ ”’`àrõä 䦇, endstream endobj 777 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚ32Ó35V0P0b#CCc…C®B.C˜ˆ ’HÎåròäÒò¹ô=À¤§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒýƒúõþÿ€AÏþ—«'W !‘$‡ endstream endobj 778 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 779 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 780 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 781 0 obj << /Length 109 /Filter /FlateDecode >> stream xÚ37Ñ32W0P0U°T0³T06RH1ä*ä23Š(ƒ%’s¹œ<¹ôÃÌŒ¹ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÁà„úÿF3 €î.˜{¹\=¹¹X@ endstream endobj 782 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 783 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 784 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 785 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 787 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 788 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 789 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 790 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 791 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 792 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 793 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 794 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 795 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 796 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 797 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 798 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 799 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 801 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 802 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 803 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 804 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 805 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 807 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 808 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 809 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 811 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 812 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 813 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 814 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 815 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 816 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 817 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 818 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 819 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 820 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 821 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 823 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 824 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 825 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 826 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 827 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 828 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 829 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 830 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 831 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 832 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 833 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 834 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 835 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 836 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 837 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 839 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 840 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 841 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 842 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 843 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 844 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 845 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 846 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 847 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 848 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 850 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 851 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 852 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 854 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 419 0 obj << /Type /ObjStm /N 100 /First 892 /Length 3642 /Filter /FlateDecode >> stream xÚå[ÛŽ·}Ÿ¯à¨‡×*ü`;ÄaÈE؇´²ØR ­çïs»›älï:³­Ù@€1èž&‡—ºU§Š=щ±&ºlJÂW2.d½7>¢ì£ ?{gBøV ËŤÌßňGûàŒÆ|ˆ!˜Ñ.X“³à;™’Ñ>¨qVÑ!Dãœc‚‡RLŒÎ8_"j2æFÈGŒ À%/‡=„ÑF$kœ&Œ1r¶hœÐ&“‡„) ‰LÎxØXŒw‰Ùx1bJx(îÅȉc .}òl[ð àA¢ñ¢¨AÁ« 7ðÙaN|±è­Ök1§(b8DtTFpª,Õã!£»¢M ¥Z ]RªbB"¥r d…HRPAc BË!ft/`²~¶…ð,µ”!!©"GÕyS¿Ñ‘“ê‰ÓEm JUbT…`-Ä‚IÌÇBR!µD¾2%oI!Æ„*9¦åôüDŸÐ„$Б‚S<8“Ä•Cbm$iFR`›bD!©ùHf¨JJ®Ò4j1 Øb4@ÆâP£.àÁ™ì"t€^ "µøÆ¨¹PÁ‚õ[ˆ"'Åãæ ãâ!HÁª*\ ‚E93—”†nÌ ›s¡†ŒÁ…ONDÈz"\´µÃp.`h}JX±Pœç„Ô—ó’0B¬ ¢ÌXr.¢ ž0J9<~8þðŸߘã·×?ÞŽ_½w{óîö#D¥Ø”ߎßÝ||ÿë‡W7ëÖ¬Ußܼ~{ýåûßÌK‹ qÞhñW ñ}¡ [Û}ñEþkó2Öþ9þýÿ$S„deòXñï~ýù竵é Ìnž?7Ç´Ø£µÓ leÎì{²´üâªæ´ãtîƒñŽß~xÿêû›[ó¼}ý¸ùíÖ´©îgÚ‡ Ó°;;™öþÿÀt˜Wþ'1·LËn¦õbLŸðy"AÓ‘@ð »WÁ=‘Ú/À§lùŒ»ùLOÁç^֢ݲ–w³Vž|çîæ3nøŒþ<>£Üå3†'߬»ù,[>u7Ÿù³ÕgÚzœäöò™üÓèö‘°ä÷-ñn lFJ»% Ÿ­¦Åmù,{ù{ŸÛ¦M}ÉS…!Àn6Mûå“6ò‘°[>ñiÖÁÖ»l-›œiÙÔmø¼œe;U6çºu[ê÷2­áÉ•{‘¯[`­²›iýl-[ÞÂçl÷ò™ÝçËç>縛Ït¶?mJ ]žB‘KÆT°àe‹ÁsÞ-Ÿr¾|Ê]ù$ ù ˜?£©K MÓ§"¤œ]F”[{Yδ—eã K8[”§M)‰:%lÊOó'—ÉÖoÝ-’|¾Hòf÷Iž| ç4 1L‚êÇÛ®.°;«kã犒Žßÿú¯ÛZde8ÿzýËM|¦è›ëÛo)ÂÉ:o95>ýùjnõe³qæ™wлuB¶î’ôç_ Ê/ÍU¥÷ÅÛo¿úéúàïáø—ë¥à\9ÿööõíOk·êõOï^½ýöÝ5•[kؖó‘_•úÒëÄ$b;Í£h7,¼š%oS5FXíÊ”g…ÌO’&¦½ùÓÐÊŸÙ1¸‰G˵˜$PØÕ°,Vñbñ¾}óæ{…Du¼®—àR\W9^'0åŽÓ»÷·¯oÞ€?Ôð‚hJ«ô«úÕJn¿¨=^×Ëõ½6¢›/õ̳¡}ÌŒ^<és瀞óôÌ 7™¥ÕÔ”dÊPjë… øqÖòæxó¼Þ"oLË÷ŽÎfVÖû9ösìKã\è {Ϸě𦼱³+m_BÀpRKÄI£àׂ¢Ö¤»fí “Wµ±f¸ ÊZ@»ø(…uá<ë<ý°ëŠÑì:T”œ] ð¦Î­ íVB3×ÃJ(Ô‘Ü:)4‘ÖÃ*!Ùu,ÛäVr G[ÉÁbMn%ªA©´ò¶•h©Ë]KìÆR§î^¦Ñ*®åÓú±tß/g±y³›’‡]æåÂ=Þ+Ó=û}Þà–çÄ›½Í£¶¡²ÜÙ×\à1Œ‹3Æq9Æ4.¹(㲊:.9iù˜å‘¶ËÃËÃ>äÈÉ= SÚ½>Bׇ÷m}ˆ½»>ÄmÖ‡¸¾>²ÎÞ“z–å>k>èT·ÜÍÁÙwÛ¾O?9r%i™$ÂÃÐíæ4!ÂSÌà­&à‹œéÕASªŽ¶f,P‚}PÃShbÆ¥t<ŒjJ7WÒÅO°?ªux! ˜§µ÷|RœâÚ#–IËòœÜ…8Á®Í¬ÌõpóÕ§Âï¹T«²ôÚòU„‰/?€Æ²ˆuiU{ϘŸçûLÁ-À³Á…î¯#vO½jzmE€G½Fïâ \ðª Î8a¯&P×·Z‚/Õ€÷c \GÊŠ2pa „ [ u½ÐC•î WÙ  ô«QF¤7ÃE-_I Ì· À Ü<;{vö¾[¡@¼Ú`mCPsjè)¥w¤Øq‡4§Í—%<ák žð¥‰5ß²XGã« w`Xi¸ƒK¯á“¤qB¹£ ÌeDHYG„”óè®rR±#B*nteÅ©„!•8"¤’F„Tdt¥Ñâiç-ž³7Z|}»ç±Î2îÂR|Vm·§ôcÌËÂê(W =8ʸu”©;JœgEs–çnàíÅõÐ9Y{u¶Ì™=€ž3U¶_lŒ¸‘[ÜÊ-v¹Ñ…ä)¦{]pÿÀÝÆŽà «ÅzºÏ<ÃâžçûPcOêÙ/ù '˜;ÍÄ*)ÔœÀÜk¡˜…¯ËðUÀ©_„'óh*$`©wá;|Œ×9‹ þ§^Åû;.¾ºô“´ÁC®“tÕŸ<Ð"ú“‚KiÁhäþ‚pY_¿ —¥ÂXI R ±œì¸ 1*1Z,· 1*üfQ-‘¶ZzŒj9Clµ 1*fbTXË!FÅ CŒŠ†Ž:¤ÁVKÁVKà y°ÕÊ`«%ÚÑVÇ÷Ð8××;ëÓù–Èï°D±"%~Ùmˆä$gé]7D+†è†hƒ!ZàY—%žø$«á'X;¦÷îê×\ãÓTÃÌZåÝDÔ€„{>/ªÍK ìH2~Žyâ¥4Ar€©F;Ž˜á9x¾gï›R†Ýl÷š‡Á4¶¾ÿ_f€©÷M$ß-B7ä¢ÅæÜå1»<ŽMÒÐ$i*IcšJÒ˜¦’H&)Û<ɸ͓ŽÛ<åq›§1M%2¦©DÆ4•Ș¦ ãVn¨¹nå›ëVy,Ðr{AÖ±êþ¬ÄÉV•¶UUîb• fPI&­½Mkÿ?ÚÝþAæ¼ìýœŒ â{Ó“e^°oæ-ÀºeWYS1¸<.´‹ñ¡ã»é\‰ñúzЃ ííííí$^. ƒËÝ—|Á…ví2Ú´+hWЮð?w}pÉù Þä÷³2¼…G!IÞØÃ³C0 !=c¤Á@_Ò"w€/i13y-ô’yI‹†¼Ô®–¸KZäØ%-M™´lY Ͻ¬Rв@  %ˆu[ìÎädKDžíåž,ÒžS*(ÄŽµù28Cm®,1á¬=Y¤Í‘%¶³¬Kl{æH›CgmN ¥%'ÐYZn‚GÔ-!#üÏ:€­´1Œjù.¡JÏPiK~ÁûiK~ Ádì*mÉ/À6ïæË8(æf«öþÒÉ!æ{Ë«…jx0¯fªãÁ¼«šCJ“.o|¬ï}h™ßê¨o‹T«²~kœ°p}= :A¹ó}þýä×ù½ú<ÿú)÷y¿GÍóÔc .ÒZR?Í¡ í?“CxÆ$žï‰ˆ­ IhÎÿ’ _{‰…¯Á ¦æ³™X*v’´´QÇ»$¾03?ã.~“Ûc–(óä%3®õ–2_i>¥}‘‹,¹.þåµF®Ës˜`E|™xÖ]ùŸë)Ôúdùî{­˜Õµtš×&,V]ñŸ´UWó¤êc½ÍDœ*ýœ C½6I´›zøZÈêgaâ ˆë5ù©VB?qs³í´Ux6äÛ$—€~¦t Jø¼A !lY† Îéøÿ(V endstream endobj 859 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 860 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 861 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 862 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 863 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 864 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 865 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 866 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 867 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 868 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 869 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 870 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 871 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 872 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bS #…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿA ÉÀþÿÃ(9THü±ÉåêÉÈ’:Õ° endstream endobj 873 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 874 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 875 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 876 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 877 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 878 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 879 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 880 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 882 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 883 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 884 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 885 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 887 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 888 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 889 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 890 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 891 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 893 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 894 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 895 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 896 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 897 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 898 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 899 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 901 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 902 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 903 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 907 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 908 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 909 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 910 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 911 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 912 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 913 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 914 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 915 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 916 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 918 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 919 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 920 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 921 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 923 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 925 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 926 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 927 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 928 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 930 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 931 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 932 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 933 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 934 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 935 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 936 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 937 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 938 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 939 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 940 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 941 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 942 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 944 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 945 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 946 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 950 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 951 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 952 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ52T02R03RH1ä*ä24Š(XC¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿüÿó‡a0C ¹\=¹¹¶ h endstream endobj 953 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 954 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 955 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 956 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 957 0 obj << /Length 109 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCs3…C®B.K ×ĉ'çr9yré‡+Xré{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]dêþ7 ÂzlÐ+”Á Ѫ-õ@>—«'W Êî/ä endstream endobj 958 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 959 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 960 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 961 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 962 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 963 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 964 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 965 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 966 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0U04T03P06TH1ä*ä25 (Ae’s¹œ<¹ôÃLM¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿAà˜üÿ‡Îj-Ô\®ž\\~,Ü endstream endobj 967 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 968 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 969 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 970 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 971 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 972 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 973 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 974 0 obj << /Length 250 /Filter /FlateDecode >> stream xÚEÁJÃ@†ÿC`÷Jv^@“´5maI ¶`‚ž<ˆ'õ(¨(ä’øfy”<Â÷²n‚TøNÿÌ|3³J/w ÇœòE²áUÂW;~I胖k—ƼIÿJÏo´/(zà嚢—STÜò×ç÷+Eû»kN(:ð£S=Qq`Ôðlüôï!¶ ‹ g%µþGiÀaf*¸!4-ò¹† -„mÛûV «ec29¨`(½±Äh&ÃÔ¨!Nˆ¢†l6m˜÷*7•˜ SyVÃäs£?Àçµ g„CM†îæ0F¶…Z <‡vOù¶uCt,èž~¥(`Á endstream endobj 975 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 976 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 977 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 978 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 979 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 980 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 981 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 982 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 983 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 984 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 985 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 987 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 988 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 989 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 990 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 991 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 992 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 993 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 994 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 995 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 996 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 997 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 998 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 999 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 1000 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 1001 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 1002 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 1004 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 1005 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 1006 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 1007 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 1008 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 1009 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 1010 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 1011 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 1012 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 1014 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 1015 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 1016 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 1017 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 1018 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 1019 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 1020 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 1021 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 1024 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 1026 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 1027 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 1028 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 1029 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 1031 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 1032 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 1033 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 1034 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 1035 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 1036 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 1037 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 1038 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 1040 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 1041 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 1045 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 1046 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 1047 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 1048 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 1049 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 1050 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ¿NÃ0Æ?+C$/~„Ü @pK§V*E"L02€`«÷ÉÈ£Dâ`ž”7Ѭ$7ëãî¨d¸¬*¦ ¯:}§¿$ X endstream endobj 1051 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 1052 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 1053 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 1054 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 1055 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 1056 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 1057 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 1058 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 1060 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 1061 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 1062 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 1063 0 obj << /Length 238 /Filter /FlateDecode >> stream xڭбJÄ@à?ìÂ4y1󺉗‹[8O0… •…‚Z *Úš<Ú>Ê=BÊKÖD¸Òæ+f™™¶ö‡Ç+.yÅG\×Ü4üPÑ -½Knü÷Ëý­;r×¼ôäÎ¥L®»à·×÷GrëËS®Èmø¦âò–º ÁØ`#úÁ¦” ÌJT&e« 0m´ã?H‚M¦ÈF3âC‚ …P J°@¤#ßJ“ÿ2 ‹_â.N”^‘v2%5+w:ù‹gY9–º×Cbì)û@;ä@¯ùf,B‘M¥—B‘~2ÑYGWô îøeß endstream endobj 1064 0 obj << /Length 219 /Filter /FlateDecode >> stream xÚ¥ÏÍJÃ@ð Ci®Š°» ùX/b Í¡ §ŠPB,íM$–Gé#xôPÔÝ .ÔC¡3ð;ÌÌîÎ&z’§¬8åë˜ÍYÎϽQ›¢âì¦ë<½RQ’\q“\˜2ÉrÉÛÍî…dqÇɯ#VTÎx$ltŽøc¢uZGaýÚL„ÂùÚ¨EeT°†{Øšôk€ç.àÐYàjXà î-æ‚^› Çð Þ:~ÀwÇßޑþ×ÿ'žaðÙ”æ%=Ð//ó]ã endstream endobj 1068 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×31R0P0F¦ :Å« Ì ƒYɹ\Nž\úá@—¾˜ôôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàg°?Pÿàÿ¬`€ŸËÕ“+ è±"g endstream endobj 1069 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 1070 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 1072 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 1074 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 1075 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 1076 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 1077 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ33×3Q0P04¦æ –& )†\…\& ¾ˆ –IÎåròäÒW01æÒ÷ sé{ú*”•¦ré;8+ré»(D*Äryº(000`f0É&ùÁ¤=˜¬‘ŒÿA$?˜ü"ÿCÈ ÙÿÀ$Då(9„Éÿà$ûÿ?àXþÿÿ&ÉåêÉÈie£\ endstream endobj 1078 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 1079 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 1080 0 obj << /Length 339 /Filter /FlateDecode >> stream xÚÒMJÄ0àWº(d“˜\@ÛÊLe@ˆŒ#Ø… +âJ]ºPtÞÀ+õ^¡7˜.»}¾÷R¡ÝŒ–Ò¯$!Éû©ÎNV¶°•=>µUi7+û\ª7µæÁÂnª8óôª¶µÊïíz¥òkVy}c?Þ?_T¾½½´¥Êwö¡´Å£ªw EàÇ`Çxè› ŽD6&<©{p-­èø×ðxš&hY:@B$Òü›ñ(‹iµš LJ¹v‰:ßòu–ôø'ƒ ÿO˜c‚?€\pÂýb&$¢ gìƒÄ¾”H¾C"œ¬¯À9Ëtà j‚òyDÐnçåtÐ;ÆŒÀÀ…«5Ñ@ê nI;ÇO4sPêÊ…‹e4±¨BÒÅ(ôΗ¢S9¦ÝÄ^Ø+4IÖI“¤½ìNÝ%5÷(5p(­˜a NÆÔU­îÔÃâÛE endstream endobj 1084 0 obj << /Length1 1416 /Length2 6052 /Length3 0 /Length 7019 /Filter /FlateDecode >> stream xÚwT“ÛÒ6Ò„ RE:QCHè½÷*¥† ”$$‘Š ½IïU©*½ƒH‘* H¥ƒ)*J/_PϽ÷Üÿ_ëûVÖJÞ™yföÌÞϳ×Λwøí‘v05$ËI•uu5Á $, 89áXWØß~§) #RÿPFà X¼O‚Åu‘ ÖW X“‹K@@!Hòo -TxÀíº@-$†p*#QÞh¸£¿Îß@n(,))~çW:PÑ ††C! .ësï…¸P8 ëýÜ2NX,JJPÐÓÓSâ†@¢åxî=áX' ! C{Àì#õ n°?£ 8ÆNpÌï€Òë AÀx‡+ C`ð)ö04¿:ÐHS¨‚!~ƒu~îÿl,þW¹?Ù…àˆ_É(醂 ¼áG ÜÔWÓÀzaï!û ăÄçC< pWˆð«uPMÑÁOøg>  Ga1¸ëÅŒ‚eðÛ¬Š°WFº¹ÁX à¢?8Åï»·àŸÃuA =>[p„½ÃÅöP‚&¸û˜¦Ê Þø·Ï†Š‚$Ä…%D0w Ì ê$x±€±7 ö+¾pãgðóA!Q@ü0?¸ ÿðÁ@<`@,úÌÏç?ÿ´`0ÐÅí`ŽpàßÕñn˜Ãoþh¸Ð„§ºøüëÉ Ï0{$ÂÕûßð_G,htOí®’)ߟ‘ÿTRBz}ø……€üB¢ $"Ç?øý³Î]üOÿ‘«‰p@/Š]ô‹ß¨¿{öøCî? áþ³˜O]ûßL·‰‚ ø/ðÿ™ï¿Rþ4¿¨ò¿2ý¿;R{àêú+ÎýðÿÄ!npWï??»Úš#»]ÜÄùþ¥ñDŸ–[”OÌR”ؤŠÑÝwY£¨ÚÉåí»8)}ÿªîü˜èÉEW¢&®Ò¢×Ú^Y’¥CÏ"iúå“!¶É®ÏxEt—á¯ÜOn±AKÑ–©z·´eZ žT ½ý}3Ô]¬QZV¾s„b©U¥ûXTD.W˜Î<½ö3·Øc3ƒÆÇNVaÓ¾ûÅ8‘³§;­­J\SîQˆšhÜBÍŒoFÁ“ã-°à›ZhzU´2ÎÓmqß·ÂkÑJ§× YèW†kqýºðúq4R Èžól£-28†A 9âVÙôRWø[)aœ=A‰^Þ‹ãÝ@ú·=Èa€GI`ôñ&ît“0¨@ÕâHžß½.m:Úæ(Öû´›‚PnòÎù¹æTý-7EÐà©¡pýD/]ŸO+ßSúæeIêÅøƒ•aݤe}J'?~ÚiîÇWÑô­'ÄF·(.ì6åFñŒU1½ÒR"H& ùìsÖæ®°#3ÓN–ì5v‹Vös»s¤ÍõïJ,¦óÇ=.×o›ÝbÿÊH¸\Ÿùz²½Ž¼¯†Ñç N*àܲÚnòŒÖ{Y6¦!·§â·÷l:;¾û^òµ–¯µU`çûåAŽ%×HÛÀv­MYZÏ!¾¶­N1Åvy:<ïmA-¸@ÎIß«Í Ä½´iNŒF !O¹HúÑ ÎøG7&¬“ @7³«Ît}g a¸³ÐÆjS¨¨á%Äù¦Ä'›Á$y÷¦g*…=žÇÇÆºäÝ±Ž¶KÈøŽh"ƒP „ˆØ(‘.mÐ’ÐÌœô ƒ·øF¦¨Ç.Q~1««êG!³TN²^DµzÉõ;|Ш9¶`·2VÝïpÎ0ì‹ôä;¡X^¦ßf¤QͺJ,ãÌgPÕ»¹™Ù7MfíëoÖHÛ‹<Í7.¤œ•º³tìAwªË;3!͇¾~Ù<º‚wÕx£À`lÞ³[âÞc'¶ŽÑïi™èyßç¨MùØ¿lq ýô5¯Ì'Bgt“+¼½Ðož-¹Ô_´p|ð­n^N>vj¹Ö8ïcò›¡gÆØ¢ Œ-Ö´Ü&h^ceé` ÷>ùÚxÍ/8/ »:eþ4¨ù–xÀ¶;6xÁáØ¯fu$‰§2T‚ØÈpÌ<ÙûL¦VÈ9Yߺe1¨™Š³ýJ¬IvsÈ‚ÜxŒ`^iÅ3e7äü hˆ³Ôï jú†ýg'z¹HšÈËÖž*Eß`»ö׺ˆ6 pû{#Ö muòd¨+pai–ê@¥î&EVØÉ [ïîÞ¢‘[eÚÐõU`Wî盟ÆÈÙ^ÚÆ7ÇÞ“·Q´¤é&C,¢€ê€lQ¡ûÂR Ù Ì}2÷ÔG|À‡çPSMÆJ"1n´î­Ãlˆ}@@Ðìs½ÍP!+(²¸/²s.»ÅúþÒÃ{ºÂÉš·CC{²Ê×r÷ã½OÚ:&ÝÍ|á;¼u]‘¢~Ï %‹nTæÞƒ´ÔR_ƒÝ[Ïð‹#{&ä§úfcZI?ô2úòô `±X»ÿ@hÛE)!¼çÌõ›œgœù†Ì'{1•=Ä^4¯hý–Õø92oeÚÑÝä®Ã¹¨Úa¥kz¯­;4ve»P,ë1î‹”‘Š¥ïÎ×Ìœ;+òfÚ:ކ<¯ª&ç.ú,=XipÕ„=Xe·öVAú°S™@¶Î¥fÁxú3ä(î¨H~ˆ!Mù5­¥Ùf·<ä2õ¨ƒ>™ÙÜ;Â¥’Ü’G ÙƒøÁ„r® ѽ+oFKŽêÞ$¬âŸ×¹gzÿ¹Ýó‹AЃAgz9Õq—ê€ê›æÝí:q­õ‡OzãMR+÷3—€ºa®ÇÆ,}ˆÑ3ïÌ.˜IOÏùOLˆ"ñLV$2D˜}È׊Xa•¾¼ÊŒk œÕ+çJfJRoV¨ ”$”îѼ´1¬†Kâ(j 0ù(¨MHäúÁAÌË}!•ÜPíéWõHCC°†—óxÚ.Ù%±âç½*o¤×»zçòo©^ùÕF¯Òˆ,½ëx7ä›sL×iÕ3²‘ò±÷1»@Bò,èq3ƒiU4©4yg-e uiè…Çx8[~<+§Jt^^¯ÏMÒfÉÿf4#[ΦV'@ƒ‡m°WÇj ºŸÿИÁNÇOPnHÔ…æ ìçSý3qzÑŸá·™¥’?ÜyjbC¯sW>¾®·ÿ†žrùª‘îþ{øÖû«SrÉר{†ÂW®¬üæýà|Û¬3[eCb-Šc{Ìw;çfƒZä|ÿ`dãÓú”N¢´ÍC€½AŠ–&G}sJç½>î ôn†îk´ùZ þTD’wR^ˆÕ|ºa>Îó÷R¼Ü|Æbt‡D+DF±3¡8Þ=ïíÊýhIçRÓ0öe;Ñ–IÍ·/käíŒ/ÜFyéOâŒé$ã¦U› Íôù§R&:¢)+5ÖQ« × ¤l·È,q§¯©GÇØ‚UMI|²Á;àÁ ãªdSÓQQo3m_\ÀèÎRêwß©zìåg%ûõSÙrܤðT»ñ„–˪EukÝÙ{aÛS¼3drE×Ôìyæ¾ÀgÚ{üصô´õʲj!\öûñÁ…a#1,¸ÎµkÖö¥]Æj$An3æ&ý« Oöýôq•ê5#ìÕB¨è—·Ê‹ QÝ¢T½^:*oÛÓ"ëžvë±¾3$êD}ÍrèñZRáNy4ˆÈ«žšÈš†ÏÄ<y¹Ú9ÙôéX=GVIĶ£jñŒŸ¨ô´áËÞµµ ’@Ü«”•Xt9 åÆÂ(G¡Òs BÁȸÏRJô{À‰¹\êÌ9£Càb +Œm a7Ù7£9‘»Š^$w¾˜{ý»Rõ)?µKË˦œž—ÂÅÝ“—ÚlånQ³ s6Š­~h¿ß<ÖNCv‡ÃFî6®bATÓƒòø^þ=‚‚Ô|&QñTÂM7¹÷9‹Ø¾UOúÖrº?éHBI+j¾e?õz#£²zѵ€D½w¹•»æ}¥Ú—¿‰Qµ+ÎŒ÷ÚÚ.·:K RÞ ¸_p~fRÄÉ{,Ælùq§^iu1q*^¦cån4ŠÈ¹, ½gݳÂ/™ƒ—h=Ïiø9|eRØ=ð³v¯9Û9Äï)Àò5VCyãòVÿ[º @eqø²ŸÜëZº’NT*󤂹ucøÔ÷µ€O*´2Ìõô8?œ»˜~ê¡2Yß··,,“÷ÏP@®TbÊZÕç j1n<ó7æ „IJ±ó†+ðLW§—ËÍSåt©ÉõÏ6Cü/ý\üuF>-}}u@]¶Ëú…ÓÇ —ŠÌ&8¹„ÝXü¡ÆúÆ¡—ú¹@|(å&ƒþAhÆý¨oÎKjtÆ3-ï®Þá€l1NWc’jó >Zº@]ÀÈ*¾Õ‡daƒ«óĪav[Qw”ËÝw:¹BOÍi75ó3{ÆÓˆÑ¯,§ë_?zsþéĆ´õHXlFÛß@É/¯Èrx¯*t|Ç…ôiÐPŸb;÷¤•î2ãjJr*ºý™8ëÀ²‘÷úÉU®³Ãï¼eYvK¬q¢ªÑŒ8޳GЯs £HTì+Åï„NÅh EÈ«p[­·‰g.Q-MƒêªNã\kò׃B€ù´ å̶ÉÙK ’Q7Ó– :‰ãT+C,ÅJ\[Å_L¼&Ò¡üª#L+!‰È—ÆvŸfÛD—+Ú~¾Jj•{ñEÛË]¸³pá ¶˜µ,s=îïˆÙÎpPþ ìªj¼BEs’À–õº¦P*—›UC®¶6uwp¶f\ºâàcï‡'Á~nfYëü?êt‡p[Œ_\Nôäi'¦QÎ&Ó"H˜š³¤ÞL©Ÿ úúEªë·¨9'Ku[»Kû6‰‚Œî¹í>kaÚ ÷ŒÚñ½­¥e’[/Î=Ú¢÷œÏ¨ bäÓrgYÇVEJ0R­V½ÌÒBå!¯ªå]Ûj«¡t4Ëgw voÂÈò§7ø±àÇ™{ãídB“gN]NW|æI×G’™Cy´Á±o{ˆ–¾J¨sRG †ZÞlö4èþK>Fœ¾æ€l2‹Þ|žÓ JŽü4¥r3¥ÞY…|ì¶„ô•‡O¶kÏw0Ĭ¹Ö•²ŽÊߟÆ×ÎÊ­m~À]–ޱ±JlAûãÿj$VDbRt)?Ww|Ü”vô†YŠòHIV’cïòÞMŽLÞ±ø½ã>'4åÞÍ rvX©ôÚÀµ€Q³n{ÿõ3jÚâ9AÁœx¹¾0Æ ^iúÜýJü`cÅ‹¤2ª ÔgǽKžÞVó–Y3!w·ogò9 µë÷¥}ööŒ›DQ…¶ç¾Ž-Ö{º5Nµ@Úê²¹Ðe¿àÕ¡é¤*ÛT^h•`…'´û]mþ¦ùèäk¦Ð,cùí«…aÄégÝä•©€÷ ЧÞM&†. Dqø7’ºþæoÛBƒ}[ÌïŽç™¾êæ^ÇÍl¸ùx¼zÜ©‡åÍü‘¥"PI¯dJ °‘ƺŒÏñgfoˆ°rד¨•m¥3^9œýZÍt‰HQ?—»<óÆ¡Š“{æ5¤2­qKˆ‹$I¡½å_a·´+|SöêŽÁzR*÷¦ŠŒtseWÃñü¤æÊ‘†Žõiýü‰b­c¨zâ[=£ÞHhÐøÏæhÐÙ%ñ÷Ê­••ò£Ö*édgÑq#¶)ÛtY®îeÜBV³méz0ælíµ$P ëùâQ8åà…uLÚö5ºëÔ¶wýÎÙeµgÏåUVµ™33¹jøv"òÑ–B䢽&P­›Ÿî™<)u"©ã%´ÍCŸ(R”%šHôôv#ãxQ˜+,GWU ÷]]Ší|;ƒÒ†ñшœ„!ïáÐ úàÉz?¶—kÚëµMƒn¿`ZŒÎIF©JµzögçŒÐ«Bi(s;K;e5÷Ö#еzm¿¿I2ç1ôÚšKX#êò"˜r*¹MÖ¬¢Á¸‘; ê#„Öùw4Ñk^Y mÜ ,”r'¦ïésòÖž­=S“–¹wžû.ä§§ïö‹†yòqjÚ]cAtÛi{Å–b—ÝFKo~íɲk)§+n”ñÇ|NT¹«¬'¢mY?»½*¯zû‡!bô ùÖÆ¢ËíÙÜÝ£¼c_- žó] KbfR:¿;I£&ò*2<)[V™§ß’_~O(ý4·®þ®—º#‘„ !ØcMSwÑ;Š C‚^DP—Õ·²¡ív®¬­S !I<ö*í„K?ü驌ÝQrVnÓ%ÀR.C8›´ìÕLbõé‡qTâFhWh5G„ËÞò[…%²º¢´(ˆn@øë”t·û«a¾'i»vŸØÒ)®`uÂ$Fª@©ýá¾Ãc­úl<óîïV¨Ô’±ä)ú¹„ù²^Õ…ÍÝ$QSW?Ù¬vËž'Rò¥VŒêK®„*ú 2<±¤Xô¶¦¼#ëeÝñ„äelûü1}²0g¥©% ùùàÏ+*$/câY,ïz«$M¶]v3+²¹`9Oñõä¡Ö´] ,ë„C ¾Ì+~­lcÔ-á>E®Uo…W_é?=$% !lOA îÇbG˜(¼(’wöøéyÅë·4†m dvÀý€¦ ãK5Ó.ïESíÍ1Ç)«‚ì]ÌPâ+îÞ†£2½l‹^²»üYáÄ?Õ‡éü*ï5}ÃAÓÇw+†ùyà„?ÜL'æ¹Ku2R–Ì£ž]:CÉ VQ¶qÕŒýT­~´?™/6âdáÒmôŽÉ¿§\Dnw´ÔXÃG®èy];pð ÈRŸEž¯*¶Ìêj†“!9;Ôí·a²2O÷ÿ+Í£‚õDÞÀà¼ò.§`1éaEš/%T‡Š8x·Ö˜˜:÷οšš0ëœYç˜)T|¼°Lï~û@®RtÕ|dÛ†l#/×` ±ø ÿ‡aq·ÓFzÚ\“_K°_¯g¯î~Õè¤uÒPÔ‘Çò”Û9æÜn…—^ÖÍ|:š¢é¹6lUÖ¾ÅȘ6{”ö‚G“ž°ó²Çª1m§ò—tN×Q?Ä!Eƒú g^ÔØ—Q©>L<éçê¤{ô‘´§¸àð¡N“€<¨v–ÿýÒ”‘­ò‚Gâî0ãŒúb»B  [Ý07Z‰56Ó· eý." ïÅá•àõ™úÇãCóFƼÒG mu:›o š›È]\‘YÐ÷Á¸T/©Y ß6qªvMKÛÏ cbÏÏÏ0îaÆ¥­NÄÐSÛ:‰\Rf÷"»ZÒãKŽÏ êtìå¢#µ/g^U8~oùÍHOJâI>ý_ŽÄëEód&òs<Ëã†vœ#'SÈ膀´5¹H±«K]½þ»v¦ÌXÎHIœò¤'ÀµŸj«gÄÒŸÑï:‡G'2E¥0}Ê1tžìÌ;ðh#o Â~峊½Æ»5¸_ŽË+w: š<´ä*êæ k?_ÿé.PÕÈÚ6û®0ìF×Páf¯k’©—ðžqöó+ûœ:v8&R;#ÜX­ R*î½Ñ+„𠸧ï]Ý÷'Qו™ e™\oáuF«Ã<.ëùølrNñ[D/åð§ñå6Ñ X¦Kœ”aªQ¹®_]ÞÈ’pëq@@äu£†U†¬¤²kˆØ#Œ$™Õ„`§X÷¼ø©cKptzy錔–åø AIBûζt36â ¸|²Eé[ý³ðîÏ>¡vî圱ý5GD-?\TÊu¶¼ Z$™É"ŸÝqr›Úç,ú8jLÄË­„ò®Å…K;J´2pœrÝ·»‡©¸\s~­¥ØË© a~ÅѲ$:©cNLJ”‘–à j³ux™L>¦µ Í‹³âŸyíÍÏ->”‘j©èÅynþ¤À¤c>áyR†ìX PHiød”{ëäG‹ %ŸÅºø¬ÍíQxz õqKʽø®ý¥w‡–ûÇŸÖ;V>|³F‘‘àúÙz`G¤®ÿaž¯…¸¸\³èx®¨æ•Âm‰è®ñËI6.ðrûÂø‘vèõ …kzÃ7ÙŒãÝ(IÉùþÚ(›^ endstream endobj 1086 0 obj << /Length1 1385 /Length2 5930 /Length3 0 /Length 6881 /Filter /FlateDecode >> stream xÚxTSÛº5Ò¤7¥^Þ{ï]¤„$@ $HB©ÒD:HG^¤w¥ H—® ½+M@}Ñã¹÷žûÿc¼72ÆÎ^ß7¿¶Öœ;›“ÍÐDP Šr€©£AP ¢gb€@Q! P„„“ÓŽAÀþ¶“pšÃ<ÐpRú?*00kSc°@= í‰€D qi„4¥þ¢<¤ª`/8 'ÐF!ahN”»¯ÜɃ­ó÷-€ IIIü(¹Á<à0 Æ8Ãܰ!`ÀÃ0¾ÿHÁ#ëŒÁ¸K {{{ ÝÐB('y^€7ã 0†¡a^0(à×È}°ìÏhB$œSg8ú/‡ Êã ö€°C¢±!žH(Ì€­0ÑÒ¸Ãuÿþl$úWº?Ñ¿Á‘¿ƒÁÊÍŒô…#Žp ` ®+„ñÁÀHè/ FaãÁ^`8ì€ün PW2€±þ™ ñ€»cÐBh8â׌¿Ò`·Y UA¹¹Á4ɯþTá0vß}…ÿ®+åôÿ{åGBõt6CÂx´Tÿ`°&’Ûœ`€PJ\\ €=À| ο ˜úºÃ~;›±3ú»£ÜŽØ1`pGö‹Ä ö‚0ž°@ÿÿtüsE pàs‚#Iþk†9þµÆž¿Ü` ÄÒþúüëÎË0( ‰ðý7ü÷ k*i›)ëñÿù_Nee”À_PD (%€@ q€„„ ðŸy Áð?}üG¬Òú«]ì>ýݲ×ðü/àŸ¹ôQXæÂ<ÿ&ú} ‚½€þÏtÿòÿcù¯,ÿ+Ñÿ»#uOâ·Ÿç/Àÿã»Á¾Xæzb°*ÐCaµ€üo¨ì/éêÁ pO·ÿöjaÀX5(!°ŒÝÞýËG«Ã}`PC8âükþ²›ýÒŽ„¢Ðð_Olø_>¬È ®Ø§KÍß.VCÿ¬«†„  ¿Ä&"&{x€}I°g]‰üAXUBa>¿É B¢0ØvÆ@€#ʃä×Á‚°ŒvC\Ñ0Úù—äù!žX±ý&¶øßëßʆÁ|`’ùD&ÜåexûE“·àÆÁòJgt‚U_”†kö™¿³.a¦Æäe{hխᧆse3L|Ÿ.F}î¿ÎYJÓÌÃà¨õ­) æ~=yíc…¢Æ$žF¯Q}N4b¡°·Æ·æN¶˜¹|$Ñ-ºõb³ðª½uOjà(>£dKc¼Ÿçøä{Ü—­Ó†Ïy–JuQ÷Ñ)]“AkvÏß²tÜëcN5¾ßÓÁºå£Ùðí ÿÆaHCz€=¼QÑ/Öªò¡Ÿ.Ú̺¬Û~ÚLäÑýÖ±ñô+)Èú\æîzˆ»ívƒþg÷ïå”UÔÜs¤Dתô‚¹¤üñI£ÌƒTɾHR“ÇBEfB8ÎŽ$ëú‚=kŽÇÍ1Tuß4ÜÏz˜?дÖ2 køAÎñŠBÕ%¿{оÿ(li þÆW ÕUûéáÞ–Å&ÕP½‚(«»Ë%'ÍTVñÓo , Õu¯DÖìDZnTµ”¡4SýI@7}&hw¹»Ú=ÚPdgß,ôo³gª¥d´ÄOáž~çJYKGÜVÿI?H— רô‚U=×ᨸj,?A¦ra(.Zìæ! görœF…ñ;ŽÝÊÖÛ;¸]xŽP`†ð-E±ª² 2®Ü´)w‹X§|/ ×)7œŒcÓºûrêå÷­[_Œ©~Øa¦,d2ºÞ¥x*òÜ)Çð½-¡™ºaö,Û?`íË£@°è†z)/µóDÒ¿’‰°p“¤i¡TÚ]µ*SǶ`¾4þƒL¥uˆ6ÌU÷tÑ«5w?I¡».å¶LJv­Üð{yðþµ’ŠÎûì_S3oN\÷2VI+ÂÏ6Ru&a ŸR´È Φèp¥¦âàˆØRÒº0´Å-¯ËðžÏ¤)†j jú¹ò@ÎEÃ|¾'°Æ †ì› ™jÕ9ú댖 ‘~±ªnÏ?Þ÷z?fßò}޵Y—Ó _q/C3,"™ZvÉ;NûùðbWâ´@?G=»³Y‰žÂiÝžÂJ²;ßL¸„ùìM¹EC:pMƒ"Y±P?IÌöP45Út£NÒ±5ÀèkTÖbÀ^OV ”˜Úœä$D®AZø-ÉØï9ÍɉãŽä¸-•ªóûSÙõÿŒŒUåÔáÝ™Ào¯úçsÑ"ŽÜ*'¾K«5v/¦^(Ú@X%“k‘Œ¸Ã6¯éD]Þu5»yð£BqÆ Tú!ðÁ¥öx鿦+î» >r ¢xÖ lûçßšFç¶§î£ÚBmg9š¸b7NŽm¨$©ñëMè®ðð× ««¶¼™l¦½Á`²Ü•ÊOóãu+ô!&ìù2ñÛ©—ž¶8&Ñ$JbÇâÊrT‹^ÈÅ Ó5¢ªŒøÚ±vöGçe46Â#‚AþQýƒŠySiü™3áä×®Ê àQwäàâZýÔÇiÿr2ý²PœÏΜè¯å;‡¹œ–ÙýBúÐõJó…õѰ.pY¦Íé¶Â´)îÁ±&‘œîL)žøÓ ʫۮ„ÀxçmT‚ ÀÏð€ÍÈýœøuÓy‹‡øyûk™¢º{iÛ]ýë^s¬R®¤¾Tqô šI¾î2Œªƒ³k€d†Pö¸ô¡q¸Må‡,? vÎÐØ‡"o¶íÚ´ñ'ÃEƆÛ›M-Ò?;ÞñvĩݙÛ.‚rWölt1 ¶4’¾ÁfêpÅFÎw1Åν¿Iê6ü¨úÞ%co.¹äØ«Óù'ᓆ1íàY˜³™ã¤â*]^í»…·áÄŽRì ÜÂPSoöËî2m´ÒU…çûæÐ$Ç/xݦþÌÿ0¡0µ7E­÷îå<^’^ÿÞ¬pÕ ýfîÞ¥&,3bÞP¥~ÇKÿÓ»†x iñ>Ù'¼\›P¾ÒÍ„W±)ü[5<ë-æÓGË1¥•‰PG& Z¿%<»¹ïìþÜåw‡#,õÅ<]·zRk#>3ø ¿¯kœ÷›Ôí¹Ð­zµÿ® Å× Ú{c ã=“oÍ'J+‘•DQuoVæš•ÖSZ^w`µ£šWùÖ8¦!>èQ½–G†Ñ|õÏ`°²øbÇâNo×…È[¬š ^ ¢Òx8û“ñžÏ¡@–¹!õ=æ ð.jêh¿“-Éþ¾€®"yèO_ÓÌ'!= æn›OW”¼uRbH.ù­BÄ#ü š™—G¤=ZYUÝÏF÷ðDCÎ ‘¨ÓöãnÙq«Že˜à>Hø‚<6O"$–OMìÎShäQ!*.ÍßF¥\žãž:±ŸÛxßsT+ÎÔu—˜w‚úßCFŠFªPÇ’ñ}:ÞFNž¸góliÈC…fb¢rF»÷jIuÍ£ž¾ùyyáFF‹’ÙpÒî ±Û'´•Ù½0j‚31®»¿:ë‹c"$D'áŠù Y†Åã1O޼à=Úd.0Í?À)>ƒ‚tò \+*ÞÆ¸|ª( bBýn–k¼`Y¹ý º)~\fa´Ãé>uKûeËœe!cA·(FËØÛù\êNtŸuòB–0Õ;jïB“ÜÝ«Õù*J¿Ô.¥{}ö0˜‚Ž"%7 ©&ñ¥Âøª™ö-¥¿tnÉ´gJó,é²8âŽ<¡ë‘Jâ'¹Èð³øÓµ#‰yÇ”’œzjtøvC,uºq͹ýæï¼UbYà%F~:»Q7mÚžBÕ“‘°¨;ºL®½÷ùxÇV^ze]|(–Íyß,ÒÍvD»dù- 'íÁW1óð=Ç ³˜Ý†!ç—“r?c3±ÿgºÅ  {¶Ñ™RG%¬qëÉ|$,üNîJÁ5¯å\*DĨTC%²¾L“&}N«nx:ÇL$´#¬^ÊÄ4Ø2 ,HÃg¯´Æà ±3{ÃHºÈ ƒŸÁÖgÜÜ?iG¢êkjWÓB~Úî*M‰–¬Ñít)³šŸ>ä8”R+h¥Op‘#yl£¨ØÎñ÷¾^mG!&z^¤þÉiª«înŽrÆözÖ¾RiõJǃ—c‡Ã·—_-MÜm Œa,Lÿzaèxëqå‰ÀŒI_žøéZûuæg…%Ö‰^{Ù$mo¨ýþäæiWϹÇÏ<¦ð¢Ý1¡Àü–ÑoSšJo¾ëTÉHÔÔf&†ÊݪzíÈvóÚm¾áŽr!á-o‚ÞhcÉVÅùùÇ™~dæÅ}.-·§¹žË[²½qK… )Ž"èÉ-~²Oš«hn_äH¾s½9x]Ö÷"[ß“ œB¸[TÚÑ'TÜÿ£__Ô…yIÙ쪤eÉ{Sï‚"¨Ñ¤`ó§UÚ<²1ô AFü4W)ŸmË@"÷%D‡bõÖ%WÓ`€ìòh_áÓóNÖ Æƒꟻóåü)òªàFÙü‡¾ÜnûhÙ ³)w6»NÜ£ö…/ëÜÅúYõŸW®§Ë“ãö•޼r±©§FžˆZÊkçû)Ì«Ëé_<ºÖá€$cyâÿঃ<û¼$ßöãÎÁ×R_Ñ ÔjÌÎ{@ðI´æZ7Y¼ª÷jË…Ma0iSÝô™¿ZÝPQÏcïy†• *!:ó•-gFLö™Ÿ+‡«+‡Íݽj:üCˆcsþ·jÊ6|‹4Åãá“ï¢9gOÝo#ŒªŸ%mfDã;¬”Ò »Ÿ\k8yÆlšü S}BßîÇ´URrÆèáÏ78.?Ùé®\‚·ã5k¸ÄÛ1úú½ìçGÜ|ôW,ƒM¯!1²LÓ±®ÇÂD e"n ¼¹Ãcާ-Õ©+«¾wxÖªí9üË™(KØÚX³…\èeŸ–SÇ-å þÊiÇŸÕ–?[c&œ t˜Ÿ=çøÆñRŽ–ñcèl¶Â.TQÂKi#ZΘF¾;Í<Ãɧ¨ÉÜØ±S”+£}¾’~}Ðýƒ¡Dër•§NÅHÙy„fÁ¤hpŸ¯ªÜOkuçůâ=#ø‘mw;“ª€·vš§å[VQà =½V’†ºp²ý^\ÕCç*Ë¢ú8º÷ÐuÞ¦†žþ‰ôèöÖ±š ÃÜÇü‚9UeùfŸÖª1»0doÓˆà¯hŸ´ê„IÐ(+xRψàP&¦LÝz'WB©×ÔÉØOÓmm*iJ׿x¶b¥ÉâJnXmÓðoö0¶µšÈd  yÆ¡^ú.MSuþØœQÁý˜Ðwâi ­á§º\[h÷@¿r$ÁÙüY¾†Îœ¡sÝCýzëf|­!»Ý¨`¢CSz¿¥IGâ-bÙ©´”ØËköw±¿Êj mîö«•öÆÄ¡„ A÷Kƒ©VõE\ À'(Om Ñœ ÊÝúc¯•Ý®Ó E ÿl½©%Q…Ùø'ezÇ6_¥-dh©¼n'<¢L¿n¹*s=\ùvqt‰%M¼áŠ–ŒB›ia@èFš~ïÌÌfýEX’Ü„eÌWIbõ¯b‚=‚õ0ò¾rÕ|k!*xmÉ:0}LJµùîÆ‹¾âÔË“k÷OÏçò™uCp÷Âò “¹$0 Ü3O ?§» 'OXeš¼ü¢ò°N¡K;¬M8I]ÜL¨(¿E€{Êÿ^Çh*ÈÀ>4U1!·r„ÞY:óAi̖۬³½õ¾7ø ø87³7$FuX`¾:\VÇ_IUÔTYõê’E"¦Î šùb¦¬ßwkc¨7™Ð4/VEìRÃÃiÕŒ —Rì-G|äÓX®€šø†®¢‡©4Ê×ç$sŸî’åWèym,ó¸ÜÄ”„­-ÈŽÆ GY6£6}F¸o-n=2˜KdŒr#Š}WuHllÝys<¥/ërg“èwèVo;¨ŠfŽü•LàmŠÃG÷õ‚r 3<Òs°øZ…³Gk4÷2î²êD9Eâ—õmv—mQÐ(Æf›V¦¦¹Ágìœý:öF: Þ¬{ªFd'G“žp_õJJ ]Í”´m90z)CøƒÔºøHÅŠ£¸R§–-†òãH§Sb-õ-i…nLÊ\‰™Á(¤ŸÜEDÅͺèc…„|ˆ«Å7×¢‚²ÜaËjî°—ŸXŠé³)èºeÍJ^Îê/Jꢠ.‹èYrQÊHyÒŒ;LŒGinËT(¿šDí¡þ:Q4VÒ¿Ïæ8Ö­%G8’áFÿenÛl]”Ñ‹á±nUÚÙÛÞ(wšÓ ¶ µ^à uÔ­±^C ©Õã*ö¬×NÉÊ19±£}ó†ŸâNe”mâ Ê’E¿vñ)ß­ óD¶áq4-kõ“ïþ̳3 €ý°Gr;ãÕ²}h  ‘poц^,8WaîõÀàîdMÃ5VÊ}çu<›˜b‡Ã.â«¶Ý »]Ù‰‹‘´~~|Ê} swyõXvmƒvþ2ÅBN½D­Ð¥2LqÜAXÄô}Æa‡µ‰žc=suº! ØÏQ~W­  )yÇ´À²&åøEoã©(&²±âgk¾KyDqO{Iýæé§„’¼Akº)Ýç<Ü8+jº:Þ9”˜„+Ýòä;œA„šI÷q*}FNÑÕhŸƒ"Í\Yuªµõȹë#Î%7Zî‰ßz„ã&°4ál"hq:žoTûwSÍù\éú{oýœ:0¢\:šãÂ@lÙp=Ü»ÇnÌn»1ñÕéÁ)`­£Z?Œ;»Ü!GȬP–«ú`Zex/d-†ØàëÑž=õQ‰{Rºór©–øM•4+R¯ïœ·ªM­ 36ŸCa¸1ìOÍ]ž,W„ûÆb¼|¦¥=¡F‰ôž÷|íh_šBÙ“ËŸ;ðo½6ˆ°™CTû|ä÷>^·|©BÙ¥ªÃj@Èð:Ò1‹ÇIÑÛÆ±Øo¶÷ˆnGõz+;'®¶_™\µåf±Ï–#²ÏüdZjÓµ|§ï«Í^=¼íîQêªGÚ¤H Ø ãzõL45Ñ319ßìåd 9àÝv7¸XšUÎ~K¤Á“$] –$vÁß;_ƒ.¹wÌÍHD[ÛRò%ýã–C”ÑKÆÓÃužKß ÑЋ‡r)xõ!§Žß}}Úü˜ð­Ëµszµ]B5˜¹È$•œÞM /­`ˆ6dÀüc¡ô$£Ù¼ÈD³ü (jöM2;E—‘Eë³0ƒ«/‰wù ü¾· AšO\ )V\—ËïçæÆhâ÷wåö$¨S¬neÔŸ]¼9ÜPCi-«Ç¤ g+\¾ÉX!³£…êõù¶^š¶Ö&¤~Ž4*È™²N2~dßv[°V:]{æQ~ìý ïƒé]çqP]ÊÉ¢í¶+íÞö"ñ=b¦YI·çß™·P@áCe‚+^07rå⼩PÊÑê±w¥ª½8Eúzûd1| ëkëê}R<%ønAƒWã›ó#ýé… õu†{_w’ˆ¦Ü/·`›5ÔÇ9gS¢rå®âqKÂÝ.–xªW#_ûi¿DÕn)|²r –ñ!'«m»mo*Õ¨¥Ö4¨ G+çy“èça/hMšª/\GŽ?îï7™—ÞS®# ÖýZný ^—ôÝÎ×3!qÓ³0!Ïš^âò"~ožñôü¡I<1¼92v’ diLUu Y¤(šbƼšfRzBŒóW­«k{›¾Ûf‚Ëtk8M×O ÚÖ(\.›Ï^,®je,½—Ò¢î!|ëd§ ¿P˜mÂ3ïõ†YµPý$s[“ endstream endobj 858 0 obj << /Type /ObjStm /N 100 /First 985 /Length 5053 /Filter /FlateDecode >> stream xÚí\]7r}Ÿ_ÑVÝá÷ °¬ëÄö«ìf†Æòµ<ˆ¬1fƋͿÏ9ü¬îé{%6oÁ@Ý$›MVO«/”|\Ô¢[´NiÉ g ~Ñ1²£ui^LÔjÉ..&£–]Z¬Q…¼X3ÇXœRþB+’~ÐZÇ–*?BEñ•°£¾—/®þùx{|ÇÿÁ¦â½l¾<¼»¹ÿéø3¢Tz­â¬œ™­¶8)çfK¤ ¢ç¡Ã¡Ÿ¡{¡W¡3¡¡ë Ç(ŽÂ§ñfð${r<©ŒN"'“¶ÉÖ…¤ãœ+z’39™TL&ñ’oI³dW’*¹”Jæ$a’'I…³£a*eaáf£V…I*€6Ä_ء«¾;‰Z ÂÍ'Ÿ§›OAMÏž‚ž.;#\öpqtÙÃÅÑeG—=\]öpqtÙÃÅyng5]v..;‡•ÈÃÅžÜô¸8*L›Fبiœ7 ŸúJç0¾|Fµð¸Q:Ù(l”N6J'¥“ÒÉFéd£t²I:Ù$l’N6I'›¤“MÒÉ&éd“t²)Iß—²ôEYI_”µô0ÙHÓâg|«0>\ŽëŒßËkÆ×ËSCº[`{ÿÂÏjò}-'ß÷Sð} 3É÷Á<;Xs€w¯W0|kåŸÓØù§\×$0Gx„Ël¦`Ø—>°¹¼;2(–£v4è2E“"Æ Äõqk.ïÖrÐ|êÐÇöñkÏrMþW+[¼:ÀæÿŸœ9¯H5ȤšGh ó­¡l¡5 0ж—GÇdÀˆá@ªy„pX»<"8Ï„ž¤šGüFRáIuDo$ÕqÞ"©:qŒÉ#ž‡æÏ ê&©æσCóˆç#Uœ¤šG<ϤӈͱyÄæ±är&©æšƒ6óˆÌ“ŒÀ´™G\ÎÔÏËA›yDåØ4y剓æIªy„ä dFDÚÌ# mæ3“6ÂñÄõñ“T³ I‡Ú?‚ŸºÂ‡é“øÐDû<±$øÖŒX2}J,9¿Î‰5º¬ R¯!“•xQ‹±Œ+³•&Q¬ T{HFm]ÄS!­Æú”k³\'{[ˆ4Xñ1¬ëzÇa^õѬ«†´k©Wˆ”Ñl8Àg˲Áhë>MÿÚn©cm©ëSRt¯]°4¾\±]Û2‰§U‰Zný« Í¥í¹¶ÇüÕQ?Àý˜È<ÓcÌŠœUIˆÙéx,h½üµ[ϤþEÒ8Ó`ÝU1×EÎff‹ -æ±>Æ=1·TRJAM7¥K^)LY‚er‰9¥q`Ìüœr[Kšg…â¼Î:0x¢Ñ‡ &]ò”*Û’yÉÓ]fÏô ³.L¶0ÇÂÔJɨ”`²äOJÚ¤dKJ’¤äFJJ¤dBJdžVJ–£$7JNcVJâ¢ä+Jš¢d'JR¢ä"j gØyÒ1¾f"´ ³ÑóEŸ§“†kÈ#47<æú™;Í#N‡kÈ#Nç wÄéðÙÇ™UÍã oÇÞ 3„å¤fæ[óôáÔ³O"fiLÆ #ÉÏ2óˆ æè™oÍã|§žçy ÌSëÃÅ9æ †+_(†“óº|™±ja¨Åm –f¸ZžñŒAÍ€5=3¯yãø¡fãøù&ÌÌkžiXèÅ90'²$²$²$²$²$²$²$²Œ³Bà<ŽFŒ_ÆÉˆñËH3~§dÆ/ã”Ìøeœ’¿d²d²d²`Ÿ‰˜5´ &¢ÔDØÂo\3nAÍÏ,kùqîõ‘ÏL/…™eÍãËèa¦YQ‹3ÏŠZ‰Öò©kž6ñO‰T+ªZäZQ5"ÙŠªÙV~ŸéVT½È·¢DÂÕ(2®¨&qÌE5‹s.DQ"銪YWTH»¢jÅ©˜ß űU/2¯ZÍ„1¿ø¨™1Ö%A—DòÕ,²¯@D‰ô+ªZä_³w"ÿÊ/{­V?w~l0£J£êÔÙÜó£#¶ÀccQçWÉX‹v*±h'‹6Ãd,Ê …Á¢â×MF*¯åÞJ³¥¾£þþ r­s!tÔQÌ6Kò9âœx(”Òïˆ'ùýLœùè§Ä)»± FÞ±D+@§-q ¤˜´D/\ó{2Õã ·Ï…Sß•b êýuÛsˆæ×¶‚ÙÚC\0ÓŒ¦—wœÞ OÈ÷Ó¢¤/œÞ”[r¸Óâ ‡ -þ.Xéá‚ø~¨•‹+žsyEl^­ˆÍë±y³¢.oWä4wz!'ïWläÊ~|\ñO+¾ñùc‰!<üLrŸiZùÁgº±òÆGC8ñ•¦ündK =Äì$†xpõüPš·½ÂcþÊ·‘°ûHŒËSR?È ˆ†~æP¤zÿýŠ•»¹1¸Ûa~Æ÷匂ÃëÜ´å¤â¸éGKܦÔÊy‰îyˆ%Èé}Œà?’6.ÎP€Øèå×FInßeð:‚ø Îoü$™n/£dßÌ›E¯¸Þ®q½]ãz»F·ÚŸÑ¯ög<‘'zq¼{}{ýÛýÍmÝJuÿ½üÛWß?ÿË¿~ùí·_k¦Ïß^½¹[œÜlO-w[á*GOÌ­øÅÝëã»{þ ;âê·?¯ßü‚j¶æ4|öTóá×÷Wo¯_ñîÍÛ#ZÐðòþøë_–h..ÿÚÞrV×mÅ=ûÙå›ÛãÕýñöòíñîîI•ã«k¼­Ur£Ø¾ø÷??ÿнüÛ)Å =ÍåLõ'cS1hù8Åœ:©ØW¯ÿûîíÕÝ/­>,­‡¡ž_Ýùä᢭@¨¿l+1É.(AvÁ ® îÓo¡}0}ÜN¯µZ‘íüDôŽßƒ°ï€ÝÍï4² Ôo‰|ùE\ù?®+éÛ/ºžù3ªz¯þ–¿ª÷ºÙ^=n’ºÛ]=îm’Ü&Éíy=T=nSV‹©G›ÅèV¯è,¦SœÄ´Áëa÷Xï®MæZ½ œ¤­©Qî¾Ýë™Ø&¯4úÈIR¼­…ÉmÐzÊ]l=.VÜÂg9‰­§¿ÅÖ³î­Þà³ÍêlÍ_?r’†¹­˜ã^5²Í„mhšTñÈIR¬Áe›Éºz„ǽ áô'Lâš©ºz–Ž Z•¸ûvÏŸ0‰kר‡»6YƒÍ5Ø\pŸ0Ihƒ7Su±iҬΥ¦Iz¯&FLÒ“;m’f²îý´a¥¨=+Ô°1_[a£Ú†h ßv]rŸ0‹m³Xßí¨ÙOc%çúï7RsrWÓUç^ŽnèÝa¬ÝÀwóþ¿{ýŽCg´´È‰®¨üRºÆôU´8^½¾/®¹YÅ ÞjqÊÞ´ïo/?´–>¬½îçëæüëÍ2¾;þcJµL÷Ázîn¬žókCíÈÕÉɬFR;#Ù1’:7Rçî2RJètçžl­™äé,âIžvðNîxî(áN;hÇv<‹v”h§°ã;ž;H°ãØa€΂$Øqì0ÀgÁì°v`û³`{ vØÛ°ýY°½;ì€íØþ,ØN‚íwÀvlwl'Áö;`»¶; ¶“`»°ÝÛžÛJ°ÝØv€mÏ‚m%Ønl;À¶gÁ6l»¶`›³` ¶ÝÛ °ÍY°Ûì€mØú,ØZ‚möœÉ[Ÿ[K°ÍØÚN§t–!%ùï`=Iä¬5ÊQv€žòÄ(•å‹<Ü#øìÅÍë§/ï¯nïŸ0ƒSB€Ï~C°pÐlp²A¡¥Ø[ا:¢Þbž.%[,[ZÔtùÍõ¯×÷›iG¿W[Ùê‡ôjHÏ–•h-I¶D´˜•°‰-+a3Z¬ÚŠ6f½öƒªº²@ëiǓ͖,[“²äV}¨±w»r™'³Ó ±ˆŽ—X¢Sâ½…èÔÏ1½…èÄ•6D'Jm ¨öi_,ÿdtÚËœ(Õ´'I±,ÁIRtKpòJ‚“Wã`n«Â®\œuô:!бZZŠl‘èX cÍJÔÌÙré ‡q˜ÛVsx(Wx2{íËå]Ù—3l‘`8Ë †ƒÖKûr„ge޳+g½NFx‚ÜHŽðD #²%ï æÇŽD¯‚gW“f¶H40§Ž¯xÜjùƒf‹Ô/Pc¿O`œtôÚ—+ž•­³²•@xVfÏjùቒ¡5Žû¦ÏYG¯‚žWDÂ#猄gE‘ð$‰i$!W~2{íË_y7è©“D0³¡xw|}}óî_Š+m ÑHžn‡nÑJ®ÎzWBN¿êù@Êù{´K:[¹O•Þ¶r¯¶ÌÕl¥3³j« Ý—Õ[Uè°¬~àVÒ¬zŸœžÉšÓþÝbEeíVI[hw«$µaÛJul<)¸Y nÍÁ‹ [‹s [uŠƒ [uŠ“iIrÑJ%»­Å·ÄpRpJ³ê}ZðâgâVðâkâVpWb•ÂpùÓÖ(Šßy`ßÅ÷duRðâdï3‚ż]èâ‹z”:[‰bÞ*Y\PÞ*YÝÐVðê]ξ2ÎTª[Z ^¢kë7mE’Må°›67mä*}R\Ê ûž’–çf6µ~#)ƒX¿‘”1aؾ‹åßl†•§v` wg¿“B2LŒ@(nöM‰Ñ6Ý—lz1Hˆe&${JL+Ñôþ´ Œ-ÒFFy+¬8oÅ‚ o̲„ Û&ÓÔIQ)ì{RT†zãè‡ÍfIËÁaÝÄÍvÊôʸ¢ç˜¿'¤[>¿üÿ­à{!ôBì…ôÞƒ¥$¿1GËu·tlýÿ)ZÁô‚í÷žHYÆ ýsB‹CuËx×ÿ¿¢R/t)´ú/)e|¶íRë.µîR·ó±n‡ú÷“@޾ˮ»ìºË®ó9àwÆ|q¼C·òÿf<øLýåÕýÕÛ›7õ+…ø¢Ñ¿:ÈLF1ÓòŸn´TÇ›ã·7?/ÿ|wìÝKã7W?ßÞ={vùÝï¿Þý PxyùâóÏu/¼â¯˜þøÛñÝEÖ¥­%û_zt³ endstream endobj 1123 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.16)/Keywords() /CreationDate (D:20171125154537-05'00') /ModDate (D:20171125154537-05'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/Debian) kpathsea version 6.2.1) >> endobj 1124 0 obj << /Type /XRef /Index [0 1125] /Size 1125 /W [1 3 1] /Root 1122 0 R /Info 1123 0 R /ID [ ] /Length 3174 /Filter /FlateDecode >> stream xÚ%˜yxNׯÏúöNÈ"‰9f‘ð!æ$† AD™e 5¶j¨y®¡”¶Ô<„ÃQE©r=ím‹Vo[кÚzÜVç[ÚjÝÖ}ß%üž³ß}¾=­w­srÇqîûÇçˆrÎáÕHŸc ûòJQF-W†°D9µ>¼ ‰ j½yU¨xÕ©¥±DSK¦Ö‹Í"”Zµžl†áÔúRëÁfIm µîlÖ jRË¡–ÊfQ‹Ú0j)lF1Ôò©%³KÔ¦VL­›uˆº8 ¿®¹+›õˆúÔ"©ua³ÑZ4µÎlÆ¨Õ¡Ö‰ÍÆDjM©ud³)ÑŒZ7jØlN´ ¦ç—ÄfK"šÛˆZ{6[ Ô:PkÇf"ÑšZjmÙlCø©u¥ægS;ÚQK¥¦·è IÔzQkͦ.¨#5‡¯›Ñ]êö“Åq"Ô*zBºDDèIj<4PA ­Æ\Í .Qû¨¯ÔpD&ÑèOdˆÄb0‘"Ž„é2qJ5a6¯„«/g3—J #†yÄ"Ÿ( ‰b"GóŽZDT%⼦Z)G.¡i˜r&ª;<Á_©^qž§®Ñ&3Å£ï½@qªV£p¥±¼RŸÖe‡¦A°8ñCô>¦†Gß{aâ$MTM³B-)NjªjL÷¢Äɘ£šf€Ú;FœœÕhy~öêˆSÐPµºœ¼6¡ ‰ú┇j/îÑÅ^œ8ãªÖˆhF4gÊiÕhjŽõš‹37EµD/ÎÒCªÑÀ­ç%гú¼j­9y}^ÑÏž_œ iÚAÇz´£×^œªVª15<ÚÑ£½Žâìí§™=4ÇŒ÷ºŠsè+íèÆ#¦_<šÐKçÄlí 1=šÐë)Ιíªiè¦éD¯8oäi-êÑŽ^¦8rTÓÙYâ|ø¾jô©G‹zÙâ\í®šNNëy¹â|ùºjô¤GëyyâܪRm'׌$ Åù©¯vЉ^ ÷¡Ã—D™8¿îÖ[ʹ}–f¯Rœ{é,ç~sÁïÙ±L›A„ ¼­Í" 'ýaD°Høií !B‰šD¸Ht¨vDšñq¼Š!¢DêïÕÞZ„VÇX‘f–Q›ÐÊZÐzÚ€ÐJ'’xWïÓژвْh.’tO{µD²þùãERϩ֊hC$Фg«¦–Ò¡Xðü~‘µ£-Ñh/’û`—¬~µOG‘¢Cªu"º]DF§¨Ö•H&RˆT¢/ÑCd½¥'Ñ‹H#z}ˆt"‹È™2NoÎ$ús¥ºß!Ä‘9çµw 1ˆÈ&9D‘+²ø-½o(1ŒNä#ˆ|¢˜(YñˆÞ\DŒ$JDÖ«Æ’æ¯$ÊD6å©F7¹\Ÿë#‘ݬ‰âŠ˜Sï9\3ÃãÒ>®9°C{-ÁýºÕ‰@‘ã×µC Ý䉜-W-˜'BE.$¨Fÿ¹5ˆ‘KcU‹$h)·¦ÈåªEqMy¥4Zä‹NÚA'º´™[[䛿U«CÐkn=‘ÛáªÑ.Ým(roºj´²K;ºMÄgv©¦sЄnsñElS­'×ûôI/¾è ÚA'ºt¢›(¾¸RÕôÁ¬O]dbüMÕhBWŸ°íÅ×ášjúÖRÕI|©IOº4¡›,¾ô5ª¥pòæ¼¢¹ÜâË¡=Å—ëïÓ€ÂB ¨:q(þPŒÌÊÂòL ¢>PÙ Õ=x¨xx<0f0v*0n0~ 0a 0¶ð=²x4‰ø˜t xì0ùU`Ê`j0Úã¼y:'ŸQÌ\ÌbÇì)Àœ*Ý3ÅeZ¹â›û :æ ú ‡‹¸–Åóôæ~D"K|OlBÇ’eXî#Ž++VuV¿ <ý=ðl°&X»xŽK[ÇæúyÀ†QÀÆw€Íí-;€­/Û~ªf;xB;Ÿ\þlW:°{°g'°—¡ØÇeìûØÏñÛ/–‡ê‡S€#~à¥aÀQ®åG9ÎÙ^Æ[†ïñäyàTàUàôÀ™›ÀYžÐÙËÀkÜàëKÞø xKsÚeAqYPÜlñ{àX—…ÇÍ%†Šï<½0xûgàâ£À»Ïÿ: ¼÷ðýr©;ð!ñÑiàcFÿ®àrpe.p•ñøìðù·À5úïz(ðEoàˇ€¯è’÷€›ƒÿLÖU±¹,d. ™›/¾¯o¡÷V4ðm2ð]ðývà‡ÃÀ??7þÛø…‘¹Í ¸ó>ðð{ ànmàÆòÏŽÀ=à[¿ÞÔy –H·X|÷y¦÷ÿíˆq~‹4¾Û*ƒ»@‚™@d”©†,3Õ‰ Kœ‚ç!ˆ¹ ÅrMXsâo ü% n2‘0ƒ©Ñ¨YÀ.Mœcjaõ&¶01X©‰Å9›Úˆ¾©Ë9êq¼úÈKÓ2 ᣛF8NÓV1MMÍ`eÓœCµÀ‰›–ÈUÏA[!÷MBa2ÓoÚpèÁí÷¤Ö Æ4iY@oÓ'˜@™tI*—Éä"û%ý¹¾¬FÀ€``$0(Èfï`˜ß䌆,r¹ð¡(KfØ›Àp$¬ÉûÈG¦˜‚N@a‘ÆW_ÞùôsËÄñœ‹O%HSSÊ]Žäi”ååð†©ˆ&óQ\ƨ·€Ñ{€‡Øûp0&ëÿÆÁMfü `B<0‰hå M¿*æ±Pâ.0….™º ˜›éìâkf"íͬ§Ù9 íÜëÀ<”3Ÿ_,äÏ­_–À÷f)ƒ· k–#íÍŠ.ÀJõ¬Z¬F¦˜gèÝ5H³¶ðqײþ °ÑgÕ3›ìfó9`+C±qÛÆÙ¶ Týì@m2;i³ç9€‹”4»¸´Ý¨üf×¼—ãyìÝGK½°ØBaÜ^DY7‡JÃ(¥æHgà¥G€£x.˜c¯Ç™~'“(¯æ•g5–D%†ŽØ_iê <º·™$é—‹¨Hæ]Tó>ÃóóÒà#nÿcøS:ö2j±¹Â<¿Êå~FÇ^£Ÿ¯1ã¯sÍ_r¼¯øþ&*¡ùšS~Ãáoñ·ß¡´˜ïQ;Í_?o~a®Þæ~ïPû•Ùý{cà.³ûæôŸ<œ{(¯æ/žîß¼ºÿ:v$X•õ!­Á2l@•¾sùCX±Õà0[=BZÙ`݆`G6ô†ðØä‘„l€(,ÈÖj DØ6²±Ïu`o[·.P¶ œ¶a9‡2bcû¶ Ï™Å6»´À Ù–C€xìÍ& Œ6fµ­QrmäŒõãÉdÛÁÔ¶=2Ô&­:¼ tÂ3ÏvFQ°]V붉jDu±]a.Û¿MþHÙ¤VÝÛƒCõ¬GÀ‰¶\bÓɶwЧ-xØtÊöEé³ìÈŒ%Pl?DÆö d±wÀ'À žF6êÍé Ér‰¡xVØax+°Ã‘y6¡ÈçY bÚB®¥è$PŒt±%<âRÎ[ÆÙʸ…rTy[÷[y…÷0;ÏAûp/` ,`Ç"9í8˜ËŽÇŠ€d·ñèµ|«²“ø‹ÉH?;¯Lvêt`ú8\l§ãog ðØ™H0; –·³‘yvÎ:`.ÂvÞZ`>µïv!}*¿]ŒfŸ@ɰKFK'Ëð~e—siOò V<¬DŠÛ§>Vñ`Wã½É>ÍU=ƒZb×  Ûµ]ç8Àº#ÀzžÁƦÚ`"„»‰aÜl !POíÖÇm ÊvÔ[…êhw æØË€ç‘’ÖeŒvñœw³¹‡?ó.vÃýJ©ÝÏÃ9°I§ '"ˆH±yó‹<âÃÜÖ®ï({”ùqŒ ö2ê³=rhOÒ¬¯àIlOÑR§ëx5 ý‡£–Ø3wT‹{å²^ÅúAK"žhE$D&ÑÐö²ˆ„~ÇÔOWúÕj0¡ß1‡¹ÄPB¿ 'òýL ß1õR!QDèwÌ¢”ÐϸúÝV?Ôê—ÅJ ‚•‚=çÿ Q‡ endstream endobj startxref 330408 %%EOF verilator-3.916/verilator.txt0000664000177100017500000051160113206353161016274 0ustar wsnyderwsnyderNAME Verilator - Convert Verilog code to C++/SystemC SYNOPSIS verilator --help verilator --version verilator --cc [options] [source_files.v]... [opt_c_files.cpp/c/cc/a/o/so] verilator --sc [options] [source_files.v]... [opt_c_files.cpp/c/cc/a/o/so] verilator --lint-only [source_files.v]... DESCRIPTION Verilator converts synthesizable (not behavioral) Verilog code, plus some Synthesis, SystemVerilog and a small subset of Verilog AMS assertions, into C++ or SystemC code. It is not a complete simulator, but a compiler. Verilator is invoked with parameters similar to GCC, Cadence Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage and waveform tracing code. For C++ and SystemC formats, it outputs .cpp and .h files. The files created by Verilator are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module, and passes this filename on the command line. These C files are compiled in C++, and linked with the Verilated files. The resulting executable will perform the actual simulation. To get started, jump down to "EXAMPLE C++ EXECUTION". ARGUMENT SUMMARY This is a short summary of the arguments to Verilator. See the detailed descriptions in the next sections for more information. {file.v} Verilog package, module and top module filenames {file.c/cc/cpp} Optional C++ files to compile in {file.a/o/so} Optional C++ files to link in +1364-1995ext+ Use Verilog 1995 with file extension +1364-2001ext+ Use Verilog 2001 with file extension +1364-2005ext+ Use Verilog 2005 with file extension +1800-2005ext+ Use SystemVerilog 2005 with file extension +1800-2009ext+ Use SystemVerilog 2009 with file extension +1800-2012ext+ Use SystemVerilog 2012 with file extension --assert Enable all assertions --autoflush Flush streams after all $displays --bbox-sys Blackbox unknown $system calls --bbox-unsup Blackbox unsupported language features --bin Override Verilator binary -CFLAGS C++ Compiler flags for makefile --cc Create C++ output --cdc Clock domain crossing analysis --clk Mark specified signal as clock --compiler Tune for specified C++ compiler --converge-limit Tune convergence settle time --coverage Enable all coverage --coverage-line Enable line coverage --coverage-toggle Enable toggle coverage --coverage-user Enable SVL user coverage --coverage-underscore Enable coverage of _signals -D[=] Set preprocessor define --debug Enable debugging --debug-check Enable debugging assertions --debugi Enable debugging at a specified level --debugi- Enable debugging a source file at a level --default-language Default language to parse +define+= Set preprocessor define --dump-tree Enable dumping .tree files --dump-treei Enable dumping .tree files at a level --dump-treei- Enable dumping .tree file at a source file at a level -E Preprocess, but do not compile --error-limit Abort after this number of errors --exe Link to create executable -F Parse options from a file, relatively -f Parse options from a file -FI Force include of a file -G= Overwrite toplevel parameter --gdb Run Verilator under GDB interactively --gdbbt Run Verilator under GDB for backtrace --getenv Get environment variable with defaults --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 --l2-name Verilog scope name of the top module --language Default language standard to parse +libext++[ext]... Extensions for finding modules --lint-only Lint, but do not make output --MMD Create .d dependency files --MP Create phony dependency targets --Mdir Name of output object directory --mod-prefix Name to prepend to lower classes --no-clk Prevent marking specified signal as clock --no-decoration Disable comments and symbol decorations --no-pins64 Don't use vluint64_t's for 33-64 bit sigs --no-skip-identical Disable skipping identical output +notimingchecks Ignored -O0 Disable optimizations -O3 High performance optimizations -O Selectable optimizations -o Name of final executable --no-order-clock-delay Disable ordering clock enable assignments --output-split Split .cpp files into pieces --output-split-cfuncs Split .cpp functions --output-split-ctrace Split tracing functions -P Disable line numbers and blanks with -E --pins-bv Specify types for top level ports --pins-sc-uint Specify types for top level ports --pins-sc-biguint Specify types for top level ports --pins-uint8 Specify types for top level ports --pipe-filter Filter all input through a script --prefix Name of top level class --profile-cfuncs Name functions for profiling --private Debugging; see docs --public Debugging; see docs -pvalue+= Overwrite toplevel parameter --relative-includes Resolve includes relative to current file --no-relative-cfuncs Disallow 'this->' in generated functions --report-unoptflat Extra diagnostics for UNOPTFLAT --savable Enable model save-restore --sc Create SystemC output --stats Create statistics file --stats-vars Provide statistics on variables -sv Enable SystemVerilog parsing +systemverilogext+ Synonym for +1800-2012ext+ --top-module Name of top level input module --trace Enable waveform creation --trace-depth Depth of tracing --trace-max-array Maximum bit width for tracing --trace-max-width Maximum array depth for tracing --trace-params Enable tracing parameters --trace-structs Enable tracing structure names --trace-underscore Enable tracing of _signals -U Undefine preprocessor define --unroll-count Tune maximum loop iterations --unroll-stmts Tune maximum loop body size --unused-regexp Tune UNUSED lint signals -V Verbose version and config -v Verilog library +verilog1995ext+ Synonym for +1364-1995ext+ +verilog2001ext+ Synonym for +1364-2001ext+ --vpi Enable VPI compiles -Wall Enable all style warnings -Werror- Convert warnings to errors -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 Assign non-initial Xs to this value --x-initial Assign initial 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. --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, the cmos and tran gate primitives, deassign statements, and mixed edge errors. This may enable linting the rest of the design even when unsupported constructs are present. --bin *filename* Rarely needed. Override the default filename for Verilator itself. When a dependency (.d) file is created, this filename will become a source dependency, such that a change in this binary will have make rebuild the output files. -CFLAGS *flags* Add specified C compiler flags to the generated makefiles. When make is run on the generated makefile these will be passed to the C++ compiler (gcc/g++/msvc++). --cc Specifies C++ without SystemC output mode; see also --sc. --cdc Experimental. Perform some clock domain crossing checks and issue related warnings (CDCRSTLOGIC) and then exit; if warnings other than CDC warnings are needed make a second run with --lint-only. Additional warning information is also written to the file {prefix}__cdc.txt. Currently only checks some items that other CDC tools missed; if you have interest in adding more traditional CDC checks, please contact the authors. --clk *signal-name* Sometimes it is quite difficult for Verilator to distinguish clock signals from other data signals. Occasionally the clock signals can end up in the checking list of signals which determines if further evaluation is needed. This will heavily degrade the performance of a Verilated model. With --clk , user can specified root clock into the model, then Verilator will mark the signal as clocker and propagate the clocker attribute automatically to other signals derived from that. In this way, Verilator will try to avoid taking the clocker signal into checking list. Note signal-name is specified by the RTL hierarchy path. For example, v.foo.bar. If the signal is the input to top-module, the directly the signal name. If you find it difficult to find the exact name, try to use "/*verilator clocker*/" in RTL file to mark the signal directly. If clock signals are assigned to vectors and then later used individually, Verilator will attempt to decompose the vector and connect the single-bit clock signals directly. This should be transparent to the user. --compiler *compiler-name* Enables tunings and workarounds 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.dat. Verilator automatically disables coverage of branches that have a $stop in them, as it is assumed $stop branches contain an error check that should not occur. A /*verilator coverage_block_off*/ comment will perform a similar function on any code in that block or below, or /*verilator coverage_on/coverage_off*/ will disable coverage around lines of code. Note Verilator may over-count combinatorial (non-clocked) blocks when those blocks receive signals which have had the UNOPTFLAT warning disabled; for most accurate results do not disable this warning when using coverage. --coverage-toggle Specifies signal toggle coverage analysis code should be inserted. Every bit of every signal in a module has a counter inserted. The counter will increment on every edge change of the corresponding bit. Signals that are part of tasks or begin/end blocks are considered local variables and are not covered. Signals that begin with underscores, are integers, or are very wide (>256 bits total storage across all dimensions) are also not covered. Hierarchy is compressed, such that if a module is instantiated multiple times, coverage will be summed for that bit across ALL instantiations of that module with the same parameter set. A module instantiated with different parameter values is considered a different module, and will get counted separately. Verilator makes a minimally-intelligent decision about what clock domain the signal goes to, and only looks for edges in that clock domain. This means that edges may be ignored if it is known that the edge could never be seen by the receiving logic. This algorithm may improve in the future. The net result is coverage may be lower than what would be seen by looking at traces, but the coverage is a more accurate representation of the quality of stimulus into the design. There may be edges counted near time zero while the model stabilizes. It's a good practice to zero all coverage just before releasing reset to prevent counting such behavior. A /*verilator coverage_off/on */ comment pair can be used around signals that do not need toggle analysis, such as RAMs and register files. --coverage-underscore Enable coverage of signals that start with an underscore. Normally, these signals are not covered. See also --trace-underscore. --coverage-user Enables user inserted functional coverage. Currently, all functional coverage points are specified using SVA which must be separately enabled with --assert. For example, the following statement will add a coverage point, with the comment "DefaultClock": DefaultClock: cover property (@(posedge clk) cyc==3); -D*var*=*value* Defines the given preprocessor symbol, without allowing. Similar to +define; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility. --debug Select the debug built image of Verilator (if available), and enable more internal assertions (equivalent to "--debug-check"), debugging messages (equivalent to "--debugi 4"), and intermediate form dump files (equivalent to "--dump-treei 3"). --debug-check Rarely needed. Enable internal debugging assertion checks, without changing debug verbosity. Enabled automatically when --debug specified. --debugi --debugi- Rarely needed - for developer use. Set internal debugging level globally to the specified debug level (1-10) or set the specified Verilator source file to the specified level (e.g. "--debugi-V3Width 9"). Higher levels produce more detailed messages. --default-language *value* Select the language to be used by default when first processing each Verilog file. The language value must be "1364-1995", "1364-2001", "1364-2005", "1800-2005", "1800-2009" or "1800-2012". Any language associated with a particular file extension (see the various +*lang*ext+ options) will be used in preference to the language specified by --default-language. The --default-language flag is only recommended for legacy code using the same language in all source files, as the preferable option is to edit the code to repair new keywords, or add appropriate "`begin_keywords". For legacy mixed language designs, the various +*lang*ext+ options should be used. If no language is specified, either by this flag or +*lang*ext+ options, then the latest SystemVerilog language (IEEE 1800-2012) is used. +define+*var*=*value* +define+*var*=*value*+*var2*=*value2*... Defines the given preprocessor symbol, or multiple symbols if separated by plusses. Similar to -D; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility. --dump-tree Rarely needed. Enable writing .tree debug files with dumping level 3, which dumps the standard critical stages. For details on the format see the Verilator Internals manual. --dump-tree is enabled automatically with --debug, so "--debug --no-dump-tree" may be useful if the dump files are large and not desired. --dump-treei --dump-treei- Rarely needed - for developer use. Set internal tree dumping level globally to a specific dumping level or set the specified Verilator source file to the specified tree dumping level (e.g. "--dump-treei-V3Order 9"). Level 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9 enables dumping of every stage. -E Preprocess the source code, but do not compile, as with 'gcc -E'. Output is written to standard out. Beware of enabling debugging messages, as they will also go to standard out. --error-limit After this number of errors or warnings are encountered, exit. Defaults to 50. --exe Generate an executable. You will also need to pass additional .cpp files on the command line that implement the main loop for your simulation. -F *file* Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the directory containing the specified file. See also -f. Note -F is fairly standard across Verilog tools. -f *file* Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the current directory. See also -F. Note -f is fairly standard across Verilog tools. The file may contain // comments which are ignored to the end of the line. Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment variable. -FI Force include of the specified C++ header file. All generated C++ files will insert a #include of the specified file before any other includes. The specified file might be used to contain define prototypes of custom VL_VPRINTF functions, and may need to include verilatedos.h as this file is included before any other standard includes. -G*name*=*value* Overwrites the given parameter of the toplevel module. The value is limited to basic data literals: Verilog integer literals The standard verilog integer literals are supported, so values like 32'h8, 2'b00, 4 etc. are allowed. Care must be taken that the single quote (I') is properly escaped in an interactive shell, e.g., as -GWIDTH=8\'hx. C integer literals It is also possible to use C integer notation, including hexadecimal (0x..), octal (0..) or binary (0b..) notation. Double literals Double literals must contain a dot (.) and/or an exponent (e). Strings String must in double quotes ("). On the command line it is required to escape them properly, e.g. as -GSTR="\"My String\"" or -GSTR='"My String"'. --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. --getenv *variable* If the variable is declared in the environment, print it and exit immediately. Otherwise, if it's built into Verilator (e.g. VERILATOR_ROOT), print that and exit immediately. Otherwise, print a newline and exit immediately. This can be useful in makefiles. See also -V, and the various *.mk files. --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.) --l2-name *value* Instead of using the module name when showing Verilog scope, use the name provided. This allows simplifying some Verilator-embedded modeling methodologies. Default is an l2-name matching the top module. The default before 3.884 was "--l2-name v" For example, the program "module t; initial $display("%m"); endmodule" will show by default "t". With "--l2-name v" it will print "v". --language *value* A synonym for "--default-language", for compatibility with other tools and earlier versions of Verilator. +libext+*ext*+*ext*... Specify the extensions that should be used for finding modules. If for example module *x* is referenced, look in *x*.*ext*. Note +libext+ is fairly standard across Verilog tools. Defaults to .v and .sv. --lint-only Check the files for lint violations only, do not create any other output. You may also want the -Wall option to enable messages that are considered stylistic and not enabled by default. If the design is not to be completely Verilated see also the --bbox-sys and --bbox-unsup options. --MMD Enable creation of .d dependency files, used for make dependency detection, similar to gcc -MMD option. On by default, use --no-MMD to disable. --MP When creating .d dependency files with --MMD, make phony targets. Similar to gcc -MP option. --Mdir *directory* Specifies the name of the Make object directory. All generated files will be placed in this directory. If not specified, "obj_dir" is used. The directory is created if it does not exist and the parent directories exist; otherwise manually create the Mdir before calling Verilator. --mod-prefix *topname* Specifies the name to prepend to all lower level classes. Defaults to the same as --prefix. --no-clk Prevent the specified signal from being marked as clock. See "--clk". --no-decoration When creating output Verilated code, minimize comments, whitespace, symbol names and other decorative items, at the cost of greatly reduced readability. This may assist C++ compile times. This will not typically change the ultimate model's performance, but may in some cases. --no-pins64 Backward compatible alias for "--pins-bv 33". --no-relative-cfuncs Disable 'this->' references in generated functions, and instead Verilator will generate absolute references starting from 'vlTOPp->'. This prevents V3Combine from merging functions from multiple instances of the same module, so it can grow the instruction stream. This is a work around for old compilers. Don't set this if your C++ compiler supports __restrict__ properly, as GCC 4.5.x and newer do. For older compilers, test if this switch gives you better performance or not. Compilers which don't honor __restrict__ will suspect that 'this->' references and 'vlTOPp->' references may alias, and may write slow code with extra loads and stores to handle the (imaginary) aliasing. Using only 'vlTOPp->' references allows these old compilers to produce tight code. --no-skip-identical Rarely needed. Disables skipping execution of Verilator if all source files are identical, and all output files exist with newer dates. +notimingchecks Ignored for compatibility with other simulators. -O0 Disables optimization of the model. -O3 Enables slow optimizations for the code Verilator itself generates (as opposed to "-CFLAGS -O3" which effects the C compiler's optimization. -O3 may reduce simulation runtimes at the cost of compile time. This currently sets --inline-mult -1. -O*optimization-letter* Rarely needed. Enables or disables a specific optimizations, with the optimization selected based on the letter passed. A lowercase letter disables an optimization, an upper case letter enables it. This is intended for debugging use only; see the source code for version-dependent mappings of optimizations to -O letters. -o Specify the name for the final executable built if using --exe. Defaults to the --prefix if not specified. --no-order-clock-delay Rarely needed. Disables a bug fix for ordering of clock enables with delayed assignments. This flag should only be used when suggested by the developers. --output-split *bytes* Enables splitting the output .cpp 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 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 files into multiple functions. Defaults to same setting as --output-split-cfuncs. -P With -E, disable generation of `line markers and blank lines, similar to GCC -P flag. --pins64 Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64. --pins-bv *width* Specifies SystemC inputs/outputs of greater than or equal to *width* bits wide should use sc_bv's instead of uint32/vluint64_t's. The default is "--pins-bv 65", and the value must be less than or equal to 65. Versions before Verilator 3.671 defaulted to "--pins-bv 33". The more sc_bv is used, the worse for performance. Use the "/*verilator sc_bv*/" attribute to select specific ports to be sc_bv. --pins-sc-uint Specifies SystemC inputs/outputs of greater than 2 bits wide should use sc_uint between 2 and 64. When combined with the "--pins-sc-biguint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. --pins-sc-biguint Specifies SystemC inputs/outputs of greater than 65 bits wide should use sc_biguint between 65 and 512, and sc_bv from 513 upwards. When combined with the "--pins-sc-uint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. --pins-uint8 Specifies SystemC inputs/outputs that are smaller than the --pins-bv setting and 8 bits or less should use uint8_t instead of uint32_t. Likewise pins of width 9-16 will use uint16_t instead of uint32_t. --pipe-filter *command* Rarely needed and experimental. Verilator will spawn the specified command as a subprocess pipe, to allow the command to perform custom edits on the Verilog code before it reaches Verilator. Before reading each Verilog file, Verilator will pass the file name to the subprocess' stdin with 'read_verilog ""'. The filter may then read the file and perform any filtering it desires, and feeds the new file contents back to Verilator on stdout with 'Content-Length'. Output to stderr from the filter feeds through to Verilator's stdout and if the filter exits with non-zero status Verilator terminates. See the t/t_pipe_filter test for an example. To debug the output of the filter, try using the -E option to see preprocessed output. --prefix *topname* Specifies the name of the top level class and makefile. Defaults to V prepended to the name of the --top-module switch, or V prepended to the first Verilog filename passed on the command line. --profile-cfuncs Modify the created C++ functions to support profiling. The functions will be minimized to contain one "basic" statement, generally a single always block or wire statement. (Note this will slow down the executable by ~5%.) Furthermore, the function name will be suffixed with the basename of the Verilog module and line number the statement came from. This allows gprof or oprofile reports to be correlated with the original Verilog source statements. --private Opposite of --public. Is the default; this option exists for backwards compatibility. --public This is only for historical debug use. Using it may result in mis-simulation of generated clocks. Declares all signals and modules public. This will turn off signal optimizations as if all signals had a /*verilator public*/ comments and inlining. This will also turn off inlining as if all modules had a /*verilator public_module*/, unless the module specifically enabled it with /*verilator inline_module*/. -pvalue+*name*=*value* Overwrites the given parameter(s) of the toplevel module. See -G for a detailed description. --relative-includes When a file references an include file, resolve the filename relative to the path of the referencing file, instead of relative to the current directory. --report-unoptflat Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the 10 widest variables in the loop, and the 10 most fanned out variables in the loop. These are candidates for splitting into multiple variables to break the loop. In addition produces a GraphViz DOT file of the entire strongly connected components within the source associated with each loop. This is produced irrespective of whether --dump-tree is set. Such graphs may help in analyzing the problem, but can be very large indeed. Various commands exist for viewing and manipulating DOT files. For example the *dot* command can be used to convert a DOT file to a PDF for printing. For example: dot -Tpdf -O Vt_unoptflat_simple_2_35_unoptflat.dot will generate a PDF Vt_unoptflat_simple_2_35_unoptflat.dot.pdf from the DOT file. --savable Enable including save and restore functions in the generated model. The user code must create a VerilatedSerialize or VerilatedDeserialze object then calling the << or >> operators on the generated model and any other data the process needs saved/restored. For example: void save_model(const char* filenamep) { VerilatedSave os; os.open(filenamep); os << main_time; // user code must save the timestamp, etc os << *topp; } void restore_model(const char* filenamep) { VerilatedRestore os; os.open(filenamep); os >> main_time; os >> *topp; } --sc Specifies SystemC output mode; see also --cc. --stats Creates a dump file with statistics on the design in {prefix}__stats.txt. --stats-vars Creates more detailed statistics including a list of all the variables by size (plain --stats just gives a count). See --stats, which is implied by this. -sv Specifies SystemVerilog language features should be enabled; equivalent to "--language 1800-2005". This option is selected by default, it exists for compatibility with other simulators. +systemverilogext+*ext* A synonym for "+1800-2012ext+"*ext*. --top-module *topname* When the input Verilog contains more than one top level module, specifies the name of the top level Verilog module to become the top, and sets the default for if --prefix is not used. This is not needed with standard designs with only one top. --trace Adds waveform tracing code to the model. Verilator will generate additional {prefix}__Trace*.cpp files that will need to be compiled. In addition verilated_vcd_sc.cpp (for SystemC traces) or verilated_vcd_c.cpp (for both) must be compiled and linked in. If using the Verilator generated Makefiles, these will be added as source targets for you. If you're not using the Verilator makefiles, you will need to add these to your Makefile manually. Having tracing compiled in may result in some small performance losses, even when waveforms are not turned on during model execution. --trace-depth *levels* Specify the number of levels deep to enable tracing, for example --trace-level 1 to only see the top level's signals. Defaults to the entire model. Using a small number will decrease visibility, but greatly improve runtime and trace file size. --trace-max-array *depth* Rarely needed. Specify the maximum array depth of a signal that may be traced. Defaults to 32, as tracing large arrays may greatly slow traced simulations. --trace-max-width *width* Rarely needed. Specify the maximum bit width of a signal that may be traced. Defaults to 256, as tracing large vectors may greatly slow traced simulations. --no-trace-params Disable tracing of parameters. --trace-structs Enable tracing to show the name of packed structure, union, and packed array fields, rather than a simgle combined packed bus. Due to VCD file format constraints this may result in significantly slower trace times and larger trace files. --trace-underscore Enable tracing of signals that start with an underscore. Normally, these signals are not output during tracing. See also --coverage-underscore. -U*var* Undefines the given preprocessor symbol. --unroll-count *loops* Rarely needed. Specifies the maximum number of loop iterations that may be unrolled. See also BLKLOOPINIT warning. --unroll-stmts *statements* Rarely needed. Specifies the maximum number of statements in a loop for that loop to be unrolled. See also BLKLOOPINIT warning. --unused-regexp *regexp* Rarely needed. Specifies a simple regexp with * and ? that if a signal name matches will suppress the UNUSED warning. Defaults to "*unused*". Setting it to "" disables matching. -V Shows the verbose version, including configuration information compiled into Verilator. (Similar to perl -V.) See also --getenv. -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 --vpi Enable use of VPI and linking against the verilated_vpi.cpp files. -Wall Enable all code style warnings, including code style warnings that are normally disabled by default. Equivelent to "-Wwarn-lint -Wwarn-style". Excludes some specialty warnings, i.e. IMPERFECTSCH. -Werror-*message* Convert the specified warning message into an error message. This is generally to discourage users from violating important site-wide rules, for example "-Werror-NOUNOPTFLAT". -Wfuture-*message* Rarely needed. Suppress unknown Verilator comments or warning messages with the given message code. This is used to allow code written with pragmas for a later version of Verilator to run under a older version; add -Wfuture- arguments for each message code or comment that the new version supports which the older version does not support. -Wno-*message* Disable the specified warning message. This will override any lint_on directives in the source, i.e. the warning will still not be printed. -Wno-lint Disable all lint related warning messages, and all style warnings. This is equivalent to "-Wno-ALWCOMBORDER -Wno-BSSPACE -Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEWITHX -Wno-CMPCONST -Wno-COLONPLUS -Wno-ENDLABEL -Wno-IMPLICIT -Wno-LITENDIAN -Wno-PINCONNECTEMPTY -Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED -Wno-WIDTH" plus the list shown for Wno-style. It is strongly recommended you cleanup your code rather than using this option, it is only intended to be use when running test-cases of code received from third parties. -Wno-style Disable all code style related warning messages (note by default they are already disabled). This is equivalent to "-Wno-DECLFILENAME -Wno-DEFPARAM -Wno-INCABSPATH -Wno-PINCONNECTEMPTY -Wno-PINNOCONNECT -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNUSED -Wno-VARHIDDEN". -Wno-fatal When warnings are detected, print them, but do not exit the simulator. Having warning messages in builds is sloppy. It is strongly recommended you cleanup your code, use inline lint_off, or use -Wno-... flags rather than using this option. -Wwarn-*message* Enables the specified warning message. -Wwarn-lint Enable all lint related warning messages (note by default they are already enabled), but do not affect style messages. This is equivalent to "-Wwarn-ALWCOMBORDER -Wwarn-BSSPACE -Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX -Wwarn-CMPCONST -Wwarn-COLONPLUS -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 controlled with --x-initial. --x-initial 0 --x-initial fast --x-initial unique (default) Controls the two-state value that is used to initialize variables that are not otherwise initialized. --x-initial=0, initializes all otherwise uninitialized variables to zero. --x-initial=unique, the default, initializes variables using a function, which determines the value to use each initialization. This gives greatest flexibility and allows finding reset bugs. See "Unknown states" --x-initial=fast, is best for performance, and initializes all variables to a state Verilator determines is optimal. This may allow further code optimizations, but will likely hide any code bugs relating to missing resets. Note. This option applies only to initial values of variables. Initial values of clocks are set to 0 unless --x-initial-edge is specified. --x-initial-edge Enables emulation of event driven simulators which generally trigger an edge on a transition from X to 1 ("posedge") or X to 0 ("negedge"). Thus the following code, where "rst_n" is uninitialized would set "res_n" to "1'b1" when "rst_n" is first set to zero: reg res_n = 1'b0; always @(negedge rst_n) begin if (rst_n == 1'b0) begin res_n <= 1'b1; end end In Verilator, by default, uninitialized clocks are given a value of zero, so the above "always" block would not trigger. While it is not good practice, there are some designs that rely on X → 0 triggering a "negedge", particularly in reset sequences. Using --x-initial-edge with Verilator will replicate this behavior. It will also ensure that X → 1 triggers a "posedge". Note. Some users have reported that using this option can affect convergence, and that it may be necessary to use --converge-limit to increase the number of convergence iterations. This may be another indication of problems with the modelled design that should be addressed. -y *dir* Add the directory to the list of directories that should be searched for include files or libraries. The three flags -y, +incdir and -I have similar effect; +incdir and +y are fairly standard across Verilog tools while -I is an alias for GCC compatibility. Verilator defaults to the current directory ("-y .") and any specified --Mdir, though these default paths are used after any user specified directories. This allows '-y "$(pwd)"' to be used if absolute filenames are desired for error messages instead of relative filenames. EXAMPLE C++ EXECUTION We'll compile this example into C++. mkdir test_our cd test_our cat <our.v module our; initial begin $display("Hello World"); $finish; end endmodule EOF cat <sim_main.cpp #include "Vour.h" #include "verilated.h" int main(int argc, char** argv, char** env) { Verilated::commandArgs(argc, argv); Vour* top = new Vour; while (!Verilated::gotFinish()) { top->eval(); } delete top; exit(0); } EOF See the README in the source kit for various ways to install or point to Verilator binaries. In brief, if you are running Verilator that came from your operating system (as an RPM), or did a "make install" to place Verilator into your default path, you do not need anything special in your environment, and should not have VERILATOR_ROOT set. However, if you installed Verilator from sources and want to run Verilator out of where you compiled Verilator, you need to point to the kit: # See above; don't do this if using an OS-distributed Verilator 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 make -j -C obj_dir -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 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; to aid this Verilator can create a makefile dependency file. See the examples directory in the distribution. EXAMPLE SYSTEMC EXECUTION This is an example similar to the above, but using SystemC. mkdir test_our_sc cd test_our_sc cat <our.v module our (clk); input clk; // Clock is required to get initial activation always @ (posedge clk) begin $display("Hello World"); $finish; end endmodule EOF cat <sc_main.cpp #include "Vour.h" int sc_main(int argc, char **argv) { Verilated::commandArgs(argc, argv); sc_clock clk ("clk",10, 0.5, 3, true); Vour* top; top = new Vour("top"); top->clk(clk); while (!Verilated::gotFinish()) { sc_start(1, SC_NS); } delete top; exit(0); } EOF See the README in the source kit for various ways to install or point to Verilator binaries. In brief, if you are running Verilator that came from your operating system (as an RPM), or did a "make install" to place Verilator into your default path, you do not need anything special in your environment, and should not have VERILATOR_ROOT set. However, if you installed Verilator from sources and want to run Verilator out of where you compiled Verilator, you need to point to the kit: # See above; don't do this if using an OS-distributed Verilator export VERILATOR_ROOT=/path/to/where/verilator/was/installed export PATH=$VERILATOR_ROOT/bin:$PATH Now we run Verilator on our little example. verilator -Wall --sc our.v We then can compile it cd obj_dir make -j -f Vour.mk Vour__ALL.a make -j -f Vour.mk ../sc_main.o verilated.o And link with SystemC. Note your path to the libraries may vary, depending on the operating system. export SYSTEMC_LIBDIR=/path/to/where/libsystemc.a/exists export LD_LIBRARY_PATH=$SYSTEMC_LIBDIR:$LD_LIBRARY_PATH # Might be needed if SystemC 2.3.0 export SYSTEMC_CXX_FLAGS=-pthread g++ -L$SYSTEMC_LIBDIR ../sc_main.o Vour__ALL*.o verilated.o \ -o Vour -lsystemc And now we run it cd .. obj_dir/Vour And we get the same output as the C++ example: Hello World - our.v:2: Verilog $finish Really, you're better off using a Makefile to do all this for you. Then, when your source changes it will automatically run all of these steps. See the examples directory in the distribution. BENCHMARKING & OPTIMIZATION For best performance, run Verilator with the "-O3 --x-assign=fast --x-initial=fast --noassert" flags. The -O3 flag will require longer compile times, and --x-assign=fast --x-initial=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 -fno-stack-protector" -f Vour.mk Vour__ALL.a OPT_FAST specifies optimizations for those programs that are part of the fast path, mostly code that is executed every cycle. OPT_SLOW specifies optimizations for slow-path files (plus tracing), which execute only rarely, yet take a long time to compile with optimization on. OPT specifies overall optimization and affects all compiles, including those OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2", and link with "-static". Nearly the same results can be had with much better compile times with OPT_FAST="-O1 -fstrict-aliasing". Higher optimization such as "-O3" may help, but gcc compile times may be excessive under O3 on even medium sized designs. Alternatively, some larger designs report better performance using "-Os". Unfortunately, using the optimizer with SystemC files can result in compiles taking several minutes. (The SystemC libraries have many little inlined functions that drive the compiler nuts.) For best results, use GCC 3.3 or newer. GCC 3.2 and earlier have optimization bugs around pointer aliasing detection, which can result in 2x performance losses. If you will be running many simulations on a single compile, investigate feedback driven compilation. With GCC, using -fprofile-arcs, then -fbranch-probabilities will yield another 15% or so. Modern compilers also support link-time optimization (LTO), which can help especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in both compilation and link. Note LTO may cause excessive compile times on large designs. If you are using your own makefiles, you may want to compile the Verilated code with -DVL_INLINE_OPT=inline. This will inline functions, however this requires that all cpp files be compiled in a single compiler run. You may uncover further tuning possibilities by profiling the Verilog code. Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run either oprofile or gprof to see where in the C++ code the time is spent. Run the gprof output through verilator_profcfunc and it will tell you what Verilog line numbers on which most of the time is being spent. When done, please let the author know the results. I like to keep tabs on how Verilator compares, and may be able to suggest additional improvements. FILES All output files are placed in the output directory name specified with the -Mdir option, or "obj_dir" if not specified. Verilator creates the following files in the output directory: {prefix}.mk // Make include file for compiling {prefix}_classes.mk // Make include file with class names For -cc and -sc mode, it also creates: {prefix}.cpp // Top level C++ file {prefix}.h // Top level header {prefix}{each_verilog_module}.cpp // Lower level internal C++ files {prefix}{each_verilog_module}.h // Lower level internal header files In certain optimization modes, it also creates: {prefix}__Dpi.h // DPI import and export declarations {prefix}__Inlines.h // Inline support functions {prefix}__Slow.cpp // Constructors and infrequent routines {prefix}__Syms.cpp // Global symbol table C++ {prefix}__Syms.h // Global symbol table header {prefix}__Trace.cpp // Wave file generation code (--trace) {prefix}__cdc.txt // Clock Domain Crossing checks (--cdc) {prefix}__stats.txt // Statistics (--stats) It also creates internal files that can be mostly ignored: {each_verilog_module}.vpp // Post-processed verilog (--debug) {prefix}.flags_vbin // Verilator dependencies {prefix}.flags_vpp // Pre-processor dependencies {prefix}__verFiles.dat // Timestamps for skip-identical {prefix}{misc}.d // Make dependencies (-MMD) {prefix}{misc}.dot // Debugging graph files (--debug) {prefix}{misc}.tree // Debugging files (--debug) After running Make, the C++ compiler should produce the following: {prefix} // Final executable (w/--exe argument) {prefix}__ALL.a // Library of all Verilated objects {prefix}{misc}.o // Intermediate objects ENVIRONMENT LD_LIBRARY_PATH A generic Linux/OS variable specifying what directories have shared object (.so) files. This path should include SystemC and any other shared objects needed at runtime. OBJCACHE Optionally specifies a caching or distribution program to place in front of all runs of the C++ Compiler. For example, "objcache --read --write", or "ccache". If using distcc, it would generally be run under either objcache or ccache; see the documentation for those programs. SYSTEMC Deprecated. Used only if SYSTEMC_INCLUDE or SYSTEMC_LIBDIR is not set. If set, specifies the directory containing the SystemC distribution. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). SYSTEMC_ARCH Deprecated. Used only if SYSTEMC_LIBDIR is not set. Specifies the architecture name used by the SystemC kit. This is the part after the dash in the lib-{...} directory name created by a 'make' in the SystemC distribution. If not set, Verilator will try to intuit the proper setting, or use the default optionally specified at configure time (before Verilator was compiled). SYSTEMC_CXX_FLAGS Specifies additional flags that are required to be passed to GCC when building the SystemC model. System 2.3.0 may need this set to "-pthread". SYSTEMC_INCLUDE If set, specifies the directory containing the systemc.h header file. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/include. SYSTEMC_LIBDIR If set, specifies the directory containing the libsystemc.a library. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/lib-SYSTEMC_ARCH. VCS_HOME If set, specifies the directory containing the Synopsys VCS distribution. When set, a 'make test' in the Verilator distribution will also run VCS baseline regression tests. VERILATOR_BIN If set, specifies an alternative name of the Verilator binary. May be used for debugging and selecting between multiple operating system builds. VERILATOR_GDB If set, the command to run when using the --gdb option, such as "ddd". If not specified, it will use "gdb". VERILATOR_ROOT Specifies the directory containing the distribution kit. This is used to find the executable, Perl library, and include files. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). It should not be specified if using a pre-compiled Verilator RPM as the hardcoded value should be correct. CONNECTING TO C++ Verilator creates a .h and .cpp file for the top level module and all modules under it. See the examples directory in the kit for examples. 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 // Need std::cout #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. VPI is enabled with the verilator --vpi switch. 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 (i.e. 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 its 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. For signal callbacks to work the main loop of the program must call VerilatedVpi::callValueCbs(). 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. cat <our.v module our (input clk); reg readme /*verilator public_flat_rd*/; reg writeme /*verilator public_flat_rw @(posedge clk) */; initial $finish; endmodule EOF There are many online tutorials and books on the VPI, but an example that accesses the above signal "readme" would be: cat <sim_main.cpp #include "Vour.h" #include "verilated.h" #include "verilated_vpi.h" // Required to get definitions vluint64_t main_time = 0; // See comments in first example double sc_time_stamp () { return main_time; } void read_and_check() { vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"TOP.our.readme", NULL); if (!vh1) { vl_fatal(__FILE__, __LINE__, "sim_main", "No handle found"); } const char* name = vpi_get_str(vpiName, vh1); printf("Module name: %s\n", name); // 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" } int main(int argc, char** argv, char** env) { Verilated::commandArgs(argc, argv); Vour* top = new Vour; Verilated::internalsDump(); // See scopes to help debug while (!Verilated::gotFinish()) { top->eval(); VerilatedVpi::callValueCbs(); // For signal callbacks read_and_check(); } delete top; exit(0); } EOF 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_on [-file "" [-lines [ - ]]] coverage_off [-file "" [-lines [ - ]]] Enable/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_on [-msg ] [-file "" [-lines [ - ]]] lint_off [-msg ] [-file "" [-lines [ - ]]] Enable/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). With lint_off using '*' will override any lint_on directives in the source, i.e. the warning will still not be printed. If the -msg is omitted, all lint warnings (see list in -Wno-lint) are enabled/disabled. This will override all later lint warning enables for the specified region. tracing_on [-file "" [-lines [ - ]]] tracing_off [-file "" [-lines [ - ]]] Enable/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). For tracing_off, cells below any module in the files/ranges specified will also not be traced. LANGUAGE STANDARD SUPPORT Verilog 2001 (IEEE 1364-2001) Support Verilator supports most Verilog 2001 language features. This includes signed numbers, "always @*", generate statements, multidimensional arrays, localparam, and C-style declarations inside port lists. Verilog 2005 (IEEE 1364-2005) Support Verilator supports most Verilog 2005 language features. This includes the `begin_keywords and `end_keywords compiler directives, $clog2, and the uwire keyword. SystemVerilog 2005 (IEEE 1800-2005) Support Verilator supports ==? and !=? operators, ++ and -- in some contexts, $bits, $countones, $error, $fatal, $info, $isunknown, $onehot, $onehot0, $unit, $warning, always_comb, always_ff, always_latch, bit, byte, chandle, const, do-while, enum, export, final, import, int, interface, logic, longint, modport, package, program, shortint, struct, time, typedef, union, var, void, priority case/if, and unique case/if. It also supports .name and .* interconnection. Verilator partially supports concurrent assert and cover statements; see the enclosed coverage tests for the syntax which is allowed. SystemVerilog 2012 (IEEE 1800-2012) Support Verilator implements a full SystemVerilog 2012 preprocessor, including function call-like preprocessor defines, default define arguments, `__FILE__, `__LINE__ and `undefineall. Verilator currently has some support for SystemVerilog synthesis constructs. As SystemVerilog features enter common usage they are added; please file a bug if a feature you need is missing. Verilog AMS Support Verilator implements a very small subset of Verilog AMS (Verilog Analog and Mixed-Signal Extensions) with the subset corresponding to those VMS keywords with near equivalents in the Verilog 2005 or SystemVerilog 2009 languages. AMS parsing is enabled with "--language VAMS" or "--language 1800+VAMS". At present Verilator implements ceil, exp, floor, ln, log, pow, sqrt, string, and wreal. Synthesis Directive Assertion Support With the --assert switch, Verilator reads any "//synopsys full_case" or "//synopsys parallel_case" directives. The same applies to any "//ambit synthesis", "//cadence" or "//pragma" directives of the same form. When these synthesis directives are discovered, Verilator will either formally prove the directive to be true, or failing that, will insert the appropriate code to detect failing cases at runtime and print an "Assertion failed" error message. Verilator likewise also asserts any "unique" or "priority" SystemVerilog keywords on case statement, as well as "unique" on if statements. However, "priority if" is currently simply ignored. LANGUAGE EXTENSIONS The following additional constructs are the extensions Verilator supports on top of standard Verilog code. Using these features outside of comments or `ifdef's may break other tools. `__FILE__ The __FILE__ define expands to the current filename as a string, like C++'s __FILE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!) `__LINE__ The __LINE__ define expands to the current filename as a string, like C++'s __LINE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!) `error *string* This will report an error when encountered, like C++'s #error. $c(*string*, ...); The string will be embedded directly in the output C++ code at the point where the surrounding Verilog code is compiled. It may either be a standalone statement (with a trailing ; in the string), or a function that returns up to a 32-bit number (without a trailing ;). This can be used to call C++ functions from your Verilog code. String arguments will be put directly into the output C++ code. Expression arguments will have the code to evaluate the expression inserted. Thus to call a C++ function, $c("func(",a,")") will result in 'func(a)' in the output C++ code. For input arguments, rather than hard-coding variable names in the string $c("func(a)"), instead pass the variable as an expression $c("func(",a,")"). This will allow the call to work inside Verilog functions where the variable is flattened out, and also enable other optimizations. If you will be reading or writing any Verilog variables inside the C++ functions, the Verilog signals must be declared with /*verilator public*/. You may also append an arbitrary number to $c, generally the width of the output. [signal_32_bits = $c32("...");] This allows for compatibility with other simulators which require a differently named PLI function name for each different output width. $display, $write, $fdisplay, $fwrite, $sformat, $swrite Format arguments may use C fprintf sizes after the % escape. Per the Verilog standard, %x prints a number with the natural width, and %0x prints a number with minimum width. Verilator extends this so %5x prints 5 digits per the C standard (it's unspecified in Verilog). `coverage_block_off Specifies the entire begin/end block should be ignored for coverage analysis. Must be inside a basic block, e.g. within a begin/end pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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 was specified. /*verilator clock_enable*/ Used after a signal declaration to indicate the signal is used to gate a clock, and the user takes responsibility for insuring there are no races related to it. (Typically by adding a latch, and running static timing analysis.) For example: reg enable_r /*verilator clock_enable*/; wire gated_clk = clk & enable_r; always_ff @ (posedge clk) enable_r <= enable_early; The clock_enable attribute will cause the clock gate to be ignored in the scheduling algorithm, sometimes required for correct clock behavior, and always improving performance. It's also a good idea to enable the IMPERFECTSCH warning, to insure all clock enables are properly recognized. /*verilator clocker*/ /*verilator no_clocker*/ Used after a signal declaration to indicate the signal is used as clock or not. This information is used by Verilator to mark the signal as clocker and propagate the clocker attribute automatically to derived signals. See "--clk" for more information. /*verilator coverage_block_off*/ Specifies the entire begin/end block should be ignored for coverage analysis purposes. /*verilator coverage_off*/ Specifies that following lines of code should have coverage disabled. Often used to ignore an entire module for coverage analysis purposes. /*verilator coverage_on*/ Specifies that following lines of code should have coverage re-enabled (if appropriate --coverage flags are passed) after being disabled earlier with /*verilator coverage_off*/. /*verilator inline_module*/ Specifies the module the comment appears in may be inlined into any modules that use this module. This is useful to speed up simulation time with some small loss of trace visibility and modularity. Note signals under inlined submodules will be named *submodule*__DOT__*subsignal* as C++ does not allow "." in signal names. When tracing such signals the tracing routines will replace the __DOT__ with the period. /*verilator isolate_assignments*/ Used after a signal declaration to indicate the assignments to this signal in any blocks should be isolated into new blocks. When there is a large combinatorial block that is resulting in a UNOPTFLAT warning, attaching this to the signal causing a false loop may clear up the problem. IE, with the following reg splitme /* verilator isolate_assignments*/; // Note the placement of the semicolon above always @* begin if (....) begin splitme = ....; other assignments end end Verilator will internally split the block that assigns to "splitme" into two blocks: It would then internally break it into (sort of): // All assignments excluding those to splitme always @* begin if (....) begin other assignments end end // All assignments to splitme always @* begin if (....) begin splitme = ....; end end /*verilator lint_off *msg**/ Disable the specified warning message for any warnings following the comment. /*verilator lint_on *msg**/ Re-enable the specified warning message for any warnings following the comment. /*verilator lint_restore*/ After a /*verilator lint_save*/, pop the stack containing lint message state. Often this is useful at the bottom of include files. /*verilator lint_save*/ Push the current state of what lint messages are turned on or turned off to a stack. Later meta-comments may then lint_on or lint_off specific messages, then return to the earlier message state by using /*verilator lint_restore*/. For example: // verilator lint_save // verilator lint_off SOME_WARNING ... // code needing SOME_WARNING turned off // verilator lint_restore If SOME_WARNING was on before the lint_off, it will now be restored to on, and if it was off before the lint_off it will remain off. /*verilator no_inline_module*/ Specifies the module the comment appears in should not be inlined into any modules that use this module. This is useful especially at the top level module to reduce the size of the interface class, to aid compile time at a small performance loss. /*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*/ (parameter) Used after a parameter declaration to indicate the emitted C code should have the parameter values visible. Due to C++ language restrictions, this may only be used on 64-bit or narrower integral enumerations. parameter [2:0] PARAM /*verilator public*/ = 2'b0; /*verilator public*/ (typedef enum) Used after an enum typedef declaration to indicate the emitted C code should have the enum values visible. Due to C++ language restrictions, this may only be used on 64-bit or narrower integral enumerations. typedef enum logic [2:0] { ZERO = 3'b0 } pub_t /*verilator public*/; /*verilator public*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will also declare this module public, otherwise use /*verilator public_flat*/. Instead of using public variables, consider instead making a DPI or public function that accesses the variable. This is nicer as it provides an obvious entry point that is also compatible across simulators. /*verilator public*/ (task/function) Used inside the declaration section of a function or task declaration to indicate the function or task should be made into a C++ function, public to outside callers. Public tasks will be declared as a void C++ function, public functions will get the appropriate non-void (bool, uint32_t, etc) return type. Any input arguments will become C++ arguments to the function. Any output arguments will become C++ reference arguments. Any local registers/integers will become function automatic variables on the stack. Wide variables over 64 bits cannot be function returns, to avoid exposing complexities. However, wide variables can be input/outputs; they will be passed as references to an array of 32-bit numbers. Generally, only the values of stored state (flops) should be written, as the model will NOT notice changes made to variables in these functions. (Same as when a signal is declared public.) You may want to use DPI exports instead, as it's compatible with other simulators. /*verilator public_flat*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will not declare this module public, which means the name of the signal or path to it may change based upon the module inlining which takes place. /*verilator public_flat_rd*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat (see above), but read-only. /*verilator public_flat_rw @() */ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat_rd (see above), and also writable, where writes should be considered to have the timing specified by the given sensitivity edge list. /*verilator public_module*/ Used after a module statement to indicate the module should not be inlined (unless specifically requested) so that C code may access the module. Verilator automatically sets this attribute when the module contains any public signals or `systemc_ directives. Also set for all modules when using the --public switch. /*verilator sc_clock*/ Rarely needed. Used after an input declaration to indicate the signal should be declared in SystemC as a sc_clock instead of a bool. This was needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require clock pins to be sc_clocks and this is no longer needed. /*verilator sc_bv*/ Used after a port declaration. It sets the port to be of sc_bv<*width*> type, instead of bool, vluint32_t or vluint64_t. This may be useful if the port width is parametrized and different of such modules interface a templated module (such as a transactor) or for other reasons. In general you should avoid using this attribute when not necessary as with increasing usage of sc_bv the performance increases significantly. /*verilator sformat*/ Attached to the final input of a function or task "input string" to indicate the function or task should pass all remaining arguments through $sformatf. This allows creation of DPI functions with $display like behavior. See the test_regress/t/t_dpi_display.v file for an example. /*verilator tag */ Attached after a variable or structure member to indicate opaque (to Verilator) text that should be passed through to the XML output as a tag, for use by downstream applications. /*verilator tracing_off*/ Disable waveform tracing for all future signals that are declared in this module, or cells below this module. Often this is placed just after a primitive's module statement, so that the entire module and cells below it are not traced. /*verilator tracing_on*/ Re-enable waveform tracing for all future signals or cells that are declared. LANGUAGE LIMITATIONS There are some limitations and lack of features relative to a commercial simulator, by intent. User beware. It is strongly recommended you use a lint tool before running this program. Verilator isn't designed to easily uncover common mistakes that a lint program will find for you. Synthesis Subset Verilator supports only the Synthesis subset with a few minor additions such as $stop, $finish and $display. That is, you cannot use hierarchical references, events or similar features of the Verilog language. It also simulates as Synopsys's Design Compiler would; namely a block of the form: always @ (x) y = x & z; This will recompute y when there is even a potential for change in x or a change in z, that is when the flops computing x or z evaluate (which is what Design Compiler will synthesize.) A compliant simulator would only calculate y if x changes. Use Verilog-Mode's /*AS*/ or Verilog 2001's always @* to reduce missing activity items. Avoid putting $displays in combo blocks, as they may print multiple times when not desired, even on compliant simulators as event ordering is not specified. Signal Naming To avoid conflicts with C symbol naming, any character in a signal name that is not alphanumeric nor a single underscore will be replaced by __0hh where hh is the hex code of the character. To avoid conflicts with Verilator's internal symbols, any double underscore are replaced with ___05F (5F is the hex code of an underscore.) 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, depending on --x-initial setting, are typically 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 (since typically control signals are active-high). --x-assign applies to variables explicitly initialized or assigned to X. Uninitialized clocks are initialized to zero, while all other state holding variables are initialized to a random value. Event driven simulators will generally trigger an edge on a transition from X to 1 ("posedge") or X to 0 ("negedge"). However, by default, since clocks are initialized to zero, Verilator will not trigger an initial negedge. Some code (particularly for reset) may rely on X->0 triggering an edge. The --x-initial-edge switch enables 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 buses [0:15] are not supported as they aren't easily made compatible with C++. Gate Primitives The 2-state gate primitives (and, buf, nand, nor, not, or, xnor, xor) are directly converted to behavioral equivalents. The 3-state and MOS gate primitives are not supported. Tables are not supported. Specify blocks All specify blocks and timing checks are ignored. Array Initialization When initializing a large array, you need to use non-delayed assignments. Verilator will tell you when this needs to be fixed; see the BLKLOOPINIT error for more information. Array Out of Bounds Writing a memory element that is outside the bounds specified for the array may cause a different memory element inside the array to be written instead. For power-of-2 sized arrays, Verilator will give a width warning and the address. For non-power-of-2-sizes arrays, index 0 will be written. Reading a memory element that is outside the bounds specified for the array will give a width warning and wrap around the power-of-2 size. For non-power-of-2 sizes, it will return a unspecified constant of the appropriate width. Assertions Verilator is beginning to add support for assertions. Verilator currently only converts assertions to simple "if (...) error" statements, and coverage statements to increment the line counters described in the coverage section. Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. (Arguably SEREs are much of the point, but one must start somewhere.) Language Keyword Limitations This section describes specific limitations for each language keyword. `__FILE__, `__LINE__, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `define, `else, `elsif, `end_keywords, `endif, `error, `ifdef, `ifndef, `include, `line, `systemc_ctor, `systemc_dtor, `systemc_header, `systemc_imp_header, `systemc_implementation, `systemc_interface, `timescale, `undef, `verilog Fully supported. always, always_comb, always_ff, always_latch, and, assign, begin, buf, byte, case, casex, casez, default, defparam, do-while, else, end, endcase, endfunction, endgenerate, endmodule, endspecify, endtask, final, for, function, generate, genvar, if, initial, inout, input, int, integer, localparam, logic, longint, macromodule, module, nand, negedge, nor, not, or, output, parameter, posedge, reg, scalared, shortint, signed, supply0, supply1, task, time, tri, typedef, var, vectored, while, wire, xnor, xor Generally supported. ++, -- operators Increment/decrement can only be used as standalone statements or in for loops. They cannot be used as side effect operators inside more complicate expressions ("a = b++;"). '{} operator Assignment patterns with order based, default, constant integer (array) or member identifier (struct/union) keys are supported. Data type keys and keys which are computed from a constant expression are not supported. cast operator Casting is supported only between simple scalar types, signed and unsigned, not arrays nor structs. chandle Treated as a "longint"; does not yet warn about operations that are specified as illegal on chandles. disable Disable statements may be used only if the block being disabled is a block the disable statement itself is inside. This was commonly used to provide loop break and continue functionality before SystemVerilog added the break and continue keywords. inside Inside expressions may not include unpacked array traversal or $ as an upper bound. Case inside and case matches are also unsupported. interface Interfaces and modports, including with generated data types are supported. Generate blocks around modports are not supported, nor are virtual interfaces nor unnamed interfaces. priority if, unique if Priority and unique if's are treated as normal ifs and not asserted to be full nor unique. specify specparam All specify blocks and timing checks are ignored. string String is supported only to the point that they can be assigned, concatenated, compared, and passed to DPI imports. Standard method calls on strings are not supported. timeunit, timeprecision All timing control statements are ignored. uwire Verilator does not perform warning checking on uwires, it treats the uwire keyword as if it were the normal wire keyword. $bits, $countones, $error, $fatal, $finish, $info, $isunknown, $onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time, $unsigned, $warning. Generally supported. $display, $write, $fdisplay, $fwrite, $swrite $display and friends must have a constant format string as the first argument (as with C's printf). The rare usage which lists variables standalone without a format is not supported. $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc The sized display functions are rarely used and so not supported. Replace them with a $write with the appropriate format specifier. $finish, $stop The rarely used optional parameter to $finish and $stop is ignored. $fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fscanf, $fwrite File descriptors passed to the file PLI calls must be file descriptors, not MCDs, which includes the mode parameter to $fopen being mandatory. $fscanf, $sscanf Only integer formats are supported; %e, %f, %m, %r, %v, and %z are not supported. $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal, $setup, $setuphold, $skew, $timeskew, $width All specify blocks and timing checks are ignored. $random $random does not support the optional argument to set the seed. Use the srand function in C to accomplish this, and note there is only one random number generator (not one per module). $readmemb, $readmemh Read memory commands should work properly. Note Verilator and the Verilog specification does not include support for readmem to multi-dimensional arrays. $test$plusargs, $value$plusargs Supported, but the instantiating C++/SystemC testbench must call Verilated::commandArgs(argc, argv); to register the command line before calling $test$plusargs or $value$plusargs. $timeformat Not supported as Verilator needs to determine all formatting at compile time. Generally you can just ifdef them out for no ill effect. Note also VL_TIME_MULTIPLER can be defined at compile time to move the decimal point when displaying all times, model wide. ERRORS AND WARNINGS Warnings may be disabled in three 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 Second, warnings may be disabled using a configuration file with a lint_off command. This is useful when a script is suppressing warnings and the Verilog source should not be changed. 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] = ... It is also possible to disable this error when one of the assignments is inside a public task. This is not illegal in SystemVerilog, but a violation of good coding practice. Verilator reports this as an error, because 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. BSSPACE Warns that a backslash is followed by a space then a newline. Likely the intent was to have a backslash directly followed by a newline (e.g. when making a `define) and there's accidentally whitespace at the end of the line. If the space is not accidental, suggest removing the backslash in the code as it serves no function. Ignoring this warning will only suppress the lint check, it will simulate correctly. 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. COLONPLUS Warns that a :+ is seen. Likely the intent was to use +: to select a range of bits. If the intent was a range that is explicitly positive, suggest adding a space, e.g. use ": +". Ignoring this warning will only suppress the lint check, it will simulate correctly. CDCRSTLOGIC With --cdc only, warns that asynchronous flop reset terms come from other than primary inputs or flopped outputs, creating the potential for reset glitches. CLKDATA Warns that clock signal is mixed used with/as data signal. The checking for this warning is enabled only if user has explicitly marked some signal as clocker using command line option or in-source meta comment (see "--clk"). The warning can be disabled without affecting the simulation result. But it is recommended to check the warning as this may degrade the performance of the Verilated model. CMPCONST Warns that you are comparing a value in a way that will always be constant. For example "X > 1" will always be true when X is a single bit wide. Ignoring this warning will only suppress the lint check, it will simulate correctly. COMBDLY Warns that you have a delayed assignment inside of a combinatorial block. Using delayed assignments in this way is considered bad form, and may lead to the simulator not matching synthesis. If this message is suppressed, Verilator, like synthesis, will convert this to a non-delayed assignment, which may result in logic races or other nasties. See Ignoring this warning may make Verilator simulations differ from other simulators. DECLFILENAME Warns that a module or other declaration's name doesn't match the filename with path and extension stripped that it is declared in. The filename a modules/interfaces/programs is declared in should match the name of the module etc. so that -y directory searching will work. This warning is printed for only the first mismatching module in any given file, and -v library files are ignored. Disabled by default as this is a code style warning; it will simulate correctly. DEFPARAM Warns that the "defparam" statement was deprecated in Verilog 2001 and all designs should now be using the #(...) format to specify parameters. Disabled by default as this is a code style warning; it will simulate correctly. DETECTARRAY Error when Verilator tries to deal with a combinatorial loop that could not be flattened, and which involves a datatype which Verilator cannot handle, such as an unpacked struct or a large unpacked array. This typically ocurrs when -Wno-UNOPTFLAT has been used to override an UNOPTFLAT warning (see below). The solution is to break the loop, as described for UNOPTFLAT. ENDLABEL Warns that a label attached to a "end"-something statement does not match the label attached to the block start. Ignoring this warning will only suppress the lint check, it will simulate correctly. GENCLK Warns that the specified signal is generated, but is also being used as a clock. Verilator needs to evaluate sequential logic multiple times in this situation. In somewhat contrived cases having any generated clock can reduce performance by almost a factor of two. For fastest results, generate ALL clocks outside in C++/SystemC and make them primary inputs to your Verilog model. (However once need to you have even one, don't sweat additional ones.) Ignoring this warning may make Verilator simulations differ from other simulators. IFDEPTH Warns that if/if else statements have exceeded the depth specified with --if-depth, as they are likely to result in slow priority encoders. Unique and priority if statements are ignored. Solutions include changing the code to a case statement, or a SystemVerilog 'unique if' or 'priority if'. Disabled by default as this is a code style warning; it will simulate correctly. IMPERFECTSCH Warns that the scheduling of the model is not absolutely perfect, and some manual code edits may result in faster performance. This warning defaults to off, is not part of -Wall, and must be turned on explicitly before the top module statement is processed. IMPLICIT Warns that a wire is being implicitly declared (it is a single bit wide output from a sub-module.) While legal in Verilog, implicit declarations only work for single bit wide signals (not buses), do not allow using a signal before it is implicitly declared by a cell, and can lead to dangling nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for Emacs, available from Ignoring this warning will only suppress the lint check, it will simulate correctly. IMPURE Warns that a task or function that has been marked with /*verilator no_inline_task*/ references variables that are not local to the task. Verilator cannot schedule these variables correctly. Ignoring this warning may make Verilator simulations differ from other simulators. INCABSPATH Warns that an `include filename specifies an absolute path. This means the code will not work on any other system with a different file system layout. Instead of using absolute paths, relative paths (preferably without any directory specified whatever) should be used, and +incdir used on the command line to specify the top include source directories. Disabled by default as this is a code style warning; it will simulate correctly. INITIALDLY Warns that you have a delayed assignment inside of an initial or final block. If this message is suppressed, Verilator will convert this to a non-delayed assignment. See also the COMBDLY warning. Ignoring this warning may make Verilator simulations differ from other simulators. LITENDIAN Warns that a packed vector is declared with little endian bit numbering (i.e. [0:7]). Big endian bit numbering is now the overwhelming standard, and little numbering is now thus often due to simple oversight instead of intent. Also warns that a cell is declared with little endian range (i.e. [0:7] or [7]) and is connected to a N-wide signal. Based on IEEE the bits will likely be backwards from what you expect (i.e. cell [0] will connect to signal bit [N-1] not bit [0]). Ignoring this warning will only suppress the lint check, it will simulate correctly. MODDUP Error that a module has multiple definitions. Generally this indicates a coding error, or a mistake in a library file and it's good practice to have one module per file to avoid these issues. For some gate level netlists duplicates are unavoidable, and this error may be disabled. MULTIDRIVEN Warns that the specified signal comes from multiple always blocks. This is often unsupported by synthesis tools, and is considered bad style. It will also cause longer runtimes due to reduced optimizations. Ignoring this warning will only slow simulations, it will simulate correctly. MULTITOP Error that there are multiple top level modules, that is modules not instantiated by any other module. Verilator only supports a single top level, if you need more, create a module that wraps all of the top modules. Often this error is because some low level cell is being read in, but is not really needed. The best solution is to insure that each module is in a unique file by the same name. Otherwise, make sure all library files are read in as libraries with -v, instead of automatically with -y. PINCONNECTEMPTY Warns that a cell instantiation has a pin which is connected to .pin_name(), e.g. not another signal, but with an explicit mention of the pin. It may be desirable to disable PINCONNECTEMPTY, as this indicates intention to have a no-connect. Disabled by default as this is a code style warning; it will simulate correctly. PINMISSING Warns that a module has a pin which is not mentioned in a cell instantiation. If a pin is not missing it should still be specified on the cell declaration with a empty connection, using "(.pin_name())". Ignoring this warning will only suppress the lint check, it will simulate correctly. PINNOCONNECT Warns that a cell instantiation has a pin which is not connected to another signal. Disabled by default as this is a code style warning; it will simulate correctly. REALCVT Warns that a real number is being implicitly rounded to an integer, with possible loss of precision. REDEFMACRO Warns that you have redefined the same macro with a different value, for example: `define MACRO def1 //... `define MACRO otherdef The best solution is to use a different name for the second macro. If this is not possible, add a undef to indicate the code is overriding the value: `define MACRO def1 //... `undef MACRO `define MACRO otherdef SELRANGE Warns that a selection index will go out of bounds: wire vec[6:0]; initial out = vec[7]; // There is no 7 Verilator will assume zero for this value, instead of X. Note that in some cases this warning may be false, when a condition upstream or downstream of the access means the access out of bounds will never execute or be used. wire vec[6:0]; initial begin seven = 7; ... if (seven != 7) out = vec[seven]; // Never will use vec[7] STMTDLY Warns that you have a statement with a delayed time in front of it, for example: #100 $finish; Ignoring this warning may make Verilator simulations differ from other simulators. SYMRSVDWORD Warning that a symbol matches a C++ reserved word and using this as a symbol name would result in odd C compiler errors. You may disable this warning, but the symbol will be renamed by Verilator to avoid the conflict. SYNCASYNCNET Warns that the specified net is used in at least two different always statements with posedge/negedges (i.e. a flop). One usage has the signal in the sensitivity list and body, probably as an async reset, and the other usage has the signal only in the body, probably as a sync reset. Mixing sync and async resets is usually a mistake. The warning may be disabled with a lint_off pragma around the net, or either flopped block. Disabled by default as this is a code style warning; it will simulate correctly. TASKNSVAR Error when a call to a task or function has a output from that task tied to a non-simple signal. Instead connect the task output to a temporary signal of the appropriate width, and use that signal to set the appropriate expression as the next statement. For example: task foo; output sig; ... endtask always @* begin foo(bus_we_select_from[2]); // Will get TASKNSVAR error end Change this to: reg foo_temp_out; always @* begin foo(foo_temp_out); bus_we_select_from[2] = foo_temp_out; end Verilator doesn't do this conversion for you, as some more complicated cases would result in simulator mismatches. UNDRIVEN Warns that the specified signal is never sourced. Verilator is fairly liberal in the usage calculations; making a signal public, or loading only a single array element marks the entire signal as driven. Disabled by default as this is a code style warning; it will simulate correctly. UNOPT Warns that due to some construct, optimization of the specified signal or block is disabled. The construct should be cleaned up to improve runtime. A less obvious case of this is when a module instantiates two submodules. Inside submodule A, signal I is input and signal O is output. Likewise in submodule B, signal O is an input and I is an output. A loop exists and a UNOPT warning will result if AI & AO both come from and go to combinatorial blocks in both submodules, even if they are unrelated always blocks. This affects performance because Verilator would have to evaluate each submodule multiple times to stabilize the signals crossing between the modules. Ignoring this warning will only slow simulations, it will simulate correctly. UNOPTFLAT Warns that due to some construct, optimization of the specified signal is disabled. The signal specified includes a complete scope to the signal; it may be only one particular usage of a multiply instantiated block. The construct should be cleaned up to improve runtime; two times better performance may be possible by fixing these warnings. Unlike the UNOPT warning, this occurs after netlist flattening, and indicates a more basic problem, as the less obvious case described under UNOPT does not apply. Often UNOPTFLAT is caused by logic that isn't truly circular as viewed by synthesis which analyzes interconnection per-bit, but is circular to simulation which analyzes per-bus: wire [2:0] x = {x[1:0],shift_in}; This statement needs to be evaluated multiple times, as a change in "shift_in" requires "x" to be computed 3 times before it becomes stable. This is because a change in "x" requires "x" itself to change value, which causes the warning. For significantly better performance, split this into 2 separate signals: wire [2:0] xout = {x[1:0],shift_in}; and change all receiving logic to instead receive "xout". Alternatively, change it to wire [2:0] x = {xin[1:0],shift_in}; and change all driving logic to instead drive "xin". With this change this assignment needs to be evaluated only once. These sort of changes may also speed up your traditional event driven simulator, as it will result in fewer events per cycle. The most complicated UNOPTFLAT path we've seen was due to low bits of a bus being generated from an always statement that consumed high bits of the same bus processed by another series of always blocks. The fix is the same; split it into two separate signals generated from each block. The UNOPTFLAT warning may also be due to clock enables, identified from the reported path going through a clock gating cell. To fix these, use the clock_enable meta comment described above. The UNOPTFLAT warning may also occur where outputs from a block of logic are independent, but occur in the same always block. To fix this, use the isolate_assignments meta comment described above. To assist in resolving UNOPTFLAT, the option "--report-unoptflat" can be used, which will provide suggestions for variables that can be split up, and a graph of all the nodes connected in the loop. See the Arguments section for more details. Ignoring this warning will only slow simulations, it will simulate correctly. UNPACKED Warns that unpacked structs and unions are not supported. Ignoring this warning will make Verilator treat the structure as packed, which may make Verilator simulations differ from other simulators. UNSIGNED Warns that you are comparing a unsigned value in a way that implies it is signed, for example "X < 0" will always be true when X is unsigned. Ignoring this warning will only suppress the lint check, it will simulate correctly. UNUSED Warns that the specified signal is never sinked. Verilator is fairly liberal in the usage calculations; making a signal public, a signal matching --unused-regexp ("*unused*") or accessing only a single array element marks the entire signal as used. Disabled by default as this is a code style warning; it will simulate correctly. A recommended style for unused nets is to put at the bottom of a file code similar to the following: wire _unused_ok = &{1'b0, sig_not_used_a, sig_not_used_yet_b, // To be fixed 1'b0}; The reduction AND and constant zeros mean the net will always be zero, so won't use simulation time. The redundant leading and trailing zeros avoid syntax errors if there are no signals between them. The magic name "unused" (-unused-regexp) is recognized by Verilator and suppresses warnings; if using other lint tools, either teach to tool to ignore signals with "unused" in the name, or put the appropriate lint_off around the wire. Having unused signals in one place makes it easy to find what is unused, and reduces the number of lint_off pragmas, reducing bugs. USERINFO, USERWARN, USERERROR, USERFATAL A SystemVerilog elaboration-time assertion print was executed. 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 also compiles under Microsoft Visual C++ Version 7 or newer, but this is not tested every release. Can you provide binaries? Verilator is available as a RPM for Debian/Ubuntu, 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-commercial-simulator)? Generally, the implied part is of the question is "... with all of the manpower they can put into developing it." Most commercial simulators have to be Verilog compliant, meaning event driven. This prevents them from being able to reorder blocks and make netlist-style optimizations, which are where most of the gains come from. Non-compliance shouldn't be scary. Your synthesis program isn't compliant, so your simulator shouldn't have to be -- and Verilator is closer to the synthesis interpretation, so this is a good thing for getting working silicon. Will Verilator output remain under my own license? Yes, it's just like using GCC on your programs; this is why Verilator uses the "GNU *Lesser* Public License Version 3" instead of the more typical "GNU Public License". See the licenses for details, but in brief, if you change Verilator itself or the header files Verilator includes, you must make the source code available under the GNU Lesser Public License. However, Verilator output (the Verilated code) only "include"s the licensed files, and so you are NOT required to release any output from Verilator. You also have the option of using the Perl Artistic License, which again does not require you release your Verilog or generated code, and also allows you to modify Verilator for internal use without distributing the modified version. But please contribute back to the community! One limit is that you cannot under either license release a commercial Verilog simulation product incorporating Verilator without making the source code available. As is standard with Open Source, contributions back to Verilator will be placed under the Verilator copyright and LGPL/Artistic license. Small test cases will be released into the public domain so they can be used anywhere, and 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 generated 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, and very large commercial designs have topped 16GB. 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 examples/tracing_c/sim_main.cpp file of the distribution. You also need to compile verilated_vcd_c.cpp and add it to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag. Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file. #include "verilated_vcd_c.h" ... int main(int argc, char** argv, char** env) { ... Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd"); ... while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += #; tfp->dump (main_time); } tfp->close(); } How do I generate waveforms (traces) in SystemC? Add the --trace switch to Verilator, and in your top level C sc_main code, include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then create a VerilatedVcdSc object as you would create a normal SystemC trace file. For an example, see the call to VerilatedVcdSc in the examples/tracing_sc/sc_main.cpp file of the distribution, and below. Alternatively you may use the C++ trace mechanism described in the previous question, however the timescale and timeprecision will not inherited from your SystemC settings. You also need to compile verilated_vcd_sc.cpp and verilated_vcd_c.cpp and add them to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag. Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file. #include "verilated_vcd_sc.h" ... int main(int argc, char** argv, char** env) { ... Verilated::traceEverOn(true); VerilatedVcdSc* tfp = new VerilatedVcdSc; topp->trace (tfp, 99); tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd"); ... sc_start(1); ... tfp->close(); } How do I view waveforms (traces)? Verilator makes standard VCD (Value Change Dump) files. They are viewable with the public domain GtkWave (recommended) or Dinotrace (legacy) 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 solid-state disk, instead of to a network disk. Network disks are generally far slower. How do I do coverage analysis? Verilator supports both block (line) coverage and user inserted functional coverage. First, run verilator with the --coverage option. If you're using your own makefile, compile the model with the GCC flag -DVM_COVERAGE (if using Verilator's, it will do this for you.) At the end of your test, call VerilatedCov::write passing the name of the coverage data file (typically "logs/coverage.dat"). Run each of your tests in different directories. Each test will create a logs/coverage.dat file. After running all of your tests, verilator_coverage is executed. Verilator_coverage reads the logs/coverage.dat 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 examples/tracing_c/logs directory. Grep for lines starting with '%' to see what lines Verilator believes need more coverage. Where is the translate_off command? (How do I ignore a construct?) Translate on/off pragmas are generally a bad idea, as it's easy to have mismatched pairs, and you can't see what another tool sees by just preprocessing the code. Instead, use the preprocessor; Verilator defines the "VERILATOR" define for you, so just wrap the code in an ifndef region: `ifndef VERILATOR Something_Verilator_Dislikes; `endif Most synthesis tools similarly define SYNTHESIS for you. 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. If you use --exe, this is done for you. 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? Use a recent compiler. Newer compilers tend do be faster, with the now relatively old GCC 3.0 to 3.3 being horrible. Compile in parallel on many machines and use caching; see 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. Also see the --output-split option. To reduce the compile time of classes that use a Verilated module (e.g. a top CPP file) you may wish to add /*verilator no_inline_module*/ to your top level module. This will decrease the amount of code in the model's Verilated class, improving compile times of any instantiating top level C++ code, at a relatively small cost of execution performance. 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->our->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 Verilator 3.000 by rewriting Verilator from scratch in C++. This added many optimizations, yielding about a 2-5x performance gain. In 2009, major SystemVerilog and DPI language support was added. Currently, various language features and performance enhancements are added as the need arises. Verilator is now about 3x faster than in 2002, and is faster than many popular commercial simulators. AUTHORS When possible, please instead report bugs to . Wilson Snyder Major concepts by Paul Wasson, Duane Galbi and Jie Xu. CONTRIBUTORS Many people have provided ideas and other assistance with Verilator. The major corporate sponsors of Verilator, by providing significant contributions of time or funds include include Atmel Corporation, Cavium Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc., and SiCortex Inc. The people who have contributed major functionality are Byron Bradley, Jeremy Bennett, Jie Xu, Lane Brooks, John Coiner, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers included Jeff Dutton, Jonathon Donaldson, Ralf Karge, David Hewson, Iztok Jeras, Wim Michiels, Alex Solomatnikov, Sebastien Van Cauwenberghe, Gene Weber, and Clifford Wolf. Some of the people who have provided ideas and feedback for Verilator include: Ahmed El-Mahmoudy, David Addison, Tariq B. Ahmad, Nikana Anastasiadis, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad Bagri, Andrew Bardsley, Matthew Barr, Geoff Barrett, Julius Baxter, Jeremy Bennett, Michael Berman, David Binderman, Johan Bjork, David Black, Daniel Bone, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Charlie Brej, J Briquet, Lane Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Ted Campbell, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Enzo Chi, Robert A. Clark, Allan Cochrane, John Coiner, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, John Demme, Mike Denio, John Deroo, Philip Derrick, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic, Jonathon Donaldson, Sebastian Dressler, Alex Duller, Jeff Dutton, Usuario Eda, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete, Fabrizio Ferrandi, Brian Flachs, Andrea Foletto, Bob Fredieu, Christian Gelinek, Glen Gibb, Shankar Giri, Dan Gisselquist, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Xuan Guo, Neil Hamilton, Jannis Harder, Junji Hashimoto, Thomas Hawkins, Robert Henry, David Hewson, Jamey Hicks, Hiroki Honda, Alex Hornung, David Horton, Jae Hossell, Alan Hunter, Jamie Iles, Ben Jackson, Shareef Jalloq, Krzysztof Jankowski, HyungKi Jeong, Iztok Jeras, James Johnson, Christophe Joly, Franck Jullien, Mike Kagen, Arthur Kahlich, Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Olof Kindgren, Sobhan Klnv, Gernot Koch, Soon Koh, Steve Kolecki, Brett Koonce, Wojciech Koszek, Varun Koyyalagunta, David Kravitz, Roland Kruse, Sergey Kvachonok, Ed Lander, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber, Igor Lesik, John Li, Eivind Liland, Charlie Lind, Andrew Ling, Paul Liu, Derek Lockhart, Arthur Low, Stefan Ludwig, Dan Lussier, Fred Ma, Duraid Madina, Mark Marshall, Alfonso Martinez, Yves Mathieu, Patrick Maupin, Jason McMullan, Elliot Mednick, Wim Michiels, Miodrag Milanovic, Wai Sum Mong, Sean Moore, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Bob Newgard, Cong Van Nguyen, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, James Pallister, Brad Parker, Maciej Piechotka, David Pierce, Dominic Plunkett, David Poole, Mike Popoloski, Rich Porter, Niranjan Prabhu, Usha Priyadharshini, Mark Jackson Pulver, Prateek Puri, Chris Randall, Anton Rapp, Odd Magne Reitan, Frederic Requin, Alberto Del Rio, Oleg Rodionov, Paul Rolfe, Jan Egil Ruud, John Sanguinetti, Galen Seitz, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Steven Slatter, Brian Small, Alex Solomatnikov, Wei Song, Art Stamness, John Stevenson, Rob Stoddard, Todd Strader, John Stroebel, Sven Stucki, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu Takatsukasa, Peter Tengstrand, Wesley Terpstra, Stefan Thiede, Gary Thomas, Kevin Thompson, Ian Thompson, Mike Thyer, Hans Tichelaar, Steve Tong, Michael Tresidder, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Thomas J Whatson, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston, Joshua Wise, Clifford Wolf, Johan Wouters, Ding Xiaoliang, Jie Xu, Mandy Xu, Luke Yang, and Amir Yazdanbakhsh. Thanks to them, and all those we've missed including above. DISTRIBUTION The latest version is available from . Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. SEE ALSO verilator_coverage, verilator_profcfunc, make, "verilator --help" which is the source for this document, and internals.txt in the distribution. verilator-3.916/doxygen.config0000664000177100017500000022175313205574202016376 0ustar wsnyderwsnyder# Doxyfile 1.7.5 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = Verilator # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "Verilog to C translator" # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = veripool-logo.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doxygen-doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = doxygen-mainpage \ include \ src \ test_c \ test_regress \ test_sc \ test_v # 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.916/doxygen-mainpage0000664000177100017500000000023312671044616016704 0ustar wsnyderwsnyder/*! \mainpage Verilator Doxygen Documentation * * \section intro_sec Introduction * * This is a full doxygen analysis of the Verilator source tree. */verilator-3.916/COPYING0000664000177100017500000010451312111011551014543 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.916/verilator.pc.in0000664000177100017500000000045713205574202016466 0ustar wsnyderwsnyderprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ datarootdir=@datarootdir@ includedir=@pkgdatadir@/include Name: verilator Description: fast free Verilog simulator URL: http://www.veripool.org/verilator Version: @PACKAGE_VERSION@ Requires: Libs: Cflags: -I${includedir} -I${includedir}/vltstd verilator-3.916/internals.pdf0000664000177100017500000047646713206353160016241 0ustar wsnyderwsnyder%PDF-1.5 %ÐÔÅØ 37 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ-±jÄ0 †÷<…F{°bɶlw,ôà ÝL—Ò!л¶.Gš^^ÿ캋øõ#}ßcÆ PD¦à¡œ²Åˆ÷(–¡|À›zÕ1©Óú=OÛ²jãÈ)‡™¤ÇãE³¨í´^¦ù§W/Ó_÷;Íú½> stream xÚm’MoÛ0 †ïþ:R‡¨"iÉÒ1Nàbµ±XiEÁšÒK3ìïŽÒ´|!½_’â,7Kt*šèÉ«ôS!‘)UEÞ„È*=«G¸×awüµßj„“ž ¼JpÔæØDôCÈÐ48펇íþ-_Ým宂?Û½~J·7K¶Ÿ¬­ñ„Êf›yצºMý ,êTü.†'«ðZ´•úñR<>Yõ,O·ÊŽAý= _ûÊD{Õß‹ÙÐ…¥áÒÓGw>Sru±}=h–¾vrX8½åB)~*Ô*iÆ„ €zÉA;½«¥ID_ ÐU†YGY×´i­™ [læ©éZ=!Ç.Œ3œ™y·rËØ—ߺ~èó1ºÿ°L•WªiW™“aÞË0Åo m nÌÐe4Õ}:³³GL|V.êÙfµÊZq,o•ÕÓÅGIÓ|´õÔ°”%ª§ZzJ›µ´‹!bt#ÞáâÝôiÝÌ6ïc,,ßùþ.q@ƒ()›Êãû¿]ë±°ªŒ endstream endobj 62 0 obj << /Length 1692 /Filter /FlateDecode >> stream xÚXYsÛ6~÷¯àô%ÔŒE“/å-‡=ãL·±zÌ$y€IX”"U²âüúî”M·}H¸X,°×·»ß®Ï.®¢Ô[«,μõ½ÅqxyœÅJxëÊûâÿ¾(„¯Œ®å"òûÅ2ò[ Ìb)Dâ‹`eH ÿºYÄ…ß+ÓȺcÖG ¼Ü?ÈzñmýáâJ„Uq!‚,I½Õ¸9 CÿÝÍûK>}õó ÞøÇ->»\Ÿý}tèEƒ™"ˆÂÜ+wg_¾…^[¼0«Â;’àÎYÄ@ÕÞíÙ¯goÑ߸ð¢$IgE$"gK"°Lñ?½ùxÉvŸ„(ôÀº Ï“ÿžÓ˜Ð]§êá²$X[Õ±U}ýiýy!"ÿæýoïÖ×7ŸþÛŒõVCГ0ö¿†"©Ó•îÊCסU ¬" áë‰U,'›Š·ö¦Ý¹Û°n6Ì«T/umo¿o £ß}k‚Å2K#ÿºeÅú­âÃhéúñ0x‚¶GQ°JS¶Ý¨{eTS*Î;©@¢RUƒ5í~±£•é8²íýªœìÝa³!›q ~ÜÕj×N_ŒHeu·Ê*‚œ´L‘¹x-x• ^ñž& ÛhQ QpoT§8޲×mcoìù»¥#ýþõÅÅñx dºf@'ì¶uКMðo (ÆÊˆÆÊÈ2ª ÚÊ€²‚‚ pºÓ" ò,sø\x”§þUÝ"¸Ž/  *(U˜FQø; a š¶èÏ‘×í=ŸDY¥´gî8w¸È!½um/ÀäVN8L%+FˆSImíÙSЕû=€lSLKÕu_Ã4„ÑÐîM‰Éz=ƒŠ+ 0=‡ûÀ FošØZêxÑY–`€;d;l`öñ;+ÛÝŽK µn,["9%S„¹ÿyð5uP#´´5ƒÆê¸“˧l‚Ñi¸MÚ€ÖD™_«ïº¤‡…ð>vÔ"`uÔý–©+r{i:¶(J'’ou×6Xç«Ø5¦È~u(Uç.š ½¼ëz#K¬¼ð»G[:ßq½ò{C5™#¼ÒðÍíš2H tüY©åŒ;üréQ©NoƒX…þq«K<±å=4¿Ç­ìO9ºÓwµ½BÏšn›ƒðk¦#0°€æ’{>tM ,Ümg²+‹ù¹†ôòÉ"›P¤vò/ \Jþtpб(&ðÝË®c^W9H©ñF&Þ€–[T·>gYêþ§±ï>²¨QèqÃý•#ZHå~93½Ó?†n¬ûS·­ßïTí^ ºyÒˆc¤i€àj‰cP³Ø4ϰÔuÍ–˜íÉd*¶l¶ëüU¥J²~–NØtß;Û®á?È\ò®0y¶¯tç|òa‘B-Y8®kM g¢{NŸQS/sÙÖö~Tz˜ŽœR“<¡Å/¹Ü⃘©m¼kåö:Tí ²ïU£hæe¹)]Í¢ØÎMZ½²š ~RW?–…Í ?7ÑI*ö7 _šyäÿt[ºãO¼5VZ‘® û¿ùää1ŠÛÚÞLO™<òÙØ²<˜‰½r쬲gΡ™ÍÐ$pòI§uB|L¸wàwÈé¹)йN ÞÀ±4$ÇðÌ$®|†­Cʾ–À‰Î2šúÑQ¥ÕɆ¤”îWž[#4s¨­'s$ðuQ[–~>ˆnqà ÓQ–zŠ4·“„!›.¡ä8ò³“Èb`rAi`fÇ=…)I'¹î˜ÑÓס$u¾…¾£¯À‘ü™¢K$‰O­Ðð‚ ÎÉàdšBrR¸öæt/ø÷2ž…ÃÉñbˆÇŒ“6:.È6H ôGÛîb(9÷N·kj°“î Kq2<KE…Yš¶³¹÷ÆOa‹É›-Îp–SªßõÚ™z§· y^ÃÛl€c~RxETDÌ¥eYT¸Úöo ÿˆ}|A endstream endobj 68 0 obj << /Length 2814 /Filter /FlateDecode >> stream xÚ•ÉrÛÈõ®¯`ùfÌV57Û±\ž83IYãfæ-e@°H¶¿>ok  ²çBôòºûí_ß^]ßøÑ&SYÄ›Ûû*Ü$A¬ÒÌln‹ÍïÞ§mj<Û•U¾õ½a»ó½ÝvgLè•ù1÷¾Þ©7خΫž—þ•ÃZâyµýóöçë£gO©Qqm4?càf­µ÷æ×¼åÓ7~Åÿû_½½½úß•ÐzãOhåëd³?]ýþ§Þ°õóF+“¥›G?Éhæ@Ù¢ òÞ¼S¹‹ªò›x¼ƒ‡­µß a6„ß]Y[y±,,YÊš„–ÊgšÁ¹ì—ì.}ä왢*à÷ ~ÀÂ;p¦C)b,Bp–yáßuyí4˜ÁÁ%‹‚ãþ±¥t'Ñ=àFËèî›î$wÁ­ånn,ŽiòøPƒ¶ó¥¬¢àÜÛü@BøK‰gÑ ÁÕ¨”xùcWVìG"ƒñÞü„‡~âÉܳ‹{PC!ú‹Œ_€ƒÉT2ÿ´ø@yoª¼ïé˜üÖS4‚ú“„ò&,|Úf‚ôÐt¼tZbPV~-˜Ë /øª~i80]DÕ T™Ž¹‘ʵ[z2‹¼Woy€¿aöâTSX¤ØßÁc’ÅFðu(ÔŠ·îÄM-à÷È“¨ÒߣÁÄ*ÖXR ±øöè°Îïú¡Ë÷i¨XHiÇBûp¸ 9\@h(ù‚öNR8¹o:HÜÀèT”eƒ7§–ýb}vøqÍùuPk”Ç€[˜Î(gkÛaÀ|J}¬U˜úvÂ+gr fMA¶$÷ànÛŸs6ˆägŒ¤¸z¤fð=tÍØö KÎ Ö„¸DˆK8Æø†ˆ³ÏP¥¥Á…"(zæ³Ýs–Ì‹ ¬¿ñ¨v)+O'‡JA]ZBg!§¦!Ä/B¢ËÓW`»†lEq¤¾Á¸ÉþBÑ—üÔrJërB=#* Á(ˆfjöþ~­™Òg{ŸS•…äYÐ<½=§'¿R®ÝìeÒÉ‚—É1ÚÎË5 ÖLÒø"Ù»ïW5"Ra6ÙämÕzHSahÎ<{Õ¤°˜{E™w³çR=qÂ\ RPâ†;Ç0 `Žr£‹­¨‡/x¼ ˜¢A~³ZëbiNj™IVàÖè2!ù¥ï±ÈW©ŽÏ,2ÏØ_™9ôg.¿@ŹôQ²Ý,À$ÛAx ¡³­HÓ Þ} £QDÞ/¿>|`ÛKßäRy¦L²“\’²päu3ðDTµžÑ‘CÿnFêy”%Om2'mMõ-uÚçÒ çOm¿È·O` ’¾‡²å"É 3oÇ`–a>y„é¹é>⇠¶¬céhñÌžT¯°FÑ:b<Ÿ(*•O÷ïíe4BP*eÂg ÆÙ‚lõvõí•Z =ÑL’_Y€öKÙ’=aU’KNqÇNU„{7äP¨<{êmð=œ®$ I UÃd7wùþózùò_I=œ`Ö.Š×C‡”Òít™_PÙd¢Ì³÷cÅkÄ}øByo¹Re†t²M„K%†gYJ°s‘ëèç ª8›ç0v¨@+ÔE‘ŠÎ†Ð…—ò˧¹„‡ìHŽ©U›‹ˆÚYûRŠ{ÒµHòËÚÉR†UÑ·HºFÈ¥‡‰BÏ-‰žF¨Šu‘wÏ‚“·z+ð¤”pÑWŒÍÈ‹”mà*Q9¿©\Qïæ~Qî†DÞVªÚK?ôqÁœ£qM„ۙ܀ ~!9—´Ëà¯gúÅ;#לñ`ÞôXM`¥uzÎ Û®çÙ9@çòHΟ§!‚0h\ÉÃÙ‹j=ÑñåGá¥Ó³ì~?v8×w#™üù_)òZ€Ø¥€]ŠÁ8£\kÂàSÙ—ƒKœ~¨øL൮ØÅM'‹Ø¨|#媰{çšl0æ ò(MöØ 5窷çeô£¨»L‹YÄ÷JÿÉN™|T.¼¡Žœ«W ÇŒŒTOþÚÇÖ×’—se¬c¥£x™ï³±$þSJ µÅø YDûsÿÆgÓq]K\˜z4#Ø—«ya ²syu–rlMrQ¢¢`Öñˆ¢”‹<.ná­ö\dÊbÿ¢ãí|B;Â~A¼ÔHÛ[^%b"G ,L2ÅUì290¥5€r°ö±´Fd¶`ª{›¯[:<Ù¬ù&©P¨GxÑ”C‚WíbÒò™]|2ﺼ=þ˜M¼ÂD'b—6^„0Ü@F…:žLׯÞòâÞ¡µ¼:4TJ'j}¡´>uä’³øùDSŒ{}H²fånÙ fwÖ˺^I™6]Õ†­äÜçK0*ãH‡(‚!Q$}Î]œDÞ;YÀn/Beg±ž¥.¯v]^=c‚Ìù€ÿGý´lÅ å”×e;VÔ¾ Aí§2Æá…c~Nr?ü6ãÐŽÃTøœø,¨)ó:\ôÀ1œs©wÝÕ´=~*¿­1cÃTÙÍ0UY§\ÆÏû9l’À[IñqÚ¿__?>>*¢é¡ü¦Øû®×j[ÎQ˜ZA—¡ÉWúœý‰©5Š4Ë“w™ÉEJ•‚ÿeÙΔsîîãÞ9y(¥eE*-¹£É%D(nòg²üeüYp÷Ó endstream endobj 76 0 obj << /Length 2482 /Filter /FlateDecode >> stream xÚ½Y[ܶ~ß_1Ø'mà‘EQ¥-b;ÞÖA£ðÂ}H‚B;âÌÑH]<6úçsnÔeVÛ4@чÅP‡äṇÜ×7/ïU¼Éü, “ÍÃ~£ÂÐ6&Lü4Ó›‡bó£÷ñ.ÕžmË*¿S^·U^ƒön«uäi?S µ÷®¾ S¯·mW“¾Ïf¼!¯î~~øîå½fG…©ö“(Þ|ŒÎAxoÞû–wßÿý=rüçÜ|óöáæ×«ƒÅÔ¾ Ìfwºùñç`SÀÔw›À×Yº¹ÐÂÓF'ÆaTm>Üüãæ5ê«Ã'ú&iêGÚˆ¾ú¯m~>~´-)k?³ì 3…‘ŸÉf«b?ÖŠ÷=KP;ԙǿ`‹£eÂcÞÉhGVì±,Ú7-O}BeáÐrgŸš—äüy@±ü»m¤4:%Z.>渟™0%¯å·ëoWæ½-Äs+è õU¬+öyÝ ýŠÚZùÚŒ{±Â —ùq˜‚i”ŸÅ ¯Ü5h¹bFãøåõšl*óS“¹5m^ÿ²Æ(À8œÛêÌx—c¹Ãð;Â'XëDú‚±÷!CáÌÐUˆŒGJ^š¶ì§Žéä$œhÚR¡>0™ŒäC‹Eמq€^гÔ{…¢n¶&ð Å$1Ëx°50Ú­9Cû& . [ûœÂ£å^®°MçLÎëö’ÑŸ'{B ‰iZNÂOwqìåm™?V–)¥$7dyãsÛpìê%Ø °…Ïš§™¯¢h™'˶NJ°Õ*…3û#gÑ1%o-ײ ï¥oø·;³ˆ;ÑÆAôÄöqÂóÐÕu _ÕuÁ7‚h«DgÉЀyh^i£ç#Fãúç0:† ¢+Œ~¦¢&ÊÔ˜­*“ Ññ‚Ï<=Tk„ê§Ó'8 m°u׸±ñò×ù±ªC µm.õ«êð‡` dv¿ät0 àH`‡8 »¡‰¥—¥ÐB½ë…+« óÜ•›|Í)ujv›¦ZS…O§Žx ôõËNÀeuáŠ}SUÍåÏBèø©c·Q..Q×5  d©€ûR$E…åñåBbA$²q“)¥0#©&ìt :˳_ ;Šçê3ËÌöí`yTî…B %Î{HcIptÌe#Kéh‡Ö¶¶ŽA/0jjÙÌekyMxÄ ÛPCUkêë(¦£oQ°{X½V|ãÀ×Ó [¥n8Ÿ«ÒJ‘-¯Kñ®©;°ÇÚ[n¨8ÙZ+¢d#H!ïN+þ 3Hþè*ËÇ!)(á‡'0i¸+Ò ”2[ØŸÕ¬ˆY^70Æ N• ¶ Ƙ©/‡ñÕg `•s»ÖW¹R:ÁV•™_(W·¬Lp!¿¶Ÿ‚;òT §²äc]Û×|j´N€êJžÚ°d!×<øHaùVЧ™{ÿÊ"~ÿb¡LìÝC*iüô˜«‚¯#í’ ]Šå^¥r O¦Uœ\€ÿôÉ Äw6lTš€+¥9„±¼ú („@¢\…Í…íÊû¨„ŽtžKz"çLíÊúP‰\0d3Œ¶¯øM¼ÅK»•JæJƺpÉxj:ÁŸ®ìyÍt5 ñé¿Ç­¡»¾‡‰‡1ÚÒ^DY±HÈ<è2ŸºÕfz „â# %©\ÂÁ½ã™².û’z ?ЍÿÒ oŽKI„»ílßWÖ½ÞÝòvbÅT'9|¨,² Ó`ôc˜¤ »á[Ò\å«~b¨èP+A“yEE“/ Óº”cWÜ<8ìç–·rL*žÆH¡7Z¢bº•îKÿ,‘ÊH£ÃìÊõl·Ìù$=‹CÒ¥C𷇋^Ç—cÞ3¸þÒň£˜ø1^Ö¸Ùs¤àÛiïÝþ™kœË ÷ºce“ŠƒÙï ö^f%Zb”¸õ íÜâg:ûë ÕŠÃ h3/âžÉ‹8yíE\ñ Oqn5•¶áZ q6ŸFžÊèÕÝà«{'/[-õÀ\è/PÇy4“ÔÅ ŒS3ñ €¿b63HiVwj®™ÿJéîâß|5j{¯öüQ¨¥--9Çp!u/02@£×ã›^mKM1„kF?ãÌ,8d)6+tFãV@SyBãñBÈcM®ün}­T9û_Ý ÆÑ‹®„;|Žã=z&øåg¼¹b <¸5d÷ÁÕÐÖÎ0Ä.=+·€ü—õj.ßcfR›mï×Âê Œ ²Æp›âV&\®OïRHÝè­zBŽÈvL^/ ¦”5ÿæ+'xó¯ïß>üíý·/Vcßր帝Ôñ—KZj¸lP€‚r¾+¬¼¸âlÏ¿‰ÍPüÙÔnÁøÖ‚ÿá¼+§Šµð»Î”I0ÖKÁÜM5¢¤\äþ¹õÐ%o endstream endobj 81 0 obj << /Length 2105 /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¨p-Rlªà¡YÊØ‘ã¡Ûž±Þu¶4¼ƒ¸Zeãm°—ÏÖñ¾ŸÿÍg;ÏU¯¿²8,Îs/nFÿbæ^M$ €NMI60‹¤=fæ9¶Z‡y,G2%©dºJfP©¬‡ÂI÷nJÎH‹E¨òxX×=º9 ¥y˜KuItOmÍùÍ»"ôÀ9¶8;רúX™ÚŒès‡Ï›¸IS)?CÚ¦´ ¹ó/×Á¾ê…ºabsÖYrã-âŽù wÖ¾ DÆÀ [Õ©«9ÏÔìDã£:rÕ´BÀáþ´]•î{š„‹¿s¥q6Úômï!DgŒªÒ0Æu=IüÃãóÙ_ŒÈ±»¥£Ç„˜¯Ayå‘UÆŒš¯ #TŒt–ì°©ŸÆ—æÐ[[Y7IʀɆYT73y¦ËÊŒ”ÈŹO[>¿]Ûϱö–CòUÒ‹}-è1gÐw=`èì)ܲ–Ø>õ+Ñ4ò EzE=øCÜíE'|ÏÎ¥ï’0“a’$ŠŽ[]Ôu|â°VѶ¾´´·Ô2çx$ä°í½¯#:šÄbúè)'E¢žC†¦PƒJÕ}Ûô., zz­~*C!Ũ>%ó ´.Ô{þj835= ¹‘z.õÈC€Ô û‹í­Ã”pæ³Kf*>L z»¨ßw§¦@6eBä`Œ=°5¥Æ mtÇm‡’g¨©[ “L›½{÷á—!ë0çp¹ñ4&Ñv‡xIö–T\ˆQ{Êt’ÃðÞhz|¦R}X õZꢊs:åU´}Ö¼J€›ÏOâvûßOí,eÇQ˜‹¡üNºu¯E¢®’,È,·û9ÔCâQrÌÀ…%òÿü $á¥~ò™[g`ÇY$ÍdÔxPcƒ*LâÑÃß(÷èqÀ_·^§ š²Žé >š«i_G`ƒñIlB©ƒ/R—\u„jÀøâ7ޏ®VÂÿáA©œû½9ê‘™ ïÑ-†7!4ŽTUø­{ˆ(w¨©»ëÚzºVFÁ[°ëxÃÂXè¤ÖÅ®u<=0ãléƒU9ªeÁ,<·ùµm±F—ÒÿQ%3ÕÊ8‚€<óÿïQž ~6H~6ÈáÙ 1»5…9:À„¥ÔUê•ë‘]ÎßÜÝ™&|f¥2¯TØ"ýwû;3ÜTüà'ÄÜ\Î9f¦ä"(€ó“œy$§ÃŸ{Éð_âßsßo6 endstream endobj 89 0 obj << /Length 2931 /Filter /FlateDecode >> stream xÚ¥Z[Û¸~Ÿ_al"/bF$uÍClvRÌb3iw¼ŠÝE¡±é±YòJr¦óï{.¤.çRô‰¯‡çò‹ýÃúâÍ/r‘'*Y¬w ©”ˆ©JD–ëÅz»ø-ø¼Ìt`Ú²*–2è—+4Ði—+­£@‹\&ØÕÁU½TYЛ¶.ªŽ‡>0–§¢Zþ±þéÍN®RZŠLg‹¯‰àä0 ƒ÷Ÿ~¼ºþïÿéúóåõúêÓõ pq¹¾øóBÂŽp!RµaºØ.~û#\laê§E(tž-îiáa¡“T(èU‹›‹\üðÈ›“,‘N™˜wø€TuÓ›-w‹Ûå ÞÒàƒ¾âKÍk˜ÈTPT¯øZveß´vkÑîlw¼Áž´©Š®3vY³³¬QSÖ¨øš:Ö¼ëúëÏ|8/ž‘§"Vn©X®âDïM^ç,à=üæ•”"c>ÂK‘Ô"ÉÕ” fk<ÄDRDù Óòp¬ÌÁ°b,WQ ´7žã“\¨T»mÅfc޽çt• §L¿o@(Y°QÄ: î÷åå³·w_èéÔ‚ÀÚ»Óœ¨‚›ÖìLkêaîÈ$©–sîôpc‚xkn˺ë ÜB_ há ÏA¿Ò$ùF¦dP>¹&RÄ:rëg‚Ä«HŽ;VUiì(ršˆùŠWÀUl¾85ᜥ{7îù–ò•ŒÁ¢æ|xZ'sÙ@:² ­™ÂNYFÔ|)ë;%¥b¢†uŽ·øõ{‡¥0§iŠ1^¸/;Qs£‚㤰f+*´B8“<ÿ©†{U¬ƒ#Û}‡\ìÊÛ Øhg¶åï¡N6§ªÇ§<ð \Mm¿/zì¡2ÐÀ†€‚¦ß¸<”ÏÛ€h,ñPL®>÷L»kÚƒ½ºæ³-{dh"ôÓõmCg t;õÏS‘ægb¯'вOŶ5cÕ³ã‘ÂµÎØÒ pвvŠßÒAF½Àý‡¹×gá=–u‚½õÕŽG n: _$&Úð :­!ˆ)z¡çálÇ-+tvÍ©Æ`@'ùd€c*ÊçOïºÞ Hf™Õ3ì!¶³ö4_x¤¬¹e­Ã²”:N ˆ¸(M|$m™=Ê¢ã‰=±GL3üQÖ{à’us¸ t¨-Z‹Ñ¤>~j<}Üa­„ÿO÷òºT.oñáK°'Éy»½a¦§*qµó+g4=£EW#›mDÀ!Â`ÜÀæ·þP$až#(‹,µ)ÊצæÇ*¶FB]D!& ¸ý=ŽE„ €3æˆØàãéS']ÛÍW»ïy¼nþÏ“núCÿäYÉËÏòsîÈd(¢8›óÀ°µjS¸N¿Ër¸G,\€@À]ô…j;rD«¶Øo!•""ÚkŒ•èDõSk¶TB¦g„I„ Hßaü5l_Ù¸‡`Áj@ñÖ®[Æ ¼¤,n+ƒðd½/í×Þ!×`hUõÀ#lÖÐÁÇ0ãÇwÇ¢µÈó=¡ÆèªX9²S•*ƒo ˆâÞ~QT-'(eµ…ƒ½±l¨„㻚íÑo¡y4,#IÄA)ÞÑŽ ÈL™Wý+x9­ÎƒÎôsÚ®ýùgê!Ô©‰š¿uìÛÓä‚ «c/­6Å6ÆÞ4hÔ¬¸^@áGr‚(›í©ò¹LGò|æ›–”ž.€wuÜ+û׎VÃØ9õ8°›Á#¨ÿüØ,—qóô .½!ï’%îÀ4 ÇRøØTNÙ"·S¼Oãà„†Zo­žÀê¬*>¨—ò!ݲE×`mn ·tCü_—öÊ«ø‘³ÈÜTÕ+Tüä;°×±#GAªWá8qÞŸæyxœëÇ6”8CÇZ-Ô RbK™ƒ½5… “(±΃µ^>Ja¬'lüàMUu,¤xáƒi™gÞC#HRÔógJ'L3M>’uä2)žªÙZ"k„¡C$ÁbŒWË ûûUëº-&¸X oöyS‹“Áª“çž…QA|fv¯m Ž2¾/;ãÂ‘Òæ#Ó@½jF·àAc+‰ÓØ 3gƒÓñ8€¼ÝõÊ& Úx“Må£TD sV ZYíPÖ‘üÚ‘À Pß·åí©§P4Ò2¸´ñ»!„I_PúÒ‡OË äT>]DþÍ®¹nzWÎ8WŸ,ತúÝÍ;“ äŒì%GÀ¸¨çÕzŽŠ8³Ç”g0¼æ¸Õ¢]ªDž%ú'f2f½ÆkãY æK, ^’'U£ÚÒfˆ098À)¢ åâ¶¥-ß¹»NÎõ>VŠR $ícÑ©”ÈêG"‰¡šætç2ð0…·çßò ~âôHŠ4‘ž¢r ˰¨Û±äbµØ¤¶NÓ¸×ÛExfž¸¢'~Z÷‹BpÿÙT)I»½4fZÏ¡o³œ¦Ë¼œŽcH˜ó£Oð8Áer^-}”ã:Q6“cüÔñP“Å>VƒÃp+Vqe2?8ÜÖÔºüódx¨*wìj ¿k›÷îÚâ¸çý}[Œ5þ¶ãß.+ ¢TÏ‘òȰñeƒ»¸3ݬâ äÈÊhUjŒ€ñ­°EÄV 6°!ô›²⦶*ßAËá8+Ž[ÜðÔ©³k]ÕÁüh2¨ø¾8>ƒ¶·o)P‰üå=Ò´†\à ÉHRlymë  >Y¦¿©7PXÉÏÑTµ‡¢ýÂ=~ÜÏÒ¥€t„ö±&Eˆ¡õ÷%æÓÔƒ€Ó°‡lyĦ*Ã…Ä¿tàùüb yoíTjò„T½õb.d6X %_+Ë$y AÆ_=¥"fÖöªÍ‹×… 4f;ÉXŽà©Vð0ýpí¦èzž+ŽÇ¶9BÒ›Šª xRiAÃóT ?½¢ˆv6`85w'ÁŸL³\$YzW>Åšøb;óæ€÷Øyƒ¾";n>}¼\ÿŸô÷Ë'Øžj¡ÂlòK[I0mþI;³Õ žæÈ#TI„Ö¸ø‚¦ÇLX¹¤MpË8˶?@åæ@d¾<ül²·1ÕiyŠ>±Ç”ò9åšy]ÂÒ ­¸Ÿ—(6kÜ•…­ÍÎ|JÓ‰G‘·På-îä™È0/y¨øþ7o¸¬qýéÇKîݬ߭/}E·ô=§`üaê¾DSiÄP|\•~ Çý2†Xyȸ Ñíá¦Ñ7­T"t—Ý6M%¸»nOö"d ¶e ÀëÆö%¡*ס\´ñgu+ûC3b(ÓPíà½söM§áˆý©Ia`ëF¼zCF4ƒ{Ó7ÈUÐ[_„ø¤ßãÏ{Ž.DHÊ|£0}* N /Ëò—¤·̇ɠ·¯:oàÄ䞸홨0W3ú)ǰ5¬høÁ²¬·åÐÑ~Ù_48}yåjew͘ç ûXîüû‡­pa”É•6,HÜŸþ Ww‘è endstream endobj 97 0 obj << /Length 2336 /Filter /FlateDecode >> stream xÚYKsä¶¾ëWL9S©˜ H‚LN»ÊnJ®D›ÔÊòÁöBÚ|ŒIÎÊú÷é@rf(iœƒïþÐýu7æÃíÅwŸd²ÊEžFéêöa%£HÄ+¥"ËÕê¶XýÜ]f*°]Y™K —k´Pé.×JŹL±ª‚ëæ2Ê‚Áv©znú·6ìMuùËí÷ß}Rál«HI‘©lò61¬†apõù×7ÿäùWŸoî>ÞÜ^¾ù‚ \|¼½øýBÂŒp%Ç£*!C½ÚÔ?ý® èú~ •g«'X¯TªEµjõåâ¿Ne޵PaºJ³LÄJóqn·¶·—ë8RÁ¦­kËÂõÜb:ꊂ²Þ]®¡£íÃ#xÀÐrY›ß°Õ-Ôï;W3hއŒE˜Œxì{Ûýåç0 áOòðƒSÇ¡ÈdêG·_˜ŠG¸¡ò+b?Ý*9˜û¾nÚÂ.ì±Va"Ò|µ–RäIÂÔè™å¶|OeÏÚÐØ¯$nÇÍ÷<¦lùD*¸öÐ:ý¡Åžð_Ë=Eùs¨”í¬‡Gíö¶Gý³ ]/ð¼ ÂZ&"ùh7í€'’I0lÍÀµ©*Dq „N…>Düª²¦»Å]:» ÌPqì§à°Éƒé‡wXÍ‚Òí[´,}ß|ëZHLSýæOè ¹¹}ËMåð­[¸õ£[„uâÃ!WSvÕ3×Û‡Á6ô!N‚O—YxÌí¦ÞUâ;npÛ)Võ¶ñ+àºþÆPÁ°´¬UÈÏ<»fA‹=-)Ü9#¡£ J@Ãc*8Lþ¡3µ²€£4†­®Ü{½ÂéIef“ÂX릒XùZöåÐú%K×½©ÚÞ @³<˜ñMÓvµ©¾á¯‡}³Ê–,f5Jp4)wÑZXR›å:ß0Ù’&Ê›K Rè÷%ß=Tz»i›bA1%èY8éÙ×ýnAÜ8Çì<¤¼tûàö:0×Ó²HdÉüv°D8@ãfd_tÓ*ÚRGI‚j0†G˜T>H…tÔ &lȃëxà’aŠ»Hþð·Ò#œ0ýNýXÖ×"+}ìùs¨Q©³<¸ß»ÕKWî:ö]€³T12Èìäu‹­Ò4¨mߣЧ¥m|ÍõÖÇÙr<À4  ¡°»ÎnÌ` <Èé“ 0‚µ¦çi ÐOõ|´PbÜõÃòy'ë$€eºrp†%Á—¶¶…ÓHèN !Øo°ykk7±ž›Ìz:[Ïa{‡}šNŒCK °ÚW4îÉíÀfí»®}å<8¿#…‚g4Î8/°5¸Îz¸†61§¤îùi ~CLþRA@PEäÌ@Qspók•‹Ì9Œk0C”qj!º? {õ–—DOå£vŒUYXŠböÉ€·øÕËrÜœ>9f2›²*3XþönƒÜ(.4»‹ÎMݺ±èKàæµÔÁGÃ÷Ësˆôl´îȧ~}rÅPôãžÐD²*lãÂè»%æ‚51vô̵X"¢±ß­K Þf+¼»PÍÙꎎB{a«Õ~<'ŠÑ¸mwÈ,¦â/c”,2G1…X“Aa(ü5ä9OÏ¶Ž¤:Q‡°¾@Ý@¦™žƒ²bD¹~„l.”§ì¿.©¦aù‘È Ð-™%ìã¼Õ‰ l×9†G§¨Ú977–Ü)”l“\›¹õÙˆÑ3spJ‘èô'0—MW:ÞÁkJBtá,½škxF•x™ÜõäŽç|¢ŒÃ¹Œ¥.qœÎ‘Oç,pG ñ±²Ç˜A%’y&*nœH;Y± ÒoÛ}åz<¿ð,Rþ³i‡%­Àdmä`wžÂ9\…yÂ!x.žVà>ž;¢¦"5÷¾rœºm*Œ®8Ž^ >%2í¨‰Ê¾’Œxj¥X\ú ªtLýë¾w¼ÙíªÒºfÔ¬Ó½sŒGF•5›Ý-A ¤Sì:·uŽÐ¿¯í‘ÆBÇÑÛùÂèuŠyÚiÍ#Œ]´¢¦R,D¢…”>,NÐ}ß7”Üü1\SÔô±(‡· vL¨ê$N"‘k}ªZ©PÕUðµÞ·,dT!H¨Îƒ6Ç• /l¸¨JVMÁR)ЧÅI éIÓØ [tÞsÀ²äƒ2¡¦ÕÀt·˜ÞÊTÈøÈšå€<‡GïÍæ·¥#ˆÈÓ‘\ÜÛ@éFz´žEÅÐ pÏÓ¥S½ø“ÚàÙ{Q¤ŽÏÑp€‹Ú@4ß9‰W"Íà„ùY ‘¤r®¸°á‚2ø~ ¦‚ëöH®³q§²‡žÌÄzÖöýÂ3Ot¨ ހ߱'šÒiκ½/8uxR(„9ŠøoIamÓéAæLÒ3¦lÜÂ{Ö±²rѲ§¨6ôºâ%|ïà2}º=Ó<ÚEõ”I"Â(Yä­‘­Êà˜Ä“éŠþL÷0©©Ž_RS )¸<.»\›(_×Ñ(:OGÕtõ¤£šâ{,´(5‚ÜZW 5^g.!ôzp7>Mª0ä§Y®vvW™uí«Ìi>™A°f€²·”†’Gá Óßñ‘XÎ^Æ “S˜r§® ÜüÎ-YkADõkÛ-½Ê¸'âÞeŒïYKÆg9J·å¤3©óºé”.B*8¾áã·Ï'ûý|šá¡PÌh¬-üª-—Ó³Íõ$ïn_ÉÐ¥?C°ý”ž Æw/â'Éß<ÌÍ¡³ÍÌØŒÝæ:Žc|gWÏňãçä ¸C’R`FN§ÒþG­ÿ ÿ? endstream endobj 104 0 obj << /Length 1928 /Filter /FlateDecode >> stream xÚµXmsÔ6þž_qßêK9aYòf 4 Ú0`:Š­ã >û°| ™Nÿ{wµòÙNÜBúáÆ«•¼Ú]=ûh}–·ñp–²4 ¢Ùr5ãAÀä,"–¤b¶Ìgo¼WóDxº)J5ç^;_p¯¡™/„ž`)PÞI5¯ÕM¥JCªg t±·SåüÝòÉíGÂlΑÌ|ÚF‚eß÷½‡Ï>9}Lï?|~úêøtyòüô />pxßñ½«‚q?že›ƒ7ïüYSOf>i2»´ 73Å,©œüzðcÁ0f)˜àÑ,J&ELîܾ=_„AèUu®·‹ûåÚl1ô·~èÃÓdað)=§>ó@Hˆ=…Ýœ³4 ÉZoWn;+‹ûäKµú¨ÊOõçõ¸€1†Ów1%¡¿÷EU9 »*× ‰Y}¡sÃ×±ŸÙZ¡Ùê½6SÞ}C¬a'òûÆj2ã"ð^3ÀKbÇ×EY":Rï±U7iôÖ²Ò·` ¹§€Ò÷ôbRW´¤X‘¶]ëþÆ´¤uîÑL¦vF;#ŠT•¾¤qUϰs®µšæ[õrh˜Þ–*sºzÕÏ QdÃsÃ8 éíZ¡w`^8é²(¡þJìठœ…up.£|õP2 …íjîþDÒcË´[0†Ú·DÁè ü©;}¦Êr﨓²ºitÖ–W8 à ÝÛÀD,x°@c exvk¨eó…”Ò;*-»´Å%²puÇ1˰ §`Sn Æ÷&KÅÁPøåò{X¡çw4p‹ÆÝ¾7æ§v*·]•àÃJé¢ã÷NqÕ˧Oï’þˆâf¡g6åæ;d‘Äÿ”‰¯ä‹å7<ìð ÜšFôÎwïݪº¡§rKëF“”ï6[,Kž½p ŸÝŠŒåÀ²¨Þ“’*´.ºëÁ,ð Ç;÷¦-î¡¥ü¢0꼜$ Ë8©„:jI 4œ~]£íËŠ†…{RÅ‚pøƒ!A“o¸š˜Ò­tlÒöZ³kôÞ’q¢Uwöºjo±.r³©#>ªj°Ó`6O JÛnˆJ àœ$ A îJ¦Î h)ìL¦,O£¸©¥ûœpEâ+ñºÈÛµÓ»µ¡ÛÂ9ezÛžíÎS¾¶Ö¿év×TÇÀÃÆÂ ð.×q }¸Šœsx‹§ÂÔû‘ MÉ"yOÔn…åOÐ7v÷>®¶—[{÷th"S7“ö‚ƒ§²³WظM¦þ´¦{Nôa_‹fsòQ»!u}«º, bnjsxO€ ðÿѰo#g,þÎ1ŒðºsûÈ:´‚6¶`Ì)K$™?É¡ô´ÅêŠÊ2†r†–öb'CEV*cˆ÷®ñ dO@K)·GaVo6ö|ÁF£?YOvÞhÛö¶4W¸ìQŸ ¼½ÁÃoÜÌÚFoìL²©ìñˆ|™ö¸xÂg? ºe64Úâ²+h<üÆ ¹VØSPnpQÑ® 8‹ ŒbŒŸGˆ,K”Idñ÷ƒW¶ß A@cEÛ-Ýï×·8$<€iÛÀ›ƒÄ%!ÐÛVÙŽl" B²˜ó.>»ÉD“}3³ÑíÚ¡}WàØM㱌ä Å'«/ÚÆò½ii!BÎx(Æô ëjÒ¨ÄO¢ýéÞ¢Ó8ßµ$|À,ïŒ)‡™ŽS@DHŠ•Í|1¸è”q‹-(îLzÍĸD/€È©:)ÙVÄB´DÇr}²:ôîÚÇù—F7nêb·íKw|{sŸÉ0oû‹£-u}P=$uÆ(‚¶Še8´/«XöÝšž}¹a%¢FåÀ/E]áí‚ã¬'i"¿Ú§3„¥m—AÏ«ÝîÓ˜‚n—ùrX·ÿ }åº*‘„œ„ã*üÇsÉGÔ-9¦ËÞ|0qNWƒ•· ]ýEnKUjÂyüjˆxÏ&Ê´gÏŸ/Ç=_éxü1×u2Q€ä•…'îªUw‘¢ÚuLÆØÙý7±@4½FJ­ Ì)–N˜B±§…Â{øã¡ƒ©wæW•ÚÙ™ý\6S”*pûÓY„~ص˜¡ôtA- ÊýER±‚îz/HZ{3„]‘‚¢†¾,Œ¼H­YK:Ìú~9}4IŸEa|- ôÅËq>H…'e{ ·ÌºÏÚé鮘—,Ü3.ÿ‹ã¯â0´ÞÐSу._t,îÚ9rs÷4e"‘ÿyw× Ð¥qÉÀ~¹»äÒ˜;yæ®ëz7YÏ^H¾âþ‘Q4 ê v¥¡¤bøÞ ãkÝž`ǾîK,Söc¦íx¥+Éþ«ìOi× ý)ÃÂ.2[äÂMeôoB“XÜÚ·Æï»¤ m¹«í¯¯åõ= _×^vÓ4•¦!pʨÒmYLk° ï‚Üu:ìڛ훰acŽ×l{ímˆŠº^˜þÔ¼t¶$XA¼ÀwÀdš’I÷?æß~¹sÖ endstream endobj 109 0 obj << /Length 2034 /Filter /FlateDecode >> stream xÚXY“ã¶~Ÿ_¡Ú'Nj‘ÅcSI•g¼ë¬+ÞÚx”}±][’ó2ÑοO7º!R#&ë'F£Ï Þïn6ïƒí*i$£Õn¿ ¤á*–‘HRµÚå«_¼Ï·‰òLW”ú6ð†Ûuà50èn×J…žiáPyê[™xƒéj]öDúI-öF]Þþ¶ûqó^ù³£”‰(NV>³ɾï{»w»À 7ïv7ÜÀᯂ³jJ~¼Êª›_~óW9,ý¸ò…J“ÕÉ2V+ÅB¨\=Þüëæm”É*… #9%‰U<\žþÊ3þ LqÒ†÷蕼 ÓÔ3× v7èg4ÙtÏ…7xaOߣå`âÐÐîSW †HšWL?ÐZoxe8òàþß?<ºµl(šúòˇ«SاfÛ•î^Ð84'DºÝ’9•¶ÑƒH ·,1¶´úaÀxÆ^aãyEÕ‚Äìh¯£EøÕyÎ0„÷웎h{]”cgzfåï Ř²$fGíÇ,3=O~õ·þYŠùª«¶4ÄîÎÍPÈÑØÏï¬ÁQKÛ)ôPG"•WÁIú`(± Ná¬é:ðsùBÓ¡+Ó™” .]žÚY¿“ÙaDçÛÚ#°êØŒeNÔ'Ôõ…è–­˜gë r-…–šÓ –œpÃÇ_}}å*“³´•2Á6vUöåIç É-¡8¢3SQŸÅPë t3w0ÛBšÖ¬}Qg嘛…s×ü³•á¥×Ñà˜­Üzc5‚9$"ø¡Sãï b)Òø¬h°`J"à°¹!äLá(“Q×’#%¢ÔmÌšª-J³ ^ÁP*Ç×tË:J_:óÕdãðmQý`ZÒ’?ôtÛv Ô¬Œàc­7%¹8P"¥× IZ9Ÿ:Óꮨ $ÞRiÀ÷籦Áî6 )?—1°4T¯0ÎjEµ©¦šV\w¡×êž)/˜ÍHäÊBJ?ÐRQ÷Ã$Äf. öîB)Ë3ÿDšÃJ«¹Ž·€Ó¿]¦¿ëã x¯z SI)uŽáåy3V°mÚqèïh#a-¶î†öífÓ[öL4Ýa©Øñü8õ>áÝu¦|ûÜ‚Û~§{9oß5ñ>|B¯~÷‘èžÔë(<éÙ»°V0©eɨfêÏ\ k™Å1Ë켋B޾`t‚Ì'#b ßôcî<Ö:TœÅ*ü¿Ö½ËQ‘RRey^6)"qû`Ç@ GpL<€«u†’Ðzü~F)ßÓ„&nסŸx0+öȃÎè¼â1â.~]4{çÝÉ“È çšj÷uZlUç–›KÝŠÏçªKÉäiíQ×”åT{6éf5G³ï»â™M÷ít· ìŒb/ÇVßžºÃ¢Äöƒ©iRð÷Ó»Ÿÿ)ˆñ;LZs= V…‘x0S7©´“2ðñ ŸPRüÏÀo¦ey§cA×/­ab.d š=¿È¹Ör3À`rJµ#öLeK“¦~0ã:¼ë%yΦ`kÞXw˜î±Õ endstream endobj 115 0 obj << /Length 1581 /Filter /FlateDecode >> stream xÚWßoÛ6~Ï_!}ˆ•DI–:¬@›¤EÛ¤í¯{h‹€‘h[¨,¹¢'ö¿ï~PŽœi[_,òx<ò¾;~w~¹8zú*ˆLdI˜8‹¥„¡ˆœy˜ˆ4“΢p¾¸Ÿg©tu[Vj¸ÝÌ ÜíÌ“2r¥È‚‡Ò}SÏÂÔít[«Ê°èRlîöªš}[¼}úJú££¤Ÿˆdž:>ƒeß÷ÝÅùÕâÍû׸áè|qôã( ß öW“"ðçN¾9úòÍw XzëøBf©³#Å#“¹aT9WG¿½De8öQ†"S'ISÉ9ÿäJWKïùŸ·zØý5óâ0O=rÇOpÌZæ{¹ýêÇþñgÂ¥«55Nª{œÅ‡éŽA5ø…8\°éÜÂýa ØÅ‘Û­ÑŽæÉF¸÷8‹ ÿ-]³„QSwkÕ±zê$º™y°Í1ºL·M¿Z³ŠjWýFsìŒ]ol¸Æ¨…  –îÕ7›mYév­(2‰EUÖ‚Lı×w:ï;=aKBŽø{['¨p%.ü‘Å1¯ukÍI·lªªAwve½â,U­]Ûª¶+ó¾R-%½Ñ˾z6qEÿ0.·6Ôíõ’¬V&œ¸p‰ÌOàj±È"Þù‚OªJÓñ¨Yòµ¾ú23,Ä$ÂïCÈè¾Æè‚µ…[ôm¸ ‹vk]óˆÃŽ‹ ¼ýå@ZÜ–ª„çú?ެ{¥»ñe#78¼{Ye®:{y›4Ò¬O×›!z]ÙÔ,œà$°b°e›L+uñ¼¹àŒ.;Ø+ä-2^wj³­4OˆÄÖvò8]@´CÒjúªà©ÙrHòryo °gAfñ¼¥VÿèËV›á$°´Cë Aj^Ïèq¼¤`ÎsZß Gwì¼ü§ó֥طʌ„¼Eg…>r÷áIŽ-9ÉiÛ¯ÏùûåØ;»º|qqq}zñáô ½³×/pÃâüìúôÃååùûÅñ·“)8Û,“Š#ΔÀý´RË@È9<~™‰tHÌOz˜ŽÂXPÐÌ ŽwÝì£`ãß²RÙY+TfÃ1gƒt«ÊJ O,3ƒÎ~S³Ñö0‚1”싆”04B‚¬W“¯Â”uÇDñ²-pSU³Îᔜ›#rÔ? rOUG@§¤Da%;ðL Ë´€ÒáAkä^Ý›NoNñ!²æFafßó¤n:ÞtC‡ižŒÂ?ùú[­ÅDÞ¦äQöVM½â[þTò¾A# eɼŒ3Äš¾äw$]C °"ArzÂ*ÖqžØÂapmO¨Â0Y[m_}3²@󵃾â y}×-’ÞÊLy MmœÈ¡* ÆäÀÓthpÔ‹=¶g©Èd2lߨïxã,Ü (§Ú¸Z¯lØI‘§.ÖX—ñ á[”£TðìfH\ÑKÕW­Ð~}{zè6±@6B\fXðMD9ÔTXÞ¶ œ°±ÊL‹\A½€Û]i4¯.ˆ55wY4îG@S±þÏDýÓD–Úãþ£µøƒàÁ&¥(UœQ„p¦¬aF ¡ø˜7ÍÒ!7!Hÿãù§ ^ÙXfê+"^¦þWk­-?¹ÝºÌ‹5+Ý3.S1QÉ=¶Cë»o󭪧º‰¡G8è&¶h +÷ÞN~¯Ë;LÞgÏ>¶MŸ™¬¬Þ”É„Ð6ûVÁ¢~¯UÛGM2U‚[jÓÊâq ϲ¶žÁdÜÈá…"FÁ<Iˆÿ&D”Z øßù7©¸êó endstream endobj 120 0 obj << /Length 1877 /Filter /FlateDecode >> stream xÚ•XK“Û6¾Ï¯àm©ª!D|É9Ùk{Ö)ÛåØŠ·6JA"$1æ+$8ùßžºAIcNmrR£ 4_ènèÅúfùš'ÞŠ­Ò(õÖ;G‹½,JY¾Þºð~ö?/r᫾¬ä‚ûzp¿¡_Bľ`+žQøošE”ûZõ¬T½“ ËüQV‹_×ß/_‹ðb«(ÏY.„â6`…‡aè¿|õâÇ»»7ïïÌ’›Wë›?n8Ì =>9'3o[ßüükèðé{/db•{G;±öDš±¤ÊûtóÃÍ sJ‘^žRdLĉ—‚ ±ÈÐ_"¢›Wˆ‰;'ÿ{P -Ëü­9ìAÙŸ/e³G­>(Þ=ÿæõ«OëÛGz­Ò±¬*”6²ß¡Ô’ñ±QÝ"Ó  ÞjUЦ­Ud¬lÎÖÁqp2àœ­’äqàtÛc@t¯[qûŸZTÕò‹‰‘ÂÑ0ö$iúŽ_†\Ú8ŸÜ|?Yÿ2ô†í¨‡²pöêÒäÃePD:àð%?&ï[ƒh’úÒšdþÛ¼Eæ=à§á4hUøÙ~ ‘5“û´êƒ9ˆê«AÞâÊ;lbε“c¥À„ }(œS’áF©Â† t; 98l|qÁ3–'+w† 8¨ª›9ià&^E¶íti¹"RŠSj¢OѾEl ª¦¡_ ôjß«a ;‰e&ðذ#‰Üá`ÞVÒF[…ƒ²¼J‘ýq0Wà’ƒ)zºídóŒÎ]^þGæQÂV¡8Ïh£ÄYÇÁ‡¶xöÌDëƒ Îv¥+sš{75Š"àÄD3œaˆŽ‘Ú_B!TOjó×£ì Tv¯üÂn¯pŠÕ|Õ›A0ÌüŠVüGêåk{‹¶—Ë+Ì“í0‡—sà[ƘÜ'&Ât‹„²Z#‚cä9€2Îòpº1·x‡²¢;ùRmJÙ,ÜŒ%=.ßÂÅ8Cf“y‰ŽãèiGyÎYëéÓÞ Á â¸³¹A@VàYúϳÃDZilzŽVùç͸–Ž!0P9šìŒ3‡vì·jÀ!.Èü¡­jÞ"–O0$>dÃHÒër;V²¯Ns™°‹+khå€]î³ò¥M\ÀõÍŽƒ%#|ézJK࿲³%wÛ+9Ki2j’‚ù…cPÙêòÞ&¸ê„Ÿxz+`·<¦›…ø6\¥lÎëµÍàéʯ•>P%2(ôÛ~(Zª„¡½ ¨´¿ Aˆh¢"·š‚®ƒ-”¹¿m^ÆY65Áïùö ¥ ìíÕG£lǪ˜s¾WŒ¥«mª(5zJ…éÛ• –ç™cÑRéírP[ë]_êÓ²*ëRlÛ6» r³0ÎÝro³¤ÞˆâÙjâ{”{<†®$0£ÅËc(‡q ­X~î‘øã ‡ÖÈÕ.…ƒ‹„eiêJK¡6ã~ÆI3ú¦X\õ6‰¹Hô#iæì¦vjSí“•µ ÃÑ{œ`ZA”NÐÆ]_Ö²?áš„nÔ(O8áªÌ?uXtZXÉ-Øœ’“n§}ç¢Þ‚s¨ÿ­({ÊzÌô , +ZJkèÁÀžvA¡4…k²ÄàÿüÒ.à™;&÷#R cÝY]ŠWŠÛoêªQ³ïew Y¶ÝÑ™‰÷åWr]\ÕŽˆEiâèxк{¶\GfÁ"ÖšÕý~9Gf1~Nè…;T½À‚nš=óøº”ÕÒvJi8uͶ¤ŠŒ“ Oó· `r(LÈò躵ÁÉ®{段ÐjªPn¯È¯ÊFáÌ–œtÑŽ4I$I¦Ï™aІÚpËHÇÅuw¼»xq¿ÁÚƒæwêw‘Ä>j¿bÛØ?˜5²îLªžì’Rƒ/Ë3q¿é‹‚µáŠ•Züýs)™Óµ ½½±ýò³n»ßvmk)ûT÷ôh›ÿ™œksÀ¹´/ ê/Á†fcÛ:ÆfeL+³s…5ƒ®W;åÞŽ@är7õ¤@‹Pnº’ó“"õ©WCó/Új¯ðjäa+§;Üìo²nûsHwcE Q©é!•{OðºM12/^´hË’ëüŠS#kðÜìïKuÄþP-̃ˆ–üt÷qÁ9÷?Ã|{Ì]Ý0g!O]ݯ÷ºfØ¡ìèæ*Ö(½üºïaGèhŸm=;躚»ÓФ‰óûƒÑ=ÎW 2Ú5povĹ*@_š³:R|‡Zz"h­ˆå÷ÓѨêUJ;ÜÝó8JƾCÕ .V_:İ’Ž±»T≰=•Ç)Œ® üƒL¾6‘ÇUyâj0—ƒàr9ˆøÅ”ÂóOkÖæ®L†°]q]_1bÝñø\T•½’ðEÝcÌO8„«$‰ÿ»Ç­öm0Ûí-uíƒ^ë†þ"xÞP®z0IʰÊ&)g9ƒ6%€¬ŸFôÚâÜý_ó·y endstream endobj 128 0 obj << /Length 1913 /Filter /FlateDecode >> stream xÚ¥koÛFò»á|¡Ã}ðe$Å9‰“sÎMÒDÉ¡p c%®-¢©#©Èî!ÿ½3;KJ¤)÷€†5œ×Îk÷Õìèù[8‰—„‰.Ì÷}÷Íù«¯ïÞ]|x‡[ŽÎgGÿ=b@ã;¬SNxÌœÅêèêÚwRXzïøžHbgkWŽ#”;_Ž~9z…V ¾o¥Œ½@N*H‘Îg—_f“iÀ׿Oü[´uîû„y¡ÙOýOù?P9gxœ'Δ1/ âÂN‰èço¾^žwÌŸsdg˜I`†qÌyÇ3þ|·)׺äD}…ÄŸ®Êü;åVì·³Ï;™*ŠÉŒä³N$ç?ügÚ¼ôïסôÉ[a”¡*2qËMsƒ¨m–jÚsõñš€ÿ\|>7ªzƒŸ¶yuöåâõ›rùõSçÚº˜3™´êi.÷Ôk–¸1«Q½ôku7eE£ïtE´¿oÓ—=D¥Š;ܪ_^ vê_S$ö‚~Ê} cbÖ‹#ö³%*bß½-ó¼ÄÐÞfÈ QõfµRUö‡®é»iiÕ|2…€/1ê¿ã‹×÷jµÎíGºY­OLÐh"WeÕ.ëFe9Áea÷«r³´¿ùBê<5N÷­ÃCÒ:+(óH#j½h2ò•´ÓÖ¯eÀ1‹iÿ1žØ1%ðJ³…jÐHü4,XfÿºRÕÍ\"¯Z)ow¤”𽬠"Oø²Mx ÕÇgÁb/”aK“ÕO1„*%w´åš¯Gr<Ó %‚Ôuˬ­UÄ~S¤-8.)­Þ2±¹ýX–`žØÉ:!ŽÛefÏ䯡ǡVõò¤;¶Me }\8®R1°ñlÔxéq6eZãKŠ/‚"é÷ËäH±Pz —ý€ú6aŒ¹gŸIZV÷Tºguó¡4q™êÔÚ¢´ž-;[×üCìTšVº¶XŒGZméŠÒø Õ£Áob{FEqkú‹£#/’IK #9‚IOÄÿ~:À¤“b-[iUtÆ™F‘4% f%(^(t“gµ]Ýâq«¡£rÕ®¯¬O2¬+ ˆ;µ«;Î<8Ò‹ÃÁ™›Ö‚U${U$Ž,#\èÑB‹®tÔ©¥. ™g…&ˆsK^Ðwçü¨ËMµ°0“ëB­,ÿcul2„„Ô•%äh­U™U(¨õq'¸Ò*=!ðøã›yØ,í¢*RK¥Ôñ@šåhHRkö<¯ ø;ÿŸ¸·ìSÕ({ ¦\S%ÐÏ–>%U •õ¨rЇÿB­-Ö±ÔLË~Æâˆ¿ó¬©ÇSgœ7¥:í¨½!'­z}S¥»Pµnð“»¥ï“ t¡ã«y>^9`B5¡Ò)ÓÇÇ Ô]M»&`ˆ€_”v‘¦À“@@ ÖŒR°Ô³…d›Ù›YaÖ6À™˜¶˜0;Á/uOc—ÝQ÷Âö'eýG²Þ4c¸@Š·sLÈvs `É.†ÃTÈÚi¦&r8%YóáåjUZA¦2á†Ö­˜Î5QÓ@ø8Ä=”Žïº*§c9ŸnÚæçÜŽ4‡[b-1욯ia©>=MÑ· 7©f@}\êcæEA× VºYZO‰&èýŽ*™°x0™N,“f\î¿2Ňà‚ãc@âÃ|Ë/‘ûãm$¬ŸEÄM‘­ 9'Ïߙ؂o“Æ]-ÝëVè¨ywJ•ÝM….Â’—…Ešó‚m¥°ØV ÊŽ,O-ÿ½J«Ël:–vÛ!ÜÃeçŒÆ'úÀÊ´ÇÆsÄ£u…=fÑ» 'ß tÿÆ`Bú×Ð> stream xÚ­YmoÛ¶þž_al&5Kê]ÅîpÓ&-²eÙnãº~P,:&®,y’Ü$úßï9<-ÙLã^¬-jŠ<"ÏËsÞ¨—ó“ç¯E4ÉXûñd¾œßgá$ñc–fÁd^L>xï§iàÉF•ùTxÝt&¼Ít¡°LÄ8 ¼‹jê§^'›*/[šú5‡¹ÄÛæåôãüçç¯>8ÊOS–Á„Ó1°‹àœ{gç/ß½ysqõ_99ŸŸüu"€†O„e.`‚'“ÅúäÃG>)`éç gA–Nî4ázÄ óaTN®OþsòòPÊ0a'1° 10_Ià:õA„ûYÖU¾6ÓõÒ,¯TkÖêé D. ÁéõÜP ÐXL<³ö'x^ÞáBŽjz0[¨Š~ùFu 7 l:‹2AÊÊýÓe+Q5 ÞL–E±¿¨›F¶ÍQ]ð›^¡¹èÊ| ½®¦YkÑú–&¤6S§:%[šA~—uCïÉû|½)¥±¡?´!X$KzþúÛÙ»Ës"é;™Ÿe=YÜn%RØÉïiæ§×¿86ò9â­'Be=#o¶1^w«™V<%LDÉXK²1ÐÌIVf_#—VQSøÛk*/»º¡)«|x\3"å,M­ÌWçóË À‡C70ôÃ't“1€tOóòôúâÕÙüß]ªŽ|Pµjˆ•Ÿ ¨fHP9)óCãé§ÓÀ÷Š`¤ÑÐ: â‘Fºl² |j&"ÆÁØfÇY¥Þ ôTÈhZ­µŠa.·Áƒ>(JÌA01t-˜×nÓk¹®›‡izè$"õÞµr¹-‰ˆ¬ThU©ê–æïT·¢ÜÞá:…¼ÙÞÞÊÆ©)+Ö@Q—yÛ‘Bd¡Ì¨Båm×øÿV’lŽTÒoK„.'áq‚¬Í»bhÚ€EšöGN–„r²‚?Žm ¶‹0ê©~r0)8‹ëeuãØÔ—ÄÙ·ñò½cŸ@ Ã'™±Ø×îžzw+Ù¸¼àöÔF6XÊ홪ÝÓ¾Žº`HøÿFƒP6´€ õÓÌC4 ìøPj(ಆEp®0 Æ ÓÁ7ÞÚ [-h‚ò Ž4è€#€;„ÎHš¤ÉU‰xv„†0bIöÒ|ï7eÜ·ª*Ô"ïdÛ.Çg[Ѹ·Ê ‘Qd ýˆ‚ʂƭªr·•_P“8‹Oz 9øx#%Šízƒ£TÕ»•Z ÒW†L'¿ 0[bþ©µÌ«–†4Uo |ØÑÈ?yVr-©(¡YŒúwÓ©µúœwª®\ñ`“·}"ÃÐ{sö’RÅ"¯(ìßá¦y׳‹k6% 9ŸÑ°•=Fƒ¡Å¢ðg r¦ƒ+Üš‚ŒðX‡13ú6¸#V™¢qȺ®·ÍÂDqÔMiƘp`z¥N„òbVÀ}°a°‹Y#xÒØÊú÷ý=úäÇ!¡ƒ¨@Þ»¹Þÿ¼û‡B{ìèl’ÇTjð\‚$²ëÐoi9âµ—z^[—&Ü ×÷#'É¢<†¯tŒÍ^hJ ÍŽªÌƒ3º 9^§9ýjÞ9‰†@Œ#S¡Â:Î6툄àlw‘–ì"~ïgC函zaS?Ö„£"®¢€fAùù›Hè€GøÇ8ËÀÇjÎ]rˆ<ɨÐ$G¬ÉIk]ëAÀp×D)‹Ó=·ú¢!GÙè¤^+çCGzÊõªFcßµÄ <}šF±——[ó¨+ áº­€~0ëXÆ¢‰1jÙ“W³«w——G×0gy—›ê%z ùŽõÿas2àÕÔ+Ýã|šîú9±^ºß”jÑ×LÅ€ÚMx¦mÒMPè}÷ï¢û¿©¿#ÂAþU¦ù^ÝêëVµæXÔ6%rÄ]}ÚvW½Hgó! &ÎïYÊÚ©eöüÎ.ÐT ~ 0ÚïaJï$Þ„²9L¿¬1m)â> @“²@H¤ )È[ÑhÓ(jqZ»Bƒ;Uh׃a½Ü[ƒ$¿f.=έäzdiœL„ç}òûk+uq°ƒ·~#ÊoM:Õé3oòE·kËz—í9ºÞ\°j¨–uY¯zá{zo5QdbïB‡®7¬U·•,˜+BéíF‡ÿСFò¢ÞÞ”„*fò^k(h*£[SmÌnšU‘"ÐZçd¹{B}±‘.6pûHEžk+©ýØho!v$§ÛHëÛªUŸ¶õóÇ H[qüžm´öX§#|è1vUäc„Ìßur½¾-Ø%¯õ Ýz xw á1ãb/‡\™Ë±ƒ›‚â¦ÚÚ¥¯ 1ÅÐJ#56ì:ŽL zcÉœw³ˆsR#&‚¾¿Wmwl2~÷9û—7&¤4½C*;åPtÛ²âýé[Wé‘1ÎmŨºG mªÔAHV‘—7*¿ÁŠZ)J%¼Ìb1@é ÷šÆ–žw±‘žé†¼÷¥–žL§$;öBtçÉÇ÷šÜ3—Šr¡pƒMª +~ÝBaªNcH IfwÓ :"ó “€&ßž¿v]ŠE,JmA9à'ô}`¼,iDyú; õ·.£c³Œúí>\¾ÿèÂKÄ„ìßzŒ.`<µ>÷áíû`Û¬öu qšÓd)—ÈöºÄGÝ©Âo£nWmÍøÌÀ#CgÌŒR <@«À›2_‰@5(Gˆ¤Ó³Ø ÞÈ¥lšþ®6-³ËÏ\™ÚÜçŽà-^ø/üTùAëÂ×øzÇ÷™¿ð£,%’eijŸhü·ôÃ/4¼CRH•Þ¢ü/ÍhƒÑ+3»; 8l™û2ãý– ž³ÛU¤£]à ª °;_˜/®~çºå$5_.ð#ãÞ­¬d“—Ïp‹ÌÜ^"ð® Oqº’>„”ð. ] : :´È&‚µìVÆôĪ\]°œÚwÞº*.°¸ž›ã˜$:â)ì¯Öp0td-\_÷ê꧈¼ÃH ÏÆá ÊVßÙ îèCÜ ³HCJÓ5Ó0žíj›ýrœ×¹uŠP#›Êo]½˜Àbj \>~ëÚ}*rƒ9<âcćÝÕ©¾dÓA˜~JEWËÜ41‡vØÀøêüòòâ þ9¿@ÂN£ƒjŽ8.Fëšfo‰Eu®f\ðdx}\oÄWa7’Õ|œêUÛ`‰“ÞZW²zÖöÃxÏ*¹èdчÍß![!$ a¿Uò¾û*[ßüÍJ–OÇï¸/hÛ§ó0d‰ŸŒ°t­ÖªÌ›r›fφâû1iÕ÷K¦ÛÕQ^xbÊþ>z[Êö0¦ï>…Ýhg5U1ŒwëOA#dq=¦1[ÿD,„×0l¦X(Aý§áÿzp¥ò endstream endobj 137 0 obj << /Length 1502 /Filter /FlateDecode >> stream xÚ•WmoÛ8 þÞ_ܾ8À¬Ú–_{××ÛVlÀ–+p؆@±•Ä«c{²Ü4ÿþHQNâÖÛpýPSEñå!©Ü,..ßúÑ,cYijÅzæ gI³4ã³E1ûìÜÍSîHUVbî;zîúN„š»œ‡g™#Éwõ‹Üæ¼+wl °¸|’z·¡Œ;‡¹‰(-öe·%Ê„6;$;‰EHf"-‰ 6Ä/ò†}Q7à’]?7R€ÿÂà¥6HÏÌ ¼¡~peÂò9·à¢j÷–¯©¡¤¸5¶:PAº4íåû žLàZ]65jÖ$d«œ^“À0tÞœ)’b×VÒ¶¤à¼ûy,ŒR¨lÎBh'Æz}©—¢Ú/‹ 3y0…ÑÑ«ç­ÁRÓm´mß‘Á%õRCŽ™`€cXÁÝ“häÍn¡»ú•Ѷ™1vù@a0ýZ-We½,V›ÁôVÉuùH«;ò‹ê0H<º¢ëÊMMë¾.¿÷ò™ãÇ»GéÎs+ø¡(‘ÍêÛÒ,|çÎÃH›o¡``ÿÙ¡ã®i¢̶×ìÁª=%äÀ¦Âx8”Æáÿd ƒè¿$Êg‹á®'âšÄ,áÑ0ž¨²žßd,ŒãAÊN Ô=dNÉ(k ãÐjÓﰘɨ;6q³›E,É2òÀ ôÿ‡¹(=ÆØ‹ôai“NÛ7Žà@ÍOòspÐè¡Ô!=Ô¼90F,È|kULVY@zMÏüHîñ¡ygy‚<=FÈSÿ_Pið„‡Ì‰Ë‡J/¡ÜÚ²’ ›”ïPhÝ‘Í?ðBîÚF eÍÇAk°Ý6emãŒM¿ˆ¢0+üÚçvV×Þãjmò±–kÚYÓ2‹Ü$Í ?÷úˆ›»sܰ¼m¯b?"ç¦Nâ¦&Ҳ鮮ºC›Ô Ê—.ÊMÆË!~޲_uIÛ·Nï>̪¥zhƒôÈD+JS·ø¼”C_—y?Ì~V‹æÓÒ¸¡n«mÝP¤ßûRÉbrö.ŒQøIOO¦”&~éÓÑ2/¿x<̉)‹¡ÑG™cn†â‡ÿô22£¤öÛÒ¼L¶´$ZÔYŒn¨ib’–^(Õ®ßÁóâ@<Ý {<¬‹A»ÐS݉ÂNØôøgéá!KcèkL$0•òüM©IX¥^M¨“¼8$ª²–ÇyÞHa*i·Š~×v«©qè&‹ýlÜ<÷Bç[*ƒ?;ý±)äBèª[B†ô_µ¾]U××g>Œ‘ Ód¬ñ °§UåK §±·¦g ^51´ÏUZð·¶Ô`^;UP/lÛRWD䢪Ύ¸¯ 0fZÞšªóNýÝžU):D•é” }këßN³ÖL•_2¨\[“Èi‡öÜÒèZº€¤Ž¬5­ýæêÚkúÂÔ˜öã€eðcÓ…y¦6‡~8üÆüQnåQ endstream endobj 142 0 obj << /Length 1771 /Filter /FlateDecode >> stream xÚ}XÝoÛ6Ï_!ì%ò3õé§!m“¢Åt«—nh‹€–h[,¹’ÜÔö¿ïŽw”-GéCà#y<ÞýîSy1?»¼ñ#g&f±ŒùÒñ¥¡“ÈX¤³À™çÎ'÷n’®nŠRM|·›L}·¢™Lƒ t1óc$÷M5‘©Ûé¦ReK[ïì%îN•“/ó·—7wô””žðRÇ£Wìyž{õêÕ›Û×týŠ~n¯?qs}…ºÌÿúóå]ÏϾù Ásü^ó@ø^âd›³O_<'‡£·Ž'‚Yê<Æĉ@•·³?Î^<Aœ¦" RîãZW¨ÂÌ}ýêkUvíСçí-ýîZ½Ü•Dw5ïUˆ\® :ßm;Uå̲V¥4 •!˜]£2Þz,J™Õ›M]•{ZµëY°jêûbE¤7ÉKCÐP7ª«ÑiàrWe]QW-.&S ;ƒ¤±N4©±¦k…qæwܩ͕L0ˆ¹ë%{Yžx9‰ëæïE h¶èÉ> –ÈúC<ÄdÍb÷Ÿ ¾¹#Nƒ"0•<(£ ðö~[dª$Ü·ÕšBXÑzÙ¨¶GßvºÊìªÞèn]T+Z–ŃÁhÄVßa”:À&Ò„³G1æƒÃg/òàÏ0Ä ñ˜~¹.0ZʼÑÕ({4`¿Â˜òÝ[ý£û·Ê2½ý)ÇóúE».odêø¡ÂX"S‹ABI¹íçv›ÜŽÎmXcnÏü>·OÂÃ3 &Ô׺s{W>r¾ ÄD™ÓrobuG‹¼&SF®Ê™‹ ÒİԪÛ5ú7c¶/…ŸœøÔÇ{nŠRD,v+ÈKÚ„ n˜­h«sÖT•VùÞÀk®´¬Vü\?*ÎmÃq0“í:·rÉìæ¡Òº:D (9¨$+þNq ”\tÛeªµªV½öLÀñ}£WnÛËî²»¿þûêÝû߯³ºÙ¨îâZ”á Å‘3›ãóësŒ†§Î#YÀld”ÙŠøŒÍá Øœ7€´”Ò]A oTC ª\ªZé7ÐL.½š*­M96šË0tK*lõ± Þøk@0/¼cª ñ“ï ¤®è‘šU¹Ãâ„M³^½G瘺_ž³*m“]Þ½GªiõkR[ìñÎ…ºk˜´x9ñ@û¨Ùð̆Óv·Ý’ MÇç¤=œAS*‰ú°o;½ÁfÚw÷zEG%@¶S+¾bš YÛç³Õ‹aÖèéhÁ©ò)„ª.#ìeD¥GÃt'l²AàÝPzîËzkª7‘1 Cm·M½m ¨ztÒìL¥\ŒÇ#ê½ø‹p³ÃÐNz\EŠÞ Å@^,÷ƒ]xmuóµOŽÍÞYG™…æX¹j9•¹3Q ¶UÂ2C€æÜ¥lµ*ìE®wȺeu+Ö­ž®[[NÂÐ?G\d0©áŠíüò$áÿ5Úã™-ÿ‰mIצÓ\Cõû…Î –¡™ŒÎË’ö¼…Z”£Ø/U³„Ág×aK\ÉÔ®Pô3Ю†&ŠÜ¯÷yѰ¢½Š—¿Š®±—?{AX2ý¸.úéæð -Ž=õµ)*=t@?H`J.¹–Úª¹…﫲® L›‚cxCÉù m.m è®ÕY?a™t7|4¯W~?*ãuE—LQ[˜dXµ‚çûf q^'[Þ=æ0á@J5Dš1 æYÿxl<²Ÿ²¦Aðĉ¤Ó–Ê â›Çˆ&xƒ´´ý~&Òu½šP§s2‰L $!‹‡õVÁÓãSÌþ!Gÿ ÖcŒŒ Ë:2†Š¹ÀaÜ|¼ª¤ÍA÷À£ðˆÝ⊄ 4ƒdD`‡r Ë~x$U5ž—î|m5(6ÛR›ŠRL3?~ÄŽÄ¢gbìM¦^Ä>Õ Üᓬ/œÄ76²BOŽB¿o¶4‘á<‘´<˜Û#£ïLÄÑAÎzD L‰^Ü‹¡Ld—M½!° áŽþQ´ùV ZxvꧺK‹>\µfúHp!Œ"˜Ã!zø!Ð:èyÙÍÍ^Ò¬!§öˆýYÑÁ:È L‡ãú øJ ҞߦV¯ÒÓàBô›–F}Ó|‘7ϸ¾bÓYt:Lù“A5˜›Üˆ!.Wš>ô‘ÞÓ@ÝЊð@ª3¼Xg ¶Xϱ—´EÎ9ð³s(:–´(*Õ쉦 ¨Ì‡J··LAA¢,ZVl£“A`ÔÕKì.0Ü׋¯Â^Ʀ'E ]Ò;™Õjµ‚êEè%‘˜!xðô‘ýÄÿKÛx endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 797 /Length 1515 /Filter /FlateDecode >> stream xÚµXÛn7}߯˜Çæ…Ë!9¼F_$×@b¶Ü´5ü:Ba4 ÇÒ¿ï™]'±´’²^I€aR»‡ä™3Ãáp™, yK‘|¡B±[Ê‘Ø3š€'âˆ&ã/cüIå9—È þ2¹H.áIÁl^gô.“GOð$OXA(X<Ì$Öêz\å#Iv$žb´e‡F¨H 6' XÞa¹€õ½à7X†â1 haEQ†Q*âb™áðÞ¡aPw6¡õ AÄAÜN‰·®@Xæ½#Ðp>…*â}ÀChâD"%<—’ÁÆK †'°LÀePM!gL‹y ȰÑÂXç™]Śυ‹ˆyó¡¶wœ ^¦ð&€’˜ZXEd*˜'BQâc’ª`\ÂâE%É‚ñÆp#.eHáKQ-!¼‡(ðLà¨oðÄ©L6RðÀòúà+/ÀÌêx ”‚ºˆ1wˆNØÕ9ê â$dׯL(.¬n‚”Ìê'‹‰Y¥¯?âTuõá¦SôM@ @ZFP‰oÖÌ%ŠI'`õwDÀ1"N’åŠá3ÉP—gÊ6!+7Z8’t±‚‚ÜY :êþÀ %DLT˱T 9WT_Q}:ŸÌ©>¡_>Oïïç3ã^Ñë×Õ/Lç‡oG¯ÖÂ| stv>¹¼8¹>žœ]œ¯‡‡îéøâdDã7ï¯Öƒs  >;?EsþÛè\Ø0ˆŸF MFW [uO6F:]Ÿžn§œèð¤asHç£÷4N®/7 ô¤P¦“³«ÉåÙÑõJ…nà)K—TïouÀÁAUOþûwJõ»O«úx>{œÎ?c;(°ª/§Ÿç_î¦xÛ'o§ï?Í¿ÒŃˆNÅÝV˜à#ù ìiîgKþþÇŸ¯»ÜGã@³/Ÿ>Ý®E:£ù"ãÿn †¤fuØ'st‹ð·¾nȦ!õ»‡ùÝÕô‘n`âɘêÉôë#}Ÿm¥íØGK¶‹{‰íõál6Ç<7šƒ•Gh ±mRÛä¶)M#­%ұᙝª¯¾üõØü~s?û§ªæ§ ¾­­Ïêã§Jý&7r[È(Þh†JÁè#´õ°CÚ¼1wË‚‹A~÷θ&sd#q3 ¿{’Ådä=œº¦hþ+ÁÄ’6Ò{ !l \áR2£D Z›iä=Ðàl,Iõ&àA+n¤Á{àr0çŽ2Spâ "/Ù¡{Ñ ÖxìOÔ0FÆ ¼~Â#íGøC‹*ÁÆe-0À+lÞ, »éT|ßÄ»ˆÔÄ›l48ÖeÞï¶£:“øÔG™*ù[_÷Ö6Y8ºå,í°(r_!‘kN Õ8_1}‚ÿÑ¥ȼ (î¶ðöR”­¼;^XÄÔÛ ©£Ž‹bÿ…Jü°}ðûV! òOßñÊc…R\V(…a ¥Þ•RêTJ¸&ûÆKz®Ê¶±’¹£D¦D¶}•XD6±RPfÄ>ÀP .z?zAÉ’¥×"#²› »ä\r¥²ÏCy¨ÓʲÓrêå´––{;-wR-F/È?GzN&HÏ´üq4ÏT¶Úþ¥sQ*2L¿ûê·ˆlŽŸ€C%J¤YŠïd?e;¥¢yeÒÝA¡À¶s_ÓO0ƒ| Ÿuz:a ÚÄfb½l£ØxÜABf[ºÊ¤¡ÊäþÊä~eÔ  YY­€ú‚´¼œÀ_˜m÷¦> stream xÚmSMoÛ0 ½ûWè(,ëöìí´lk‘¢ëºÅÝEN¬4;“•ù÷%-g ¶\$Š"ÉGrVñHIÁŠLf¤\!%Kˆ–Ë EÊš<Ó_a®¨±M[…‚º0´Á†‘R U¬ŠŠÎ»PæÔÛUíàUß*Ðiº¯Ú𥼋o¿%5É4á>LÈœsúe¾(ÎgOåüûz_ËàO ÀŒñ7?Å×dµ ž_8©áëŽp¦ŠœFÃ-Q™f¤–,‚Á •9 SI&Ï•fyÎ¥Ï)ˆ+)üÃ'PÓ:ñ^寸jÛÊ™Áyù ë6vhúÎ+š‰’ Iz Ó”VÀè²|×¶ßN©Ëv¤)+òüÄÑÆ¹Ý‡8>ì :² #ëáÔ´oYÐö5¾’2Ÿ–'†&$’™b<ƒ»è>÷;D9Úæu3¶À]ržG’ íŸËÑåŒþƉh`"ÚkÅïÅ8 ÇÚXF /.FÈõÖ»!h»¶ÆxÍp­5 !xTÖ|‹LBD,wïWÕÍšÃîÎ6˽3cyÐ&!X‘¦¾²K) ]I€¼íGëf}ôŠ“Ñ¾«ÎøA—EBv¿`À·ƒûµ¿M¿äd—ÐÛp~òò½†“Á­éŒ……ûeÛ¬¼|߬L7\Í}âï> stream xÚ31Ô35R0P0Bc3cs…C®B.c46K$çr9yré‡+pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä00üÿÃÀøÿûÿÿ üÿÿÿÿÿýÿÿ@¸þÿÿ0üÿÿÿ?Ä`d=0s@f‚ÌÙ² d'Èn.WO®@.Æsud endstream endobj 159 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 160 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 161 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 162 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 163 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 164 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 168 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ3²Ô37T0P0W04S0²T02TH1ä*ä2 (˜B$’s¹œ<¹ôÃÒ\ú ¦\úž¾ %E¥©\úNÎ @A…h ŽX.O…úÿ?€è?}àrõä ä¿Iz endstream endobj 169 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 171 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 172 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 173 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 174 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 175 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 176 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 177 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 179 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 180 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 181 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 182 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 183 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 184 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 185 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 186 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 187 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 188 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 189 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 191 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 192 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 196 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ52T2u ÍR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ(ª+¨ endstream endobj 197 0 obj << /Length 85 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3s…C®B.ˆMÎåròäÒW0çÒ÷ž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ €ËÕ“+ hz¯ endstream endobj 198 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 199 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3cs…C®B.ˆOÎåròäÒW0çÒ÷ ré{ú*”•¦ré;8+ré»(D*Äryº(üƒì*ËåêÉÈžã: endstream endobj 200 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 201 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 203 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 204 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 205 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 206 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 207 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 208 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 209 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 210 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 211 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 212 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 213 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 214 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 216 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bCSs…C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þC¨'p¹zrr4ö+³ endstream endobj 217 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 218 0 obj << /Length 89 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bC3…C®B.s ×ĉ'çr9yré‡+˜sé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þQ¸\=¹¹6VLÖ endstream endobj 219 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 220 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 221 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 222 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 223 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 224 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 225 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0TÐ5T0²P01WH1ä*ä22 (˜X@d’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒˆÁÿÿÿÇÀÄê¥ÿch`üÇØÀðŸýÐR®ÿÏÀ`””ÀÀåêÉÈ|Q  endstream endobj 226 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 227 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 228 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 230 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 234 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 235 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 237 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 238 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 239 0 obj << /Length 114 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04WÐ5W01T0µPH1ä*ä22Š(˜™B¥’s¹œ<¹ôÃŒŒ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ†þüa`üè?’›îçrõä ä—5ez endstream endobj 240 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0VÐ5W02W0µPH1ä*ä22 (˜™Bd’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ‚êÿÿc`¨ü¨æ`°›ÿp¹zrrléI endstream endobj 241 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 242 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 243 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UеP0¶TÐ5RH1ä*ä26 (˜A$’s¹œ<¹ôÃŒ¹ô≠ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿÏÄÿа—«'W *› endstream endobj 244 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 245 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 246 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 247 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F †† )†\…\@Ú$l‘IÎåròäÒ pé{€IO_…’¢ÒT.}§g ßE!¨'–ËÓEAžÁ¾¡þÀÿ0XÀ¾AžËÕ“+ ‰;“ endstream endobj 248 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 249 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F Æf )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêüƒõìäðì:¸\=¹¹{-= endstream endobj 250 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04UÐ54R06P06SH1ä*ä24 (˜XÀä’s¹œ<¹ôà M¸ô=€\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü òìÔ€Aûòøð Žöêá´ÿ#ÿ‡ÿÆ ?0`ÿ ÿ þÀÿ†ÿ@¡.WO®@.…8 endstream endobj 251 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V04S01T06QH1ä*ä26 (Z@d’s¹œ<¹ôÌ͹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿÿÿÄÿ °‘§\®ž\\ºâAŠ endstream endobj 252 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 253 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 254 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 255 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 256 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 257 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 258 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 259 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 260 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 261 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 262 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 263 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 265 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 266 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 267 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 268 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 269 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 270 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 271 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 272 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 273 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 274 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 275 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 276 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 277 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 278 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 279 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 280 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 281 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 282 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 283 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 284 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 285 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 286 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 287 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 288 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 289 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 290 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 291 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 292 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 293 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 294 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 295 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 296 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 298 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 299 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 300 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 301 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 302 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 303 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 304 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 305 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 306 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 307 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 308 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 309 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 310 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 311 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 312 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 313 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 317 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 318 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×36Q0P0T0´P06T02WH1ä*ä2² (XB$’s¹œ<¹ôÃŒ,¹ô=€„§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ÂÿÿÿÂ\®ž\\Ï5^ endstream endobj 319 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 320 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 323 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 324 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 325 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 326 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 327 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 328 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 329 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 330 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 332 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 333 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 334 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 336 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 337 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 338 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 339 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 340 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 341 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 342 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 343 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 344 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 345 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 346 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 347 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 348 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 349 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 350 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 351 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 355 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚ32Ó35V0P0b#CCc…C®B.C˜ˆ ’HÎåròäÒò¹ô=À¤§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒýƒúõþÿ€AÏþ—«'W !‘$‡ endstream endobj 356 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 357 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚÕ1 A Eÿ²]¯8;êÀvë N!he!Vji¡h«{´9ŠG°´ãd±QÄÞ<~~ „¸~·p\p/•³ìJ^[ÚÑ L}¡­V[ª™9J2ãä’ >ì2ÕtÈ–LÍ ËÅ’BÍ@.ÀY®*åtÀßà“}4˜I“½¨™kÆ\Ðê7B <µÄ/z‰¢ñ…íž¿aúš×³?I£@3zóպà endstream endobj 358 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚ}бNÃ0€á‹ó[ñòŽ«í#•Ú[wж¾£¯Ïï7´«ûkÊÑ®é)§ìë5€Ú‚,ÝÇH‡Y˜1Fu˜EÃ1˜Û$Ì`„Ú³$ª] ½ciÕÝiÇ’˜¶MÓ6Òj T§Ä%˜0Òú©`t‰è)ßšô »µýÚ£Éî§ûì0„R7¡ ŒÇ’A¢«Ó\—þt‚‡dèC@ëf;„wÛ€75>à/G°ž% endstream endobj 359 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚÑ= Â0àJ‡Â[rß LK©¥S¡V0ƒ “ƒ8©£ƒ¢s{4Ò#tìP“ö¥qj |ä‡÷Ã[Æ‹$Dõ^†Åx àQ¢Î¾>ê‡ó 2ü€Q|£n‹->¯+ðl·ÂxŽÇýˆ¥^oÇémIiTEí¸²êud=X4ƒi;87v¶LNó7މoò™üTÏŒêd²T}Xö÷_õ§—QOË^Wþo5Q;ŽG2Ê7öOõ×Ò<êq.ÖœÔWX ØÃuRÖä endstream endobj 360 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚ½‘=NÄ@ …¥ÉÍ!¾L"±ËnC¤e‘H¢J ´$GóQr„-·­ñŒ7qF}#[ãŸ÷–«Óõ9Õ´ “†–g´XÑsƒo¨¬Sxm™§WÜtî5áZúúxÿ|Á°¹½¤Öª±Û´ (E¸TV";§‘èYäepšÒ{ðJý¥9†~P(eÔRÂé™XföìdH-Ø ÌXq*óKÏíÄ8§ãþ/÷ü§~ÖbyœoƃÑöq?´}Ý`ôƒéáÁô©ÀôºÓïëØ0fW Ø';´¬jœô÷#˜©†úcŠÍªþyÄ< ^ux‡ß³ = endstream endobj 361 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ37Ö32V0Pa3 Ss…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ@˜þ¥ÿÃè õ?ØÿÓp,ÿBóÿ‡ÐÌ@@4#P2Íðÿ„®ÿ€JÛÿ@£ÿ@hytúú?iBöÿAu?œ†ú«þª¿aá¥aá ?öÿ¨á[ÿþ°ø@‰Ÿ?P\®ž\\2oÉ™ endstream endobj 362 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ}б Â0à+Â-}½'0­Út µ‚ÄI‡‚¯ì˜¡Û¤…¦VÇÇår~>ÅS hR(Šéâ#^ô¦-Ç &ÙŽ"ŽlUÜ"“kºßgdÉfA!²”ö!”)isÞÀKT •¡oéY<py~# ³ˆ?@Iæz­S=©Z¿ˆ¿‹Ah1s–Ì!oâ9)ù–¹ÁÓʦ«:#Ç¥Ä-~·Ê endstream endobj 363 0 obj << /Length 159 /Filter /FlateDecode >> stream xÚ33Ð3°T0P0bS3Ss…C®B.S# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÁ¬CýfÅPÿLÉC(~ÅŽB1£PŒX© ª‚Å€Dý@¦!;˜úÿ7UÓ€j š ø(ÚP °ÅEq¹zrrco©· endstream endobj 364 0 obj << /Length 262 /Filter /FlateDecode >> stream xڽѱNÃ0à«2Dº%à{p<¸-“¥R$2 ÁÄ€˜€‘súh~”> stream xÚ37Ñ37V0Pas#Ss…C®B.3 ßÄI$çr9yré‡+˜Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÿ‡H|ÀÃ`¨ÿÁÀÀøÿÃÐdüŒ!íAœ b"—ËÕ“+ ¸0Õ endstream endobj 366 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ36Ó32T0P0aSs…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…h 1±\ž. ÿÿÿÿƒŒê0 uŒî'.WO®@.•õy9 endstream endobj 367 0 obj << /Length 138 /Filter /FlateDecode >> stream xÚ35×31V0PaScSs…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þVŠ¡þÃ0¤ØRüPŠ %BÙ£Põê?˜b„PÌŠÿ˜ªÿÝÿ8(.WO®@.‹† endstream endobj 368 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}Ò±jÃ0à·è ì{‚ʦIëBÀ¦P…vÊP:µ;´´ÒÁ~°~?‚Æ &×S !HÁßIËwWÅÙÅœ :—[U4¿¤—ß±šI_„6|<¿á²A·¦j†îV^Ñ5wôùñõŠnyM%º=–T> stream xÚeѽJÄ@ÀñYR¦É#džÀMü¸\·pž` A+ ±RK EA±ˆ¾™¾I|ƒ³Sˆgwv/'W,üfþÅn³¿ÓìQEþ4»tÐÐuw8›Ë\ùÑ/®nqÑ¢=§Ùí±Ü¢mOèáþñíâôj´Kº¨©ºÄvIÌ@ƼÚÀ˜À èøU´Á;€é=zÅ‹¬ž'|+ž|1 #G”R (¤ø¹¤2))€RT¸58BÒ )*¤¨¢BŠ ˜0Dtc„㈒ß(rþTd¾†À¿á±<\B¹…"!OÈL¬ÑmÁ%”‚Á£è!ü)ä Y‚Ùµx†n«Äº endstream endobj 370 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚµ‘1NÃ@EQ Mã#ì\Ì*Š •¥$\D‚*J(SAíÍGñ\º°2üñÈ "JË»Ïþ£ïÿÍã]>‘{™Êm”,—éƒ|DÞr!B~ôÊzó’Ó¥d‘ÓÈœ– ùþúùätöú$Pçòϊ˹‘vdW¢º3Vª-p¥uèÁµ›/ˆ «Æ—=›:Ô`Nzº¸wÏèʼn¬8røöØ,œÍVÃpÚž£¯Ý¥xèçóœðdnÿ¿&8둉ç°;æb9©•ßÞ³µ0ÔrEÓªõUXîЂyjóÖA‡^ªýŸó:œŸŸ'?—üÆ¿°ÛÈI endstream endobj 371 0 obj << /Length 233 /Filter /FlateDecode >> stream xڥѽ Â0ð‡Â->Bï4bÛ­àØAÐÉAAëækù(>BG‡Ð3͇‚uP=¤òAYý‡Ú¯K]¹k̵ÚpÍ&ŽËœÛÈ…MšÊgd ŸÎoç°Úk|x–¯pÿ +‡Â@Zä/0ƒ´d73(Mº\5|¢³3¿WU =e0ƒ>¬ß endstream endobj 372 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚeϱNÃ@ à?êÉyƒÆ/iJ"•¥‘J‘È€D'ÄŒ X{÷hy”^åc¡¯êŠ™D5‡=îþÙü:þé§“ÎÇ|ñ_.þ(Ø_’ IŸ˜4B±±ÌCjÑz8½–nZ:Ð7¡6 endstream endobj 373 0 obj << /Length 152 /Filter /FlateDecode >> stream xÚ33Ó31V0Pa3cS3…C®B.SK ßÄI$çr9yré‡+˜Zré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿƒANúÃÿÌÿêi†úõ Zþ@ˆæ‡Ó5`šNW€ifœôýà˜fÄI3€i0™4?(pÓ\®ž\\wG³æ endstream endobj 374 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚíÑ1‚P Ð’.^@?'ILtr0Nêè ÑÍGã(ÑP[ˆ‰““£Cû_Û´Ë‚Á0$êûy4Šhïã CmJ9î&»#&š5…!š¹´Ñd ºœ¯4ÉrJ>š”6>y[ÌRbæ\æò €[B§øãgpq ‰¸þD¬…b¢ ¤û7 ›%é¸ÇXzÂ’¯²+pîC‘7 M=$¿©¯¬qÓ˜«ŽÀY†+|œ¼T endstream endobj 375 0 obj << /Length 271 /Filter /FlateDecode >> stream xÚ}нNÃ0ÀqG"Ý’GȽ8‰DÃÔH¥Hd@‚‰uFlU›GË£¸o©‹‡¨ÇÝÅ|4RâülK§¿\•ç%æXâYUŽ>ð³Šy{9Þ<½Â¢û€³ ì ƒmnñãýóìâî °K|,0_A³D"êMLäþá¿1 /äΘ­¢c Œô/jEË802F¦x©åZ0WðýFf ÖÇàa2+x…3‘ ô .Hbìþ‰‚[¥TS'J &f N”@MüA­àÖy@»Qpâ: œèÜ7v#"Úõû†ö.€¶ÔBMíúŠGH'‘ SÄ~ }J× ÜÃ2ÿš` endstream endobj 376 0 obj << /Length 345 /Filter /FlateDecode >> stream xÚÑÁJÃ@à 9ö’7èî hšÒÒZÁ=yOêу¢ÐC1yŸÄCÄYðrkKÆ™ÝMEÛƒ·YþÙ?[Ï'j¬&ê(UÙ\Íæê."›Òp¬f ÷rû –¥H®T6ÉERž«ç§—{‘,/NT*’•ºNÕøF”+…ˆZ"(ÐüǶ…€Wëžœ;ËÁ÷ b#yí6ì sû"¶ßÇü¾ô£s¨Ý>‰Âæ·yGA¡¢Ú9ß¹±ŽÉ!yCacp^Wƒµµ$ä–ެÛéà ¥°¹·–ƒ;ë »êBú9>׺‰vݱ Õ°µî,û˜ü¡½)”7²?­c”䝯yD¿‘·Ö¾S¨míL?h:ƒ3E©öX÷ÞCÛà›7ÞÜÈWìΛÛ9à‚i÷-ÙÚ›CyÛvø,qZŠKñ ydõ• endstream endobj 377 0 obj << /Length 199 /Filter /FlateDecode >> stream xÚuν Â0ð+„[ò¹'0­~€ÄIí›™Gé#tì =猪‹!ùAþ¹—úù€RÊÉG4Ó!Ã3vYªW}ØŸpR ßP>@¿}±¤ëåvD?YM)C?£mFé‹AhÀ0W–¹pµ•(Ô†Å&áRŽ_ïÕGW«¶RM©Êú1|šŠw5áFò—ú«ýö ]Ÿ÷æ·ñ¯¬5IW¦†º'C»§{p´Ü:ކ«ƒV†#Î \ã 8.y endstream endobj 378 0 obj << /Length 191 /Filter /FlateDecode >> stream xڵϱ Â0ÐH†Â-ýï L«–ºj3:9ˆ“::(:·ŸÖOÉ'dìP{^ŠCEœÄ<¸Ü%¹$“Q”`„c^ Ïc¸À4å¸ }âp†Ì€Úâ4µä]Pf…·ëý*[Ï1•ã.Æh&GA‚}1è”t@%’c55lË)É1•’¬(*ÉÚúzí¼Ãºgã û¶?øqÛÛ[®ë„­Da_½=@ÖMÐ é4ÕBÚ3²ò'`a`Otí„€ endstream endobj 379 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ•Î; Â@à )ÓäBænbÄ*#¸… •…X©¥…¢­Ù£å(9BÊKÆY#X[Ìó‚?›M³ŒbJ]-(Ó9Á¦¹ô±kÝâtÅR£ÚSš£ZË•ÞÐãþ¼ *·KJPUtH(>¢®> stream xÚµ= Â@FR¦É2'p³$!vÁ-­,ÄJ--­o–£è ´‹dœ±ò¯æÁ·3ì<6{AŒ†\±Æ¸+ [ˆÎDi,7P3ŒP#¾eƸßÖ ²É5¨çƒ˜->E) ït´ÿD›ŽL®Ì”Z&U¼×!˧Òm,—J¯¿–yÿ"LŸXœÞI?ðåµ]ìÀ&^-Vìæ±gÇž·Zêø¿n$ù̴ɦ†¦p h¥Á endstream endobj 381 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚ]ν Â0àS:wÉ#ä>m©Ð± ì èä Nêè (¸¥à‹õQò3ã­ þ\È'›3ʇEÁ)çrFçï2:RÞߥ}ì¶×”¬$S2{ZÏù|ºì)/&œQRñ:ãtCuňCèà:DávG|‡iÊFy”­öÐV;¡tPo¼0ðáƒÌ7ÀæÙ÷âª{äKxÕNÄ. P¡5­ô €’’ÒÒ‚¦5-éQle€ endstream endobj 382 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ3²Ô3´P0P0a S …C®B.c ßÄI$çr9yré‡+›pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä?000þÿÃÀÀþÿ?÷£¾ÁþÁÿ†ÿÿŒÿ¡óFÁð¿FØ1 bˆÿ ÓÑbõÒøÿÿÁåêÉÈŽXo5 endstream endobj 383 0 obj << /Length 264 /Filter /FlateDecode >> stream xÚ…½NÄ0 Ç]1Dòropõ @ZµU™ˆt`b81#æô x¥lŒ¼B$€Ž7œbì´Bb"Š~±ì¿?â¶?é;ª¨¡ãº§¶§æ”j|ƶoE]·„îŸp3 ½¥¶A{)~´Ã½¾¼=¢Ý\ŸSvK»šª;¶rJ“€xþâP0ów4Éð{\í .c9ØNø]ÿ”"ÿßY¹pÒ&Zm­¬m¥1¬˜÷BÏ`­XëX Ï2ÝÌ1Ï2s–Pª)£Ö—àH˜²r”Á€—L¥5ø1ýÒýáU¥—Wôš[$ÜtUòÝ’ŒáYņ'¼ðr˜Ô endstream endobj 384 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#S …C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ3Á$;˜d¦%YH2ÿÿ$ùÿÿ’ò@Aæÿ6Œÿ˜ÿW€É òÃÿÌÿ ‘ H$Ã’ÿÿÿ±ÿÿ“ärõä ä WžH endstream endobj 385 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ32Ó35V0Pa#SSK…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒØÿ0ðÿ!ùÿ("”ªÁþ3Ô#!öÿ ÌÔFÿÿÿ€#.WO®@.Nq endstream endobj 386 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32Ó35V0Pa#3S …C®B.## ßÄI$çr9yré‡+qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ3üGBìÿ˜úÿÿq¹zrrÊWù endstream endobj 387 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚÝÍ= Â` àˆC!‹GhNà×"Ú ‚ ì èä Nêè (¸µÒÁkyo =Â7:”¾¦ÅÉÁ8„<ù! úín(žt4BMl}>pÐÓº.«ÁfÏ£˜ÍR‚›©vÙÄ39Ï;6£ùX|6‘¬|ñÖGB%%9µ "” 4Dªrr•{Ef‡V5 ÜR×’S^r_Ô,µÿ¬¥»IQiâNÉë[)%ö[ôyü/ Èû[<‰yÁo¨Rµ€ endstream endobj 388 0 obj << /Length 151 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#cs…C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ1Ô`øÿùÿ Éÿÿ”gþ$mÿ7°ÿ«’Ìÿ>0Éÿþ`þ‰l@"üÿÿýÿÿ˜$—«'W Žá‰ endstream endobj 389 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ31×37U0P0bScs…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Œÿ000ðÿÿ$ëÿÿ’ÿþ700ÿc°ÀÀþ‡Aþÿ2 \ i$Á €Êêäò?ˆl •Ä4b>Ä.dÛ!îp!îdræ~ùÿ€$Ø_\®ž\\-in« endstream endobj 390 0 obj << /Length 193 /Filter /FlateDecode >> stream xڭп‚0ðš$·ðÞ h[I;˜èä`œÔÑA£3>Â#02Î+šhÔM‡þ†ûúçK£`¨#Ô8Âc¤1ˆqgàaÌSQðˆ¶H-¨†1¨ÏAÙ9žO—=¨t1A*õA½›¡ ]‘O›Pö±’JA…äy)Iˆ¼r&õÓ~ó®ßþàÇmý—·’ªkÂ]Ÿ{77”Ôx­Ü¿f}N$¹nýCâù&L-,á‹ endstream endobj 391 0 obj << /Length 144 /Filter /FlateDecode >> stream xÚ3¶Ô36V0P0bcsJ1ä*ä26òÁ" ‰ä\.'O.ýpc.} (—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹Ã?æ ÿÿñÿöÿDM}Ãÿ?þ`ÿ÷áÿæÿ@Ä8ÑPß$쀈` 4'þÿÿ‡Ap¹zrr8WÖ endstream endobj 392 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚ%Œ= ÂP„7¤¶ñÙ˜„‡Æ.à˜BÐÊB¬ÔÒBQ°“£y”á•[„ŒûHñÁÎÌθb2+$˜Š+ä’ó]n: 2ç/*NârN7ærZmåùx]9]ì–bîJŽV9qµ*ý> stream xÚ36×34Q0P0bc#Sc…C®B.#K ßÄI$çr9yré‡+Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ø0°<¶‡âz þÁŒ@ÌÄòÿÿ?ø„™bTÂðÆÿ ÿ7~`øøƒýÿ@Ç400ÿcàrõä äÎpR endstream endobj 394 0 obj << /Length 149 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#cs…C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ30ØøÿŸÁþ?’ý?ãÿÌ@5J2"‘Ì0’ñ?;ˆlàÿÿ¨Ìèâúÿ€¤üÿÿA*þÿçrõä äðŒ endstream endobj 395 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚuαJÄ@à9R,L³opÙ'p=…póSZYˆÕ¥…¢pE ûhû(û{]Ä#ãÌZ˜F˜ácfø«Ë³«Ú朻ªÍEmö%¾aµâ¹Q»WÜthMµB{Ë[´Ýùxÿ|A»¹¿6%Ú­y*MñŒÝÖ‰\Kÿ©&Ð#d!#P¬OIÇ*¿ —M «D // R2h‚``ÝRÌ“m\®ùÕ‹ãzð=@>6m8ˆ}F}:ä1Μ¢>²Šý ,EýÍfù¹œ‘]ˆîO Î sSq0€iî ›TxÓáþ¦‹j endstream endobj 396 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚeͱjÃ@ `-~„ÓôìÆ&lpˆ‡B2e™ÚŒZš-?šó&†¾ÀA–Œé– î㤻_*³—‚2z•S¼ÑbI_9þ`QJi©ŸßØthwT”h×ÒEÛ}Ðßï鈶ټS޶¥}NÙ»–˜a÷lÌ}ì!â!xHĢ µK{Ñ0S%¦ÓYLæIŒÙ±„4¬^½vA:ÓCžõÿ5ûÏ2?¹j,TÓkØ„pÂgÙ àe3D^63ÔìŸÅU‡[¼}l* endstream endobj 397 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚeϱJÄ@€áYR¦ÉÜÎ è&^¢‡óSZYˆ•ZZ( Wœ$/%ñEò[nnœYäÚ|Å,ü3[åû%åt@{Å!•Ç4?¢ûŸ°¬dšS5ÿ}º{ÄeƒîšÊ ݹÌÑ5ôòüú€nyyJºÝ”ßb³"fo8ü7a êLìàŒ¸{؈kq€ÐàEoÄÚ›A ª I¿sLÅlL;q›‰é6‘­˜ð,ú)þˆŽ"pøkë'ëaÒö“šß “6ª«jùTº…vûMtÕ%ü¥yþÖpû®É7«±šc%^–Æ ð¬Á+üš~oì endstream endobj 398 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31×37U0P0bCS…C®B.cc ßÄI$çr9yré‡+sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€ÀDübvQ$þÿG%úAüȨÿÿÿÁåêÉÈB•\ endstream endobj 399 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚmÏÏJÄ0ð¯,Ì%ÐZ%c‹ã7¢â!¿02I†ñ|ÜøÖÛz¿ü¾“éGÆ­…Vx|–í,ÍïGi®˜•f¾ö‡×ã“4Û› ßI³ó÷odÞy¸A# ÕŒJõ—&E½8]&”ÃRj ©Ð¤ šÙõKXÿ™"9ãØß°öC¯ú"‚ãƒùÊÞáN¤¶¶šàžç‚ +–o¨q‘Ô ™€ï@æF2ŠÌÏh.ÊpFmLF IÿA.g¹•OÕ¬—´ endstream endobj 400 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿbaš> stream xڕϱ Â@ à– Yú6O`[¼Ò¥T¨¼AÐÉAœÔÑAQèP°ÖGé#tt«—ªtò $áB¢ÓyšpÄ :áDó%¦;騿‘¤Ò8ߨ0XÇnl•B³åçãu¥°Ø­ØVK>Ú/'2%;ŽãµÇÀ%|ÃAtG*èA0‡¬`/ºPu°½Fô19€9¬a{ÑíDíªb#úØj3XÃä5S¯øS… imhO_o`{ endstream endobj 402 0 obj << /Length 229 /Filter /FlateDecode >> stream xڅϱNÃ@ `G"yh_éüp’([+•"5:T #Ö^í%pcó»He``ùÛ÷û\·wm# iä¶”º’¦–ç’߸jQD¹ùéœ^yݱßKղߢ̾{”÷Ïöë§{)ÙoäPÊâÈÝFnˆ(ºžŠèF Ñ©j…Àd|ÉŒL@Àä6ììmБÜT /åˆõ¤sg`À|¸®Œ¿8c†Â¨Ò’5 MñÃÙâ—”i\Qn+ ¥yrŠevœEs¬á‡Žwü Ô4„s endstream endobj 403 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÏ=NÄ0à¥Mã#x.N´ŽV[YZ‰HPQ * ¤Aíp³%G0¢ÀE”a²» ÍgûYš¿<]6\±ç“š½çÆóCMÏ´XiXqÓì~îŸhÝ’»áÅŠÜ…ÆäÚK~}y{$·¾:ãšÜ†ok®î¨Ý0`2™€R¤Ó—é†r@ìŠI…ÀærBÈG£b¶dÅþ2lRÌ“V;äxFïò!#äSòÕI§gìµk4I±Yòžñ€;ý!þGøaÜbóžÝ¸óài^aÐeb_È»î+:‚¶‡ÑÚ(4¢ó–®é–•™ endstream endobj 404 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚϱ ‚`ðáÁ{2As‰3È!¨©!šª±¡(hˆôÑzÁñĺïŒt©¡~Ãÿ8îÎûa@ ¨ç‘R0¤‡Gô=9›Îö€qŠîŠ|ÝÇè¦s:Ÿ.{tãÅ„8MhÍ3L®±â“+ÿ"dL-V¢K±x{°pprm î%@%*­!š¥ÞiÉfúÈ£ú1ƒÖºÕh¬´fG«£Ý¨ZŸFéȶ> stream xÚEÐ;N1 `G)Fr“#Œ/³£Ñj«HË"1Tˆ ()@PgŽ–£ä)S„{Aló)Çù“iw¹›iC]Œ4M4Oô2â;n÷²¸¡yþÝy~ÃÂÃm÷8ÜÈ2Ë-}~|½âp¸»¢‡#=Ž´yÂåH`xpœv ú$¸ä"¸,t¹?“”¬¥JIÏRÜsTR/´°vÌ „ –å6£#`f€ÀÁ3G&û-Û]\\ò\´Eõ«åV>R®ô­tŠUÌ?p¦²"ÅFÏ ¶ø¿Ìò¢!ÚS‚S¯`% ^/x?}Ï“… endstream endobj 406 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚmÐ1NÃ@Ðo¹°4°s°­ØŠR­‚„ $¨(U ¤A½¾ WñMØ#¸ÜšapJ‘æ³Úù·]_®;®¹å‹†Û–»–Ÿz£ÕƆ5wÝádÿJÛžª^m¨º±1Uý-¼¾Pµ½»â†ª?6\?Q¿cä Ài‚&dš r¢˜†2!Œ.ÁG?pS8’ôÈ|9‡]ó'ø?‚XP‹T)æL%—ü[2Õ/±jNl¥›þ§”>9Û’¼5þ‰FX ü”éà¢=Ø … Œ–W¨UÊUG@—˜ºîéž~Uí–Ž endstream endobj 410 0 obj << /Length 327 /Filter /FlateDecode >> stream xÚ•Ó¿j„0Àq%C ‹`ž *½B]®W¨C¡:”NmÇ-ív¨–GÉ#dt—&æ—?RiDø¨ ~ýi]_\V´¤;½×WôzGß*òIê’šMš ¯dß‘â‰Ö%)îôYRt÷ôûëçû‡Z‘â@Ÿõm^Hw ‰YmVìaܶb«Nß4RbÕXM›Î”\u®N›n•ònbÁý |ä± –mˆœbçÞ©¶‹LEæ´]$â±±7æ!3äi»ÈlŒzçÚ.2Ob'Þzº>¸Ñƒtî!ò¸´—Æ9™7Ê ×˜CîÒ.Ík&) 7L³Èʬ ¦k–üÓùì“ËõÁóÇ Á͹!¾·!×Kk¹KÛøÌ!×#°€Ü¥m<æá“ÆÌþçÎFkó(­°¿4J@?û¯ÉmGÉ/ðc ¥ endstream endobj 411 0 obj << /Length 267 /Filter /FlateDecode >> stream xÚµ“=nƒ@…Ç¢@šfà9Al%"’C$SX²+V*;eŠDI£pJ ÄzÖ°òÚîÌŠÕ·üì›y^çOÏ‘=“Jftˆñ“ˆìॽ±ÿÂEŽzKI„zÉWQç+úýùûD½X¿QŒ:£]LÑæ™óÑ@G¦j…ÌQ¨P¦˜ÚϘº§‰iz‚ÿVÈ8Jy›Ž¦<_’â­oSÈr¡ûºãJ^CoC¿âÁàK(®¥vR“ਾB,á|.ÅÝÚWK¥uÅÉ¡Ë`DuO6®KNý™‡‘¯6‘_i JGãT+É­”´ ç¤KP±„û²¡J¨ðÿ~ ßsÜà uÍyë endstream endobj 412 0 obj << /Length 338 /Filter /FlateDecode >> stream xÚÍ“?N…@ÆgC±É6½€QãÚ¸Éó™Ha¢•…±RK vF8Þä%^€’‚0Îì ‘¼Z ø-;;3|óqvrX”ºÐ§ú ÔÆhs¤ŸJõªL¡ù6Ç~çñEm*•ßiS¨üŠ^«¼ºÖïoÏ*ßÜ\èRå[}O‰TµÕ@W‚€dªR‰ˆ;Ȉ,Q–ˆG¨9ÛCi ì7rXKËä0—Aà@$ˆs;’²º:ñ>GOÔ11PV¨GG’ª à{ ré(µëÜ‘  J}1*7S(»$;SheIÙLõ>âoúCø¨^¥f­i0Ó¤ÚÙIñ™Î§ÉÌô¬ð§ Cœ4ôqú¢ŽHºèG®¹‹nJÛè°¬‰®³œcÔC +{ç7ZÛÎÛ¶>»ƒ Úà¿¢‹*E!¼Õe¥nÕ/ÙÏíã endstream endobj 413 0 obj << /Length 258 /Filter /FlateDecode >> stream xÚÕÓ1nƒ0`£ ‘ÞÂx'¨¡b€ ‰¦R"5S†ªSÛ±C¢d†£õ(9BF†ˆcWæGµR¦Z}lÀþ_ÇYÂ1§æÈSÎù#¡=e¹éÇ}·¿ñþEeEzÇYNzm®’®6|<œ>I—/Oœ^ñ«™æª‹kªo?nÁ‚>ƒíCK¹(Iç¸ÖªoïÐv^سs`'rVr\wƒ Iã‚—ý˼ÏÞ‹‘/ÞÁÈí¤íýênp=g¹ÇÍ?ôÿ;³†¸ÎØ—¹=Å  13èr…Ù‹ “E7™ÛòŒ™ÇZ€1µÓŒk kmªgjÖ.=W´¥€Ms³ endstream endobj 414 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚ•Ò= ð×t y G('«Æv3ñ#±ƒ‰NÆI4:—£õ(ÁÑIÓ¾ú¤H~…þi¿ÕE[ôLK;¶nc<`’˜ïgØìq˜¡\Š$A95½(³™8Ï;”ÃùHÄ(Çbe–Yc6º,wh*àúÀ´.9)"1RH HP+wh ¾yÅ›(¸/*±†øPè#qRDÒ¥LùSõÜ×õ¸c_ÿÿ½Ÿè擽®²éPèÒå[Ì+^« —& ÊIº ¬)J¢¢t*Jl)sŪJ¶SàN2\àîÀU\ endstream endobj 415 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚ³0Ò33S0P0bs  #…C®B.sc ßÄI$çr9yré‡+˜sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þCÁbY ìÿ?00ðÿÿe1 Xòp?œÅg1ÃYŒp‚UgÕÃYöxYò¤³À,æ üD²p²Øñ²øá,y8ËÆbüe‰,„^$óìà'Ò}ÌTaAÀf“õRX\®ž\\1=# endstream endobj 416 0 obj << /Length 349 /Filter /FlateDecode >> stream xÚÕ“±NÄ0 †]u¨”¥P¿´U‘®"‡D$˜02€`ny³ãMNâ¸ñ†ªÆIÜ»´EÀJ÷“ã8vâ?ÏŠã¢Â x”cµÀ²Àû\=©Ò83,OÜÊÝ£ZÖ*½Æ²Ré9»UZ_àËóëƒJ——§˜«t…79f·ª^!ðÒ û5D±Åˆˆ6XÖÌ;Ж©‡Æí¤uH@†cýN.|ÍŽrá.m@µÎ³Û¯F|Ž=›Mb¶š Ö´`]ƒÃœb{)Ð$èÀU2¤ئç¿ô' ÄcW˜¾|–rƬÇ,eŽ9sóýÃôOx^cf¥u=þÌzÆ.‡–{6œü‡·›òðÖS–1´Œ¸;ôAýe&oVýögÛ›ù`¦_#œˆ7ÄŸ¢)ÒNG¼¼ èöÝYmv¢M£Ù­è×Üf !ˆ&\oê¬VWê ?¦! endstream endobj 417 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bS #…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿA ÉÀþÿÃ(9THü±ÉåêÉÈ’:Õ° endstream endobj 418 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ3·Ô30T0P0bs #…C®B.3K ßÄI$çr9yré‡+˜Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü Ä0ø!Ô(c2~f0ÂH`0ãf°c0øáŒP†<Ãƨ‡1þCŒ0;ŒÁcÔCÌÀ¤ø Ãàrõä ä6n6 endstream endobj 419 0 obj << /Length 311 /Filter /FlateDecode >> stream xÚÔ±N„0Àñ’oé#´O ”\<'HÎ3‘ÁD'㤎ÝHàÉ ÆÁÑGð‘áBýú•Iû%)ð+,ÿ¦`ÊÕÑz­ ½ÂaJ£OJ}oà Œ9Æ™ÂÙ=º{„MùµÆyÈÏqòæB¿<¿>@¾¹<Õò­¾1º¸…f«­µ£ #q·8&ÏtáÞ3ûŸxž=%Ýüæ·õT]ˆ_¶'V1ü´± òÃîˆSï>8ƒ|º‹bGýx ²¦~Ù‡©¨_‰(Jê¯fÔß2L©Šcâ–# ןî8º~w‰¢[ÙstýJptýU,Ýr´,]ÿÄû±ž#öc},»=Ö3Ö³Tëc)íÛfôÑrLi‡G’vKA;+DEï ñß1¥]þ*Y÷‡¨ÄB8kà ~oˆ§L endstream endobj 420 0 obj << /Length 316 /Filter /FlateDecode >> stream xÚuÓ1NÃ0ÆqG"yÉâ¤êÐL–J‘È€bFÌé ¸Rc@n@G†*Æï9~ýÈðäßóò,×Õâdµ4•¡i³Z˜ûZ?é†öŠVÂÝ£^·º¼6ÍR—çþV—í…yy~}ÐåúòÔԺܘ›ÚT·ºÝçÜR*ñç<‚ÝV™s[¿(;(rOηì¼wþäpô(þàXð;¸áàŽÃуØr,¸çÎ8=ŠSpÂá`ÅáÉb æðdOæ°x§`Oæp4…ÄLáh }S8:S8šÂà^ìÃb öa±ƒb§`ûØx'îÜ·Ø‚ ~›à|Æ8'`5çlÁ8ŸqNÁ X‘‹½xúƒ> ¶àœÿµ>kõ•þJÔ@ endstream endobj 421 0 obj << /Length 325 /Filter /FlateDecode >> stream xÚÍ“±NÄ0 @ÝPÉK?¡þh H×›*‡D$˜02€`¾û´~J?¡c†ª&±ãrœNldH^âØŽ{U.+,p‰'%®Î°:ÇçÞ ºð‡ú…%O¯°n ¿÷_óÜÜàÇûç äëÛK,!ßàC‰Å#44~d´32DCÄšˆZAOÔ3%ä,F•¢b= _&gŒåË2‡½·dõÀ‚FL¤dtæ½Èêˆ^c;È“ºh†MZE=°p¡8È}ÃÚ‰âèÝ´1ª˜M¸Ótøµž°=Š[’l¥ÔýiÂþÿâìéñq<”3Mu;Ëúo˜ê†Ïš0Ñï÷q¯fUËȱ„±çšà:ëØ „Æåq’ñÌ×Ä·€•ZwÑ»¾$D#ÌB·HÜIè!iÐýh²Dåß W ÜÁxkD— endstream endobj 422 0 obj << /Length 290 /Filter /FlateDecode >> stream xÚµÓ±NÄ `H‡&ÿÒGèÿJk×NMÎ3±ƒ‰NÆIMÔèÜ{4¥ÀØá"R ÜßÈ%)ù ~ø¡Ùœo®°ÀK<+±©±¾À×>¡©Lcuåz^ÞaÛxĦqkšAtwøýõób{%ˆ>•X> stream xÚ}ѱJÄ@à?¤l“v_@“pÞ] !pž` A+ ±RK E;!÷hñMÎ7H¹à’qfwO ¦ù`vv23»œ•µ)ÍÒVf±0õÌÜWêIÍ%Xšú8œÜ=ªU«Šk3¯UqÎaU´æåùõA«ËSS©bmn*SÞªvm€| 82"‡7@бï, }8$´þtHIR2>JØÜJ =°MT;4[6ÿ±ùR׳éÄÄ~“û íD©Ï}~k£.:Âíì£6ʃH«¬Ï±¥DÎJ†wðkñ©8ÊÌ1ÁÛ‡=Iszÿ‚‰6üÑWÎBðJIľ7ìl¢:šÇa²hJ½Ý7ùCÞ¦ûßÍ8‘ÂýðˆþÝÆðâÞ5,φýkV›Ôqœ<ò Òöè÷Ã/™„µXY×dã|…ËvRJµêJ}áI± endstream endobj 424 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ³4Ô31W0P0b 3 C…C®B. rAɹ\Nž\úá \ú@Q.}O_…’¢ÒT.}§g ßE!ÚPÁ –ËÓEÁþ?ü!žu€¡þ?3õ‡Äb°ÿSÿÂâÿWÿÂbÿWÂbþWßa1þ«g€°Xu0V6V ŒeG,ëŒeÿÆ’'Åc1Œ²†%‹’œÍârõä äãCì< endstream endobj 425 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚ퓱 Â@ †S:Y|„æô]ª‚ÄIÝÄöÑú(>BGñLÓZD''—|ü¹ÿr7œÑ¦©;¤©M CA‡º>­ î0ðYÔÔmÕÃ՜՘eTÑ„ûãU8A5¤…!½ÄhH–ãàpɾe¨Û ä§P±þóï¸Vrÿ…{ÂÙŸy¹%ŸÞرWáÛ K¶¹Žp,ìŠ+¾ç¹&ûÂuaÏJNE±IÞM ºœ4y0犉%®Þ­àØ^žÃù ŽâAlæH 4È—¬6eOæ†E8Ã`ò| endstream endobj 426 0 obj << /Length 347 /Filter /FlateDecode >> stream xÚ•Ò±JÄ0Àñ YúÉ h¯w v¹Ày‚ÄIÝŽkÁÁ×êæx¯Ð7ðÆ ‡Ÿù¾/ׄë¡Hû#MHYO =ÖS}TèòDŸNôC!Ÿe9q‹c}:å/÷Or^ÉüF—™_¸e™W—úõåíQæó«3]È|¡oÝAw²Zhpà !j€Í- ´GÝ ¡ #gM°rÎÜ>²6n¦Þ3²xåf[ò22>GÞ–üÑ_Þt2À¾r º NɆݲñ•‘»aw{VdS"Ø9ræm÷¼"sØ22Çq˜ æDŽä,‹xc'²SoŒäDŽÌ¼1’³8,¶òÆ0NdoŒœõ¶> c¬Ïâ°Ø[o ³Á»DŒÜeaXì¤w ï]ðGoŸm𺷂uüzg|UNùj ¼»–¿yö l»îþ¶i[5ËóJ^Ë÷ûø· endstream endobj 427 0 obj << /Length 459 /Filter /FlateDecode >> stream xÚ­Ó±nÛ0Æq pá#/8ŠÀ“$)PÚ©CÑ©íØ¡E³ ²ß,z=GPħ£íZ™êáðáçNþëõÝõæÎݸ[wU»zýÆmnÝ·ZÿÔõº¾q›u~ïë}¿Ó«OðCµ^½׫Ý{÷û×Ów½ºÿðà@Ýgø¥/z÷è"¼‚ØÃEwø lì…€;ÀiŸ€åi24> stream xÚ…¿J1‡gÙ"0M!óº·`D«Ày‚[ZYˆ•ZZ(Úºy´}”<•aÇ™¹ãôP1|ðå—?üâéáIO :¢ƒžâ1ÅH=>cT¹Pc;÷O¸°»¡Øcw!»á’^_Þ±[^‘ØÝÊ™;Và8ƒŒ‘?dm˜gPÇj·\R…q :“dÄ„*Á |…Vbn¶;ƒg³Eó çd˜ö1Öo( Ø÷aãhDBÿcü³!ýD[Áo˜¬1¿En¥ ¹±¦ä%iêÝînª6N:ó\ÒZÛ` æ]H›_ÙI<ð?yë­œ endstream endobj 429 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚíѱ‚@ à& &]xúÞÜHLtr0Nêè ÑUy´{ጃ „zwÀ¡Í×6ÿÔd4”’™JBG´ñ„qlfiG{Ø1+P¬)ŽQÌÍE± Ëùz@‘-§¢Èi’Üb‘¤‚˜µ©ÒÁc®|æÚ!P÷Æái à±®!`{èø.ÿT¼ÊV6ß¡ýAÓõ_°yÍÀ4Õ8+p…o âøš endstream endobj 430 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚµ‘±‚0†kHná¼Ђ±0’ &2˜èä`œÔÑA£3<šÂ#02Î^KL%!_sý{½þ¬æI‚!.qa¼@¥ðÁCT±Ý9ß +@P% 7º ²Øâóñº‚Ìv+Œ@æxŒ0> stream xÚ]Ð1NÃ@Ð¥°4¾;ÛŠBƒ¥$\ ‘ŠQ%Ú¬æ£ì\¦°v˜Y)¢yÒî·çÝT—ëk.¹æ‹Šë57 ¿UôIõJ/Kn®æäõƒ6O\¯¨¸×k*ºþþúy§bóxË[~®¸|¡nËXÊp8™ÎÙë…HDÑFä#ò°Ô々Ú~Àþ¨¨7ö'ÉQÈ”´^;LKZ+45qj@.dêtÜÇv“ù!¤¸Ç"iíÐÄÌôehÖ”ôÁjÛ]ˆÿdVçµ³½ÍSuž‡è ±ýõ?h©›ÓêgåcfKxýºëhG¿Á•¡Z endstream endobj 432 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ35Ô34S0P0RÐ5T01Q07SH1ä*ä21 (˜›Cd’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.O†ÀOþÁN2bÌH$;É&åÁ¤=˜¬“ÿA$3˜äÿÿÿÿ?†ÿ8H¨úANò7PJÊÃç‚”ÿÇ`$ÿƒHþÿ ÀØ`ÿð(Èþßÿ ýß E` q¹zrr:é“p endstream endobj 433 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ33Õ37W0P04¦æ æ )†\…\&f  ,“œËåäÉ¥®`bÆ¥ïæÒ÷ôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQ```c;0ùD0ƒI~0Y"ÙÿIæÿ ò?&ù¤æDå(I²ôÿÿà"¹\=¹¹VI¢” endstream endobj 434 0 obj << /Length 301 /Filter /FlateDecode >> stream xÚ}ÑMJÅ0à)Y²é’Ø–G_]x>Á.]¹WêÒ…¢ëôh=JŽe¥ãüˆ? Ú¯if¦“tߟ ChÞ¯6 §á±s/®ßÑ\¦¼ððì£knC¿sÍ%½uÍxÞ^ߟ\s¸>kŽá® í½Ào@£B,D¸'€DdZš"-š,-ÚB/6¨3"x‰š¢äç”™œ®—ÓÊ®k‰í ƒËpÞ7q|Ì$pãFúæš¿È »ùdíL™@ÚAvüZ´H¥ÙFÓ¬¦YM«5Þk|,ZdÖìI³eb4Ðj`Môä³g!@Tt¶«`[ÈBÍ».àA8ã²EþõËwÌ•b«ÔŠW¢’üÉü'îbt7î}tû” endstream endobj 435 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚ‘½N„@LJlA² À¼€ÅgErž‰&ZY+µ´ÐhÍ=Ú> @IA烋 á·ì|ýgf.ëK xQá®Âz¯•ÿð!ðe‰õ•Y^Þý¡õÅ#†à‹[¾öE{‡_Ÿßo¾8Ü_cå‹#>UX>ûöˆ)Eà§£‰¿ŽˆN£ÈGG#›"ˆqhfHøÔ8¾ÏéäfEÊAEIÅÈ=¿ÿ„Å-ˆÎ’%$©#쵂H\ÀÕWèfä¹  Íhg™…™cgݺi†¹8iZþG«`©s+´¤É,25×ô\iÜ`2[Ì[¸¨ÈE3)Dä/ˆþbZÁ1.8Gƒ ƒ•I¬³éUuužR¯áÍ:îXÔ&¼oÝ´í]Ö¯"MºÎÝß´þÁÿéýëo endstream endobj 436 0 obj << /Length 225 /Filter /FlateDecode >> stream xڽнjÃ0ð ‚[ôº'ˆìPÛt±!têP2µ;´4›qüh~?‚G‚$ÎýÅC»õ@ú¡Bw—&ó,㈮+]pöÈo1}R2æ¢ñ8^¼~в$ÿÌIF~{Í’/wüýu|'¿Ü¯8&¿æ—˜£•kžnûLMÔÐ@;ÑÁž&žEõD-twñ>‡5 pU/jh:ØŠ¶,PW+D5À^Ôh ma#:ôYÀVpÔ=ìDÓŠºb~9¬a€g‰æ/ÌÿŸuøÿwiSÒ]]Óq endstream endobj 437 0 obj << /Length 285 /Filter /FlateDecode >> stream xڭѽJÄ@ðY l“Gȼ€&áH¢ ç ¦´²+µ´P´N-²°`“b¹u>r‡"X?²ÙLæ¿Ó6']‡¶x\c[awŠOµ}µÍšéñLß<¾ØMoË;lÖ¶¼¢e[ö×øþöñlËÍÍÖ¶Üâ}Õƒí·hF8ˆs0;àÛ¤Ž¡+*³¯Lʨ€•Yñ ‘ iþŸŒk›àäï!%Nó¹4tíaà(.JÚ‚bÒî> stream xÚ’=NÄ0…'ÚÂ’›!sHRd ‘–E"Tˆ ()@ Qa-GÙ#¤Lyxcó´‘•Oòóx~ž×ÍaÛrÅ Ô¼®¹=âûÚ>Ù¦ÁfÅíqRîí¦·å57-ϱmËþ‚_ž_l¹¹<åÚ–[¾©¹ºµý–‰ÈÒOdÀ%2…È ¸9SQväTòÔy2ÙSÁ Tà» 2NXFvY òŒø_ȹèíC!š‹"Þˆº%R­î/ºQ‘‰(Œ¶"!×V$ÞMÀ x#$“0"»W ­ ÎˆPrÂ(¨ì$Ó7´Ày?â Âîßèö"^Ò\æ%òˆI‘Éd¾«^EÀ€AíÈRɯiP7ë@tÊê4F¦¾Ã}œÒ·  CÔGƒÉžõöÊ~†\ö endstream endobj 439 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­Ò±jÃ0`™[ü¾he…ÚÎTAš@=š)Cé”dÌÐnÁò£ùQü5˜8²þ@mp CoÐ'¸ÓJ“§,ã˜3~Tœ>óLñVÑ’Ô%cžMq³ÙÓ<'¹æ$%ùæÒ$ówþ>þìHÎ?^Y‘\ð§âø‹òGÂGT‚ ´%ð1Šîs °à< (G˜®Ï‹(ºnhÄÉõ<œA홀°OîÐÂS€ÆiüX+ÒÃé"¬]ö1¨Õö n\PrÀ䚇cDôÆÞ§ý+Á"ZlÎ`eºúý1´ÌiEWÂÁL endstream endobj 440 0 obj << /Length 339 /Filter /FlateDecode >> stream xÚU‘1NÄ0E'JÉMŽ`_²)²ÊÒ²H¤@‚ŠQ-” ¨£…›øéHayøcARäIñÿù?ûî¼ïÍÎtæ¬5ûÖôæ¹UoªëðqgúË|rzU‡A5¦ëTsƒÏªnÍÇûç‹jwW¦UÍÑ<¶f÷¤†£!*y"<–Þ3Dà‰ê@¼àȓơ©ŠD,#DQÄc!C<– S 1¹©úŸ`}½EØ fðŠQæjÙÀM5ÏA°˜øcÁ²¦Ç.%ó‚Í€€ %‚Æ ç œ9æd’QÿÅœrè™’t‘pI#xÙï$u_"E`—-5KˆfXÊz‘ qv, /&Áy¹6:)z…‹©veÒuFµA¹EøÅ”àVxXVˆ;Õ³]äß‘^KFƒùa9 ÔjcªG²ëÜY•ëAEJ˜¨ëAÝ«D© endstream endobj 444 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÐÁjÂ@à ƒ4׊ÁSµ`B{êAA{,ØÒž“GË£ôrô ngvÜ]vù˜]Øaþb:™Î•QOt ·O9~ᬠڕüpüÄe‰ú]Í ÔºE]nÕÏ÷ïêåëJå¨×j—+³Çr­€Ö€Ç(àYXU€õ‰zj&®|’€aOÃd pèùcš1uÔŽ¸Æ-1H[7c(< ¤bÆgá Xk;®>É÷èN`$ŸŽ³„Ö:¢‹ -åomc)¾ŠZ¶ç†/%¾á?OFi° endstream endobj 445 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚ}бNÃ@ `W"yé#ÄOÀ% í©‰ Htb@LÀÈ@ÕÎÍ£åQînìåøí‹ e@Ê铳å³_^-¯¥’¿+ï5±÷ˆ+ õÇÛ'¯[vÏâ=»dÙµ²ß>Ø­Ÿî¤f·‘—ZªWn7BÇ”R$c̤Ž(õÔ„•Ñ(NHN͇ÌxÎì‡ÙÄø—ù%ƒ•ƒõCke2Mo胵ŭB/ç©•ð›Äpè·8Yi¹RN„L4pʉ`Eÿ¡ËÀMôÓ¢s‚Ñd޽~Fgû:5ЗêTúŒŽšHºi¬Ù só}Ë[þL[œæ endstream endobj 446 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚÐÁJÃ@àYh`Í ”f^@“[ …ZÁ zò ‚ …* =É£åQò9î!tÝ™¤‡âAO;»³Ìü¶8-Î)£‚NÎhaÉô’›wcm(f´È‡›ç7³*MzOÖšô&”MZnèóãëÕ¤«Û+ ç5=ä”=šrM¢“@åë) ¼oç\SÝ%´Ø}‡«³ØqÝKK䄸´ã‡PËFïF왎»m4â„øˆ¤cž´ÂRÀ1Uó'~¤þú@õ›h`"[bzÄ ÉOv˜ÙJ:Y³åœ ¨°»®‡8!áÎy¥»@ì4÷h? î%<$ü¹.ÍùD‰pj endstream endobj 447 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚѽnƒ0àC"ÝÂ#pOƒ(TLH ‘ÂP©:D™ÚŒZ53<Â#02 ßÙ$i¤(Aœ>l#ÝÓxñSHiLÉ+}GøƒIfÖ!/ùàë€ËÕ'%ªÙEU¾Ñßïqjù¾¢UAۈ–A¥µîÄÑ©kó¡~ÍF AkóæpÖ³Þ`…Ñ9EåÌkð&Çkkpk ³Éá9ç“\SþX¿·ù}iúžõÙÀõ,3ÐðO®ùZ®)g{I!9ÅÎê·VÓ®ÈQ5’Fb´)e¬<îþR‚gJàëàÛ‘)›gpò-áºÄ<[?—Ò endstream endobj 448 0 obj << /Length 230 /Filter /FlateDecode >> stream xÚmпJÄ@ð „´bæ ÜD؈ œ'˜B8+ µT´5y´> stream xڅн Â@ àÁB]ó^«=ì þ€ÄI¡}´>ŠàØ¡´&ZÚŠã#¹§N—,êñÑ.é>íl<¢v8·$•‹íGªiÕŒ«¨¼9O—=ªÑbL6ª ­m²6èMü”#Îi ÆÀx7.2>´Ê12¦VFS¨0•ªBÌ@‘ú3–ù`F²[ˆ…×cs4"#p}ãþ¢ýK¸—_†á_üŒà'Fújá¾À©‡K|ÒÐqj endstream endobj 450 0 obj << /Length 270 /Filter /FlateDecode >> stream xÚ…Ð?JÄPð/¤ b.°ìÎ4‰°‚XW0Å‚Vb¥–ŠÂ²ÉÑr”=BÊ!Ï™I\ˆ ¾æG&óþÌ—¥§IÆ1/ù䌳”Ós~NèR-Æœ%ß§WZÝsšQt#eŠŠ ¼¾P´º½bù^óCÂñ#kôð…ÜUà9·µæµs`Ñàâ(+Ìw€z;#h¿GØÈž‹½œÐ!¯ éW¤øñze«»e0Òá¹TV<%× ä‘Êú_ÜHõ'Ëèo@Ûííeõ7®²)Àˆ%pÀb9 czCr™&!j.Ç; w¶³‘¶uØùÍLÚœ«ô$ – ]tGßPÄ< endstream endobj 451 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0bc Ss…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿÿ!êAC=3Ø€õ`¢ñL0`'ÁÄ?3˜øƒƒ`?pü`âBL<ÀAØ£úA€=ÿÿÿñDp¹zrr¾aZ¡ endstream endobj 452 0 obj << /Length 196 /Filter /FlateDecode >> stream xڅн Â0Àñ ‚…Côï LC[T?À ‚N⤎Š‚›>šÒGèØAŒEl ù‘Ëø'ªÙ¡"ÞIDI‹Ö wÛYh¯öaµÅ¾F9§¸ƒrÌS”zB‡ýqƒ²?B9¤…¢p‰zHp6&øÌÕžp¾|b¿-j8 endstream endobj 453 0 obj << /Length 285 /Filter /FlateDecode >> stream xÚeÑAK„@Àñ' Èk‡Àù©Úv¶ ò°P§KTÇ`‹:;}³‰û ó òèÁvzÏ]Å=èüFaü;“ON&S™ÈSºòs™ÉÇ_0Ïhžð”_<<ã¬ÄøVæÆWôãr!ß^ߟ0ž]_Èã¹\¦2¹Ãr.¡²„µjÀÊ5ƒn¡rh„߯á‡à3¾Û1¾ÖÒè}Z‡ÂCÑG¨tc‚P…ÙG¢zŒ°é1Ž Ú>#é ÖcxÖ,¬ ‹³ŠA•ºwÐÅÆ!2´EÕ *kíÐ8;´âAqÂ2¨À³jØGÅXmÁ Á'ñÎmA?N¼i¿ƒÞ/K¼Á¨‡xƒ endstream endobj 454 0 obj << /Length 262 /Filter /FlateDecode >> stream xÚ…‘1NÅ0 †]e¨ä%Gˆ/m©xS¤ÇC¢L ˆ ßð¬´GëQz„ŒªÛdè"Jò)ËþÓ^žû+ªiGgÔzò;zmð„Þ³XSÛüܼqßaõHÞcuË2VÝ}¼¾aµ¿¿&>è©¡ú»€]@ƺ¼›ÙN¢ff¹üÒYÌ*˜à('‰’ ü‚Q‚ BФùŠ Id“!Ù‹¥T$·pÓa“¨èÿ‡6U.ÃοÀÅ~‹I2FE?h+(¸QÊ©š[/¹UöB–€éÃÄ oÄ\öLrƒD’Š5éßÑð¦ÃüÖ¼ˆ„ endstream endobj 455 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚнNÃ0`G,Ý@¡÷à8UÚ2E*E"L ¨tìPsüh~”> stream xÚuнNÃ0ðä¡Ò-YÙz/IÀTt!R)`b@LÀˆ&PãGó£øÌV¤¨æÎa¨øÈðS|gûîlg{Í×lywŸíœç|×ÐY+Ášg͘¹} EGÕ[KÕ™„©êÎùåùõžªÅÅ ËzÉ× ×7Ô-0j`šÜ#ЧQ æ#ÀD¼LÚ€Òc0u(e ‹+9í1ü´ _¬E—ÿÿrùŠ4ê²A)'RòÐvd/Ú”F½¶™¢”NI/ÏJB7™,ú|z’5[%°m_‰«¾}תŒ¦£G9Ð;}ŒÞ£tøŒúBq)[m0”:˜Ï}ÐiG—ôy?x endstream endobj 457 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ…ÐÍ ‚@àÂyõ 5OÐ*h&‚ä!¨S‡‚êØ¡¨³>šâ#tô°d»µDFäÀð1?00~8r(9ôÈhïâ }OÔŽ,å`wÄ8E¶"ßC6]déœ.çëY¼˜‹,¡µKÎÓ„ŒZÿ¢‚¬Ô¹Y@T7sɸ z‚l»õbô¤ãÔ x³ýÄR I´;Èø‡®à­ŠªSqk¥¯([‰Å²µ\ÑŧÅy£NS\âwpmõ endstream endobj 458 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚ}ÐÁJÃ@à ¸0HsõPè¼€nHLO…ZÁ=yBA= * ÞÌ£åQò9öP:Îvô 9}à 3Uœ5gœ|Zp5çòœsz¥²ÒnÆå<ŽžiÙ»ã²"w¥}rÍ5¿¿}<‘[Þ\pNnÅ÷9gkjV,"­ùVöFZે˜áÀ&²WŽG˜"‰ì”“jØÈVÉFxA”Í=f‘^éþÇtXD:¥ýƒ$‚ߨÀQ`¢uþõÓ@ ¤ºú3 çØF«d@âma5_³óÙjέ ñ"btÙÐ-}”^p endstream endobj 459 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚ]ÐÍJÃ@Àñ †@¯½9/ » ÄF„ZÁ„zò …Bõ(¨èMÌ>Ú>J¡Ç$ë~LµÙÃòcfØóê¬jHRYÒiE Iõ‚žJ|ÃÚmíxÁ§Ý .[T7(níE{GïŸÏ(–ëk*Q¬è±$¹ÁvEƌѱ©Q³y‰]CªÃœ*Ö>gY8U°³Î#å±`k½²ö¬&•³÷98ù7‹,¼ûàlïsÇJﯬËB>ø¬S}òŸƒ>éŸÙÔ±˜˜Œs¶aeÐø¬ý˜-«#ÕÔ¦~G~±—lÆÞ´x¿+%eÒ endstream endobj 460 0 obj << /Length 318 /Filter /FlateDecode >> stream xÚmÑAK„@ð'‚ ëU(p¾@©™äÒAØ6ÈCP§Õ1¨¨³³ßl– Sb?‚ÑEXqz㨛ëžüñÈûó&ŽÃcêÓ  GtÒè„>ä•Ħ>¦íèá™ÌRâÝÐ8 ÞæÄK/éûÛÇñfWgÓ9½ÅŸîH:§BTºÁ†4‘Ò ÜÀ-AÇ]˜+ÅÉ@kS]Ñ”„žÆNZC E$«ž6ÒÑEfŠ{œ"92gÖ=ƒ4¦x? vl¸ìÈ% É„k‹0QÔq£µá¾¢t6Œ®,¤¬ ®${Qtpc6¢äÛ,2Ȳ.Þ¹lÉ!ÿ„ŽIËÉ׈¿Øã[qÝÓÄÓ$eO·e%7ŽXÊJÛÔqèòžvKÚl'A‘8Q”ÒÈyJ®Éj㬠endstream endobj 461 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚmÁJ1EïÐÅÀ[˜?°ï4N‡Ùˆµ‚³tåB\©ËB Ý%Ÿ–OÉ'ÌreâKBEÄEáææÝ›¬ªËfÉ nøbÉ«š›†ß*ú ºQä6Ÿ¼niÝ“~âº%}'2éþž¿>÷ï¤×7\‘ÞðsÅ‹ê7 ¨€™€"‹r˜;(«<Îe+”c†I°‚ð Ôˆë<+aî#œ K°1D޲Š1ÚÄ1“D?i˜pò¥ÝÏ€<ïRÐp&–Aì7N~ø +Õ¤«Äxv˜qˆ¯J½•“œ2~AbÇNè¶§Gúé«jp endstream endobj 462 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚeνŠÂ@à Ñ6…ûN²1’NðL!hµÅ"v·\6ŠÖæM|ßDÁÒBϱÐÂóÁ{¦—t³µÇ¤šõõ'‘•¤9æ˜#ß2,Ä~jš‹âVl1ÓÍzû+v8i"v¬_‰ÆK)Æjpª'gÄ#> N ý$"òOÜÝ#ð÷$ Ò$á 6&')Éx5ðÍ“éĤ47tGü4HÓxWtAN*²sÎ] î‚¿\ÌÁ‹ó;mçN/dRÈB\ endstream endobj 463 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚuϱJAà± ¢­•7/ {›Üy¸Dð A+ „ÄRPQ°òÖ7[ð|ûW¦8¼Ì$Ml¾…ÙÝf w\9ç>rQpYòÜÑ3*)æ\V››Ù#k²7<ªÈ^H™l}ɯ/odÇWvd§|ë8¿£zÊØKdiÐ"ëû¤D%(€ï;¥œ”Û<)÷ÿ‘”Ø_ŒïOIY Ó~0-Î`> stream xÚ]Ð1NÄ0Ð¥ˆ4à¹$Ù]C*,-‹D $¨¶@T@I‚aÍ7 ¥ â)]D˜I²H@᧑ǶþxUï›W|À{ ^6†ojº§e#››Ã¹s}Gë–Ê-/*Oe›ÊöŒžn©\ŸsMå†/k®®¨Ý0€$«HЩ"² òŠNjòÚ ‚Cñ52 ûëEÿƒšèÝYý‘:èÏa_ñ ûŽ#Ø7yÑFyÛö‚“APÁ¹9ãgô/þc'‚ûË‹Lã'Ü8—…¤Þ‘ME(/YUPA2KÈ,Ÿ‘†)4@'-]Ð70¥oÈ endstream endobj 465 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚuν Â0ð“…ìÚ¡Ð{MÒZɤàØAÐÉAA]ÅGë£ô:vjNLÄÁ ?È%÷¿ë©n–$¥¨“P&)ëÓ^áSmªæª?O»#Žr+J5Š™©£Èçt½Ü(F‹1)Z+’Ì'ä9þ›‚išæüPdžŠ)™"ðš›$@›‰` 2š9I*MX‹½‡Ðf"‡fNLÅ¿ …[†[&Ë0wÇÓÒrxµÅÿ%¨þ¿)-[§9.ñ†©O‡ endstream endobj 466 0 obj << /Length 260 /Filter /FlateDecode >> stream xÚm±JÄ@†ÿ°E`š}ƒd^@s¹\ˆ…8O0…àUb¥–Š‚ÅAòhû(û[¦7Î(‚,|Åìÿ;ì¦>m×¼â–OÖ¼i¸mù©¦Wj:ê¸û¹y|¡í@Õ7U×:¦j¸á÷·gª¶·—\SµãûšW4ìÈ€þ¨™à’ȃ‹ðÈ á˜q|êùEú‹Ù"³…«‘EȤ y€D?aœK`\TÖ‹&K‰€—  ˆ*2›yY€b5–2eɛ™"“  ‰ªèã…¶£z|.Îóü¾¡‘|2@kÞP@U”ú”Ê|„³/€Øg”Ú¡«öôé8p endstream endobj 470 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ1 Â@E°L¡70sÝì ’@°ˆÜBÐÊB„€ZZ( 9ZŽ’#XZ:IV›t«þ 3ïOÌØÄrÄ#²‰xjø¨éBºN%7nt8SjImYǤ–’“²+¾]ï'RézΚTÆ;ÍážlÆ@TðJô ø@ ðhxÁ«jze/¨ š]aöåÙáýÝ;¿íÇÎAdDÉ/ak+ÚÎ?i¶¥”T“‚RSÊ"§…¥ }G«@ endstream endobj 471 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ1 Â@E¿¤L/ :ÐÍ®A"ˆEŒà‚Vb¥–‚Š‚…EŽ–£äÁÍ$±ÐNxÕÌgæý¡˜1‡qß„l">hº.§!Ǧ^íO”XRÖcR 7'e—|»Þ¤’ÕŒ5©”·šÃÙ”s Î@ t€h~//i¹ÝKxO`L®Ð“tIVãçßxÅ?üÞù¼¨>ö‡©(=C±uÚ•¿/ñ@ªÅRÓr•iniMoEËBs endstream endobj 472 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ52T02R03RH1ä*ä24Š(XC¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿüÿó‡a0C ¹\=¹¹¶ h endstream endobj 473 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚÍŽ;@PÕggÜwAí“x…„J!*” Âî%>‰EÈt3ÍØ00 •¾UjÌØrR¬Ð豆iø¥qAæ 5‚T‡¸šûv̬ɩ‚½Ò p¯ó:½_ó¢thq_þh endstream endobj 474 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Œ?øØ¾á„ËüýóƒðÚcyn€8£žáÐ@§Ô­ÿÏ¡A|8X¤¤^þ}ÜÇÿ& ð…(¼À…ã.WO®@.QåXÙ endstream endobj 475 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. þ```ÿÀÀÀâÔ±=700ȃ0P’ŸøÐ aþäy û]ɃÔÔƒôÑÃ} p…(\ìàN9~ ×r¹zrr°Wß endstream endobj 476 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 477 0 obj << /Length 130 /Filter /FlateDecode >> stream xÚ-ɱ Â0…á gð 2œ'0¹-¥™k3:9ˆ TGAEçæÑòfÚ¢|Ûÿ—ÕÒ7ôlXUÔÀ:ð¢x@='eý;ý m„;P=ÜfÌpqË×ó}…kw+*\Ç£ÒŸ;Zä“Fy2d›åÏd“L*R!s™ÉB¬¹ËY°ŽØã ,P#Œ endstream endobj 478 0 obj << /Length 164 /Filter /FlateDecode >> stream xÚ31Ô35R0P0U02S06W03RH1ä*ä26 (›Ad’s¹œ<¹ôÃŒ ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæö8qsƒÍ憺Ì ÿê››ÿØnÿÁÿ¸ÿóïý ÿÿ10Øÿ``àÁ 6P $RR ÒÒ 2d>»@nárõä äT¶Dí endstream endobj 479 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 480 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ-É1 Â@EÑ?^á ¦xЙ‰‰mŒà‚V"ÑRPÑ:³´Ù™&Nwo¾\ø’ž%红V\ó¦xA=y1žö:À¨n×w¸°ççý½ÃÕ‡ ®áYé/ ­tò‹½4è’M22ÉD³˜ÉT&2+•<å*ØñBÛ#´ endstream endobj 481 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsK…C®B.K Ïȉ&çr9yré‡+Xré{€O_…’¢ÒT.}§gC.}…hCƒX.O†z†ÿ 0XÏ ÃÀåêÉÈ[\w endstream endobj 482 0 obj << /Length 153 /Filter /FlateDecode >> stream xڅ̽AÅñ ɉ¨ŠóÌ—eëµSH¨"‘ ” ôÍ£xw³ÓN¦ø5çæþgvZ8œ8K¿àÜñbñ€·²–>žÎ7TzOo¡×²C‡ _Ï÷ºÚ.)k̓<j*¥zÑP ¢±‰R˜è.NÑO|[ƧÕmÈÜÏdSéL6•Îeé\6•NdV;üxÔ*Æ endstream endobj 483 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsc3…C®B.K ×ĉ'çr9yré‡+Xré{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]dêþ7À`=ƒ 1S—«'W fp"¸ endstream endobj 484 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ54S0´P06SH1ä*ä24PAS#¨Tr.—“'—~¸‚¡—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEA†¡žá Ö3È0຀`ý™ PÈx€±±¹™¨Ò‚¡€!ËÕ“+ &,• endstream endobj 485 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0U04T03P06TH1ä*ä25 (Ae’s¹œ<¹ôÃLM¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿAà˜üÿ‡Îj-Ô\®ž\\~,Ü endstream endobj 486 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 487 0 obj << /Length 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 488 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 489 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 490 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 491 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 492 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 493 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 494 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 495 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 496 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 497 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 498 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 500 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 501 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 502 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 503 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 504 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 505 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 506 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 507 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 508 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 509 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 510 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 511 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 512 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 513 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 515 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 516 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 517 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 518 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 519 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 520 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 521 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 522 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 523 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 524 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 526 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 527 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 528 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 529 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 530 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 531 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 532 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 533 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 536 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 538 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 539 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 540 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 541 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 543 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 544 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 545 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 546 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 547 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 548 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 549 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 550 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 552 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 553 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 557 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 558 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 559 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 560 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 561 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 562 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ¿NÃ0Æ?+C$/~„Ü @pK§V*E"L02€`«÷ÉÈ£Dâ`ž”7Ѭ$7ëãî¨d¸¬*¦ ¯:}§¿$ X endstream endobj 563 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 564 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 565 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 566 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 567 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 568 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 569 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 570 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 572 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 573 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 574 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 575 0 obj << /Length 238 /Filter /FlateDecode >> stream xڭбJÄ@à?ìÂ4y1󺉗‹[8O0… •…‚Z *Úš<Ú>Ê=BÊKÖD¸Òæ+f™™¶ö‡Ç+.yÅG\×Ü4üPÑ -½Knü÷Ëý­;r×¼ôäÎ¥L®»à·×÷GrëËS®Èmø¦âò–º ÁØ`#úÁ¦” ÌJT&e« 0m´ã?H‚M¦ÈF3âC‚ …P J°@¤#ßJ“ÿ2 ‹_â.N”^‘v2%5+w:ù‹gY9–º×Cbì)û@;ä@¯ùf,B‘M¥—B‘~2ÑYGWô îøeß endstream endobj 576 0 obj << /Length 219 /Filter /FlateDecode >> stream xÚ¥ÏÍJÃ@ð Ci®Š°» ùX/b Í¡ §ŠPB,íM$–Gé#xôPÔÝ .ÔC¡3ð;ÌÌîÎ&z’§¬8åë˜ÍYÎϽQ›¢âì¦ë<½RQ’\q“\˜2ÉrÉÛÍî…dqÇɯ#VTÎx$ltŽøc¢uZGaýÚL„ÂùÚ¨EeT°†{Øšôk€ç.àÐYàjXà î-æ‚^› Çð Þ:~ÀwÇßޑþ×ÿ'žaðÙ”æ%=Ð//ó]ã endstream endobj 580 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×31R0P0F¦ :Å« Ì ƒYɹ\Nž\úá@—¾˜ôôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàg°?Pÿàÿ¬`€ŸËÕ“+ è±"g endstream endobj 581 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 582 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 584 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 586 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 588 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 589 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 590 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 591 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 592 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 593 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 594 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ33×3Q0P04¦æ –& )†\…\& ¾ˆ –IÎåròäÒW01æÒ÷ sé{ú*”•¦ré;8+ré»(D*Äryº(000`f0É&ùÁ¤=˜¬‘ŒÿA$?˜ü"ÿCÈ ÙÿÀ$Då(9„Éÿà$ûÿ?àXþÿÿ&ÉåêÉÈie£\ endstream endobj 595 0 obj << /Length 328 /Filter /FlateDecode >> stream xÚ’±JÄ@†'¤XØ&oàÎ h.r98œ'˜BÐÊB¬ÔÒBQ°2y´{”<•[„Œ»ó¯ÁÂòÁÌÎÏ?›¿>;Yò‚k>>åºâõ’+ûbW±¸àuÎóݶ¶¼åÕÒ–—¡lËöŠß^ߟl¹½>çÊ–;¾«xqoÛ¡ø4rßLd¢X鉜ÏdZ=5¡ù Dá-FÊBÁL”‡v.dú8šÐQOöÅx…ºÁMÿEãÙ  Hÿ…žÔÍOs˜Q¡¶ åZDæç3½è „EÊ!Iàösiãçg’‰ä,¹þÞ¡K€™óÍoø9\˜`5àFøøÿ¡ñºUÀ PSÍá–6ð¹ù#Àá) ˆF>hP2Ć&˜7·t>«Ç¸!|ºH‡kÕ`Ú‹ÖÞØ/U=Å¡ endstream endobj 596 0 obj << /Length 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 597 0 obj << /Length 339 /Filter /FlateDecode >> stream xÚÒMJÄ0àWº(d“˜\@ÛÊLe@ˆŒ#Ø… +âJ]ºPtÞÀ+õ^¡7˜.»}¾÷R¡ÝŒ–Ò¯$!Éû©ÎNV¶°•=>µUi7+û\ª7µæÁÂnª8óôª¶µÊïíz¥òkVy}c?Þ?_T¾½½´¥Êwö¡´Å£ªw EàÇ`Çxè› ŽD6&<©{p-­èø×ðxš&hY:@B$Òü›ñ(‹iµš LJ¹v‰:ßòu–ôø'ƒ ÿO˜c‚?€\pÂýb&$¢ gìƒÄ¾”H¾C"œ¬¯À9Ëtà j‚òyDÐnçåtÐ;ÆŒÀÀ…«5Ñ@ê nI;ÇO4sPêÊ…‹e4±¨BÒÅ(ôΗ¢S9¦ÝÄ^Ø+4IÖI“¤½ìNÝ%5÷(5p(­˜a NÆÔU­îÔÃâÛE endstream endobj 601 0 obj << /Length1 1416 /Length2 6052 /Length3 0 /Length 7019 /Filter /FlateDecode >> stream xÚwT“ÛÒ6Ò„ RE:QCHè½÷*¥† ”$$‘Š ½IïU©*½ƒH‘* H¥ƒ)*J/_PϽ÷Üÿ_ëûVÖJÞ™yföÌÞϳ×Λwøí‘v05$ËI•uu5Á $, 89áXWØß~§) #RÿPFà X¼O‚Åu‘ ÖW X“‹K@@!Hòo -TxÀíº@-$†p*#QÞh¸£¿Îß@n(,))~çW:PÑ ††C! .ësï…¸P8 ëýÜ2NX,JJPÐÓÓSâ†@¢åxî=áX' ! C{Àì#õ n°?£ 8ÆNpÌï€Òë AÀx‡+ C`ð)ö04¿:ÐHS¨‚!~ƒu~îÿl,þW¹?Ù…àˆ_É(醂 ¼áG ÜÔWÓÀzaï!û ăÄçC< pWˆð«uPMÑÁOøg>  Ga1¸ëÅŒ‚eðÛ¬Š°WFº¹ÁX à¢?8Åï»·àŸÃuA =>[p„½ÃÅöP‚&¸û˜¦Ê Þø·Ï†Š‚$Ä…%D0w Ì ê$x±€±7 ö+¾pãgðóA!Q@ü0?¸ ÿðÁ@<`@,úÌÏç?ÿ´`0ÐÅí`ŽpàßÕñn˜Ãoþh¸Ð„§ºøüëÉ Ï0{$ÂÕûßð_G,htOí®’)ߟ‘ÿTRBz}ø……€üB¢ $"Ç?øý³Î]üOÿ‘«‰p@/Š]ô‹ß¨¿{öøCî? áþ³˜O]ûßL·‰‚ ø/ðÿ™ï¿Rþ4¿¨ò¿2ý¿;R{àêú+ÎýðÿÄ!npWï??»Úš#»]ÜÄùþ¥ñDŸ–[”OÌR”ؤŠÑÝwY£¨ÚÉåí»8)}ÿªîü˜èÉEW¢&®Ò¢×Ú^Y’¥CÏ"iúå“!¶É®ÏxEt—á¯ÜOn±AKÑ–©z·´eZ žT ½ý}3Ô]¬QZV¾s„b©U¥ûXTD.W˜Î<½ö3·Øc3ƒÆÇNVaÓ¾ûÅ8‘³§;­­J\SîQˆšhÜBÍŒoFÁ“ã-°à›ZhzU´2ÎÓmqß·ÂkÑJ§× YèW†kqýºðúq4R Èžól£-28†A 9âVÙôRWø[)aœ=A‰^Þ‹ãÝ@ú·=Èa€GI`ôñ&ît“0¨@ÕâHžß½.m:Úæ(Öû´›‚PnòÎù¹æTý-7EÐà©¡pýD/]ŸO+ßSúæeIêÅøƒ•aݤe}J'?~ÚiîÇWÑô­'ÄF·(.ì6åFñŒU1½ÒR"H& ùìsÖæ®°#3ÓN–ì5v‹Vös»s¤ÍõïJ,¦óÇ=.×o›ÝbÿÊH¸\Ÿùz²½Ž¼¯†Ñç N*àܲÚnòŒÖ{Y6¦!·§â·÷l:;¾û^òµ–¯µU`çûåAŽ%×HÛÀv­MYZÏ!¾¶­N1Åvy:<ïmA-¸@ÎIß«Í Ä½´iNŒF !O¹HúÑ ÎøG7&¬“ @7³«Ît}g a¸³ÐÆjS¨¨á%Äù¦Ä'›Á$y÷¦g*…=žÇÇÆºäÝ±Ž¶KÈøŽh"ƒP „ˆØ(‘.mÐ’ÐÌœô ƒ·øF¦¨Ç.Q~1««êG!³TN²^DµzÉõ;|Ш9¶`·2VÝïpÎ0ì‹ôä;¡X^¦ßf¤QͺJ,ãÌgPÕ»¹™Ù7MfíëoÖHÛ‹<Í7.¤œ•º³tìAwªË;3!͇¾~Ù<º‚wÕx£À`lÞ³[âÞc'¶ŽÑïi™èyßç¨MùØ¿lq ýô5¯Ì'Bgt“+¼½Ðož-¹Ô_´p|ð­n^N>vj¹Ö8ïcò›¡gÆØ¢ Œ-Ö´Ü&h^ceé` ÷>ùÚxÍ/8/ »:eþ4¨ù–xÀ¶;6xÁáØ¯fu$‰§2T‚ØÈpÌ<ÙûL¦VÈ9Yߺe1¨™Š³ýJ¬IvsÈ‚ÜxŒ`^iÅ3e7äü hˆ³Ôï jú†ýg'z¹HšÈËÖž*Eß`»ö׺ˆ6 pû{#Ö muòd¨+pai–ê@¥î&EVØÉ [ïîÞ¢‘[eÚÐõU`Wî盟ÆÈÙ^ÚÆ7ÇÞ“·Q´¤é&C,¢€ê€lQ¡ûÂR Ù Ì}2÷ÔG|À‡çPSMÆJ"1n´î­Ãlˆ}@@Ðìs½ÍP!+(²¸/²s.»ÅúþÒÃ{ºÂÉš·CC{²Ê×r÷ã½OÚ:&ÝÍ|á;¼u]‘¢~Ï %‹nTæÞƒ´ÔR_ƒÝ[Ïð‹#{&ä§úfcZI?ô2úòô `±X»ÿ@hÛE)!¼çÌõ›œgœù†Ì'{1•=Ä^4¯hý–Õø92oeÚÑÝä®Ã¹¨Úa¥kz¯­;4ve»P,ë1î‹”‘Š¥ïÎ×Ìœ;+òfÚ:ކ<¯ª&ç.ú,=XipÕ„=Xe·öVAú°S™@¶Î¥fÁxú3ä(î¨H~ˆ!Mù5­¥Ùf·<ä2õ¨ƒ>™ÙÜ;Â¥’Ü’G ÙƒøÁ„r® ѽ+oFKŽêÞ$¬âŸ×¹gzÿ¹Ýó‹AЃAgz9Õq—ê€ê›æÝí:q­õ‡OzãMR+÷3—€ºa®ÇÆ,}ˆÑ3ïÌ.˜IOÏùOLˆ"ñLV$2D˜}È׊Xa•¾¼ÊŒk œÕ+çJfJRoV¨ ”$”îѼ´1¬†Kâ(j 0ù(¨MHäúÁAÌË}!•ÜPíéWõHCC°†—óxÚ.Ù%±âç½*o¤×»zçòo©^ùÕF¯Òˆ,½ëx7ä›sL×iÕ3²‘ò±÷1»@Bò,èq3ƒiU4©4yg-e uiè…Çx8[~<+§Jt^^¯ÏMÒfÉÿf4#[ΦV'@ƒ‡m°WÇj ºŸÿИÁNÇOPnHÔ…æ ìçSý3qzÑŸá·™¥’?ÜyjbC¯sW>¾®·ÿ†žrùª‘îþ{øÖû«SrÉר{†ÂW®¬üæýà|Û¬3[eCb-Šc{Ìw;çfƒZä|ÿ`dãÓú”N¢´ÍC€½AŠ–&G}sJç½>î ôn†îk´ùZ þTD’wR^ˆÕ|ºa>Îó÷R¼Ü|Æbt‡D+DF±3¡8Þ=ïíÊýhIçRÓ0öe;Ñ–IÍ·/käíŒ/ÜFyéOâŒé$ã¦U› Íôù§R&:¢)+5ÖQ« × ¤l·È,q§¯©GÇØ‚UMI|²Á;àÁ ãªdSÓQQo3m_\ÀèÎRêwß©zìåg%ûõSÙrܤðT»ñ„–˪EukÝÙ{aÛS¼3drE×Ôìyæ¾ÀgÚ{üصô´õʲj!\öûñÁ…a#1,¸ÎµkÖö¥]Æj$An3æ&ý« Oöýôq•ê5#ìÕB¨è—·Ê‹ QÝ¢T½^:*oÛÓ"ëžvë±¾3$êD}ÍrèñZRáNy4ˆÈ«žšÈš†ÏÄ<y¹Ú9ÙôéX=GVIĶ£jñŒŸ¨ô´áËÞµµ ’@Ü«”•Xt9 åÆÂ(G¡Òs BÁȸÏRJô{À‰¹\êÌ9£Càb +Œm a7Ù7£9‘»Š^$w¾˜{ý»Rõ)?µKË˦œž—ÂÅÝ“—ÚlånQ³ s6Š­~h¿ß<ÖNCv‡ÃFî6®bATÓƒòø^þ=‚‚Ô|&QñTÂM7¹÷9‹Ø¾UOúÖrº?éHBI+j¾e?õz#£²zѵ€D½w¹•»æ}¥Ú—¿‰Qµ+ÎŒ÷ÚÚ.·:K RÞ ¸_p~fRÄÉ{,Ælùq§^iu1q*^¦cån4ŠÈ¹, ½gݳÂ/™ƒ—h=Ïiø9|eRØ=ð³v¯9Û9Äï)Àò5VCyãòVÿ[º @eqø²ŸÜëZº’NT*󤂹ucøÔ÷µ€O*´2Ìõô8?œ»˜~ê¡2Yß··,,“÷ÏP@®TbÊZÕç j1n<ó7æ „IJ±ó†+ðLW§—ËÍSåt©ÉõÏ6Cü/ý\üuF>-}}u@]¶Ëú…ÓÇ —ŠÌ&8¹„ÝXü¡ÆúÆ¡—ú¹@|(å&ƒþAhÆý¨oÎKjtÆ3-ï®Þá€l1NWc’jó >Zº@]ÀÈ*¾Õ‡daƒ«óĪav[Qw”ËÝw:¹BOÍi75ó3{ÆÓˆÑ¯,§ë_?zsþéĆ´õHXlFÛß@É/¯Èrx¯*t|Ç…ôiÐPŸb;÷¤•î2ãjJr*ºý™8ëÀ²‘÷úÉU®³Ãï¼eYvK¬q¢ªÑŒ8޳GЯs £HTì+Åï„NÅh EÈ«p[­·‰g.Q-MƒêªNã\kò׃B€ù´ å̶ÉÙK ’Q7Ó– :‰ãT+C,ÅJ\[Å_L¼&Ò¡üª#L+!‰È—ÆvŸfÛD—+Ú~¾Jj•{ñEÛË]¸³pá ¶˜µ,s=îïˆÙÎpPþ ìªj¼BEs’À–õº¦P*—›UC®¶6uwp¶f\ºâàcï‡'Á~nfYëü?êt‡p[Œ_\Nôäi'¦QÎ&Ó"H˜š³¤ÞL©Ÿ úúEªë·¨9'Ku[»Kû6‰‚Œî¹í>kaÚ ÷ŒÚñ½­¥e’[/Î=Ú¢÷œÏ¨ bäÓrgYÇVEJ0R­V½ÌÒBå!¯ªå]Ûj«¡t4Ëgw voÂÈò§7ø±àÇ™{ãídB“gN]NW|æI×G’™Cy´Á±o{ˆ–¾J¨sRG †ZÞlö4èþK>Fœ¾æ€l2‹Þ|žÓ JŽü4¥r3¥ÞY…|ì¶„ô•‡O¶kÏw0Ĭ¹Ö•²ŽÊߟÆ×ÎÊ­m~À]–ޱ±JlAûãÿj$VDbRt)?Ww|Ü”vô†YŠòHIV’cïòÞMŽLÞ±ø½ã>'4åÞÍ rvX©ôÚÀµ€Q³n{ÿõ3jÚâ9AÁœx¹¾0Æ ^iúÜýJü`cÅ‹¤2ª ÔgǽKžÞVó–Y3!w·ogò9 µë÷¥}ööŒ›DQ…¶ç¾Ž-Ö{º5Nµ@Úê²¹Ðe¿àÕ¡é¤*ÛT^h•`…'´û]mþ¦ùèäk¦Ð,cùí«…aÄégÝä•©€÷ ЧÞM&†. Dqø7’ºþæoÛBƒ}[ÌïŽç™¾êæ^ÇÍl¸ùx¼zÜ©‡åÍü‘¥"PI¯dJ °‘ƺŒÏñgfoˆ°rד¨•m¥3^9œýZÍt‰HQ?—»<óÆ¡Š“{æ5¤2­qKˆ‹$I¡½å_a·´+|SöêŽÁzR*÷¦ŠŒtseWÃñü¤æÊ‘†Žõiýü‰b­c¨zâ[=£ÞHhÐøÏæhÐÙ%ñ÷Ê­••ò£Ö*édgÑq#¶)ÛtY®îeÜBV³méz0ælíµ$P ëùâQ8åà…uLÚö5ºëÔ¶wýÎÙeµgÏåUVµ™33¹jøv"òÑ–B䢽&P­›Ÿî™<)u"©ã%´ÍCŸ(R”%šHôôv#ãxQ˜+,GWU ÷]]Ší|;ƒÒ†ñшœ„!ïáÐ úàÉz?¶—kÚëµMƒn¿`ZŒÎIF©JµzögçŒÐ«Bi(s;K;e5÷Ö#еzm¿¿I2ç1ôÚšKX#êò"˜r*¹MÖ¬¢Á¸‘; ê#„Öùw4Ñk^Y mÜ ,”r'¦ïésòÖž­=S“–¹wžû.ä§§ïö‹†yòqjÚ]cAtÛi{Å–b—ÝFKo~íɲk)§+n”ñÇ|NT¹«¬'¢mY?»½*¯zû‡!bô ùÖÆ¢ËíÙÜÝ£¼c_- žó] KbfR:¿;I£&ò*2<)[V™§ß’_~O(ý4·®þ®—º#‘„ !ØcMSwÑ;Š C‚^DP—Õ·²¡ív®¬­S !I<ö*í„K?ü驌ÝQrVnÓ%ÀR.C8›´ìÕLbõé‡qTâFhWh5G„ËÞò[…%²º¢´(ˆn@øë”t·û«a¾'i»vŸØÒ)®`uÂ$Fª@©ýá¾Ãc­úl<óîïV¨Ô’±ä)ú¹„ù²^Õ…ÍÝ$QSW?Ù¬vËž'Rò¥VŒêK®„*ú 2<±¤Xô¶¦¼#ëeÝñ„äelûü1}²0g¥©% ùùàÏ+*$/câY,ïz«$M¶]v3+²¹`9Oñõä¡Ö´] ,ë„C ¾Ì+~­lcÔ-á>E®Uo…W_é?=$% !lOA îÇbG˜(¼(’wöøéyÅë·4†m dvÀý€¦ ãK5Ó.ïESíÍ1Ç)«‚ì]ÌPâ+îÞ†£2½l‹^²»üYáÄ?Õ‡éü*ï5}ÃAÓÇw+†ùyà„?ÜL'æ¹Ku2R–Ì£ž]:CÉ VQ¶qÕŒýT­~´?™/6âdáÒmôŽÉ¿§\Dnw´ÔXÃG®èy];pð ÈRŸEž¯*¶Ìêj†“!9;Ôí·a²2O÷ÿ+Í£‚õDÞÀà¼ò.§`1éaEš/%T‡Š8x·Ö˜˜:÷οšš0ëœYç˜)T|¼°Lï~û@®RtÕ|dÛ†l#/×` ±ø ÿ‡aq·ÓFzÚ\“_K°_¯g¯î~Õè¤uÒPÔ‘Çò”Û9æÜn…—^ÖÍ|:š¢é¹6lUÖ¾ÅȘ6{”ö‚G“ž°ó²Çª1m§ò—tN×Q?Ä!Eƒú g^ÔØ—Q©>L<éçê¤{ô‘´§¸àð¡N“€<¨v–ÿýÒ”‘­ò‚Gâî0ãŒúb»B  [Ý07Z‰56Ó· eý." ïÅá•àõ™úÇãCóFƼÒG mu:›o š›È]\‘YÐ÷Á¸T/©Y ß6qªvMKÛÏ cbÏÏÏ0îaÆ¥­NÄÐSÛ:‰\Rf÷"»ZÒãKŽÏ êtìå¢#µ/g^U8~oùÍHOJâI>ý_ŽÄëEód&òs<Ëã†vœ#'SÈ膀´5¹H±«K]½þ»v¦ÌXÎHIœò¤'ÀµŸj«gÄÒŸÑï:‡G'2E¥0}Ê1tžìÌ;ðh#o Â~峊½Æ»5¸_ŽË+w: š<´ä*êæ k?_ÿé.PÕÈÚ6û®0ìF×Páf¯k’©—ðžqöó+ûœ:v8&R;#ÜX­ R*î½Ñ+„𠸧ï]Ý÷'Qו™ e™\oáuF«Ã<.ëùølrNñ[D/åð§ñå6Ñ X¦Kœ”aªQ¹®_]ÞÈ’pëq@@äu£†U†¬¤²kˆØ#Œ$™Õ„`§X÷¼ø©cKptzy錔–åø AIBûζt36â ¸|²Eé[ý³ðîÏ>¡vî圱ý5GD-?\TÊu¶¼ Z$™É"ŸÝqr›Úç,ú8jLÄË­„ò®Å…K;J´2pœrÝ·»‡©¸\s~­¥ØË© a~ÅѲ$:©cNLJ”‘–à j³ux™L>¦µ Í‹³âŸyíÍÏ->”‘j©èÅynþ¤À¤c>áyR†ìX PHiød”{ëäG‹ %ŸÅºø¬ÍíQxz õqKʽø®ý¥w‡–ûÇŸÖ;V>|³F‘‘àúÙz`G¤®ÿaž¯…¸¸\³èx®¨æ•Âm‰è®ñËI6.ðrûÂø‘vèõ …kzÃ7ÙŒãÝ(IÉùþÚ(›^ endstream endobj 619 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.16)/Keywords() /CreationDate (D:20171125154536-05'00') /ModDate (D:20171125154536-05'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/Debian) kpathsea version 6.2.1) >> endobj 149 0 obj << /Type /ObjStm /N 88 /First 793 /Length 5395 /Filter /FlateDecode >> stream xÚÝ\k¹uý>¿¢>®¨šï ,°Ydµ^XŽc[Ї¶Ô«@«YÌŒ çßç²êòöcF=³²ƒª®b±ÈËKÞs_¬±!Lf²!NÁã'M%á'OÖUü–Éf‡_39'íäYý\˜¼BBÕh¦hÊ…unНÄ8F#Z󬞧Røz™ªÁ³8U‡ÎŠXÇ&®• 1·3I áÂÖVˆÒpxÜÕ89‡å:t ¼ã¼A„C5J2¨­Ù°äÒ‹Qfë/¼MStx $$ïòä£ÃuB] -•È’€>0Šˆ†²)S0è´ 7Åû„‹:•ìÃÄq.žÖ„A„à¦Z=z#Së§Iná˜)è0$ðÊ[q.xêÈòпµ$EЉgÕ]D6â Ûµ`TE¿‘Ì ¶Z\2 lŒ™S—ÑiàÌÖ–iq/TNH³’áeÌ2èüEã·Ã¸Hwò艌O“ÎMÌJ†èN†OzF{˜(Ôw…xËñQÁÔ:¾W=Ö¨ÏÆâÖñ¢¸‰Ë«-&.3G’"¯Ð^2¬0¹ ã°9>eýÜH=¹`‚›+&¸‹dÁ“âHÛ/m% J1›¬‡> Ãú(9³úÀÂäSôQªå…W>]<{v±ùvzæB>~?mþôç¿pf¬¥dfz>||ÿþõÅ—_ÞWÕ×¹‚IçTµ¨Š‘ŸQÕ§0gŸQÕ?Sl÷ª>¿úp;={6mžS \ç9×zZ¯¥§_cF±Ð–ò@Ù\®-Ň×hvóãõÕ›—»ÛéÕ´ùñÛçÓæ»¿ßNÒãþû×lßí.6ß ÷݇Û.H¾~±ùýîæêãõ›ÝMƒ’Vôb÷örûõÕß§W,àŒæê^£›í5Þm‹‘õÔØãÞØíLJÓ Œ8fSØÞz2rG…b×;¶—œÜEj"¹£¹´ìŸ³Â#¤ÉLOÑÐD?v!„¨‚sc!T¸j8Z5ÊBpun€ü¿˜fÏn -Úòðn6Nž&;7ÄZkèµ9Ñ@˜Ú­Ïÿ³µWf·Ü´ËñÌÅ9¤µ°˜ª=ÏÕ.]ôJÒLÄLÞÏ4íòÜÖÈú×KÏXÅË6l’e˜êf ³*)ÉXÖ`b‹:cMc†óXѹ ¤@ÙHIÁ/f*c¼ÕŽSv”Æ`;—,%Ç’UA@Ï) ,l§HcQ=É,l§ÂSmRÂ%•æŽõJþØD?ÅEdì  Ë…Î É ”°²H-Ñ´Š)¸Cm½ñ´ÖÖ›îô°ÇæUD «…õ†–]\ohÒ-p×à çõ¦™s‚ln)Ê@ šq‚äS¤ ¡X)h,– w•† F˜’äŽ=d¹£ñ(´4³±j,ªFcQZ°ÆmuE&ÿd¢Š¢]<%÷xdJw ý©}d¢cu€LÎûL~¦§ÑÔý)´èÏ)ÎÐñO"ñ¦òyÈ3 ªöd©•ç”NáZž1ºæøÖ5›Œv7¦Â"jÀ3.N~%¸Ãðn %˜9-7)’¨öTUÄ` ßõvÆ:$×µà\%’æ[gö,än´ý ¤ˆsºw‡ê´0iMã nÛŽ}lƒìCôò€€Õ¶û(…`lM¸…£ì£O®iëNñÄ—-_†{‰å¯`‹Mô“Æ.ÎØ*» [ÔUtÁ=[WÉmnè*¸°¯œYå¬tf…`3~€_¿vÝdÈx“ª9#@F€PçÌJNe?uà³Fá³Vá³Ó¨?½²“œ •XèlRXèlVXHß`¡³Ua¡sFa!à é–,d”f`¡sAa¡s_Ñ»øZ²‘;ôî„ÇþªÂP·ïÙƒ¡îú ÊÀK¤ ÷X¥]©@tØù~$Q¿NÔQ¿ÌVó–<í}^L­£òÿ­³yôæ3¶oÎüý¿|Þ§ñ á‘íJ6ÿ^@1[ÛX €ædݪSpL€8¢^D½ˆzõ"êEÔ‹¨3ñmfÔK¨ã" °N¨ÝލµÍÅ“ºçØ®nÚÞÍ™ö#ŽzdYƒ¶v4ëzÕV8@µø^êPôB³×AAE ð±jøLzާt¿rãÉ߯Ñqf¨1ž`-;åP;¾×OÊwöt©Väe5®À‹õàÖÐÌ–az/7@V¿b0<:Öw#R1B©Æ¦W¼G© Jµº°¢6.¼hÆSG4c„õ#š‘ÙÑŒhÖ‹2ÄX¼(ÃÈÀüª€0/º0b±‹*dL^4!@Ûi%Šr'ÖN­=ÑôT.âæ£+¡‰ÃÎÊTˆE™ ´ © 1 øHNB´$bA»A—´±F€ ¸Y)€'äR¾•,³Ÿ:-'þ'þíÑáapãW”±2ü1t*þÊ ŒkGŒ.3 ¼2p²6p²6pÊžSö œ²gà”=§ì8eÏÀNV™NÍá´ÑÜNÍå´–á´ÑÜ©N›;u84ñƒ6~jÔÆOMÚø©Y?µhã§Veüx±C¸³Êòb‰ÒòbŠ&\59 £&z÷‰ÙGÆFí„ùÁüL!1;l¦x†Í´Bž²™TXØçÙ:fëÎ ‡•@}›ë y,†ž`‰s[PÙ0äUÊÜp,,¯’uÈ-§¹‘S µÛ;-žU]ÑÞòÉ\` ,9àB™~rKtKχ™éºÄøW/£Y¯–úª(Œsfnq¶ÝŠX{€+wúØÌrwvì¬~¶EÓôñ>çzÏ 5§µ>ÃjR´þ?Ž©=Ê7-KPÈÔ£øõgõP÷k^Ü®@e–‡ÆñV9§Þ)çÔ;åœz§œSï”sêÅû˽8_à¶ß«ð<†Ï RìÅñÈzo†Žðkˆï×ø!Þ{? Þû  Þû¨ Þû¤ Þû¬ Þû¢ Þûª Þ£`ÜðôšôxÜ>h¨öACµª}ÐP탆jö : ΋%q>Ⱥú¸èÈßCÞÁ•;@6¬ö˜€lX²²a1ÍZÊwP¼ÿo ˆ-Ùby¨ž÷ÛÌ€´–5à† Fã²'Zé2w,wsœA}3 ÍήáA¬ŒjfY–íœ;a¸‚Ö•ë¡U¬ŽÖY-§3!Q=ô—zÒb¹ö3í6ÀlYFÐËúTCyýU¯E)¹Y%Ï”ú<Û Oú#S?ã˜ähm ÷ð$°Óü´CÈäݪ@;~8Üì§CW¸ÿ07ï7Cýc#á}Ô©®ÛÀwpÛ‹ß@°‚`?Ü2 ÉKrÖëð‚˜ƒŒ2‹5ÈM1b Âè b ¢Ù ÎWä.¤8<¤`”Oã‡CrªÒ0ÃÁÄIŒZku“´ºn Ðv¸1½4|?ÜöS†OãGZ ýh7Æk7Æk7Æk7Æk7Æk7Æë´’n :þ ;­Z_)ÃS (R HR sAë+å  ;å 0-µöRY%öWµöR zP zP Æ­ŒU9(\eQ»ÃAqm'ÜCµW9Ò^¦¬)—q½¯½#«vA wêÛ'B8ÌM…p”› aä¦R$BŸ>Dþ |¶S…‰=Õ–¥Æº™K3ûQ^óSX s³`BéùlCÀg]Ø&–3JT.¥7 ÀÔ]ÕÎLZËYïÍzx%÷©\Øõåx+@oO>Ö=t–ðIµÍz¦Jø„Oð”Ãé=*Úœç†ÊOíI ôŸü@æ -‘YìY"³˜³Df±f‰Ìb̙Ŗ%2‹)›¸cÓ 0ââfQ qqk„„¸Sa€qTø$ÓÖq+2›.ƒø™».ÌÀß >FarÓ ü âc”Ðvù þ§2ùaøL”f¥a¤w,w„T{ÁmÁ[mÁ?8}na`¢`ëy&ЋPÑ*„*yT:2¯Ó±yêÁ.¹ûÏG)n×åe.nIž'OK6ÂØ´Œ8p+óÜHOQ/`PåÝ5IÞ6ùXnDž­_Ûê5Ú¹DFXÎÀކÿ̘r>Ø©s>z ©§l‹ÍÓöa;%ÛbóP¶Åæ¡l‹ÍCÙNÊÐ â{R¶ÅõlÁ“’mq<)ÛâwR¶ƒÚq¢Úq$|MÙ–Ø<ÅYgIPœÅò¤8‹MJqk•â,æ!ÅYÌCŠszhÖÆÇä`C'úß²‘ÅííµtQd1ÆÃlŒG9ØU¶éï. ýœê¼Š_EUзµx×¶z´óR¥ÉVê2w»é 2¿å¼´¹l§Q]¸¨Ý ½â:äD,ÐÑß;%t 7•ÏAåscPùÜT>7•ÏAåscTùÜU>7F•ÏQåsƒ8ÙÜ!>6Öqº9ˆÇ›8Òª´°x¿ÔÂâüR KrŽZ¸ª­®AB1Ù´/ D G ÅdŒtìÃHÇ1Œgìc¸.ý%ƒ¹‰’/í[¹¡¬£äÁ1þ(N¿Ù'ãâ$`>£8 XDQœ,¢(NBsý$*BˆWÉÝ 1–ʵãGr7èHJ´*¹­JîF§“»Ñéänt:¹NîF§“»Ñéänt:¹NîF§“»Ñéänô:¹½NîF¯“»Ñëänô:c½ÎD¯3ÑëŒAô:c½ÎÄ “»1èän :¹ƒNî m1¹r|¨ý•™ÎD"Çϔεu˜_ùЊùÈŠy¸BÔØ´˜ø©eiI£³éQ–v5Jú;æðÓ ­˜Þì'›UoãJ?7 ä7Ô_a\1ÃÐrÌÊÆšhiìö ꎒØÑ6ݳ‡øÞ/{–8µŸˆ©·Ë(L'>Dè:·+Þ½¤i”ðt ÆP{bT{¢ uVVqœ(âDI¤˜ì|#gö¾GŠã $"Õø‰H5¾@"R¥ Ñ(E8)iÄIYcL*URÕ8’Æ‘üÐ\£=þbФš%Z»\Ÿ…´¯ŒùLŸØ ‰«¦°ªÛɽ£#tÿ*ájüœº¸GjËœÖø(°uŽÇ/´€k:ù¶ê€^šàÊÖ«]•ÚÑÍêfn_–óºW8û€ã Lƒ!ʶ›_Cj›@Kk”äü݉0Jn†J.úlé؈Ùeq–=™€ÛÛÞ‡5 –T bð‘bð‘bðÑ^£—&ZÑvTQ;Ù¢Jë í½}gQ¥uè`ë´NÜKëD•Ö!Q:Ú«ŽvF•Ö!Åþ´À»»ys}ùëíÕu—Ü.î/ÿüüǯÿø¯ß¼xñe ôýöÝÍ´l?õîȵ¨á)ù_ݼáÇÓ©¢æ7Û_ÿ}wùîgÜ »á³§–¿»Ý¾¿|óÕ‡wïw(AÁËÛÝ/œ²»Øüiy+pŘñÅæÝõn{»»Þ¼ßÝÜ<ét<¿ÄÛÉœdhìëíÍ®}t}4º=6´ÿVÐ7 (AI}f¹¨‹£¯ÐoøúGòB>)O«Yÿ—o¹éºÚÞ=”©«†©£ùÔÊÔæëÇ´Þ×ÌÔ×,5ðòÛ‹m7éiO}ª‡xW¶ÛÏ“í0?æî¿ËÿX>‚¿¯mByo¬ÛªS]Èò§þ»·ï/?ðí6/Ó"Mœ–I¾ kíyñòKd5Ê¿šVC^F´´ñãõîo“ÛŸÊöêê|5­¾ÃéW—›øþA’¡·¥w_;Fµs’»¶³zN'ÛYý²ÞN8ngõÕÐN¸¯§Û1'ÚÖÚûX[T3㣔ьpù>&kÛ<ÛÓ´÷xJ¨ÃâûâÛ«7O_Þn¯oŸLÝÙš¾øx4[÷dêºx8]P _qå ÿIŠ.©OÚ¿i zóýå/—·}J½×‡„µÞ <6B1D6DB89D692329C3E532790F63CA26>] /Length 1816 /Filter /FlateDecode >> stream xÚ%ÖyœÏÕÇñïç3f0ÖÆ2ÓXÆ2¶ ÆhÌX²GBÙ—vi“êº÷vo]n.ÑC:Yã ×V %ÊRY¢¡lu-%{B¤×ûôÏóq~ßóý}¿ç|>Ÿs¾'Š¢è–‹"Y4z_¤VuðÕ2áD ]ë V#jêÚj±"[×Ú«'Š ýÍ·S+^$ˆ»t­­ZÅE 1L×Ú¨UR$ê§à õ³”(-ʈòE¥ÂpËŠrº¯™h,ŠVêHDE‘"*‰Ê¢Š¨*nIYõðÐT= S­4µj ÅÅ©åÒ-*R4ÜWMd¨W÷¹ðÚÅ_½uD]õêm^Ãð©Óø\=‹’òÃ}õE‘#Y”V:²„fäšè¿!MEKÑÌ¢ZÛÂ}ÍE ‘«ûòÄíúY ò,j<1ÜB:òEk2ShQÞÍpKH@ÈLgÑÞ¢¶–EÈt(‹NâNÑÅ¢®)¡·«è&z‹îõœ:zh,!ç=ÅÝ¢—¸Wô±¨_«pß=º/Œª¿èkѰ¸ÐÑO ,1<\(é¡ô†X4rFèªkjyÕ®WízU¬17hVèPúX‹^h~ÆYô¯õ¡¥JôªD¯úó‰™Ïª»^*㞆ÿ<ãß ÿP9z•£/kÑ„t¼Ü&΂I¿Á+'ar?xõo0e¼v ^Ï„©Ýašz§O‡K`æ1˜õ3ÌÎ9á¿“`îÇ0oÌO„I°°¼•ÆR^$‰d‹ÞîEÇ¢’â]X< –´‡ÿ= K5¾e+aùX±Vž‡wNÃ{zè*½üý–°:Öt†µà èÃÇ`]WqÖ—ë`Ã;ðñËðÉLظ6ý6ëÚ–¡ði6|Ö>¶þI-N¯Åé+Y´mÛõ¶zÑ£açS°ë~ø²¶P„¾»5æ=óàëÙ°wìËšÑþÃðÍ 8ðo8ØNḣ6Á·óa¥öH8ÚŽ †ãàû)ðóðÿ{áÄD8Ù N‚ÓðcøI9?£ÿþ¬„ž}ν 矀 ÁEMõ’bpù øe)\Y ¿*«Wwõ3p}?ܨ 7+]ûýÜbÌì#pÖŠA‹ÙEÏBìwGÁY±=¿˜¥ß%Ô›XJUÒÍ¡L2”%$Vî9(ÿ<$DK> NAJbHöI¯}Ò§šUº›ŽÊ‰bT¥",•Uai!ôXµ ¨N ¬F¨IÙZƨÍܬNE¨K X¦Yï4¨ »A#VŠe-‡ì· Ih/4…VŠ5#’ÖœZ³Çr¿<Òh­b…b•¯´žF¯½Ý§‹jfŠP¡fÙæNhKB­Åjí)ëP:ÖNÔ©u®]þ]ÛŠëÐm/t¯=Ôq—BÜS¯ìÅ¢³Þ·CŸžp+ÏúRÅÖz±þca+Ù*.ƒÔ;x ¹ C5aJè}Ãá~åã*Ñ„‡öGtmøðh}ñ<6§rì –=yF*ÄO+Ø£Ø_왩ðì x.ìò>|ÏÃ<Ãl4ëÜþª¢ù{Cxžr´ê¿/ô…5 1)B·ŒU¾ÔƱ1ÚøGa˜8&±pì•-0ùI˜Âš±×ô<¦–ƒiÂt–³Íè3UÀo¨5[õ7‡’·¹,:›·:Œ´¶Ð‡Ô×5›¯É,ð°PÏ{›]Ê)V‹U/KvÂRÅeY,o+’•×à]Öª½§Ä¯Zï_5¹°v+|˜ë²à#vy[Ϻ´ GÃê }¢}³OšÒ±QÚÄb·Í*Ìͺy‹VÙ§ Îg*‹Ï5£­‚mÓ Ø® î`?°/R…:v®†]lö¥^þ•Êq·µGkëk±w1ìÛûUz´ jÑbŸ´oU»ßÍ…ÃìòvDå}T<ÆîcÇÙ¤íûWáeë„VüI-ÝSl‘vZéùQóýi œQÞÎ*µçT‰çÙYí¢VÀ%¾v™mÎ~Q=_Ñ?~}®ª¯)¦×•ýß´nèÉ7Ùíw½èViq92ÇfÎ1W„©ºz]Qïb„n‰»ñdÕ%°åºâ¬W‚Aº’lá.ñ>(ÅàJWæ8”ã;èÊëæ$¶ —¼5¤¬‘ÐáÉg›«GGEâìR–A%à*³½º*dßUeô.õuHÓãoca»töDWø¹êÌÃÕ(„šÌÜep pµ6Cm‚íêP¬.33¼2Ðt6ó9æêõ¡£~1Aâ]C6A—¥'góMqÏAŠÕ5Õ´r>€æ1ÐB!É¥ž]KRëòô¶Vjå§CëáE:ëyõ|®¹Â§Â5½Ns^>¯š×ñÍw:›yͼm¾»Dzp ×±ÌëXæu,ó:¾ù>æ’K7*-ú`j endstream endobj startxref 161055 %%EOF verilator-3.916/src/0000775000177100017500000000000013206353162014310 5ustar wsnyderwsnyderverilator-3.916/src/V3AstConstOnly.h0000664000177100017500000000260413205574202017273 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ast node structure // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3ASTCONSTONLY_H_ #define _V3ASTCONSTONLY_H_ 1 // Include only in visitors that do not not edit nodes, so should use constant iterators #define iterateAndNext error_use_iterateAndNextConst #define iterateChildren error_use_iterateChildrenConst #define addNext error_no_addNext_in_ConstOnlyVisitor #define replaceWith error_no_replaceWith_in_ConstOnlyVisitor #define deleteTree error_no_deleteTree_in_ConstOnlyVisitor #define unlinkFrBack error_no_unlinkFrBack_in_ConstOnlyVisitor #endif // Guard verilator-3.916/src/V3LinkLevel.cpp0000664000177100017500000001417313205574202017117 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LINKTOP TRANSFORMATIONS: // Utility functions // Sort cells by depth // Create new MODULE TOP with connections to below signals //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3LinkLevel.h" #include "V3Ast.h" //###################################################################### // Levelizing class functions struct CmpLevel { inline bool operator () (const AstNodeModule* lhsp, const AstNodeModule* rhsp) const { return lhsp->level() < rhsp->level(); } }; void V3LinkLevel::modSortByLevel() { // Sort modules by levels, root down to lowest children // Calculate levels again in case we added modules UINFO(2,"modSortByLevel()\n"); // level() was computed for us in V3LinkCells typedef vector ModVec; ModVec vec; AstNodeModule* topp = NULL; for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) { if (nodep->level()<=2) { if (topp) { nodep->v3warn(E_MULTITOP, "Unsupported: Multiple top level modules: " <prettyName()<<" and "<prettyName()); nodep->v3warn(E_MULTITOP, "Fix, or use --top-module option to select which you want."); } topp = nodep; } vec.push_back(nodep); } stable_sort(vec.begin(), vec.end(), CmpLevel()); // Sort the vector UINFO(9,"modSortByLevel() sorted\n"); // Comment required for gcc4.6.3 / bug666 for (ModVec::iterator it = vec.begin(); it != vec.end(); ++it) { AstNodeModule* nodep = *it; nodep->clearIter(); // Because we didn't iterate to find the node pointers, may have a stale m_iterp() needing cleanup nodep->unlinkFrBack(); } if (v3Global.rootp()->modulesp()) v3Global.rootp()->v3fatalSrc("Unlink didn't work"); for (ModVec::iterator it = vec.begin(); it != vec.end(); ++it) { AstNodeModule* nodep = *it; v3Global.rootp()->addModulep(nodep); } UINFO(9,"modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666 V3Global::dumpCheckGlobalTree("cells", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } //###################################################################### // Wrapping void V3LinkLevel::wrapTop(AstNetlist* netlistp) { UINFO(2,__FUNCTION__<<": "<modulesp(); if (!oldmodp) netlistp->v3fatalSrc("No module found to process"); AstNodeModule* newmodp = new AstModule(oldmodp->fileline(), (string)"TOP_"+oldmodp->name()); // Make the new module first in the list oldmodp->unlinkFrBackWithNext(); newmodp->addNext(oldmodp); newmodp->level(1); newmodp->modPublic(true); netlistp->addModulep(newmodp); // TODO the module creation above could be done after linkcells, but // the rest must be done after data type resolution wrapTopCell(netlistp); wrapTopPackages(netlistp); } void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) { AstNodeModule* newmodp = netlistp->modulesp(); if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process"); AstNodeModule* oldmodp = newmodp->nextp()->castNodeModule(); if (!oldmodp) netlistp->v3fatalSrc("No module found to process"); // Add instance AstCell* cellp = new AstCell(newmodp->fileline(), ((v3Global.opt.l2Name()!="") ? v3Global.opt.l2Name() : oldmodp->name()), oldmodp->name(), NULL, NULL, NULL); cellp->modp(oldmodp); newmodp->addStmtp(cellp); // Add pins for (AstNode* subnodep=oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) { if (AstVar* oldvarp=subnodep->castVar()) { UINFO(8,"VARWRAP "<isIO()) { AstVar* varp = oldvarp->cloneTree(false); newmodp->addStmtp(varp); varp->sigPublic(true); // User needs to be able to get to it... if (oldvarp->isIO()) { oldvarp->primaryIO(true); varp->primaryIO(true); } if (varp->isIO() && v3Global.opt.systemC()) { varp->sc(true); // User can see trace one level down from the wrapper // Avoids packing & unpacking SC signals a second time varp->trace(false); } AstPin* pinp = new AstPin(oldvarp->fileline(),0,oldvarp->name(), new AstVarRef(varp->fileline(), varp, oldvarp->isOutput())); // Skip length and width comp; we know it's a direct assignment pinp->modVarp(oldvarp); cellp->addPinsp(pinp); } } } } void V3LinkLevel::wrapTopPackages(AstNetlist* netlistp) { // Instantiate all packages under the top wrapper // This way all later SCOPE based optimizations can ignore packages AstNodeModule* newmodp = netlistp->modulesp(); if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process"); for (AstNodeModule* modp = netlistp->modulesp(); modp; modp=modp->nextp()->castNodeModule()) { if (modp->castPackage()) { AstCell* cellp = new AstCell(modp->fileline(), // Could add __03a__03a="::" to prevent conflict // with module names/"v" modp->name(), modp->name(), NULL, NULL, NULL); cellp->modp(modp); newmodp->addStmtp(cellp); } } } verilator-3.916/src/V3Broken.h0000664000177100017500000000237213205574202016115 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Combine.cpp0000664000177100017500000004051413205574202016604 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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); VL_DANGLING(callp); 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) { addCall(nodep); } // Speed things up virtual void visit(AstNodeAssign* nodep) {} virtual void visit(AstNodeMath* nodep) {} virtual void visit(AstNode* nodep) { 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) { nodep->user3(true); nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit 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); VL_DANGLING(oldfuncp); } } } 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"); 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); VL_DANGLING(oldfuncp); } 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()); VL_DANGLING(nodep); } } } 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); VL_DANGLING(call1p); replaceOnlyCallFunc(call2p); VL_DANGLING(call2p); } // VISITORS virtual void visit(AstNetlist* nodep) { // 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) { 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) { 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) { 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*) {} virtual void visit(AstTraceDecl*) {} virtual void visit(AstTraceInc*) {} virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit CombineVisitor(AstNetlist* nodep) { m_modp=NULL; m_funcp = NULL; m_state = STATE_IDLE; nodep->accept(*this); } virtual ~CombineVisitor() { V3Stats::addStat("Optimizations, Combined CFuncs", m_statCombs); } }; //###################################################################### // Combine class functions void V3Combine::combineAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Name.cpp0000664000177100017500000001116113205574202016104 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Change names for __PVT__'s // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Name's Transformations: // // Cell/Var's // Prepend __PVT__ to variable names //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Name.h" #include "V3Ast.h" #include "V3LanguageWords.h" //###################################################################### // Name state, as a visitor of each AstNode class NameVisitor : public AstNVisitor { private: // NODE STATE // Cleared on Netlist // AstCell::user1() -> bool. Set true if already processed // AstScope::user1() -> bool. Set true if already processed // AstVar::user1() -> bool. Set true if already processed AstUser1InUse m_inuser1; // STATE AstNodeModule* m_modp; V3LanguageWords m_words; // Reserved word detector // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void rename(AstNode* nodep, bool addPvt) { if (!nodep->user1()) { // Not already done if (addPvt) { string newname = (string)"__PVT__"+nodep->name(); nodep->name(newname); } else { string rsvd = m_words.isKeyword(nodep->name()); if (rsvd != "") { nodep->v3warn(SYMRSVDWORD,"Symbol matches "+rsvd+": '"<prettyName()<<"'"); string newname = (string)"__SYM__"+nodep->name(); nodep->name(newname); } } nodep->user1(1); } } // VISITORS virtual void visit(AstNodeModule* nodep) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } // Add __PVT__ to names of local signals virtual void visit(AstVar* nodep) { // 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) { if (!nodep->user1()) { nodep->iterateChildren(*this); rename(nodep, false); } } virtual void visit(AstVarRef* nodep) { if (nodep->varp()) { nodep->varp()->iterate(*this); nodep->name(nodep->varp()->name()); } } virtual void visit(AstCell* nodep) { if (!nodep->user1()) { rename(nodep, !nodep->modp()->modPublic()); nodep->iterateChildren(*this); } } virtual void visit(AstMemberDType* nodep) { if (!nodep->user1()) { rename(nodep, false); nodep->iterateChildren(*this); } } virtual void visit(AstMemberSel* nodep) { if (!nodep->user1()) { rename(nodep, false); nodep->iterateChildren(*this); } } virtual void visit(AstScope* nodep) { 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) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit NameVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~NameVisitor() {} }; //###################################################################### // Name class functions void V3Name::nameAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.916/src/V3Ast.cpp0000664000177100017500000012401313205574202015754 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ast node structures // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include #include #include #include "V3Ast.h" #include "V3File.h" #include "V3Global.h" #include "V3Broken.h" #include "V3String.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_user1u = VNUser(0); m_user1Cnt = 0; m_user2u = VNUser(0); m_user2Cnt = 0; m_user3u = VNUser(0); m_user3Cnt = 0; m_user4u = VNUser(0); m_user4Cnt = 0; m_user5u = VNUser(0); m_user5Cnt = 0; } string AstNode::encodeName(const string& namein) { // Encode signal name raw from parser, then not called again on same signal string out; for (string::const_iterator pos = namein.begin(); pos!=namein.end(); ++pos) { if ((pos==namein.begin()) ? 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; if (pos==namein.end()) break; } 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; } } // Shorten names // TODO long term use VName in place of "string name" VName vname(out); out = vname.hashedName(); 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) { // This function is somewhat hot, so we short-circuit some compares string pretty; pretty = ""; pretty.reserve(namein.length()); for (const char* pos = namein.c_str(); *pos; ) { if (pos[0]=='-' && pos[1]=='>') { // -> pretty += "."; pos += 2; continue; } if (pos[0]=='_' && pos[1]=='_') { // Short-circuit if (0==strncmp(pos,"__BRA__",7)) { pretty += "["; pos += 7; continue; } if (0==strncmp(pos,"__KET__",7)) { pretty += "]"; pos += 7; continue; } if (0==strncmp(pos,"__DOT__",7)) { pretty += "."; pos += 7; continue; } if (0==strncmp(pos,"__PVT__",7)) { pretty += ""; pos += 7; continue; } 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; continue; } } // Default pretty += pos[0]; ++pos; } if (pretty[0]=='T' && pretty.substr(0,4) == "TOP.") pretty.replace(0,4,""); if (pretty[0]=='T' && pretty.substr(0,5) == "TOP->") pretty.replace(0,5,""); return pretty; } string AstNode::prettyTypeName() const { if (name()=="") return typeName(); return string(typeName())+" '"+prettyName()+"'"; } //###################################################################### // Insertion inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next) { #ifdef VL_DEBUG // Called on all major tree changers. // Only for use for those really nasty bugs relating to internals // Note this may be null. //if (debug()) cout<<"-treeChange: V3Ast.cpp:"<"<dumpTree(cout,"-treeChange: "); // if (next||1) this->dumpTreeAndNext(cout, prefix); // else this->dumpTree(cout, prefix); // this->checkTree(); // v3Global.rootp()->checkTree(); //} #endif } AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) { // Add to m_nextp, returns this UDEBUGONLY(if (!newp) nodep->v3fatalSrc("Null item passed to addNext");); nodep->debugTreeChange("-addNextThs: ", __LINE__, false); newp->debugTreeChange("-addNextNew: ", __LINE__, true); if (!nodep) { // verilog.y and lots of other places assume this return (newp); } else { // Find end of old list AstNode* oldtailp = nodep; if (oldtailp->m_nextp) { if (oldtailp->m_headtailp) { oldtailp = oldtailp->m_headtailp; // This=beginning of list, jump to end UDEBUGONLY(if (oldtailp->m_nextp) nodep->v3fatalSrc("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 } nodep->debugTreeChange("-addNextOut:", __LINE__, true); return nodep; } AstNode* AstNode::addNextNull(AstNode* nodep, AstNode* newp) { if (!newp) return nodep; return addNext(nodep, 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 UDEBUGONLY(UASSERT(dynamic_cast(this),"this should not be NULL");); UASSERT(newp,"Null item passed to addNext"); UASSERT(newp->backp()==NULL,"New node (back) already assigned?"); this->debugTreeChange("-addHereThs: ", __LINE__, false); newp->debugTreeChange("-addHereNew: ", __LINE__, true); newp->editCountInc(); AstNode* addlastp = newp->m_headtailp; // Last node in list to be added UASSERT(!addlastp->m_nextp, "Headtailp tail isn't at the tail"); // Forward links AstNode* oldnextp = this->m_nextp; this->m_nextp = newp; addlastp->m_nextp = oldnextp; // Perhaps null if 'this' is not list // Backward links if (oldnextp) oldnextp->m_backp = addlastp; newp->m_backp = this; // Head/tail AstNode* oldheadtailp = this->m_headtailp; // (!oldheadtailp) // this was&is middle of list // (oldheadtailp==this && !oldnext)// this was head AND tail (one node long list) // (oldheadtailp && oldnextp) // this was&is head of list of not just one node, not tail // (oldheadtailp && !oldnextp) // this was tail of list, might also be head of one-node list // newp->m_headtailp = NULL; // Not at head any longer addlastp->m_headtailp = NULL; // Presume middle of list // newp might happen to be head/tail after all, if so will be set again below if (oldheadtailp) { // else in middle of list, no change if (oldheadtailp==this) { // this was one node this->m_headtailp = addlastp; // Was head/tail, now a tail addlastp->m_headtailp = oldheadtailp; // Tail needs to remember head (or NULL) } else if (!oldnextp) { // this was tail this->m_headtailp = NULL; // No longer a tail oldheadtailp->m_headtailp = addlastp; // Head gets new tail addlastp->m_headtailp = oldheadtailp; // Tail needs to remember head (or NULL) } // else is head, and we're inserting into the middle, so no other change } if (this->m_iterpp) *(this->m_iterpp) = newp; // Iterate on new item this->debugTreeChange("-addHereOut: ", __LINE__, true); } void AstNode::setOp1p(AstNode* newp) { UASSERT(newp,"Null item passed to setOp1p\n"); UDEBUGONLY(if (m_op1p) this->v3fatalSrc("Adding to non-empty, non-list op1");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1");); this->debugTreeChange("-setOp1pThs: ", __LINE__, false); newp->debugTreeChange("-setOp1pNew: ", __LINE__, true); m_op1p = newp; newp->editCountInc(); newp->m_backp = this; this->debugTreeChange("-setOp1pOut: ", __LINE__, false); } void AstNode::setOp2p(AstNode* newp) { UASSERT(newp,"Null item passed to setOp2p\n"); UDEBUGONLY(if (m_op2p) this->v3fatalSrc("Adding to non-empty, non-list op2");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2");); this->debugTreeChange("-setOp2pThs: ", __LINE__, false); newp->debugTreeChange("-setOp2pNew: ", __LINE__, true); m_op2p = newp; newp->editCountInc(); newp->m_backp = this; this->debugTreeChange("-setOp2pOut: ", __LINE__, false); } void AstNode::setOp3p(AstNode* newp) { UASSERT(newp,"Null item passed to setOp3p\n"); UDEBUGONLY(if (m_op3p) this->v3fatalSrc("Adding to non-empty, non-list op3");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3");); this->debugTreeChange("-setOp3pThs: ", __LINE__, false); newp->debugTreeChange("-setOp3pNew: ", __LINE__, true); m_op3p = newp; newp->editCountInc(); newp->m_backp = this; this->debugTreeChange("-setOp3pOut: ", __LINE__, false); } void AstNode::setOp4p(AstNode* newp) { UASSERT(newp,"Null item passed to setOp4p\n"); UDEBUGONLY(if (m_op4p) this->v3fatalSrc("Adding to non-empty, non-list op4");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4");); this->debugTreeChange("-setOp4pThs: ", __LINE__, false); newp->debugTreeChange("-setOp4pNew: ", __LINE__, true); m_op4p = newp; newp->editCountInc(); newp->m_backp = this; this->debugTreeChange("-setOp4pOut: ", __LINE__, false); } void AstNode::addOp1p(AstNode* newp) { UASSERT(newp,"Null item passed to addOp1p\n"); if (!m_op1p) { op1p(newp); } else { m_op1p->addNext(newp); } } void AstNode::addOp2p(AstNode* newp) { UASSERT(newp,"Null item passed to addOp2p\n"); if (!m_op2p) { op2p(newp); } else { m_op2p->addNext(newp); } } void AstNode::addOp3p(AstNode* newp) { UASSERT(newp,"Null item passed to addOp3p\n"); if (!m_op3p) { op3p(newp); } else { m_op3p->addNext(newp); } } void AstNode::addOp4p(AstNode* newp) { UASSERT(newp,"Null item passed to addOp4p\n"); if (!m_op4p) { op4p(newp); } else { m_op4p->addNext(newp); } } void AstNode::replaceWith(AstNode* newp) { // Replace oldp with this // Unlike a unlink/relink, children are changed to point to the new node. AstNRelinker repHandle; this->unlinkFrBack(&repHandle); repHandle.relink(newp); } void AstNRelinker::dump(ostream& str) const { str<<" BK="<<(uint32_t*)m_backp; str<<" ITER="<<(uint32_t*)m_iterpp; str<<" CHG="<<(m_chg==RELINK_NEXT?"[NEXT] ":""); str<<(m_chg==RELINK_OP1?"[OP1] ":""); str<<(m_chg==RELINK_OP2?"[OP2] ":""); str<<(m_chg==RELINK_OP3?"[OP3] ":""); str<<(m_chg==RELINK_OP4?"[OP4] ":""); } AstNode* AstNode::unlinkFrBackWithNext(AstNRelinker* linkerp) { this->debugTreeChange("-unlinkWNextThs: ", __LINE__, true); AstNode* oldp = this; UASSERT(oldp->m_backp,"Node has no back, already unlinked?\n"); oldp->editCountInc(); AstNode* backp = oldp->m_backp; if (linkerp) { linkerp->m_oldp = oldp; linkerp->m_backp = backp; linkerp->m_iterpp = oldp->m_iterpp; if (backp->m_nextp == oldp) linkerp->m_chg = AstNRelinker::RELINK_NEXT; else if (backp->m_op1p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP1; else if (backp->m_op2p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP2; else if (backp->m_op3p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP3; else if (backp->m_op4p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP4; else oldp->v3fatalSrc("Unlink of node with back not pointing to it."); } if (backp->m_nextp== oldp) { backp->m_nextp= NULL; // Old list gets truncated // New list becomes a list upon itself // Most common case is unlinking a entire operand tree // (else we'd probably call unlinkFrBack without next) // We may be in the middle of a list; we have no way to find head or tail! AstNode* oldtailp = oldp; while (oldtailp->m_nextp) oldtailp=oldtailp->m_nextp; // Create new head/tail of old list AstNode* oldheadp = oldtailp->m_headtailp; oldheadp->m_headtailp = oldp->m_backp; oldheadp->m_headtailp->m_headtailp = oldheadp; // Create new head/tail of extracted list oldp->m_headtailp = oldtailp; oldp->m_headtailp->m_headtailp = oldp; } else if (backp->m_op1p == oldp) backp->m_op1p = NULL; else if (backp->m_op2p == oldp) backp->m_op2p = NULL; else if (backp->m_op3p == oldp) backp->m_op3p = NULL; else if (backp->m_op4p == oldp) backp->m_op4p = NULL; else this->v3fatalSrc("Unlink of node with back not pointing to it."); // Relink oldp->m_backp = NULL; // Iterator fixup if (oldp->m_iterpp) *(oldp->m_iterpp) = NULL; oldp->m_iterpp = NULL; oldp->debugTreeChange("-unlinkWNextOut: ", __LINE__, true); return oldp; } AstNode* AstNode::unlinkFrBack(AstNRelinker* linkerp) { this->debugTreeChange("-unlinkFrBkThs: ", __LINE__, true); AstNode* oldp = this; UASSERT(oldp->m_backp,"Node has no back, already unlinked?\n"); oldp->editCountInc(); AstNode* backp = oldp->m_backp; if (linkerp) { linkerp->m_oldp = oldp; linkerp->m_backp = backp; linkerp->m_iterpp = oldp->m_iterpp; if (backp->m_nextp == oldp) linkerp->m_chg = AstNRelinker::RELINK_NEXT; else if (backp->m_op1p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP1; else if (backp->m_op2p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP2; else if (backp->m_op3p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP3; else if (backp->m_op4p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP4; else this->v3fatalSrc("Unlink of node with back not pointing to it."); } if (backp->m_nextp== oldp) { // This node gets removed from middle (or tail) of list // Not head, since then oldp wouldn't be a next of backp... backp->m_nextp= oldp->m_nextp; if (backp->m_nextp) backp->m_nextp->m_backp = backp; // If it was a tail, back becomes new tail if (oldp->m_headtailp) { backp->m_headtailp = oldp->m_headtailp; backp->m_headtailp->m_headtailp = backp; } } else { if (backp->m_op1p == oldp) backp->m_op1p = oldp->m_nextp; else if (backp->m_op2p == oldp) backp->m_op2p = oldp->m_nextp; else if (backp->m_op3p == oldp) backp->m_op3p = oldp->m_nextp; else if (backp->m_op4p == oldp) backp->m_op4p = oldp->m_nextp; else this->v3fatalSrc("Unlink of node with back not pointing to it."); if (oldp->m_nextp) { AstNode* newheadp = oldp->m_nextp; newheadp->m_backp = backp; newheadp->m_headtailp = oldp->m_headtailp; newheadp->m_headtailp->m_headtailp = newheadp; } } // Iterator fixup if (oldp->m_iterpp) *(oldp->m_iterpp) = oldp->m_nextp; // Relink oldp->m_nextp = NULL; oldp->m_backp = NULL; oldp->m_headtailp = this; oldp->m_iterpp = NULL; oldp->debugTreeChange("-unlinkFrBkOut: ", __LINE__, true); return oldp; } void AstNode::relink(AstNRelinker* linkerp) { if (debug()>8) { UINFO(0," EDIT: relink: "); dumpPtrs(); } AstNode* newp = this; UASSERT(linkerp && linkerp->m_backp, "Need non-empty linker\n"); UASSERT(newp->backp()==NULL, "New node already linked?\n"); newp->editCountInc(); if (debug()>8) { linkerp->dump(cout); cout<m_backp; this->debugTreeChange("-relinkNew: ", __LINE__, true); backp->debugTreeChange("-relinkTre: ", __LINE__, true); switch (linkerp->m_chg) { case AstNRelinker::RELINK_NEXT: backp->addNextHere(newp); break; case AstNRelinker::RELINK_OP1: relinkOneLink(backp->m_op1p /*ref*/, newp); break; case AstNRelinker::RELINK_OP2: relinkOneLink(backp->m_op2p /*ref*/, newp); break; case AstNRelinker::RELINK_OP3: relinkOneLink(backp->m_op3p /*ref*/, newp); break; case AstNRelinker::RELINK_OP4: relinkOneLink(backp->m_op4p /*ref*/, newp); break; default: this->v3fatalSrc("Relink of node without any link to change."); break; } // Relink newp->m_backp = backp; linkerp->m_backp = NULL; // Iterator fixup if (linkerp->m_iterpp) { // If we're iterating over a next() link, we need to follow links off the // NEW node. Thus we pass iteration information via a pointer in the node. // This adds a unfortunate hot 8 bytes to every AstNode, but is faster than passing // across every function. // If anyone has a cleaner way, I'd be grateful. *(linkerp->m_iterpp) = newp; newp->m_iterpp = linkerp->m_iterpp; } // Empty the linker so not used twice accidentally linkerp->m_backp = NULL; this->debugTreeChange("-relinkOut: ", __LINE__, true); } void AstNode::relinkOneLink(AstNode*& pointpr, // Ref to pointer that gets set to newp AstNode* newp) { if (pointpr) { // We know there will be at least two elements when we are done, // (newp & the old list). // We *ALLOW* the new node to have its own next list. // Likewise there may be a old list. // Insert the whole old list following the new node's list. // Thus a unlink without next, followed by relink, gives the same list. AstNode* newlistlastp=newp->m_headtailp; if (newlistlastp->m_nextp && newlistlastp!=newp) newp->v3fatalSrc("Headtailp tail isn't at the tail"); AstNode* oldlistlastp = pointpr->m_headtailp; if (oldlistlastp->m_nextp && oldlistlastp!=pointpr) newp->v3fatalSrc("Old headtailp tail isn't at the tail"); // Next links newlistlastp->m_nextp = pointpr; pointpr->m_backp = newlistlastp; // Head/tail pointpr->m_headtailp = NULL; // Old head newlistlastp->m_headtailp = NULL; // Old tail newp->m_headtailp = oldlistlastp; // Head points to tail oldlistlastp->m_headtailp = newp; // Tail points to head } pointpr = newp; } void AstNode::addHereThisAsNext (AstNode* newp) { // {old}->this->{next} becomes {old}->new->this->{next} AstNRelinker handle; this->unlinkFrBackWithNext(&handle); newp->addNext(this); handle.relink(newp); } void AstNode::swapWith (AstNode* bp) { AstNRelinker aHandle; AstNRelinker bHandle; this->unlinkFrBack(&aHandle); bp->unlinkFrBack(&bHandle); aHandle.relink(bp); bHandle.relink(this); } //====================================================================== // Clone AstNode* AstNode::cloneTreeIter() { // private: Clone single node and children AstNode* newp = this->clone(); if (this->m_op1p) newp->op1p(this->m_op1p->cloneTreeIterList()); if (this->m_op2p) newp->op2p(this->m_op2p->cloneTreeIterList()); if (this->m_op3p) newp->op3p(this->m_op3p->cloneTreeIterList()); if (this->m_op4p) 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() { // private: Clone list of nodes, set m_headtailp AstNode* newheadp = NULL; AstNode* newtailp = NULL; // Audited to make sure this is never 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; // verilog.y relies on this 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() { // private: Delete single node. Publicly call deleteTree() instead. 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() { // private: Delete list of nodes. Publicly call deleteTree() instead. // Audited to make sure this is never NULL for (AstNode* nodep=this, *nnextp; nodep; nodep=nnextp) { nnextp = nodep->m_nextp; // MUST be depth first! if (nodep->m_op1p) nodep->m_op1p->deleteTreeIter(); if (nodep->m_op2p) nodep->m_op2p->deleteTreeIter(); if (nodep->m_op3p) nodep->m_op3p->deleteTreeIter(); if (nodep->m_op4p) 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. 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) { // Optimization note: Aligning to cache line is a loss, due to lost packing 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) { // This is a very hot function // Optimization note: Grabbing m_op#p->m_nextp is a net loss ASTNODE_PREFETCH(m_op1p); ASTNODE_PREFETCH(m_op2p); ASTNODE_PREFETCH(m_op3p); ASTNODE_PREFETCH(m_op4p); if (m_op1p) m_op1p->iterateAndNext(v); if (m_op2p) m_op2p->iterateAndNext(v); if (m_op3p) m_op3p->iterateAndNext(v); if (m_op4p) m_op4p->iterateAndNext(v); } void AstNode::iterateChildrenConst(AstNVisitor& v) { // This is a very hot function ASTNODE_PREFETCH(m_op1p); ASTNODE_PREFETCH(m_op2p); ASTNODE_PREFETCH(m_op3p); ASTNODE_PREFETCH(m_op4p); if (m_op1p) m_op1p->iterateAndNextConst(v); if (m_op2p) m_op2p->iterateAndNextConst(v); if (m_op3p) m_op3p->iterateAndNextConst(v); if (m_op4p) m_op4p->iterateAndNextConst(v); } void AstNode::iterateAndNext(AstNVisitor& v) { // 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! // 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 if (nodep) ASTNODE_PREFETCH(nodep->m_nextp); while (nodep) { // effectively: if (!this) return; // Callers rely on this if (nodep->m_nextp) ASTNODE_PREFETCH(nodep->m_nextp->m_nextp); AstNode* niterp = nodep; // This address may get stomped via m_iterpp if the node is edited // Desirable check, but many places where multiple iterations are OK //if (VL_UNLIKELY(niterp->m_iterpp)) niterp->v3fatalSrc("IterateAndNext under iterateAndNext may miss edits"); // Optimization note: Doing PREFETCH_RW on m_iterpp is a net even // cppcheck-suppress nullPointer niterp->m_iterpp = &niterp; niterp->accept(v); // accept may do a replaceNode and change niterp on us... //if (niterp != nodep) UINFO(1,"iterateAndNext edited "<<(void*)nodep<<" now into "<<(void*)niterp<m_iterpp = NULL; if (VL_UNLIKELY(niterp!=nodep)) { // Edited node inside accept nodep = niterp; } else { // Unchanged node, just continue loop nodep = niterp->m_nextp; } } } void AstNode::iterateListBackwards(AstNVisitor& v) { UDEBUGONLY(UASSERT(dynamic_cast(this),"this should not be NULL");); AstNode* nodep=this; while (nodep->m_nextp) nodep=nodep->m_nextp; while (nodep) { // Edits not supported: nodep->m_iterpp = &nodep; nodep->accept(v); if (nodep->backp()->m_nextp == nodep) nodep=nodep->backp(); else nodep = NULL; // else: backp points up the tree. } } void AstNode::iterateChildrenBackwards(AstNVisitor& v) { if (m_op1p) m_op1p->iterateListBackwards(v); if (m_op2p) m_op2p->iterateListBackwards(v); if (m_op3p) m_op3p->iterateListBackwards(v); if (m_op4p) m_op4p->iterateListBackwards(v); } void AstNode::iterateAndNextConst(AstNVisitor& v) { // Keep following the current list even if edits change it if (!this) return; // A few cases could be cleaned up, but want symmetry with iterateAndNext for (AstNode* nodep=this; nodep; ) { // effectively: if (!this) return; // Callers rely on this AstNode* nnextp = nodep->m_nextp; ASTNODE_PREFETCH(nnextp); nodep->accept(v); nodep = nnextp; } } AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) { // 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); } 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); VL_DANGLING(nodep); // nodep to null as may be replaced } nodep = tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); VL_DANGLING(tempp); } 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); VL_DANGLING(nodep); // nodep to null as may be replaced } nodep = *nextnodepp; // Grab new node from point where old was connected } return nodep; } //====================================================================== void AstNode::cloneRelinkTree() { // private: Cleanup clone() operation on whole tree. Publicly call cloneTree() instead. for (AstNode* nodep=this; nodep; nodep=nodep->m_nextp) { if (m_dtypep && m_dtypep->clonep()) { m_dtypep = m_dtypep->clonep(); } nodep->cloneRelink(); if (nodep->m_op1p) nodep->m_op1p->cloneRelinkTree(); if (nodep->m_op2p) nodep->m_op2p->cloneRelinkTree(); if (nodep->m_op3p) nodep->m_op3p->cloneRelinkTree(); if (nodep->m_op4p) nodep->m_op4p->cloneRelinkTree(); } } //====================================================================== // Comparison bool AstNode::gateTreeIter() { // private: Return true if the two trees are identical if (!isGateOptimizable()) return false; if (m_op1p && !m_op1p->gateTreeIter()) return false; if (m_op2p && !m_op2p->gateTreeIter()) return false; if (m_op3p && !m_op3p->gateTreeIter()) return false; if (m_op4p && !m_op4p->gateTreeIter()) return false; return true; } bool AstNode::sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool gateOnly) { // private: Return true if the two trees are identical if (!node1p && !node2p) return true; if (!node1p || !node2p) return false; if (node1p->type() != node2p->type() || node1p->dtypep() != node2p->dtypep() || !node1p->same(node2p) || (gateOnly && !node1p->isGateOptimizable())) { return false; } return (sameTreeIter(node1p->m_op1p, node2p->m_op1p,false,gateOnly) && sameTreeIter(node1p->m_op2p, node2p->m_op2p,false,gateOnly) && sameTreeIter(node1p->m_op3p, node2p->m_op3p,false,gateOnly) && sameTreeIter(node1p->m_op4p, node2p->m_op4p,false,gateOnly) && (ignNext || sameTreeIter(node1p->m_nextp, node2p->m_nextp,false,gateOnly)) ); } //====================================================================== // Static utilities ostream& operator<<(ostream& os, const 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 (m_op1p) m_op1p->checkTreeIterList(this); if (m_op2p) m_op2p->checkTreeIterList(this); if (m_op3p) m_op3p->checkTreeIterList(this); if (m_op4p) m_op4p->checkTreeIterList(this); } void AstNode::checkTreeIterList(AstNode* backp) { // private: Check a (possible) list of nodes, this is always the head of the list // Audited to make sure this is never NULL 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 (!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 (!dynamic_cast(this)) { cout<<"This=NULL"<(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) { // Audited to make sure this is never NULL for (AstNode* nodep=this; nodep; nodep=nodep->nextp()) { nodep->dumpTree(os, indent, maxDepth); } } void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) { if (doDump) { { // Write log & close UINFO(2,"Dumping "< logsp (V3File::new_ofstream(filename, append)); if (logsp->fail()) v3fatalSrc("Can't write "<"; *logsp<<" to "<=9)) { *logsp<castNetlist()) V3Broken::brokenAll(netp); } // Next dump can indicate start from here editCountSetLast(); } void AstNode::v3errorEndFatal(ostringstream& str) const { v3errorEnd(str); assert(0); } void AstNode::v3errorEnd(ostringstream& str) const { if (!dynamic_cast(this)) { // No known cases cause this, but better than a core dump if (debug()) UINFO(0, "-node: NULL. Please report this along with a --gdbbt backtrace as a Verilator bug.\n"); V3Error::v3errorEnd(str); } else if (!m_fileline) { V3Error::v3errorEnd(str); } else { ostringstream nsstr; nsstr<dump(nsstr); nsstr<v3errorEnd(nsstr); } } string AstNode::warnMore() const { return fileline()->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.916/src/V3Trace.cpp0000664000177100017500000006541313205574202016273 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.hash(nodep->valuep()); UINFO(8, " Hashed "<valuep())<<" "<valuep()) == hashed.end()) { hashed.hashAndInsert(nodep->valuep()); } } } } // Find if there are any duplicates for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->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->user1u().toGraphVertex()); UINFO(8," Orig "<duplicatep(dupvertexp); } } } } 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; if (dupvertexp->duplicatep()) { dupvertexp = dupvertexp->duplicatep(); UINFO(9," dupOf "<<((void*)dupvertexp)<<" "<<((void*)dupvertexp->nodep()) <<" "<duplicatep()) dupvertexp->nodep()->v3fatalSrc("Original node was marked as a duplicate"); } if (dupvertexp != vvertexp) { // It's an exact copy. We'll assign the code to the master on // the first one we hit; the later ones will share the code. codePreassigned = assignDeclCode(dupvertexp->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); VL_DANGLING(nodep); } return incAddp; } TraceCFuncVertex* getCFuncVertexp(AstCFunc* nodep) { TraceCFuncVertex* vertexp = dynamic_cast(nodep->user1u().toGraphVertex()); if (!vertexp) { vertexp = new TraceCFuncVertex(&m_graph, nodep); nodep->user1p(vertexp); } return vertexp; } TraceActivityVertex* getActivityVertexp(AstNode* nodep, bool slow) { TraceActivityVertex* vertexp = dynamic_cast(nodep->user3u().toGraphVertex()); if (!vertexp) { vertexp = new TraceActivityVertex(&m_graph, nodep, slow); nodep->user3p(vertexp); } vertexp->slow(slow); return vertexp; } // VISITORS virtual void visit(AstNetlist* nodep) { 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) { if (nodep->isTop()) m_topModp = nodep; nodep->iterateChildren(*this); } virtual void visit(AstTopScope* nodep) { 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) { 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) { 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) { 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) { 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()->user1u().toGraphVertex(); if (!varVtxp) { varVtxp = new TraceVarVertex(&m_graph, nodep->varScopep()); nodep->varScopep()->user1p(varVtxp); } V3GraphVertex* traceVtxp = m_tracep->user1u().toGraphVertex(); 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()->user1u().toGraphVertex(); if (varVtxp) { // else we're not tracing this signal new V3GraphEdge(&m_graph, funcVtxp, varVtxp, 1); } } } //-------------------- virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit TraceVisitor(AstNetlist* nodep) { m_funcp = NULL; m_tracep = NULL; m_topModp = NULL; m_highScopep = NULL; m_finding = false; m_activityVscp = NULL; m_alwaysVtxp = NULL; m_initFuncp = NULL; m_fullFuncp = NULL; m_fullSubFuncp = NULL; m_fullSubStmts = 0; m_chgFuncp = NULL; m_chgSubFuncp = NULL; m_chgSubParentp = NULL; m_chgSubStmts = 0; m_funcNum = 0; nodep->accept(*this); } virtual ~TraceVisitor() { V3Stats::addStat("Tracing, Unique changing signals", m_statChgSigs); V3Stats::addStat("Tracing, Unique traced signals", m_statUniqSigs); V3Stats::addStat("Tracing, Unique trace codes", m_statUniqCodes); } }; //###################################################################### // Trace class functions void V3Trace::traceAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Hashed.cpp0000664000177100017500000001566113205574202016431 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Hashed common code into functions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Hashed's Transformations: // // Hash each node depth first // Hash includes varp name and operator type, and constants // Form lookup table based on hash of each statement w/ nodep and next nodep // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3Hashed.h" #include "V3Ast.h" #include "V3File.h" //###################################################################### // Hashed state, as a visitor of each AstNode class HashedVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstNodeStmt::user4() -> V3Hash. Hash value of this node (hash of 0 is illegal) //AstUser4InUse in V3Hashed.h // STATE V3Hash m_lowerHash; // Hash of the statement we're building static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // METHODS void nodeHashIterate(AstNode* nodep) { if (!nodep->user4()) { if (nodep->backp()->castCFunc() && !(nodep->castNodeStmt() || nodep->castCFunc())) { nodep->v3fatalSrc("Node "<prettyTypeName()<<" in statement position but not marked stmt (node under function)"); } V3Hash oldHash = m_lowerHash; { m_lowerHash = nodep->sameHash(); if (m_lowerHash.isIllegal()) { nodep->v3fatalSrc("sameHash function undefined (returns 0) for node under CFunc."); } // For identical nodes, the type should be the same thus dtypep should be the same too m_lowerHash = V3Hash(m_lowerHash, V3Hash(nodep->type()<<6, V3Hash(nodep->dtypep()))); // Now update m_lowerHash for our children's (and next children) contributions nodep->iterateChildren(*this); // Store the hash value nodep->user4(m_lowerHash.fullValue()); //UINFO(9, " hashnode "<user4p()) { HashedVisitor visitor (nodep); } } bool V3Hashed::sameNodes(AstNode* node1p, AstNode* node2p) { if (!node1p->user4p()) node1p->v3fatalSrc("Called isIdentical on non-hashed nodes"); if (!node2p->user4p()) node2p->v3fatalSrc("Called isIdentical on non-hashed nodes"); return (node1p->user4p() == node2p->user4p() // Same hash && node1p->sameTree(node2p)); } void V3Hashed::erase(iterator it) { AstNode* nodep = iteratorNodep(it); UINFO(8," erase "<user4p()) nodep->v3fatalSrc("Called removeNode on non-hashed node"); m_hashMmap.erase(it); nodep->user4p(NULL); // So we don't allow removeNode again } void V3Hashed::dumpFilePrefixed(const string& nameComment, bool tree) { if (v3Global.opt.dumpTree()) { dumpFile(v3Global.debugFilename(nameComment)+".hash", tree); } } void V3Hashed::dumpFile(const string& filename, bool tree) { const vl_unique_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.916/src/V3Life.cpp0000664000177100017500000004261313205574202016111 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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::addStatSum("Optimizations, Lifetime assign deletions", m_statAssnDel); V3Stats::addStatSum("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); } explicit LifeVarEntry(COMPLEXASSIGN) { init(false); complexAssign(); } explicit 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); VL_DANGLING(oldassp); ++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(); VL_DANGLING(varrefp); ++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) { // 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); VL_DANGLING(nodep); } } virtual void visit(AstNodeAssign* nodep) { // 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) { // Don't treat as normal assign; V3Life doesn't understand time sense nodep->iterateChildren(*this); } //---- Track control flow changes virtual void visit(AstNodeIf* nodep) { 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) { // 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) { // 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) { //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) { //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) { m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment nodep->iterateChildren(*this); } virtual void visit(AstCMath* nodep) { m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment nodep->iterateChildren(*this); } virtual void visit(AstVar*) {} // Don't want varrefs under it virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS LifeVisitor(AstNode* nodep, LifeState* statep) { UINFO(4," LifeVisitor on "<accept(*this); if (m_lifep) { delete m_lifep; m_lifep=NULL; } } } virtual ~LifeVisitor() { if (m_lifep) { delete m_lifep; m_lifep=NULL; } } }; //###################################################################### 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) { if (nodep->entryPoint()) { // Usage model 1: Simulate all C code, doing lifetime analysis LifeVisitor visitor (nodep, m_statep); } } virtual void visit(AstAlways* nodep) { // Usage model 2: Cleanup basic blocks LifeVisitor visitor (nodep, m_statep); } virtual void visit(AstInitial* nodep) { // Usage model 2: Cleanup basic blocks LifeVisitor visitor (nodep, m_statep); } virtual void visit(AstFinal* nodep) { // Usage model 2: Cleanup basic blocks LifeVisitor visitor (nodep, m_statep); } virtual void visit(AstVar*) {} // Accelerate virtual void visit(AstNodeStmt*) {} // Accelerate virtual void visit(AstNodeMath*) {} // Accelerate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS LifeTopVisitor(AstNetlist* nodep, LifeState* statep) { m_statep = statep; nodep->accept(*this); } virtual ~LifeTopVisitor() {} }; //###################################################################### // Life class functions void V3Life::lifeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Trace.h0000664000177100017500000000222713205574202015732 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves Tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3TRACE_H_ #define _V3TRACE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Trace { public: static void traceAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3Stats.h0000664000177100017500000000762713205574202016003 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Collect and print statistics // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3STATS_H_ #define _V3STATS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" class AstNetlist; //============================================================================ class V3Double0 { // Double counter, initializes to zero for easy use double m_d; ///< Count of occurrences/ value public: // METHODS V3Double0() : m_d(0) {} ~V3Double0() {} // Implicit conversion operators: inline explicit V3Double0 (const vluint64_t v) : m_d(v) { } inline operator double () const { return m_d; } // Explicit operators: inline V3Double0& operator++() { ++m_d; return *this; } // prefix inline V3Double0 operator++(int) { V3Double0 old=*this; m_d++; return old; } // postfix inline V3Double0& operator= (const double v) { m_d = v; return *this; } inline V3Double0& operator+=(const double v) { m_d += v; return *this; } inline V3Double0& operator-=(const double v) { m_d -= v; return *this; } }; //============================================================================ class V3Statistic { // A statistical entry we want published into the database string m_name; ///< Nameiption of this statistic double m_count; ///< Count of occurrences/ value string m_stage; ///< Runtime stage bool m_sumit; ///< Do summation of similar stats bool m_perf; ///< Performance section bool m_printit; ///< Print the results public: // METHODS string stage() const { return m_stage; } string name() const { return m_name; } double count() const { return m_count; } bool sumit() const { return m_sumit; } bool perf() const { return m_perf; } bool printit() const { return m_printit; } virtual void dump(ofstream& os) const; void combineWith(V3Statistic* otherp) { m_count += otherp->count(); otherp->m_printit = false; } // CONSTRUCTORS V3Statistic(const string& stage, const string& name, double count, bool sumit=false, bool perf=false) : m_name(name), m_count(count), m_stage(stage), m_sumit(sumit), m_perf(perf) , 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)); } static void addStatPerf(const string& name, double count) { addStat(V3Statistic("*",name,count,true,true)); } /// Called each stage static void statsStage(const string& name); /// 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.916/src/V3Ast.h0000664000177100017500000026726713205623070015442 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ast node structure // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3AST_H_ #define _V3AST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3FileLine.h" #include "V3Number.h" #include "V3Global.h" #include #include #include #include "V3Ast__gen_classes.h" // From ./astgen // Things like: // class V3AstNode; // Hint class so we can choose constructors class VFlagLogicPacked {}; class VFlagBitPacked {}; class VFlagChildDType {}; // Used by parser.y to select constructor that sets childDType // For broken() function, return error string if have a match #define BROKEN_RTN(test) do { if (VL_UNLIKELY(test)) return # test; } while(0) //###################################################################### class AstType { public: #include "V3Ast__gen_types.h" // From ./astgen // Above include has: // enum en {...}; // const char* ascii() const {...}; enum en m_e; // cppcheck-suppress uninitVar // responsiblity of each subclass inline AstType () {} // cppcheck-suppress noExplicitConstructor 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, const 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, const 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) {} // cppcheck-suppress noExplicitConstructor 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* const names[] = { "%E-edge", "ANY", "BOTH", "POS", "NEG", "HIGH", "LOW", "COMBO","INITIAL","SETTLE","NEVER" }; return names[m_e]; } const char* verilogKwd() const { static const char* const names[] = { "%E-edge", "[any]", "edge", "posedge", "negedge", "[high]","[low]", "*","[initial]","[settle]","[never]" }; return names[m_e]; } // Return true iff this and the other have mutually exclusive transitions bool exclusiveEdge(const AstEdgeType& other) const { switch (m_e) { case AstEdgeType::ET_POSEDGE: switch (other.m_e) { case AstEdgeType::ET_NEGEDGE: // FALLTHRU case AstEdgeType::ET_LOWEDGE: return true; default: {} } break; case AstEdgeType::ET_NEGEDGE: switch (other.m_e) { case AstEdgeType::ET_POSEDGE: // FALLTHRU case AstEdgeType::ET_HIGHEDGE: return true; default: {} } break; default: {} } return false; } inline AstEdgeType () : m_e(ET_ILLEGAL) {} // cppcheck-suppress noExplicitConstructor inline AstEdgeType (en _e) : m_e(_e) {} explicit inline AstEdgeType (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; inline bool operator== (AstEdgeType lhs, AstEdgeType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstEdgeType lhs, AstEdgeType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstEdgeType::en lhs, AstEdgeType rhs) { return (lhs == rhs.m_e); } //###################################################################### class AstAttrType { public: enum en { ILLEGAL, // DIM_BITS, // V3Const converts to constant DIM_DIMENSIONS, // V3Width converts to constant DIM_HIGH, // V3Width processes DIM_INCREMENT, // V3Width processes DIM_LEFT, // V3Width processes DIM_LOW, // V3Width processes DIM_RIGHT, // V3Width processes DIM_SIZE, // V3Width processes DIM_UNPK_DIMENSIONS, // V3Width converts to constant // DT_PUBLIC, // V3LinkParse moves to AstTypedef::attrPublic // ENUM_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes ENUM_FIRST, // V3Width processes ENUM_LAST, // V3Width processes ENUM_NUM, // V3Width processes ENUM_NEXT, // V3Width processes ENUM_PREV, // V3Width processes ENUM_NAME, // V3Width processes // MEMBER_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes // VAR_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes VAR_CLOCK, // V3LinkParse moves to AstVar::attrScClocked VAR_CLOCK_ENABLE, // V3LinkParse moves to AstVar::attrClockEn VAR_PUBLIC, // V3LinkParse moves to AstVar::sigPublic VAR_PUBLIC_FLAT, // V3LinkParse moves to AstVar::sigPublic VAR_PUBLIC_FLAT_RD, // V3LinkParse moves to AstVar::sigPublic VAR_PUBLIC_FLAT_RW, // V3LinkParse moves to AstVar::sigPublic VAR_ISOLATE_ASSIGNMENTS, // V3LinkParse moves to AstVar::attrIsolateAssign VAR_SC_BV, // V3LinkParse moves to AstVar::attrScBv VAR_SFORMAT, // V3LinkParse moves to AstVar::attrSFormat VAR_CLOCKER, // V3LinkParse moves to AstVar::attrClocker VAR_NO_CLOCKER // V3LinkParse moves to AstVar::attrClocker }; enum en m_e; const char* ascii() const { static const char* const names[] = { "%E-AT", "DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT", "DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS", "DT_PUBLIC", "ENUM_BASE", "ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME", "MEMBER_BASE", "VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC", "VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW", "VAR_ISOLATE_ASSIGNMENTS", "VAR_SC_BV", "VAR_SFORMAT", "VAR_CLOCKER", "VAR_NO_CLOCKER" }; return names[m_e]; }; inline AstAttrType () : m_e(ILLEGAL) {} // cppcheck-suppress noExplicitConstructor 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* const 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* const 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 selfTest() { 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) {} // cppcheck-suppress noExplicitConstructor 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==TIME); } bool isDpiUnsignable() const { // Can add "unsigned" to DPI return (m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER); } bool isOpaque() const { // IE not a simple number we can bit optimize return (m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR || m_e==DOUBLE || m_e==FLOAT); } bool isDouble() const { return m_e==DOUBLE; } bool isString() const { return m_e==STRING; } }; inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstBasicDTypeKwd::en lhs, AstBasicDTypeKwd rhs) { return (lhs == rhs.m_e); } //###################################################################### class AstVarType { public: enum en { UNKNOWN, GPARAM, LPARAM, GENVAR, VAR, // Reg, integer, logic, etc INPUT, OUTPUT, INOUT, SUPPLY0, SUPPLY1, WIRE, WREAL, 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) {} // cppcheck-suppress noExplicitConstructor 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* const names[] = { "?","GPARAM","LPARAM","GENVAR", "VAR","INPUT","OUTPUT","INOUT", "SUPPLY0","SUPPLY1","WIRE","WREAL","IMPLICITWIRE", "TRIWIRE","TRI0","TRI1", "PORT", "BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP", "IFACEREF"}; return names[m_e]; } bool isSignal() const { return (m_e==WIRE || m_e==WREAL || 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, const 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* const 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, const AstBranchPred& rhs) { return os<(_e)) {} operator en () const { return m_e; } bool unknown() const { return m_e==CLOCKER_UNKNOWN; } AstVarAttrClocker invert() const { if (m_e==CLOCKER_YES) return CLOCKER_NO; else if (m_e==CLOCKER_NO) return CLOCKER_YES; else return m_e; } const char* ascii() const { static const char* const names[] = { "","clker","non_clker"}; return names[m_e]; } }; inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstVarAttrClocker::en lhs, AstVarAttrClocker rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, const AstVarAttrClocker& rhs) { return os<(_e)) {} operator en () const { return m_e; } const char* ascii() const { static const char* const 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) {} // cppcheck-suppress noExplicitConstructor 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) {} // cppcheck-suppress noExplicitConstructor 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* const 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) {} // cppcheck-suppress noExplicitConstructor 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* const 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, const 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; } // class LeftRight {}; 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(LeftRight, int left, int right) : m_hi(0), m_lo(0), mu_flags(0) { init((right>left)?right:left, (right>left)?left:right, (right>left)); } ~VNumRange() {} // MEMBERS void init(int hi, int lo, bool littleEndian) { m_hi=hi; m_lo=lo; mu_flags=0; m_ranged=true; m_littleEndian=littleEndian; } int hi() const { return m_hi; } int lo() const { return m_lo; } int left() const { return littleEndian()?lo():hi(); } // How to show a declaration int right() const { return littleEndian()?hi():lo(); } int leftToRightInc() const { return littleEndian()?1:-1; } int elements() const { return hi()-lo()+1; } bool ranged() const { return m_ranged; } bool littleEndian() const { return m_littleEndian; } int hiMaxSelect() const { return (lo()<0 ? hi()-lo() : hi()); } // Maximum value a [] select may index bool representableByWidth() const // Could be represented by just width=1, or [width-1:0] { return (!m_ranged || (m_lo==0 && m_hi>=1 && !m_littleEndian)); } void dump(ostream& str) const { if (ranged()) str<<"["< rhs if ( (m_widthMin < rhs.m_widthMin)) return true; if (!(m_widthMin == rhs.m_widthMin)) return false; // lhs > rhs if ( (m_numeric < rhs.m_numeric)) return true; if (!(m_numeric == rhs.m_numeric)) return false; // lhs > rhs if ( (m_keyword < rhs.m_keyword)) return true; if (!(m_keyword == rhs.m_keyword)) return false; // lhs > rhs if ( (m_nrange < rhs.m_nrange)) return true; if (!(m_nrange == rhs.m_nrange)) return false; // lhs > rhs return false; } VBasicTypeKey(int width, int widthMin, AstNumeric numeric, AstBasicDTypeKwd kwd, const VNumRange& nrange) : m_width(width), m_widthMin(widthMin), m_numeric(numeric), m_keyword(kwd), m_nrange(nrange) {} ~VBasicTypeKey() {} }; //###################################################################### // AstNUser - Generic 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; class VNUser { union { void* up; int ui; } m_u; public: VNUser() {} // non-explicit: // cppcheck-suppress noExplicitConstructor VNUser(int i) { m_u.up = 0; m_u.ui = i; } explicit VNUser(void* p) { m_u.up = p; } ~VNUser() {} // Casters WidthVP* c() { return ((WidthVP*)m_u.up); } LinkVP* toLinkVP() { return ((LinkVP*)m_u.up); } VSymEnt* toSymEnt() { return ((VSymEnt*)m_u.up); } AstNode* toNodep() { return ((AstNode*)m_u.up); } OrderBlockNU* toOrderBlock() { return ((OrderBlockNU*)m_u.up); } OrderVarNU* toOrderVar() { return ((OrderVarNU*)m_u.up); } V3GraphVertex* toGraphVertex() { return ((V3GraphVertex*)m_u.up); } inline int toInt() { return m_u.ui; } static inline VNUser fromZero () { return VNUser(0); } static inline VNUser fromInt (int i) { return VNUser(i); } }; //###################################################################### // 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(AstBreak* nodep) { visit((AstNodeStmt*)(nodep)); } // virtual void visit(AstNodeStmt* nodep) { visit((AstNode*)(nodep)); } }; //###################################################################### // 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, const 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_bothm_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 VNUser m_user1u; // Contains 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 VNUser m_user2u; // Contains any information the user iteration routine wants VNUser m_user3u; // Contains 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 VNUser m_user4u; // Contains any information the user iteration routine wants VNUser m_user5u; // Contains 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); private: AstNode* cloneTreeIter(); AstNode* cloneTreeIterList(); void checkTreeIter(AstNode* backp); void checkTreeIterList(AstNode* backp); bool gateTreeIter(); bool sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool gateOnly); void deleteTreeIter(); void deleteNode(); public: static void relinkOneLink(AstNode*& pointpr, AstNode* newp); // cppcheck-suppress functionConst void debugTreeChange(const char* prefix, int lineno, bool next); protected: // CONSTUCTORS AstNode() {init(); } explicit AstNode(FileLine* fileline) {init(); m_fileline = fileline; } virtual AstNode* clone() = 0; // Generally, cloneTree is what you want instead virtual void cloneRelink() {} void cloneRelinkTree(); // METHODS void setOp1p(AstNode* newp); // Set non-list-type op1 to non-list element void setOp2p(AstNode* newp); // Set non-list-type op2 to non-list element void setOp3p(AstNode* newp); // Set non-list-type op3 to non-list element void setOp4p(AstNode* newp); // Set non-list-type op4 to non-list element void setNOp1p(AstNode* newp) { if (newp) setOp1p(newp); } void setNOp2p(AstNode* newp) { if (newp) setOp2p(newp); } void setNOp3p(AstNode* newp) { if (newp) setOp3p(newp); } void setNOp4p(AstNode* newp) { if (newp) setOp4p(newp); } void addOp1p(AstNode* newp); // Append newp to end of op1 void addOp2p(AstNode* newp); // Append newp to end of op2 void addOp3p(AstNode* newp); // Append newp to end of op3 void addOp4p(AstNode* newp); // Append newp to end of op4 void addNOp1p(AstNode* newp) { if (newp) addOp1p(newp); } void addNOp2p(AstNode* newp) { if (newp) addOp2p(newp); } void addNOp3p(AstNode* newp) { if (newp) addOp3p(newp); } void addNOp4p(AstNode* newp) { if (newp) addOp4p(newp); } void clonep(AstNode* nodep) { m_clonep=nodep; m_cloneCnt=s_cloneCntGbl; } static void cloneClearTree() { s_cloneCntGbl++; UASSERT_STATIC(s_cloneCntGbl,"Rollover"); } public: // ACCESSORS virtual AstType type() const = 0; const char* typeName() const { return type().ascii(); } // See also prettyTypeName AstNode* nextp() const { return m_nextp; } AstNode* backp() const { return m_backp; } AstNode* op1p() const { return m_op1p; } AstNode* op2p() const { return m_op2p; } AstNode* op3p() const { return m_op3p; } AstNode* op4p() const { return m_op4p; } AstNodeDType* dtypep() const { return m_dtypep; } AstNode* clonep() const { return ((m_cloneCnt==s_cloneCntGbl)?m_clonep:NULL); } AstNode* firstAbovep() const { return ((backp() && backp()->nextp()!=this) ? backp() : NULL); } // Returns NULL when second or later in list bool brokeExists() const; bool brokeExistsAbove() const; // CONSTRUCTORS virtual ~AstNode(); #ifdef VL_LEAK_CHECKS static void* operator new(size_t size); static void operator delete(void* obj, size_t size); #endif // CONSTANT ACCESSORS static int instrCountBranch() { return 4; } ///< Instruction cycles to branch static int instrCountDiv() { return 10; } ///< Instruction cycles to divide static int instrCountDpi() { return 1000; } ///< Instruction cycles to call user function static int instrCountLd() { return 2; } ///< Instruction cycles to load memory static int instrCountMul() { return 3; } ///< Instruction cycles to multiply integers static int instrCountPli() { return 20; } ///< Instruction cycles to call pli routines static int instrCountDouble() { return 8; } ///< Instruction cycles to convert or do floats static int instrCountDoubleDiv() { return 40; } ///< Instruction cycles to divide floats static int instrCountDoubleTrig() { return 200; } ///< Instruction cycles to do triganomics static int instrCountString() { return 100; } ///< Instruction cycles to do string ops static int instrCountCall() { return instrCountBranch()+10; } ///< Instruction cycles to call subroutine static int instrCountTime() { return instrCountCall()+5; } ///< Instruction cycles to determine simulation time // ACCESSORS virtual string name() const { return ""; } virtual void name(const string& name) { this->v3fatalSrc("name() called on object without name() method"); } virtual void tag(const string& text) {} virtual string tag() const { return ""; } virtual string verilogKwd() const { return ""; } string shortName() const; // Name with __PVT__ removed for concatenating scopes static string dedotName(const string& namein); // Name with dots removed static string prettyName(const string& namein); // Name for printing out to the user static string encodeName(const string& namein); // Encode user name into internal C representation static string encodeNumber(vlsint64_t numin); // Encode number into internal C representation static string vcdName(const string& namein); // Name for printing out to vcd files string prettyName() const { return prettyName(name()); } string prettyTypeName() const; // "VARREF" for error messages virtual string prettyOperatorName() const { return "operator "+prettyTypeName(); } FileLine* fileline() const { return m_fileline; } void fileline(FileLine* fl) { m_fileline=fl; } bool width1() const; int widthInstrs() const; void didWidth(bool flag) { m_didWidth=flag; } bool didWidth() const { return m_didWidth; } bool didWidthAndSet() { if (didWidth()) return true; didWidth(true); return false;} void doingWidth(bool flag) { m_doingWidth=flag; } bool doingWidth() const { return m_doingWidth; } //TODO stomp these width functions out, and call via dtypep() instead int width() const; int widthMin() const; int widthMinV() const { return v3Global.widthMinUsage()==VWidthMinUsage::VERILOG_WIDTH ? widthMin() : width(); } int widthWords() const { return VL_WORDS_I(width()); } bool isQuad() const { return (width()>VL_WORDSIZE && width()<=VL_QUADSIZE); } bool isWide() const { return (width()>VL_QUADSIZE); } bool isDouble() const; bool isSigned() const; bool isString() const; VNUser user1u() 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_user1u : VNUser(0)); } AstNode* user1p() const { return user1u().toNodep(); } void user1u(const VNUser& user) { m_user1u=user; m_user1Cnt=AstUser1InUse::s_userCntGbl; } void user1p(void* userp) { user1u(VNUser(userp)); } int user1() const { return user1u().toInt(); } void user1(int val) { user1u(VNUser(val)); } int user1Inc(int val=1) { int v=user1(); user1(v+val); 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 VNUser user2u() const { // Slows things down measurably, so disabled by default //UASSERT_STATIC(AstUser2InUse::s_userBusy, "userp set w/o busy"); return ((m_user2Cnt==AstUser2InUse::s_userCntGbl) ? m_user2u : VNUser(0)); } AstNode* user2p() const { return user2u().toNodep(); } void user2u(const VNUser& user) { m_user2u=user; m_user2Cnt=AstUser2InUse::s_userCntGbl; } void user2p(void* userp) { user2u(VNUser(userp)); } int user2() const { return user2u().toInt(); } void user2(int val) { user2u(VNUser(val)); } int user2Inc(int val=1) { int v=user2(); user2(v+val); return v; } int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; } // Better for cache than user2Inc() static void user2ClearTree() { AstUser2InUse::clear(); } // Clear userp()'s across the entire tree VNUser user3u() const { // Slows things down measurably, so disabled by default //UASSERT_STATIC(AstUser3InUse::s_userBusy, "userp set w/o busy"); return ((m_user3Cnt==AstUser3InUse::s_userCntGbl) ? m_user3u : VNUser(0)); } AstNode* user3p() const { return user3u().toNodep(); } void user3u(const VNUser& user) { m_user3u=user; m_user3Cnt=AstUser3InUse::s_userCntGbl; } void user3p(void* userp) { user3u(VNUser(userp)); } int user3() const { return user3u().toInt(); } void user3(int val) { user3u(VNUser(val)); } int user3Inc(int val=1) { int v=user3(); user3(v+val); return v; } int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; } // Better for cache than user3Inc() static void user3ClearTree() { AstUser3InUse::clear(); } // Clear userp()'s across the entire tree VNUser user4u() const { // Slows things down measurably, so disabled by default //UASSERT_STATIC(AstUser4InUse::s_userBusy, "userp set w/o busy"); return ((m_user4Cnt==AstUser4InUse::s_userCntGbl) ? m_user4u : VNUser(0)); } AstNode* user4p() const { return user4u().toNodep(); } void user4u(const VNUser& user) { m_user4u=user; m_user4Cnt=AstUser4InUse::s_userCntGbl; } void user4p(void* userp) { user4u(VNUser(userp)); } int user4() const { return user4u().toInt(); } void user4(int val) { user4u(VNUser(val)); } int user4Inc(int val=1) { int v=user4(); user4(v+val); return v; } int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; } // Better for cache than user4Inc() static void user4ClearTree() { AstUser4InUse::clear(); } // Clear userp()'s across the entire tree VNUser user5u() const { // Slows things down measurably, so disabled by default //UASSERT_STATIC(AstUser5InUse::s_userBusy, "userp set w/o busy"); return ((m_user5Cnt==AstUser5InUse::s_userCntGbl) ? m_user5u : VNUser(0)); } AstNode* user5p() const { return user5u().toNodep(); } void user5u(const VNUser& user) { m_user5u=user; m_user5Cnt=AstUser5InUse::s_userCntGbl; } void user5p(void* userp) { user5u(VNUser(userp)); } int user5() const { return user5u().toInt(); } void user5(int val) { user5u(VNUser(val)); } int user5Inc(int val=1) { int v=user5(); user5(v+val); return v; } int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; } // Better for cache than user5Inc() static void user5ClearTree() { AstUser5InUse::clear(); } // Clear userp()'s across the entire tree vluint64_t editCount() const { return m_editCount; } void editCountInc() { m_editCount = ++s_editCntGbl; } // Preincrement, so can "watch AstNode::s_editCntGbl=##" static vluint64_t editCountLast() { return s_editCntLast; } static vluint64_t editCountGbl() { return s_editCntGbl; } static void editCountSetLast() { s_editCntLast = editCountGbl(); } // ACCESSORS for specific types // Alas these can't be virtual or they break when passed a NULL bool isZero(); bool isOne(); bool isNeqZero(); bool isAllOnes(); bool isAllOnesV(); // Verilog width rules apply // METHODS - data type changes especially for initial creation void dtypep(AstNodeDType* nodep) { if (m_dtypep != nodep) { m_dtypep = nodep; editCountInc(); } } void dtypeFrom(AstNode* fromp) { if (fromp) { dtypep(fromp->dtypep()); }} void dtypeChgSigned(bool flag=true); void dtypeChgWidth(int width, int widthMin); void dtypeChgWidthSigned(int width, int widthMin, AstNumeric numeric); void dtypeSetBitSized(int width, int widthMin, AstNumeric numeric) { dtypep(findBitDType(width,widthMin,numeric)); } void dtypeSetLogicSized(int width, int widthMin, AstNumeric numeric) { dtypep(findLogicDType(width,widthMin,numeric)); } void dtypeSetLogicBool() { dtypep(findLogicBoolDType()); } void dtypeSetDouble() { dtypep(findDoubleDType()); } void dtypeSetString() { dtypep(findStringDType()); } void dtypeSetSigned32() { dtypep(findSigned32DType()); } void dtypeSetUInt32() { dtypep(findUInt32DType()); } // Twostate void dtypeSetUInt64() { dtypep(findUInt64DType()); } // Twostate // Data type locators AstNodeDType* findLogicBoolDType() { return findBasicDType(AstBasicDTypeKwd::LOGIC); } AstNodeDType* findDoubleDType() { return findBasicDType(AstBasicDTypeKwd::DOUBLE); } AstNodeDType* findStringDType() { return findBasicDType(AstBasicDTypeKwd::STRING); } AstNodeDType* findSigned32DType() { return findBasicDType(AstBasicDTypeKwd::INTEGER); } AstNodeDType* findUInt32DType() { return findBasicDType(AstBasicDTypeKwd::UINT32); } // Twostate AstNodeDType* findUInt64DType() { return findBasicDType(AstBasicDTypeKwd::UINT64); } // Twostate AstNodeDType* findBitDType(int width, int widthMin, AstNumeric numeric) const; AstNodeDType* findLogicDType(int width, int widthMin, AstNumeric numeric) const; AstNodeDType* findLogicRangeDType(VNumRange range, int widthMin, AstNumeric numeric) const; AstNodeDType* findBasicDType(AstBasicDTypeKwd kwd) const; AstBasicDType* findInsertSameDType(AstBasicDType* nodep); // METHODS - dump and error void v3errorEnd(ostringstream& str) const; void v3errorEndFatal(ostringstream& str) const VL_ATTR_NORETURN; string warnMore() const; virtual void dump(ostream& str=cout); void dumpGdb(); // For GDB only void dumpGdbHeader() const; // METHODS - Tree modifications static AstNode* addNext(AstNode* nodep, AstNode* newp); // Returns nodep, adds newp to end of nodep's list static AstNode* addNextNull(AstNode* nodep, AstNode* newp); // Returns nodep, adds newp (maybe NULL) to end of nodep's list inline AstNode* addNext(AstNode* newp) { return addNext(this, newp); } inline AstNode* addNextNull(AstNode* newp) { return addNextNull(this, newp); } 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 gateTree() { return gateTreeIter(); } // Is tree isGateOptimizable? bool sameTree(AstNode* node2p); // Does tree of this == node2p? bool sameGateTree(AstNode* node2p); // Does tree of this == node2p?, not allowing non-isGateOptimizable void deleteTree(); // Always deletes the next link void checkTree(); // User Interface version void checkIter() const; void clearIter() { m_iterpp=NULL; } void dumpPtrs(ostream& str=cout) const; void dumpTree(ostream& str=cout, const string& indent=" ", int maxDepth=0); void dumpTree(const string& indent, int maxDepth=0) { dumpTree(cout,indent,maxDepth); } void dumpTreeGdb(); // For GDB only void dumpTreeAndNext(ostream& str=cout, const string& indent=" ", int maxDepth=0); void dumpTreeFile(const string& filename, bool append=false, bool doDump=true); static void dumpTreeFileGdb(const char* filenamep=NULL); // METHODS - queries virtual bool isPure() const { return true; } // Else a $display, etc, that must be ordered with other displays virtual bool isBrancher() const { return false; } // Changes control flow, disable some optimizations virtual bool isGateOptimizable() const { return true; } // Else a AstTime etc that can't be pushed out virtual bool isGateDedupable() const { return isGateOptimizable(); } // GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf) virtual bool isSubstOptimizable() const { return true; } // Else a AstTime etc that can't be substituted out virtual bool isPredictOptimizable() const { return true; } // Else a AstTime etc which output can't be predicted from input virtual bool isOutputter() const { return false; } // Else creates output or exits, etc, not unconsumed virtual bool isUnlikely() const { return false; } // Else $stop or similar statement which means an above IF statement is unlikely to be taken virtual int instrCount() const { return 0; } virtual V3Hash sameHash() const { return V3Hash(V3Hash::Illegal()); } // Not a node that supports it virtual bool same(const AstNode*) 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) = 0; void iterate(AstNVisitor& v) { this->accept(v); } // Does this; excludes following this->next void iterateAndNext(AstNVisitor& v); void iterateAndNextConst(AstNVisitor& v); void iterateChildren(AstNVisitor& v); // Excludes following this->next void iterateChildrenBackwards(AstNVisitor& v); // Excludes following this->next void iterateChildrenConst(AstNVisitor& v); // Excludes following this->next AstNode* iterateSubtreeReturnEdits(AstNVisitor& v); // Return edited nodep; see comments in V3Ast.cpp // CONVERSION #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 static_cast(AstNode::cloneTree(cloneNext)); } \ Ast ##name * clonep() const { return static_cast(AstNode::clonep()); } class AstNodeMath : public AstNode { // Math -- anything that's part of an expression tree public: explicit AstNodeMath(FileLine* fl) : AstNode(fl) {} ASTNODE_BASE_FUNCS(NodeMath) // METHODS virtual bool hasDType() const { return true; } virtual string emitVerilog() = 0; /// Format string for verilog writing; see V3EmitV virtual string emitC() = 0; virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() = 0; // True if output has extra upper bits zero // Someday we will generically support data types on every math node // Until then isOpaque indicates we shouldn't constant optimize this node type bool isOpaque() { return castCvtPackString()!=NULL; } }; class AstNodeTermop : public AstNodeMath { // Terminal operator -- a operator with no "inputs" public: explicit 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) { } }; class AstNodeUniop : public AstNodeMath { // Unary math public: AstNodeUniop(FileLine* fl, AstNode* lhsp) : AstNodeMath(fl) { dtypeFrom(lhsp); setOp1p(lhsp); } ASTNODE_BASE_FUNCS(NodeUniop) AstNode* lhsp() const { return op1p(); } void lhsp(AstNode* nodep) { return setOp1p(nodep); } // METHODS virtual void numberOperate(V3Number& out, const V3Number& lhs) = 0; // Set out to evaluation of a AstConst'ed lhs virtual bool cleanLhs() = 0; virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size virtual bool doubleFlavor() const { return false; } // D flavor of nodes with both flavors? virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors? virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors? virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode*) const { return true; } }; class AstNodeBiop : public AstNodeMath { // Binary math public: AstNodeBiop(FileLine* fl, AstNode* lhs, AstNode* rhs) : AstNodeMath(fl) { setOp1p(lhs); setOp2p(rhs); } ASTNODE_BASE_FUNCS(NodeBiop) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back. // ACCESSORS AstNode* lhsp() const { return op1p(); } AstNode* rhsp() const { return op2p(); } void lhsp(AstNode* nodep) { return setOp1p(nodep); } void rhsp(AstNode* nodep) { return setOp2p(nodep); } // METHODS virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) = 0; // Set out to evaluation of a AstConst'ed virtual bool cleanLhs() = 0; // True if LHS must have extra upper bits zero virtual bool cleanRhs() = 0; // True if RHS must have extra upper bits zero virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size virtual bool sizeMattersRhs() = 0; // True if output result depends on rhs size virtual bool doubleFlavor() const { return false; } // D flavor of nodes with both flavors? virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors? virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors? virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode*) const { return true; } }; class AstNodeTriop : public AstNodeMath { // Trinary math public: AstNodeTriop(FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths) : AstNodeMath(fl) { setOp1p(lhs); setOp2p(rhs); setOp3p(ths); } ASTNODE_BASE_FUNCS(NodeTriop) AstNode* lhsp() const { return op1p(); } AstNode* rhsp() const { return op2p(); } AstNode* thsp() const { return op3p(); } 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(const AstNode*) const { return true; } }; class AstNodeBiCom : public AstNodeBiop { // Binary math with commutative properties public: AstNodeBiCom(FileLine* fl, AstNode* lhs, AstNode* rhs) : AstNodeBiop(fl, lhs, rhs) {} ASTNODE_BASE_FUNCS(NodeBiCom) }; class AstNodeBiComAsv : public AstNodeBiCom { // Binary math with commutative & associative properties public: AstNodeBiComAsv(FileLine* fl, AstNode* lhs, AstNode* rhs) : AstNodeBiCom(fl, lhs, rhs) {} ASTNODE_BASE_FUNCS(NodeBiComAsv) }; class AstNodeCond : public AstNodeTriop { public: AstNodeCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) : AstNodeTriop(fl, condp, expr1p, expr2p) { if (expr1p) dtypeFrom(expr1p); else if (expr2p) dtypeFrom(expr2p); } ASTNODE_BASE_FUNCS(NodeCond) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) { if (lhs.isNeqZero()) out.opAssign(rhs); else out.opAssign(ths); } AstNode* condp() const { return op1p(); } // op1 = Condition AstNode* expr1p() const { return op2p(); } // op2 = If true... AstNode* expr2p() const { return op3p(); } // 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(); } virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) = 0; }; class AstNodePreSel : public AstNode { // Something that becomes an AstSel public: AstNodePreSel(FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths) : AstNode(fl) { setOp1p(lhs); setOp2p(rhs); setNOp3p(ths); } ASTNODE_BASE_FUNCS(NodePreSel) AstNode* lhsp() const { return op1p(); } AstNode* fromp() const { return lhsp(); } AstNode* rhsp() const { return op2p(); } AstNode* thsp() const { return op3p(); } 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(const AstNode*) const { return true; } }; class AstNodeStmt : public AstNode { // Statement -- anything that's directly under a function public: explicit AstNodeStmt(FileLine* fl) : AstNode(fl) {} ASTNODE_BASE_FUNCS(NodeStmt) // METHODS virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here }; class AstNodeAssign : public AstNodeStmt { public: AstNodeAssign(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStmt(fl) { setOp1p(rhsp); setOp2p(lhsp); dtypeFrom(lhsp); } ASTNODE_BASE_FUNCS(NodeAssign) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back. // So iteration hits the RHS which is "earlier" in execution order, it's op1, not op2 AstNode* rhsp() const { return op1p(); } // op1 = Assign from AstNode* lhsp() const { return op2p(); } // 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(const AstNode*) const { return true; } virtual string verilogKwd() const { return "="; } virtual bool brokeLhsMustBeLvalue() const = 0; }; class AstNodeFor : public AstNodeStmt { public: AstNodeFor(FileLine* fileline, AstNode* initsp, AstNode* condp, AstNode* incsp, AstNode* bodysp) : AstNodeStmt(fileline) { addNOp1p(initsp); setOp2p(condp); addNOp3p(incsp); addNOp4p(bodysp); } ASTNODE_BASE_FUNCS(NodeFor) AstNode* initsp() const { return op1p(); } // op1= initial statements AstNode* condp() const { return op2p(); } // op2= condition to continue AstNode* incsp() const { return op3p(); } // op3= increment statements AstNode* bodysp() const { return op4p(); } // 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(const AstNode* samep) const { return true; } }; class AstNodeIf : public AstNodeStmt { private: AstBranchPred m_branchPred; // Branch prediction as taken/untaken? public: AstNodeIf(FileLine* fl, AstNode* condp, AstNode* ifsp, AstNode* elsesp) : AstNodeStmt(fl) { setOp1p(condp); addNOp2p(ifsp); addNOp3p(elsesp); } ASTNODE_BASE_FUNCS(NodeIf) AstNode* condp() const { return op1p(); } // op1 = condition AstNode* ifsp() const { return op2p(); } // op2 = list of true statements AstNode* elsesp() const { return op3p(); } // op3 = list of false statements void condp(AstNode* newp) { setOp1p(newp); } void addIfsp(AstNode* newp) { addOp2p(newp); } void addElsesp(AstNode* newp) { addOp3p(newp); } virtual bool isGateOptimizable() const { return false; } virtual bool isGateDedupable() const { return true; } virtual int instrCount() const { return instrCountBranch(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } void branchPred(AstBranchPred flag) { m_branchPred = flag; } AstBranchPred branchPred() const { return m_branchPred; } }; class AstNodeCase : public AstNodeStmt { public: AstNodeCase(FileLine* fl, AstNode* exprp, AstNode* casesp) : AstNodeStmt(fl) { setOp1p(exprp); addNOp2p(casesp); } ASTNODE_BASE_FUNCS(NodeCase) virtual int instrCount() const { return instrCountBranch(); } AstNode* exprp() const { return op1p(); } // op1 = case condition AstCaseItem* itemsp() const { return op2p()->castCaseItem(); } // op2 = list of case expressions AstNode* notParallelp() const { return op3p(); } // op3 = assertion code for non-full case's void addItemsp(AstNode* nodep) { addOp2p(nodep); } void addNotParallelp(AstNode* nodep) { setOp3p(nodep); } }; class AstNodeSenItem : public AstNode { // An AstSenItem or AstSenGate public: explicit 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) { } }; class AstNodeText : public AstNode { private: string m_text; public: // Node that simply puts text into the output stream AstNodeText(FileLine* fileline, const string& textp) : AstNode(fileline) { m_text = textp; // Copy it } ASTNODE_BASE_FUNCS(NodeText) virtual void dump(ostream& str=cout); virtual V3Hash sameHash() const { return V3Hash(text()); } virtual bool same(const AstNode* samep) const { const AstNodeText* asamep = static_cast(samep); return text() == asamep->text(); } const string& text() const { return m_text; } }; class AstNodeDType : public AstNode { // Ideally width() would migrate to BasicDType as that's where it makes sense, // but it's currently so prevalent in the code we leave it here. // Note the below members are included in AstTypeTable::Key lookups private: int m_width; // (also in AstTypeTable::Key) Bit width of operation int m_widthMin; // (also in AstTypeTable::Key) If unsized, bitwidth of minimum implementation AstNumeric m_numeric; // (also in AstTypeTable::Key) Node is signed // Other members bool m_generic; // Simple globally referenced type, don't garbage collect static int s_uniqueNum; // Unique number assigned to each dtype during creation for IEEE matching public: // CONSTRUCTORS explicit AstNodeDType(FileLine* fl) : AstNode(fl) { m_width=0; m_widthMin=0; m_generic=false; } ASTNODE_BASE_FUNCS(NodeDType) // ACCESSORS virtual void dump(ostream& str); virtual void dumpSmall(ostream& str); virtual bool hasDType() const { return true; } virtual AstBasicDType* basicp() const = 0; // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const = 0; // recurses over typedefs/const/enum to next non-typeref type virtual AstNodeDType* skipRefToConstp() const = 0; // recurses over typedefs to next non-typeref-or-const type virtual AstNodeDType* skipRefToEnump() const = 0; // recurses over typedefs/const to next non-typeref-or-enum/struct type virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... virtual bool maybePointedTo() const { return true; } virtual AstNodeDType* virtRefDTypep() const { return NULL; } // Iff has a non-null refDTypep(), as generic node function virtual void virtRefDTypep(AstNodeDType* nodep) { } // Iff has refDTypep(), set as generic node function virtual bool similarDType(AstNodeDType* samep) const = 0; // Assignable equivalence. Call skipRefp() on this and samep before calling virtual AstNodeDType* subDTypep() const { return NULL; } // Iff has a non-null subDTypep(), as generic node function // // Changing the width may confuse the data type resolution, so must clear TypeTable cache after use. void widthForce(int width, int sized) { m_width=width; m_widthMin=sized; } // For backward compatibility inherit width and signing from the subDType/base type void widthFromSub(AstNodeDType* nodep) { m_width=nodep->m_width; m_widthMin=nodep->m_widthMin; m_numeric=nodep->m_numeric; } // int width() const { return m_width; } void numeric(AstNumeric flag) { m_numeric = flag; } bool isSigned() const { return m_numeric.isSigned(); } bool isNosign() const { return m_numeric.isNosign(); } AstNumeric numeric() const { return m_numeric; } int widthWords() const { return VL_WORDS_I(width()); } int widthMin() const { return m_widthMin?m_widthMin:m_width; } // If sized, the size, if unsized the min digits to represent it int widthPow2() const; void widthMinFromWidth() { m_widthMin = m_width; } bool widthSized() const { return !m_widthMin || m_widthMin==m_width; } bool generic() const { return m_generic; } void generic(bool flag) { m_generic = flag; } AstNodeDType* dtypeDimensionp(int depth); pair dimensions(bool includeBasic); uint32_t arrayUnpackedElements(); // 1, or total multiplication of all dimensions static int uniqueNumInc() { return ++s_uniqueNum; } }; class AstNodeClassDType : public AstNodeDType { private: // TYPES typedef map MemberNameMap; // MEMBERS bool m_packed; MemberNameMap m_members; public: AstNodeClassDType(FileLine* fl, AstNumeric numericUnpack) : AstNodeDType(fl) { // AstNumeric::NOSIGN overloaded to indicate not packed m_packed = (numericUnpack != AstNumeric::NOSIGN); numeric(numericUnpack.isSigned() ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); } ASTNODE_BASE_FUNCS(NodeClassDType) virtual const char* broken() const; virtual void dump(ostream& str); // For basicp() we reuse the size to indicate a "fake" basic type of same size virtual AstBasicDType* basicp() const { return findLogicDType(width(),width(),numeric())->castBasicDType(); } virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... // op1 = members virtual bool similarDType(AstNodeDType* samep) const { return this==samep; // We don't compare members, require exact equivalence } AstMemberDType* membersp() const { return op1p()->castMemberDType(); } // op1 = AstMember list void addMembersp(AstNode* nodep) { addNOp1p(nodep); } bool packed() const { return m_packed; } bool packedUnsup() const { return true; } // packed() but as don't support unpacked, presently all structs void clearCache() { m_members.clear(); } void repairMemberCache(); AstMemberDType* findMember(const string& name) const { MemberNameMap::const_iterator it = m_members.find(name); return (it==m_members.end()) ? NULL : it->second; } int lsb() const { return 0; } int msb() const { return dtypep()->width()-1; } // Packed classes look like arrays VNumRange declRange() const { return VNumRange(msb(), lsb(), false); } }; class AstNodeArrayDType : public AstNodeDType { // Array data type, ie "some_dtype var_name [2:0]" // Children: DTYPE (moved to refDTypep() in V3Width) // Children: RANGE (array bounds) private: AstNodeDType* m_refDTypep; // Elements of this type (after widthing) AstNode* rangenp() const { return op2p(); } // op2 = Array(s) of variable public: explicit 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(); }} virtual bool same(const AstNode* samep) const { const AstNodeArrayDType* asamep = static_cast(samep); return (msb()==asamep->msb() && subDTypep()==asamep->subDTypep() && rangenp()->sameTree(asamep->rangenp())); } // HashedDT doesn't recurse, so need to check children virtual bool similarDType(AstNodeDType* samep) const { const AstNodeArrayDType* asamep = static_cast(samep); return (asamep && type() == samep->type() && msb() == asamep->msb() && rangenp()->sameTree(asamep->rangenp()) && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp())); } 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); } virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } AstRange* rangep() const { return op2p()->castRange(); } // op2 = Array(s) of variable void rangep(AstRange* nodep); // METHODS virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return elementsConst() * subDTypep()->widthTotalBytes(); } int msb() const; int lsb() const; int elementsConst() const; VNumRange declRange() const; }; class AstNodeSel : public AstNodeBiop { // Single bit range extraction, perhaps with non-constant selection or array selection public: AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp) :AstNodeBiop(fl, fromp, bitp) {} ASTNODE_BASE_FUNCS(NodeSel) AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing) void fromp(AstNode* nodep) { setOp1p(nodep); } AstNode* bitp() const { return op2p(); } // op2 = Msb selection expression void bitp(AstNode* nodep) { setOp2p(nodep); } int bitConst() const; virtual bool hasDType() const { return true; } }; class AstNodeStream : public AstNodeBiop { // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp() public: AstNodeStream(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { if (lhsp->dtypep()) { dtypeSetLogicSized(lhsp->dtypep()->width(), lhsp->dtypep()->width(), AstNumeric::UNSIGNED); } } ASTNODE_BASE_FUNCS(NodeStream) }; //###################################################################### // Tasks/functions common handling class AstNodeFTask : public AstNode { private: string m_name; // Name of task string m_cname; // Name of task if DPI import bool m_taskPublic:1; // Public task bool m_attrIsolateAssign:1;// User isolate_assignments attribute bool m_prototype:1; // Just a prototype bool m_dpiExport:1; // DPI exported bool m_dpiImport:1; // DPI imported bool m_dpiContext:1; // DPI import context bool m_dpiTask:1; // DPI import task (vs. void function) bool m_pure:1; // DPI import pure public: AstNodeFTask(FileLine* fileline, const string& name, AstNode* stmtsp) : AstNode(fileline) , m_name(name), m_taskPublic(false) , m_attrIsolateAssign(false), m_prototype(false) , m_dpiExport(false), m_dpiImport(false), m_dpiContext(false) , m_dpiTask(false), m_pure(false) { addNOp3p(stmtsp); cname(name); // Might be overridden by dpi import/export } ASTNODE_BASE_FUNCS(NodeFTask) virtual void dump(ostream& str=cout); virtual string name() const { return m_name; } // * = Var name virtual bool maybePointedTo() const { return true; } virtual bool isGateOptimizable() const { return !((m_dpiExport || m_dpiImport) && !m_pure); } // {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(); } void addFvarp(AstNode* nodep) { addNOp1p(nodep); } bool isFunction() const { return fvarp()!=NULL; } // op3 = Statements/Ports/Vars AstNode* stmtsp() const { return op3p(); } // op3 = List of statements void addStmtsp(AstNode* nodep) { addNOp3p(nodep); } // op4 = scope name AstScopeName* scopeNamep() const { return op4p()->castScopeName(); } void scopeNamep(AstNode* nodep) { setNOp4p(nodep); } void taskPublic(bool flag) { m_taskPublic=flag; } bool taskPublic() const { return m_taskPublic; } void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; } bool attrIsolateAssign() const { return m_attrIsolateAssign; } void prototype(bool flag) { m_prototype = flag; } bool prototype() const { return m_prototype; } void dpiExport(bool flag) { m_dpiExport = flag; } bool dpiExport() const { return m_dpiExport; } void dpiImport(bool flag) { m_dpiImport = flag; } bool dpiImport() const { return m_dpiImport; } void dpiContext(bool flag) { m_dpiContext = flag; } bool dpiContext() const { return m_dpiContext; } void dpiTask(bool flag) { m_dpiTask = flag; } bool dpiTask() const { return m_dpiTask; } void pure(bool flag) { m_pure = flag; } bool pure() const { return m_pure; } }; class AstNodeFTaskRef : public AstNode { // A reference to a task (or function) private: AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced string m_name; // Name of variable string m_dotted; // Dotted part of scope to task or "" string m_inlinedDots; // Dotted hierarchy flattened out AstPackage* m_packagep; // Package hierarchy public: AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp) :AstNode(fl) , m_taskp(NULL), m_packagep(NULL) { setOp1p(namep); addNOp2p(pinsp); } AstNodeFTaskRef(FileLine* fl, const string& name, AstNode* pinsp) :AstNode(fl) , m_taskp(NULL), m_name(name), m_packagep(NULL) { addNOp2p(pinsp); } ASTNODE_BASE_FUNCS(NodeFTaskRef) virtual const char* broken() const { BROKEN_RTN(m_taskp && !m_taskp->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_taskp && m_taskp->clonep()) { m_taskp = m_taskp->clonep(); }} virtual void dump(ostream& str=cout); virtual string name() const { return m_name; } // * = Var name virtual bool isGateOptimizable() const { return m_taskp && m_taskp->isGateOptimizable(); } 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(); } void addPinsp(AstNode* nodep) { addOp2p(nodep); } // op3 = scope tracking AstScopeName* scopeNamep() const { return op3p()->castScopeName(); } void scopeNamep(AstNode* nodep) { setNOp3p(nodep); } }; class AstNodeModule : public AstNode { // A module, package, program or interface declaration; // something that can live directly under the TOP, // excluding $unit package stuff private: string m_name; // Name of the module string m_origName; // Name of the module, ignoring name() changes, for dot lookup bool m_modPublic:1; // Module has public references bool m_modTrace:1; // Tracing this module bool m_inLibrary:1; // From a library, no error if not used, never top level bool m_dead:1; // LinkDot believes is dead; will remove in Dead visitors bool m_internal:1; // Internally created bool m_recursive:1; // Recursive module bool m_recursiveClone:1; // If recursive, what module it clones, otherwise NULL int m_level; // 1=top module, 2=cell off top module, ... int m_varNum; // Incrementing variable number int m_typeNum; // Incrementing implicit type number public: AstNodeModule(FileLine* fl, const string& name) : AstNode (fl) ,m_name(name), m_origName(name) ,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false) ,m_internal(false), m_recursive(false), m_recursiveClone(false) ,m_level(0), m_varNum(0), m_typeNum(0) { } ASTNODE_BASE_FUNCS(NodeModule) virtual void dump(ostream& str); virtual bool maybePointedTo() const { return true; } virtual string name() const { return m_name; } AstNode* stmtsp() const { return op2p(); } // op2 = List of statements AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks // METHODS void addInlinesp(AstNode* nodep) { addOp1p(nodep); } void addStmtp(AstNode* nodep) { addOp2p(nodep); } void addActivep(AstNode* nodep) { addOp3p(nodep); } // ACCESSORS virtual void name(const string& name) { m_name = name; } string origName() const { return m_origName; } bool inLibrary() const { return m_inLibrary; } void inLibrary(bool flag) { m_inLibrary = flag; } void level(int level) { m_level = level; } int level() const { return m_level; } bool isTop() const { return level()==1; } int varNumGetInc() { return ++m_varNum; } int typeNumGetInc() { return ++m_typeNum; } void modPublic(bool flag) { m_modPublic = flag; } bool modPublic() const { return m_modPublic; } void modTrace(bool flag) { m_modTrace = flag; } bool modTrace() const { return m_modTrace; } void dead(bool flag) { m_dead = flag; } bool dead() const { return m_dead; } void internal(bool flag) { m_internal = flag; } bool internal() const { return m_internal; } void recursive(bool flag) { m_recursive = flag; } bool recursive() const { return m_recursive; } void recursiveClone(bool flag) { m_recursiveClone = flag; } bool recursiveClone() const { return m_recursiveClone; } }; //###################################################################### #include "V3AstNodes.h" #include "V3Ast__gen_impl.h" // From ./astgen // Things like: // inline AstAlways* AstNode::castAlways() { return dynamic_cast(this);} //###################################################################### // Inline ACCESSORS inline int AstNode::width() const { return dtypep() ? dtypep()->width() : 0; } inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; } inline bool AstNode::width1() const { return dtypep() && dtypep()->width()==1; } // V3Const uses to know it can optimize inline int AstNode::widthInstrs() const { return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1)); } inline bool AstNode::isDouble() const { return dtypep() && dtypep()->castBasicDType() && dtypep()->castBasicDType()->isDouble(); } inline bool AstNode::isString() const { return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString(); } inline bool AstNode::isSigned() const { return dtypep() && dtypep()->isSigned(); } inline bool AstNode::isZero() { return (this->castConst() && this->castConst()->num().isEqZero()); } inline bool AstNode::isNeqZero() { return (this->castConst() && this->castConst()->num().isNeqZero()); } inline bool AstNode::isOne() { return (this->castConst() && this->castConst()->num().isEqOne()); } inline bool AstNode::isAllOnes() { return (this->castConst() && this->castConst()->isEqAllOnes()); } inline bool AstNode::isAllOnesV() { return (this->castConst() && this->castConst()->isEqAllOnesV()); } inline bool AstNode::sameTree(AstNode* node2p) { return sameTreeIter(this, node2p, true, false); } inline bool AstNode::sameGateTree(AstNode* node2p) { return sameTreeIter(this, node2p, true, true); } inline void AstNodeVarRef::init() { if (m_varp) dtypep(m_varp->dtypep()); } inline void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); } inline int AstNodeArrayDType::msb() const { return rangep()->msbConst(); } inline int AstNodeArrayDType::lsb() const { return rangep()->lsbConst(); } inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); } inline VNumRange AstNodeArrayDType::declRange() const { return VNumRange(msb(), lsb(), rangep()->littleEndian()); } inline void AstIfaceRefDType::cloneRelink() { if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep(); if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep(); if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep(); } #endif // Guard verilator-3.916/src/V3Premit.cpp0000664000177100017500000003346213205574202016474 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Premit's Transformations: // // Each module: // For each wide OP, make a a temporary variable with the wide value // For each deep expression, assign expression to temporary. // // Each display (independant transformation; here as Premit is a good point) // If autoflush, insert a flush // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Premit.h" #include "V3Ast.h" //###################################################################### // Structure for global state class PremitAssignVisitor : public AstNVisitor { private: // NODE STATE // AstVar::user4() // bool; occurs on LHS of current assignment AstUser4InUse m_inuser4; // STATE bool m_noopt; // Disable optimization of variables in this block // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstNodeAssign* nodep) { //AstNode::user4ClearTree(); // Implied by AstUser4InUse // LHS first as fewer varrefs nodep->lhsp()->iterateAndNext(*this); // Now find vars marked as lhs nodep->rhsp()->iterateAndNext(*this); } virtual void visit(AstVarRef* nodep) { // it's LHS var is used so need a deep temporary if (nodep->lvalue()) { nodep->varp()->user4(true); } else { if (nodep->varp()->user4()) { if (!m_noopt) UINFO(4, "Block has LHS+RHS var: "<iterateChildren(*this); } public: // CONSTRUCTORS explicit PremitAssignVisitor(AstNodeAssign* nodep) { UINFO(4," PremitAssignVisitor on "<accept(*this); } virtual ~PremitAssignVisitor() {} bool noOpt() const { return m_noopt; } }; //###################################################################### // Premit state, as a visitor of each AstNode class PremitVisitor : public AstNVisitor { private: // NODE STATE // AstNodeMath::user() -> bool. True if iterated already // AstShiftL::user2() -> bool. True if converted to conditional // AstShiftR::user2() -> bool. True if converted to conditional // *::user4() -> See PremitAssignVisitor AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // STATE AstNodeModule* m_modp; // Current module AstCFunc* m_funcp; // Current block AstNode* m_stmtp; // Current statement AstWhile* m_inWhilep; // Inside while loop, special statement additions AstTraceInc* m_inTracep; // Inside while loop, special statement additions bool m_assignLhs; // Inside assignment lhs, don't breakup extracts // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } bool assignNoTemp(AstNodeAssign* nodep) { return (nodep->lhsp()->castVarRef() && !AstVar::scVarRecurse(nodep->lhsp()) && nodep->rhsp()->castConst()); } void checkNode(AstNode* nodep) { // Consider adding a temp for this expression. // We need to avoid adding temps to the following: // ASSIGN(x, *here*) // ASSIGN(CONST*here*, VARREF(!sc)) // ARRAYSEL(*here*, ...) (No wides can be in any argument but first, so we don't check which arg is wide) // ASSIGN(x, SEL*HERE*(ARRAYSEL()...) (m_assignLhs==true handles this.) //UINFO(9, " Check: "<user1()) { // Not already done if (nodep->isWide()) { if (m_assignLhs) { } else if (nodep->firstAbovep() && nodep->firstAbovep()->castNodeAssign() && assignNoTemp(nodep->firstAbovep()->castNodeAssign())) { // Not much point if it's just a direct assignment to a constant } else if (nodep->backp()->castSel() && nodep->backp()->castSel()->widthp() == nodep) { // AstSel::width must remain a constant } else if (nodep->firstAbovep() && nodep->firstAbovep()->castArraySel()) { // ArraySel's are pointer refs, ignore } else { UINFO(4,"Cre Temp: "<varNumGetInc())); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname, nodep->dtypep()); m_funcp->addInitsp(varp); return varp; } void insertBeforeStmt(AstNode* newp) { // Insert newp before m_stmtp if (m_inWhilep) { // Statements that are needed for the 'condition' in a while actually have to // be put before & after the loop, since we can't do any statements in a while's (cond). m_inWhilep->addPrecondsp(newp); } else if (m_inTracep) { m_inTracep->addPrecondsp(newp); } else if (m_stmtp) { AstNRelinker linker; m_stmtp->unlinkFrBack(&linker); newp->addNext(m_stmtp); linker.relink(newp); } else { newp->v3fatalSrc("No statement insertion point."); } } void createDeepTemp(AstNode* nodep, bool noSubst) { if (debug()>8) nodep->dumpTree(cout,"deepin:"); AstNRelinker linker; nodep->unlinkFrBack(&linker); AstVar* varp = getBlockTemp(nodep); if (noSubst) varp->noSubst(true); // Do not remove varrefs to this in V3Const // Replace node tree with reference to var AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false); linker.relink(newp); // Put assignment before the referencing statement AstAssign* assp = new AstAssign (nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true), nodep); insertBeforeStmt(assp); if (debug()>8) assp->dumpTree(cout,"deepou:"); nodep->user1(true); // Don't add another assignment } // VISITORS virtual void visit(AstNodeModule* nodep) { UINFO(4," MOD "<iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCFunc* nodep) { 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) { 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) { startStatement(nodep); { bool noopt = PremitAssignVisitor(nodep).noOpt(); if (noopt && !nodep->user1()) { // Need to do this even if not wide, as e.g. a select may be on a wide operator UINFO(4,"Deep temp for LHS/RHS\n"); createDeepTemp(nodep->rhsp(), false); } } nodep->rhsp()->iterateAndNext(*this); m_assignLhs = true; nodep->lhsp()->iterateAndNext(*this); m_assignLhs = false; m_stmtp = NULL; } virtual void visit(AstNodeStmt* nodep) { UINFO(4," STMT "<iterateChildren(*this); m_stmtp = NULL; } virtual void visit(AstTraceInc* nodep) { 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 "<rhsp()->castConst(); if (shiftp && shiftp->num().mostSetBitP1() > 32) { shiftp->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"); } if (nodep->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) { visitShift(nodep); } virtual void visit(AstShiftR* nodep) { visitShift(nodep); } virtual void visit(AstShiftRS* nodep) { visitShift(nodep); } // Operators virtual void visit(AstNodeTermop* nodep) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstNodeUniop* nodep) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstNodeBiop* nodep) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstUCFunc* nodep) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstSel* nodep) { 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(AstArraySel* nodep) { nodep->fromp()->iterateAndNext(*this); { // Only the 'from' is part of the assignment LHS bool prevAssign = m_assignLhs; m_assignLhs = false; nodep->bitp()->iterateAndNext(*this); m_assignLhs = prevAssign; } checkNode(nodep); } virtual void visit(AstConst* nodep) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstNodeCond* nodep) { nodep->iterateChildren(*this); if (nodep->expr1p()->isWide() && !nodep->condp()->castConst() && !nodep->condp()->castVarRef()) { // We're going to need the expression several times in the expanded code, // so might as well make it a common expression createDeepTemp(nodep->condp(), false); } checkNode(nodep); } // Autoflush virtual void visit(AstDisplay* nodep) { startStatement(nodep); nodep->iterateChildren(*this); m_stmtp = NULL; if (v3Global.opt.autoflush()) { AstNode* searchp = nodep->nextp(); while (searchp && searchp->castComment()) searchp = searchp->nextp(); if (searchp && searchp->castDisplay() && nodep->filep()->sameGateTree(searchp->castDisplay()->filep())) { // There's another display next; we can just wait to flush } else { UINFO(4,"Autoflush "<addNextHere(new AstFFlush(nodep->fileline(), nodep->filep()->cloneTree(true))); } } } virtual void visit(AstSFormatF* nodep) { nodep->iterateChildren(*this); // Any strings sent to a display must be var of string data type, // to avoid passing a pointer to a temporary. for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) { if (expp->dtypep()->basicp()->isString() && !expp->castVarRef()) { createDeepTemp(expp, true); } } } //-------------------- // Default: Just iterate virtual void visit(AstVar* nodep) {} // Don't hit varrefs under vars virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit PremitVisitor(AstNetlist* nodep) { m_modp = NULL; m_funcp = NULL; m_stmtp = NULL; m_inWhilep = NULL; m_inTracep = NULL; nodep->accept(*this); } virtual ~PremitVisitor() {} }; //---------------------------------------------------------------------- // Top loop //###################################################################### // Premit class functions void V3Premit::premitAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Begin.h0000664000177100017500000000225113205574202015715 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Removal of named begin blocks // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3BEGIN_H_ #define _V3BEGIN_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Begin { public: static void debeginAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3FileLine.h0000664000177100017500000001620613205574202016365 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Error handling // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3FileLine_H_ #define _V3FileLine_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Error.h" #include "V3LangCode.h" //###################################################################### class FileLine; //! Singleton class with tables of per-file data. //! This singleton class contains tables of data that are unchanging in each //! source file (each with its own unique filename number). class FileLineSingleton { // TYPES typedef map FileNameNumMap; typedef map FileLangNumMap; // MEMBERS FileNameNumMap m_namemap; // filenameno for each filename deque m_names; // filename text for each filenameno deque m_languages; // language for each filenameno // COSNTRUCTORS FileLineSingleton() { } ~FileLineSingleton() { } protected: friend class FileLine; // METHODS int nameToNumber(const string& filename); const string numberToName(int filenameno) const { return m_names[filenameno]; } const V3LangCode numberToLang(int filenameno) const { return m_languages[filenameno]; } void numberToLang(int filenameno, const V3LangCode& l) { m_languages[filenameno] = l; } void clear() { m_namemap.clear(); m_names.clear(); m_languages.clear(); } void fileNameNumMapDumpXml(ostream& os); static const string filenameLetters(int fileno); }; //! File and line number of an object, mostly for error reporting //! This class is instantiated for every source code line (potentially //! millions). To save space, per-file information (e.g. filename, source //! language is held in tables in the FileLineSingleton class. class FileLine { int m_lineno; int m_filenameno; bitset m_warnOn; private: struct EmptySecret {}; inline static FileLineSingleton& singleton() { static FileLineSingleton s; return s; } inline static FileLine& defaultFileLine() { static FileLine* defFilelinep = new FileLine(FileLine::EmptySecret()); return *defFilelinep; } protected: // User routines should never need to change line numbers // We are storing pointers, so we CAN'T change them after initial reading. friend class FileLineSingleton; friend class V3ParseImp; friend class V3PreLex; friend class V3PreProcImp; void lineno(int num) { m_lineno = num; } void language (V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); } void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); } void lineDirective(const char* textp, int& enterExitRef); void linenoInc() { m_lineno++; } void linenoIncInPlace() { m_lineno++; } FileLine* copyOrSameFileLine(); public: FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filenameno = singleton().nameToNumber(filename); m_warnOn=defaultFileLine().m_warnOn; } explicit FileLine (FileLine* fromp) { m_lineno=fromp->m_lineno; m_filenameno = fromp->m_filenameno; m_warnOn=fromp->m_warnOn; } explicit FileLine (EmptySecret); ~FileLine() { } FileLine* create(const string& filename, int lineno) { return new FileLine(filename,lineno); } FileLine* create(int lineno) { return create(filename(), lineno); } static void deleteAllRemaining(); #ifdef VL_LEAK_CHECKS static void* operator new(size_t size); static void operator delete(void* obj, size_t size); #endif int lineno () const { return m_lineno; } V3LangCode language () const { return singleton().numberToLang(m_filenameno); } string ascii() const; const string filename () const { return singleton().numberToName(m_filenameno); } const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); } const string filebasename () const; const string filebasenameNoExt () const; const string profileFuncname() const; const string xml() const { return "fl=\""+filenameLetters()+cvtToStr(lineno())+"\""; } string lineDirectiveStrg(int enter_exit_level) const; void warnOn(V3ErrorCode code, bool flag) { m_warnOn.set(code,flag); } // Turn on/off warning messages on this line. void warnOff(V3ErrorCode code, bool flag) { warnOn(code,!flag); } bool warnOff(const string& code, bool flag); // Returns 1 if ok bool warnIsOff(V3ErrorCode code) const; void warnLintOff(bool flag); void warnStyleOff(bool flag); void warnStateFrom(const FileLine& from) { m_warnOn=from.m_warnOn; } void warnResetDefault() { warnStateFrom(defaultFileLine()); } // Specific flag ACCESSORS/METHODS bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); } void coverageOn(bool flag) { warnOn(V3ErrorCode::I_COVERAGE,flag); } bool tracingOn() const { return m_warnOn.test(V3ErrorCode::I_TRACING); } void tracingOn(bool flag) { warnOn(V3ErrorCode::I_TRACING,flag); } // METHODS - Global static void globalWarnLintOff(bool flag) { defaultFileLine().warnLintOff(flag); } static void globalWarnStyleOff(bool flag) { defaultFileLine().warnStyleOff(flag); } static void globalWarnOff(V3ErrorCode code, bool flag) { defaultFileLine().warnOff(code, flag); } static bool globalWarnOff(const string& code, bool flag) { return defaultFileLine().warnOff(code, flag); } static void fileNameNumMapDumpXml(ostream& os) { singleton().fileNameNumMapDumpXml(os); } // METHODS - Called from netlist // Merge warning disables from another fileline void modifyStateInherit(const FileLine* fromp); // Change the current fileline due to actions discovered after parsing // and may have side effects on other nodes sharing this FileLine. // Use only when this is intended void modifyWarnOff(V3ErrorCode code, bool flag) { warnOff(code,flag); } // OPERATORS void v3errorEnd(ostringstream& str); void v3errorEndFatal(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); } private: void v3errorEndFatalGuts(ostringstream& str); }; ostream& operator<<(ostream& os, FileLine* fileline); inline void FileLine::v3errorEndFatal(ostringstream& str) { v3errorEnd(str); assert(0); } #endif // Guard verilator-3.916/src/V3Gate.cpp0000664000177100017500000015547113205574202016121 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Gate optimizations, such as wire elimination // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Gate's Transformations: // // Extract a graph of the *entire* netlist with cells expanded // Perform constant optimization across the graph // Create VARSCOPEs for any variables we can rip out // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include VL_INCLUDE_UNORDERED_SET #include "V3Global.h" #include "V3Gate.h" #include "V3Ast.h" #include "V3Graph.h" #include "V3Const.h" #include "V3Stats.h" #include "V3Hashed.h" typedef list GateVarRefList; #define GATE_DEDUP_MAX_DEPTH 20 //###################################################################### 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 VNUser visit(GateLogicVertex* vertexp, VNUser vu=VNUser(0)) =0; virtual VNUser visit(GateVarVertex* vertexp, VNUser vu=VNUser(0)) =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()) { ret = dynamic_cast(edgep->fromp())->accept(v, vu); } return ret; } // Returns only the result from the LAST vertex iterated over // Note: This behaves differently than iterateInEdges() in that it will traverse // all edges that exist when it is initially called, whereas // iterateInEdges() will stop traversing edges if one is deleted VNUser iterateCurrentOutEdges(GateGraphBaseVisitor& v, VNUser vu=VNUser(0)) { VNUser ret = VNUser(0); V3GraphEdge* next_edgep = NULL; for (V3GraphEdge* edgep = outBeginp(); edgep; edgep = next_edgep) { // Need to find the next edge before visiting in case the edge is deleted next_edgep = edgep->outNextp(); ret = dynamic_cast(edgep->top())->accept(v, vu); } return ret; } }; 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(); } } VNUser accept(GateGraphBaseVisitor& v, VNUser vu=VNUser(0)) { return v.visit(this,vu); } }; 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; } VNUser accept(GateGraphBaseVisitor& v, VNUser vu=VNUser(0)) { return v.visit(this,vu); } }; //###################################################################### // 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) { m_substTreep = nodep->rhsp(); if (!nodep->lhsp()->castNodeVarRef()) clearSimple("ASSIGN(non-VARREF)"); else nodep->iterateChildren(*this); // We don't push logic other then assignments/NOTs into SenItems // This avoids a mess in computing what exactly a POSEDGE is // V3Const cleans up any NOTs by flipping the edges for us if (m_buffersOnly && !(nodep->rhsp()->castVarRef() // Avoid making non-clocked logic into clocked, // as it slows down the verilator_sim_benchmark || (nodep->rhsp()->castNot() && nodep->rhsp()->castNot()->lhsp()->castVarRef() && nodep->rhsp()->castNot()->lhsp()->castVarRef()->varp()->isUsedClock()) )) { clearSimple("Not a buffer (goes to a clock)"); } } //-------------------- // Default virtual void visit(AstNode* nodep) { // *** Special iterator if (!m_isSimple) return; // Fastpath if (!(m_dedupe ? nodep->isGateDedupable() : nodep->isGateOptimizable()) || !nodep->isPure() || nodep->isBrancher()) { UINFO(5, "Non optimizable type: "<iterateChildren(*this); } public: // CONSTUCTORS GateOkVisitor(AstNode* nodep, bool buffersOnly, bool dedupe) { m_isSimple = true; m_substTreep = NULL; m_buffersOnly = buffersOnly; m_lhsVarRef = NULL; m_dedupe = dedupe; // Iterate nodep->accept(*this); // Check results if (!m_substTreep) { clearSimple("No assignment found\n"); } for (GateVarRefList::const_iterator it = m_rhsVarRefs.begin(); it != m_rhsVarRefs.end(); ++it) { if (m_lhsVarRef && m_lhsVarRef->varScopep() == (*it)->varScopep()) { clearSimple("Circular logic\n"); // Oh my, we'll get a UNOPTFLAT much later. } } if (debug()>=9 && !m_isSimple) { nodep->dumpTree(cout,"\tgate!Ok: "); } } virtual ~GateOkVisitor() {} // PUBLIC METHODS bool isSimple() const { return m_isSimple; } AstNode* substTree() const { return m_substTreep; } const GateVarRefList& rhsVarRefs() const { return m_rhsVarRefs; } }; //###################################################################### // Gate class functions class GateVisitor : public GateBaseVisitor { private: // NODE STATE //Entire netlist: // AstVarScope::user1p -> GateVarVertex* for usage var, 0=not set yet // {statement}Node::user1p -> GateLogicVertex* for this statement // AstVarScope::user2 -> bool: Signal used in SenItem in *this* always statement // AstVar::user2 -> bool: Warned about SYNCASYNCNET // AstVarNodeRef::user2 -> bool: ConcatOffset visited AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // STATE V3Graph m_graph; // Scoreboard of var usages/dependencies GateLogicVertex* m_logicVertexp; // Current statement being tracked, NULL=ignored AstScope* m_scopep; // Current scope being processed AstNodeModule* m_modp; // Current module AstActive* m_activep; // Current active bool m_activeReducible; // Is activation block reducible? bool m_inSenItem; // Underneath AstSenItem; any varrefs are clocks bool m_inSlow; // Inside a slow structure V3Double0 m_statSigs; // Statistic tracking V3Double0 m_statRefs; // Statistic tracking V3Double0 m_statDedupLogic; // Statistic tracking V3Double0 m_statAssignMerged; // Statistic tracking // METHODS void iterateNewStmt(AstNode* nodep, const char* nonReducibleReason, const char* consumeReason) { if (m_scopep) { UINFO(4," STMT "<clearReducibleAndDedupable(nonReducibleReason); } else if (!m_activeReducible) { m_logicVertexp->clearReducible("Block Unreducible"); // Sequential logic is dedupable } if (consumeReason) m_logicVertexp->setConsumed(consumeReason); if (nodep->castSenItem()) m_logicVertexp->setConsumed("senItem"); nodep->iterateChildren(*this); m_logicVertexp = NULL; } } GateVarVertex* makeVarVertex(AstVarScope* varscp) { GateVarVertex* vertexp = (GateVarVertex*)(varscp->user1p()); if (!vertexp) { UINFO(6,"New vertex "<user1p(vertexp); if (varscp->varp()->isSigPublic()) { // Public signals shouldn't be changed, pli code might be messing with them vertexp->clearReducibleAndDedupable("SigPublic"); vertexp->setConsumed("SigPublic"); } if (varscp->varp()->isIO() && varscp->scopep()->isTop()) { // We may need to convert to/from sysc/reg sigs vertexp->setIsTop(); vertexp->clearReducibleAndDedupable("isTop"); vertexp->setConsumed("isTop"); } if (varscp->varp()->isUsedClock()) vertexp->setConsumed("clock"); } return vertexp; } void optimizeSignals(bool allowMultiIn); bool elimLogicOkOutputs(GateLogicVertex* consumeVertexp, const GateOkVisitor& okVisitor); void optimizeElimVar(AstVarScope* varscp, AstNode* logicp, AstNode* consumerp); void warnSignals(); void consumedMark(); void consumedMarkRecurse(GateEitherVertex* vertexp); void consumedMove(); void replaceAssigns(); void dedupe(); void mergeAssigns(); void decomposeClkVectors(); // VISITORS virtual void visit(AstNetlist* nodep) { nodep->iterateChildren(*this); //if (debug()>6) m_graph.dump(); if (debug()>6) m_graph.dumpDotFilePrefixed("gate_pre"); warnSignals(); // Before loss of sync/async pointers // Decompose clock vectors -- need to do this before removing redundant edges decomposeClkVectors(); m_graph.removeRedundantEdgesSum(&V3GraphEdge::followAlwaysTrue); m_graph.dumpDotFilePrefixed("gate_simp"); // Find gate interconnect and optimize m_graph.userClearVertices(); // vertex->user(): bool. True indicates we've set it as consumed // Get rid of buffers first, optimizeSignals(false); // Then propagate more complicated equations optimizeSignals(true); // Remove redundant logic if (v3Global.opt.oDedupe()) dedupe(); if (v3Global.opt.oAssemble()) mergeAssigns(); // Consumption warnings consumedMark(); m_graph.dumpDotFilePrefixed("gate_opt"); // Rewrite assignments consumedMove(); replaceAssigns(); } virtual void visit(AstNodeModule* nodep) { m_modp = nodep; m_activeReducible = true; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstScope* nodep) { UINFO(4," SCOPE "<iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstActive* nodep) { // 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) { if (m_scopep) { if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block"); AstVarScope* varscp = nodep->varScopep(); if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp"); 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->rstAsyncNodep()) vvertexp->rstAsyncNodep(nodep); } else { if (!vvertexp->rstSyncNodep()) vvertexp->rstSyncNodep(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) { iterateNewStmt(nodep, (nodep->isJustOneBodyStmt()?NULL:"Multiple Stmts"), NULL); } virtual void visit(AstAlwaysPublic* nodep) { bool lastslow = m_inSlow; m_inSlow = true; iterateNewStmt(nodep, "AlwaysPublic", NULL); m_inSlow = lastslow; } virtual void visit(AstCFunc* nodep) { iterateNewStmt(nodep, "User C Function", "User C Function"); } virtual void visit(AstSenItem* nodep) { // 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) { // 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) { bool lastslow = m_inSlow; m_inSlow = true; iterateNewStmt(nodep, (nodep->isJustOneBodyStmt()?NULL:"Multiple Stmts"), NULL); m_inSlow = lastslow; } virtual void visit(AstAssignAlias* nodep) { iterateNewStmt(nodep, NULL, NULL); } virtual void visit(AstAssignW* nodep) { iterateNewStmt(nodep, NULL, NULL); } virtual void visit(AstCoverToggle* nodep) { iterateNewStmt(nodep, "CoverToggle", "CoverToggle"); } virtual void visit(AstTraceInc* nodep) { bool lastslow = m_inSlow; m_inSlow = true; iterateNewStmt(nodep, "Tracing", "Tracing"); m_inSlow = lastslow; } virtual void visit(AstConcat* nodep) { if (nodep->backp()->castNodeAssign() && nodep->backp()->castNodeAssign()->lhsp()==nodep) { nodep->v3fatalSrc("Concat on LHS of assignment; V3Const should have deleted it"); } nodep->iterateChildren(*this); } //-------------------- // Default virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); if (nodep->isOutputter() && m_logicVertexp) m_logicVertexp->setConsumed("outputter"); } public: // CONSTUCTORS explicit GateVisitor(AstNode* nodep) { AstNode::user1ClearTree(); m_logicVertexp = NULL; m_scopep = NULL; m_modp = NULL; m_activep = NULL; m_activeReducible = true; m_inSenItem = false; m_inSlow = false; nodep->accept(*this); } virtual ~GateVisitor() { V3Stats::addStat("Optimizations, Gate sigs deleted", m_statSigs); V3Stats::addStat("Optimizations, Gate inputs replaced", m_statRefs); V3Stats::addStat("Optimizations, Gate sigs deduped", m_statDedupLogic); V3Stats::addStat("Optimizations, Gate assign merged", m_statAssignMerged); } }; //---------------------------------------------------------------------- void GateVisitor::optimizeSignals(bool allowMultiIn) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->inEmpty()) { vvertexp->clearReducibleAndDedupable("inEmpty"); // Can't deal with no sources if (!vvertexp->isTop() // Ok if top inputs are driverless && !vvertexp->varScp()->varp()->valuep() && !vvertexp->varScp()->varp()->isSigPublic()) { UINFO(4, "No drivers "<varScp()<varScp()->varp()->v3warn(UNDRIVEN,"Signal has no drivers " <scopep()->prettyName()<<"." <varScp()->varp()->prettyName()); } } } else if (!vvertexp->inSize1()) { vvertexp->clearReducibleAndDedupable("size!1"); // Can't deal with more than one src } // Reduce it? if (!vvertexp->reducible()) { UINFO(8, "SigNotRed "<name()<name()< (vvertexp->inBeginp()->fromp()); UINFO(8, " From "<name()<nodep(); if (logicVertexp->reducible()) { // Can we eliminate? GateOkVisitor okVisitor(logicp, vvertexp->isClock(), false); bool multiInputs = okVisitor.rhsVarRefs().size() > 1; // Was it ok? bool doit = okVisitor.isSimple(); if (doit && multiInputs) { if (!allowMultiIn) doit = false; // Doit if one input, or not used, or used only once, ignoring traces int n=0; for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { GateLogicVertex* consumeVertexp = dynamic_cast(edgep->top()); if (!consumeVertexp->slow()) { // Not tracing or other slow path junk if (edgep->top()->outBeginp()) { // Destination is itself used n += edgep->weight(); } } if (n>1) { doit = false; break; } } } // Process it if (!doit) { if (allowMultiIn && (debug()>=9)) { UINFO(9, "Not ok simp"<outBeginp()<<" on"<<(vvertexp->outBeginp()?vvertexp->outBeginp()->outNextp():0) <<" "<name() <outBeginp(); edgep; edgep = edgep->outNextp()) { GateLogicVertex* consumeVertexp = dynamic_cast(edgep->top()); UINFO(9, " edge "<nodep()<inBeginp(); edgep; edgep = edgep->inNextp()) { GateLogicVertex* consumeVertexp = dynamic_cast(edgep->fromp()); UINFO(9, " edge "<nodep()<=5) logicp->dumpTree(cout,"\telimVar: "); if (debug()>=5) substp->dumpTree(cout,"\t subst: "); ++m_statSigs; bool removedAllUsages = true; for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; ) { GateLogicVertex* consumeVertexp = dynamic_cast(edgep->top()); AstNode* consumerp = consumeVertexp->nodep(); if (!elimLogicOkOutputs(consumeVertexp, okVisitor/*ref*/)) { // Cannot optimize this replacement removedAllUsages = false; edgep = edgep->outNextp(); } else { optimizeElimVar(vvertexp->varScp(), substp, consumerp); // If the new replacement referred to a signal, // Correct the graph to point to this new generating variable const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs(); for (GateVarRefList::const_iterator it = rhsVarRefs.begin(); it != rhsVarRefs.end(); ++it) { AstVarScope* newvarscp = (*it)->varScopep(); UINFO(9," Point-to-new vertex "<propagateAttrClocksFrom(vvertexp); } // Remove the edge edgep->unlinkDelete(); VL_DANGLING(edgep); ++m_statRefs; edgep = vvertexp->outBeginp(); } } if (removedAllUsages) { // Remove input links while (V3GraphEdge* edgep = vvertexp->inBeginp()) { edgep->unlinkDelete(); VL_DANGLING(edgep); } // Clone tree so we remember it for tracing, and keep the pointer // to the "ALWAYS" part of the tree as part of this statement // That way if a later signal optimization that retained a pointer to the always // can optimize it further logicp->unlinkFrBack(); vvertexp->varScp()->valuep(logicp); logicp = NULL; // Mark the vertex so we don't mark it as being unconsumed in the next step vvertexp->user(true); logicVertexp->user(true); } } } } } } } bool GateVisitor::elimLogicOkOutputs(GateLogicVertex* consumeVertexp, const GateOkVisitor& okVisitor) { // Return true if can optimize // Return false if the consuming logic has an output signal that the replacement logic has as an input typedef vl_unordered_set VarScopeSet; // Use map to find duplicates between two lists VarScopeSet varscopes; // Replacement logic usually has shorter input list, so faster to build list based on it const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs(); for (GateVarRefList::const_iterator it = rhsVarRefs.begin(); it != rhsVarRefs.end(); ++it) { AstVarScope* vscp = (*it)->varScopep(); if (varscopes.find(vscp) == varscopes.end()) varscopes.insert(vscp); } for (V3GraphEdge* edgep = consumeVertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { GateVarVertex* consVVertexp = dynamic_cast(edgep->top()); AstVarScope* vscp = consVVertexp->varScp(); if (varscopes.find(vscp) != varscopes.end()) { UINFO(9," Block-unopt, insertion generates input vscp "<verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { // Take the Comments/assigns that were moved to the VarScope and change them to a // simple value assignment AstVarScope* vscp = vvertexp->varScp(); if (vscp->valuep() && !vscp->valuep()->castNodeMath()) { //if (debug()>9) vscp->dumpTree(cout, "-vscPre: "); while (AstNode* delp=vscp->valuep()->castComment()) { delp->unlinkFrBack()->deleteTree(); VL_DANGLING(delp); } if (AstInitial* delp=vscp->valuep()->castInitial()) { AstNode* bodyp=delp->bodysp(); bodyp->unlinkFrBackWithNext(); delp->replaceWith(bodyp); delp->deleteTree(); VL_DANGLING(delp); } if (AstAlways* delp=vscp->valuep()->castAlways()) { AstNode* bodyp=delp->bodysp(); bodyp->unlinkFrBackWithNext(); delp->replaceWith(bodyp); delp->deleteTree(); VL_DANGLING(delp); } if (AstNodeAssign* delp=vscp->valuep()->castNodeAssign()) { AstNode* rhsp=delp->rhsp(); rhsp->unlinkFrBack(); delp->replaceWith(rhsp); delp->deleteTree(); VL_DANGLING(delp); } //if (debug()>9) {vscp->dumpTree(cout, "-vscDone: "); cout<valuep()->castNodeMath() || vscp->valuep()->nextp()) { vscp->dumpTree(cerr, "vscStrange: "); vscp->v3fatalSrc("Value of varscope not mathematical"); } } } } } //---------------------------------------------------------------------- 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); VL_DANGLING(nodep); } } } } //---------------------------------------------------------------------- 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(); VL_DANGLING(nodep); } } virtual void visit(AstNode* nodep) { 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: "); // Some previous input edges may have disappeared, perhaps all of them. // If we remove the edges we can further optimize // See e.g t_var_overzero.v. } } //###################################################################### // 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(AstNode* node1p, AstNode* node2p) { return node1p == node2p || sameHash(node1p,node2p); } public: bool check(AstNode* node1p,AstNode* node2p) { return same(node1p->user3p(),node2p->user3p()) && same(node1p->user5p(),node2p->user5p()) && node1p->user2p()->type() == node2p->user2p()->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()->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) { 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) { 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) { 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*) {} // NOP //-------------------- // Default virtual void visit(AstNode*) { m_dedupable = false; } public: // CONSTUCTORS GateDedupeVarVisitor() { m_assignp = NULL; m_ifCondp = NULL; m_always = false; m_dedupable = true; } // PUBLIC METHODS AstNodeVarRef* findDupe(AstNode* nodep, AstVarScope* consumerVarScopep, AstActive* activep) { m_assignp = NULL; m_ifCondp = NULL; m_always = false; m_dedupable = true; nodep->accept(*this); if (m_dedupable && m_assignp) { AstNode* lhsp = m_assignp->lhsp(); // Possible todo, handle more complex lhs expressions if (AstNodeVarRef* lhsVarRefp = lhsp->castNodeVarRef()) { if (lhsVarRefp->varScopep() != consumerVarScopep) consumerVarScopep->v3fatalSrc("Consumer doesn't match lhs of assign"); if (AstNodeAssign* dup = m_hash.hashAndFindDupe(m_assignp,activep,m_ifCondp)) { return (AstNodeVarRef*) dup->lhsp(); } } } return NULL; } }; //###################################################################### // Recurse through the graph, looking for duplicate expressions on the rhs of an assign class GateDedupeGraphVisitor : public GateGraphBaseVisitor { private: // NODE STATE // AstVarScope::user2p -> bool: already visited // AstUser2InUse m_inuser2; (Allocated for use in GateVisitor) V3Double0 m_numDeduped; // Statistic tracking GateDedupeVarVisitor m_varVisitor; // Looks for a dupe of the logic int m_depth; // Iteration depth virtual VNUser visit(GateVarVertex* vvertexp, VNUser) { // Check that we haven't been here before if (m_depth > GATE_DEDUP_MAX_DEPTH) return VNUser(0); // Break loops; before user2 set so hit this vertex later if (vvertexp->varScp()->user2()) return VNUser(0); vvertexp->varScp()->user2(true); m_depth++; if (vvertexp->inSize1()) { AstNodeVarRef* dupVarRefp = (AstNodeVarRef*) vvertexp->iterateInEdges(*this, VNUser(vvertexp)).toNodep(); if (dupVarRefp) { 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); } // Propagate attributes dupVvertexp->propagateAttrClocksFrom(vvertexp); // Remove inputs links while (V3GraphEdge* inedgep = vvertexp->inBeginp()) { inedgep->unlinkDelete(); VL_DANGLING(inedgep); } // 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); } } } m_depth--; return VNUser(0); } // Given iterated logic, starting at vu which was consumer's GateVarVertex // Returns a varref that has the same logic input; or NULL if none virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) { lvertexp->iterateInEdges(*this); GateVarVertex* consumerVvertexpp = (GateVarVertex*) vu.toGraphVertex(); 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 VNUser(m_varVisitor.findDupe(nodep, consumerVarScopep, activep)); } return VNUser(0); } public: GateDedupeGraphVisitor() { m_depth = 0; } void dedupeTree(GateVarVertex* vvertexp) { vvertexp->accept(*this); } V3Double0 numDeduped() { return m_numDeduped; } }; //---------------------------------------------------------------------- void GateVisitor::dedupe() { AstNode::user2ClearTree(); GateDedupeGraphVisitor deduper; // Traverse starting from each of the clocks for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->isClock()) { deduper.dedupeTree(vvertexp); } } } // Traverse starting from each of the outputs for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->isTop() && vvertexp->varScp()->varp()->isOutput()) { deduper.dedupeTree(vvertexp); } } } m_statDedupLogic += deduper.numDeduped(); } //###################################################################### // Recurse through the graph, try to merge assigns class GateMergeAssignsGraphVisitor : public GateGraphBaseVisitor { private: // NODE STATE AstNodeAssign* m_assignp; AstActive* m_activep; GateLogicVertex* m_logicvp; V3Graph* m_graphp; V3Double0 m_numMergedAssigns; // Statistic tracking // assemble two Sel into one if possible AstSel* merge(AstSel* pre, AstSel* cur) { AstVarRef* preVarRefp = pre->fromp()->castVarRef(); AstVarRef* curVarRefp = cur->fromp()->castVarRef(); if (!preVarRefp || !curVarRefp || !curVarRefp->same(preVarRefp)) return NULL; // not the same var AstConst* pstart = pre->lsbp()->castConst(); AstConst* pwidth = pre->widthp()->castConst(); AstConst* cstart = cur->lsbp()->castConst(); AstConst* cwidth = cur->widthp()->castConst(); if (!pstart || !pwidth || !cstart || !cwidth) return NULL; // too complicated if (cur->lsbConst()+cur->widthConst() == pre->lsbConst()) return new AstSel(curVarRefp->fileline(), curVarRefp->cloneTree(false), cur->lsbConst(), pre->widthConst()+cur->widthConst()); else return NULL; } virtual VNUser visit(GateVarVertex *vvertexp, VNUser) { for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; ) { V3GraphEdge* oldedgep = edgep; edgep = edgep->inNextp(); // for recursive since the edge could be deleted if (GateLogicVertex* lvertexp = dynamic_cast(oldedgep->fromp())) { if (AstNodeAssign* assignp = lvertexp->nodep()->castNodeAssign()) { //if (lvertexp->outSize1() && assignp->lhsp()->castSel()) { if (assignp->lhsp()->castSel() && lvertexp->outSize1()) { UINFO(9, "assing to the nodep["<lhsp()->castSel()->lsbConst()<<"]"<activep(); if (!m_logicvp) m_logicvp = lvertexp; if (!m_assignp) m_assignp = assignp; // not under the same active if (m_activep != lvertexp->activep()) { m_activep = lvertexp->activep(); m_logicvp = lvertexp; m_assignp = assignp; continue; } AstSel* preselp = m_assignp->lhsp()->castSel(); AstSel* curselp = assignp->lhsp()->castSel(); if (!preselp || !curselp) continue; if (AstSel* newselp = merge(preselp, curselp)) { UINFO(5, "assemble to new sel: "<replaceWith(newselp); preselp->deleteTree(); VL_DANGLING(preselp); // create new rhs for pre assignment AstNode* newrhsp = new AstConcat(m_assignp->rhsp()->fileline(), m_assignp->rhsp()->cloneTree(false), assignp->rhsp()->cloneTree(false)); AstNode* oldrhsp = m_assignp->rhsp(); oldrhsp->replaceWith(newrhsp); oldrhsp->deleteTree(); VL_DANGLING(oldrhsp); m_assignp->dtypeChgWidthSigned(m_assignp->width()+assignp->width(), m_assignp->width()+assignp->width(), AstNumeric::fromBool(true)); // don't need to delete, will be handled //assignp->unlinkFrBack(); assignp->deleteTree(); VL_DANGLING(assignp); // update the graph { // delete all inedges to lvertexp if (!lvertexp->inEmpty()) { for (V3GraphEdge* ledgep = lvertexp->inBeginp(); ledgep; ) { V3GraphEdge* oedgep = ledgep; ledgep = ledgep->inNextp(); GateEitherVertex* fromvp = dynamic_cast(oedgep->fromp()); new V3GraphEdge(m_graphp, fromvp, m_logicvp, 1); oedgep->unlinkDelete(); VL_DANGLING(oedgep); } } // delete all outedges to lvertexp, only one oldedgep->unlinkDelete(); VL_DANGLING(oldedgep); } ++m_numMergedAssigns; } else { m_assignp = assignp; m_logicvp = lvertexp; } } } } } return VNUser(0); } virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) { return VNUser(0); } public: explicit GateMergeAssignsGraphVisitor(V3Graph* graphp) { m_assignp = NULL; m_activep = NULL; m_logicvp = NULL; m_numMergedAssigns = 0; m_graphp = graphp; } void mergeAssignsTree(GateVarVertex* vvertexp) { vvertexp->accept(*this); } V3Double0 numMergedAssigns() { return m_numMergedAssigns; } }; //---------------------------------------------------------------------- void GateVisitor::mergeAssigns() { GateMergeAssignsGraphVisitor merger(&m_graph); for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { merger.mergeAssignsTree(vvertexp); } } m_statAssignMerged += merger.numMergedAssigns(); } //###################################################################### // Find a var's offset in a concatenation class GateConcatVisitor : public GateBaseVisitor { private: // STATE AstVarScope* m_vscp; // Varscope we're trying to find int m_offset; // Current offset of varscope int m_found_offset; // Found offset of varscope bool m_found; // Offset found // VISITORS virtual void visit(AstNodeVarRef* nodep) { UINFO(9,"CLK DECOMP Concat search var (off = "<varScopep() == m_vscp && !nodep->user2() && !m_found) { // A concatenation may use the same var multiple times // But the graph will initially have an edge per instance nodep->user2(true); m_found_offset = m_offset; m_found = true; UINFO(9,"CLK DECOMP Concat found var (off = "<dtypep()->width(); } virtual void visit(AstConcat* nodep) { UINFO(9,"CLK DECOMP Concat search (off = "<rhsp()->iterate(*this); nodep->lhsp()->iterate(*this); } //-------------------- // Default virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS GateConcatVisitor() { m_vscp = NULL; m_offset = 0; m_found_offset = 0; m_found = false; } virtual ~GateConcatVisitor() {} // PUBLIC METHODS bool concatOffset(AstConcat* concatp, AstVarScope* vscp, int& offsetr) { m_vscp = vscp; m_offset = 0; m_found = false; // Iterate concatp->accept(*this); UINFO(9,"CLK DECOMP Concat Offset (found = "< bool: already visited V3Graph* m_graphp; int m_seen_clk_vectors; AstVarScope* m_clk_vsp; GateVarVertex* m_clk_vvertexp; GateConcatVisitor m_concat_visitor; int m_total_seen_clk_vectors; int m_total_decomposed_clk_vectors; virtual VNUser visit(GateVarVertex* vvertexp, VNUser vu) { // Check that we haven't been here before AstVarScope* vsp = vvertexp->varScp(); if (vsp->user2SetOnce()) return VNUser(0); UINFO(9,"CLK DECOMP Var - "<varp()->width() > 1) { m_seen_clk_vectors++; m_total_seen_clk_vectors++; } GateClkDecompState* currState = (GateClkDecompState*) vu.c(); GateClkDecompState nextState(currState->m_offset, vsp); vvertexp->iterateCurrentOutEdges(*this, VNUser(&nextState)); if (vsp->varp()->width() > 1) { m_seen_clk_vectors--; } vsp->user2(false); return VNUser(0); } virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) { GateClkDecompState* currState = (GateClkDecompState*) vu.c(); int clk_offset = currState->m_offset; if (AstAssignW* assignp = lvertexp->nodep()->castAssignW()) { UINFO(9,"CLK DECOMP Logic (off = "<rhsp()->castSel()) { if (rselp->lsbp()->castConst() && rselp->widthp()->castConst()) { if (clk_offset < rselp->lsbConst() || clk_offset > rselp->msbConst()) { UINFO(9,"CLK DECOMP Sel [ "<msbConst()<<" : "<lsbConst()<<" ] dropped clock ("<lsbConst(); } else { return VNUser(0); } } else if (AstConcat* catp = assignp->rhsp()->castConcat()) { UINFO(9,"CLK DECOMP Concat searching - "<lhsp()<m_last_vsp, concat_offset)) { return VNUser(0); } clk_offset += concat_offset; } if (AstSel* lselp = assignp->lhsp()->castSel()) { if (lselp->lsbp()->castConst() && lselp->widthp()->castConst()) { clk_offset += lselp->lsbConst(); } else { return VNUser(0); } } else if (AstVarRef* vrp = assignp->lhsp()->castVarRef()) { if (vrp->dtypep()->width() == 1 && m_seen_clk_vectors) { if (clk_offset != 0) { UINFO(9,"Should only make it here with clk_offset = 0"<lhsp()<<" <-> "<rhsp(); rhsp->replaceWith(new AstVarRef(rhsp->fileline(), m_clk_vsp, false)); for (V3GraphEdge* edgep = lvertexp->inBeginp(); edgep; ) { edgep->unlinkDelete(); VL_DANGLING(edgep); } new V3GraphEdge(m_graphp, m_clk_vvertexp, lvertexp, 1); m_total_decomposed_clk_vectors++; } } GateClkDecompState nextState(clk_offset, currState->m_last_vsp); return lvertexp->iterateCurrentOutEdges(*this, VNUser(&nextState)); } return VNUser(0); } public: explicit GateClkDecompGraphVisitor(V3Graph* graphp) { m_graphp = graphp; m_seen_clk_vectors = 0; m_clk_vsp = NULL; m_clk_vvertexp = NULL; m_total_seen_clk_vectors = 0; m_total_decomposed_clk_vectors = 0; } virtual ~GateClkDecompGraphVisitor() { V3Stats::addStat("Optimizations, Clocker seen vectors", m_total_seen_clk_vectors); V3Stats::addStat("Optimizations, Clocker decomposed vectors", m_total_decomposed_clk_vectors); } void clkDecomp(GateVarVertex* vvertexp) { UINFO(9,"CLK DECOMP Starting Var - "<varScp(); m_clk_vvertexp = vvertexp; GateClkDecompState nextState(0, m_clk_vsp); vvertexp->accept(*this, VNUser(&nextState)); } }; void GateVisitor::decomposeClkVectors() { UINFO(9,"Starting clock decomposition"<verticesNextp()) { if (GateVarVertex* vertp = dynamic_cast(itp)) { AstVarScope* vsp = vertp->varScp(); if (vsp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { if (vsp->varp()->width() > 1) { UINFO(9,"Clocker > 1 bit, not decomposing: "<valuep()->castNodeAssign()) { UINFO(5," Removeassign "<rhsp(); valuep->unlinkFrBack(); assp->replaceWith(valuep); assp->deleteTree(); VL_DANGLING(assp); } } // Speedups virtual void visit(AstVar* nodep) {} virtual void visit(AstActive* nodep) {} virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit GateDeassignVisitor(AstNode* nodep) { nodep->accept(*this); } virtual ~GateDeassignVisitor() {} }; //###################################################################### // Gate class functions void V3Gate::gateAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Parse.h0000664000177100017500000000333613205574202015750 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Reading of Verilog files // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3PARSE_H_ #define _V3PARSE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Global.h" class AstNetlist; class V3InFilter; class V3ParseImp; class V3ParseSym; //============================================================================ class V3Parse { private: V3ParseImp* m_impp; // CONSTRUCTORS VL_UNCOPYABLE(V3Parse); public: // We must allow reading multiple files into one parser V3Parse(AstNetlist* rootp, V3InFilter* filterp, V3ParseSym* symp); ~V3Parse(); // METHODS // Preprocess and read the Verilog file specified into the netlist database void parseFile(FileLine* fileline, const string& modname, bool inLibrary, const string& errmsg); // Push preprocessed text to the lexer static void ppPushText(V3ParseImp* impp, const string& text); }; #endif // Guard verilator-3.916/src/Makefile_obj.in0000664000177100017500000001730013205574202017207 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator: Makefile for verilog source # # Code available from: http://www.veripool.org/verilator # #***************************************************************************** # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # # Verilator is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # #****************************************************************************/ #### Start of system configuration section. #### # Unfortunately configure uses relative paths, and this makefile is called # from a level lower, so we need to move up if it's relative, not if absolute. config_srcdir = @srcdir@ ifeq ($(config_srcdir),.) srcdir = .. else # Run an experiment ifeq ($(wildcard $(config_srcdir)/../Makefile_obj.in),) srcdir = $(config_srcdir) else srcdir = $(config_srcdir)/.. endif endif incdir = $(srcdir)/../include # Bldsrc may differ from srcdir if configure wan't run from the kit top bldsrc = .. # Programs CC = @CC@ CXX = @CXX@ LINK = @CXX@ LEX = @LEX@ LFLAGS = -d PERL = @PERL@ YACC = @YACC@ prefix = @prefix@ # Directory in which to install data across multiple architectures datarootdir = @datarootdir@ # Directory in which to install package specific files # Generally ${prefix}/share/verilator pkgdatadir = @pkgdatadir@ # Compile options CFG_WITH_CCWARN = @CFG_WITH_CCWARN@ CFG_WITH_DEFENV = @CFG_WITH_DEFENV@ CPPFLAGS += @CPPFLAGS@ LDFLAGS += @LDFLAGS@ EXEEXT = @EXEEXT@ CFG_CXXFLAGS_SRC = @CFG_CXXFLAGS_SRC@ CFG_CXXFLAGS_PARSER = @CFG_CXXFLAGS_PARSER@ # Compiler flags that turn on extra warnings CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@ #### End of system configuration section. #### VPATH += . $(bldsrc) $(srcdir) TGT = ../../verilator_bin ################# ifeq ($(VL_DEBUG),) # Optimize COPT = -O2 else # Debug COPT = -ggdb -DVL_DEBUG # Debug & Profile: #LDFLAGS += -pg -g #COPT = -ggdb -pg -g endif ################# #LIBS += -ldl #CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl # -lfl not needed as Flex invoked with %nowrap option # -lstdc++ needed for clang, believed harmless with gcc LIBS = -lm -lstdc++ CPPFLAGS += -MMD CPPFLAGS += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir) CPPFLAGS += -DYYDEBUG # Required to get nice error messages #CPPFLAGS += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool CPPFLAGS += $(COPT) CPPFLAGS += -MP # Only works on recent GCC versions ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_WEXTRA) $(CFG_CXXFLAGS_SRC) -Werror #CPPFLAGS += -pedantic-errors else CPPFLAGS += $(CFG_CXXFLAGS_SRC) endif CPPFLAGSWALL = $(CPPFLAGS) CPPFLAGSPARSER = $(CPPFLAGS) $(CFG_CXXFLAGS_PARSER) # Allow RPM builds to specify hardcoded data directories # To do this: ifeq ($(CFG_WITH_DEFENV),yes) CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\" CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\" CPPFLAGS += -DDEFENV_SYSTEMC_INCLUDE=\"$(SYSTEMC_INCLUDE)\" CPPFLAGS += -DDEFENV_SYSTEMC_LIBDIR=\"$(SYSTEMC_LIBDIR)\" ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\" else CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(VERILATOR_ROOT)\" endif endif HEADERS = $(wildcard V*.h v*.h) ASTGEN = $(srcdir)/astgen BISONPRE = $(srcdir)/bisonpre FLEXFIX = $(srcdir)/flexfix VLCOVGEN = $(srcdir)/vlcovgen ###################################################################### #### Top level all: make_info $(TGT) make_info: @echo " Compile flags: " $(CXX) ${CPPFLAGS} clean mostlyclean distclean maintainer-clean:: -rm -f *.o *.d perlxsi.c *_gen_* -rm -f *__gen* -rm -f obj_* .objcache* distclean maintainer-clean:: clean maintainer-clean:: maintainer-copy:: #### Top executable RAW_OBJS = \ Verilator.o \ V3Active.o \ V3ActiveTop.o \ V3Assert.o \ V3AssertPre.o \ V3Ast.o \ V3AstNodes.o \ V3Begin.o \ V3Branch.o \ V3Broken.o \ V3CCtors.o \ V3Case.o \ V3Cast.o \ V3Cdc.o \ V3Changed.o \ V3Clean.o \ V3ClkGater.o \ V3Clock.o \ V3Combine.o \ V3Config.o \ V3Const__gen.o \ V3Coverage.o \ V3CoverageJoin.o \ V3Dead.o \ V3Delayed.o \ V3Depth.o \ V3DepthBlock.o \ V3Descope.o \ V3EmitC.o \ V3EmitCInlines.o \ V3EmitCSyms.o \ V3EmitMk.o \ V3EmitV.o \ V3EmitXml.o \ V3Error.o \ V3Expand.o \ V3File.o \ V3FileLine.o \ V3Gate.o \ V3GenClk.o \ V3Graph.o \ V3GraphAlg.o \ V3GraphAcyc.o \ V3GraphDfa.o \ V3GraphTest.o \ V3Hashed.o \ V3Inline.o \ V3Inst.o \ V3Life.o \ V3LifePost.o \ V3LinkCells.o \ V3LinkDot.o \ V3LinkJump.o \ V3LinkLValue.o \ V3LinkLevel.o \ V3LinkParse.o \ V3LinkResolve.o \ V3Localize.o \ V3Name.o \ V3Number.o \ V3Options.o \ V3Order.o \ V3Os.o \ V3Param.o \ V3PreShell.o \ V3Premit.o \ V3Scope.o \ V3Slice.o \ V3Split.o \ V3SplitAs.o \ V3Stats.o \ V3StatsReport.o \ V3String.o \ V3Subst.o \ V3Table.o \ V3Task.o \ V3Trace.o \ V3TraceDecl.o \ V3Tristate.o \ V3Undriven.o \ V3Unknown.o \ V3Unroll.o \ V3Width.o \ V3WidthSel.o \ # Non-concatable NC_OBJS += \ V3ParseImp.o \ V3ParseGrammar.o \ V3ParseLex.o \ V3PreProc.o \ # verilator_coverage VLCOV_OBJS = \ VlcMain.o \ #### Linking ifeq ($(VL_VLCOV),) PREDEP_H = V3Ast__gen_classes.h OBJS += $(RAW_OBJS) $(NC_OBJS) else PREDEP_H = OBJS += $(VLCOV_OBJS) endif V3__CONCAT.cpp: $(addsuffix .cpp, $(basename $(RAW_OBJS))) $(PERL) $(srcdir)/../bin/verilator_includer $^ > $@ $(TGT): $(PREDEP_H) $(OBJS) @echo " Linking $@..." -rm -rf $@ $@.exe ${LINK} ${LDFLAGS} -o $@ $(OBJS) $(CCMALLOC) ${LIBS} V3Number_test: V3Number_test.o ${LINK} ${LDFLAGS} -o $@ $^ ${LIBS} #### Modules %__gen.cpp: %.cpp $(ASTGEN) V3Ast.h V3AstNodes.h $(PERL) $(ASTGEN) -I$(srcdir) $*.cpp %.o: %.cpp $(OBJCACHE) ${CXX} ${CPPFLAGSWALL} -c $< %.o: %.c $(OBJCACHE) ${CC} ${CPPFLAGSWALL} -c $< V3ParseLex.o: V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c $(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $< V3ParseGrammar.o: V3ParseGrammar.cpp V3ParseBison.c $(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $< V3ParseImp.o: V3ParseImp.cpp V3ParseBison.c $(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $< V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp $(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $< #### Generated files # Target rule called before parallel build to make generated files serial:: V3Ast__gen_classes.h V3ParseBison.c serial_vlcov:: vlcovgen.d vlcovgen.d: $(VLCOVGEN) $(srcdir)/../include/verilated_cov_key.h $(PERL) $(VLCOVGEN) --srcdir $(srcdir) touch $@ V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h $(PERL) $(ASTGEN) -I$(srcdir) --classes V3ParseBison.h: V3ParseBison.c # Have only one output file in this rule to prevent parallel make issues V3ParseBison.c: verilog.y $(BISONPRE) @echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer." $(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o V3ParseBison.c $< V3Lexer_pregen.yy.cpp: verilog.l V3ParseBison.h $(HEADERS) ${LEX} --version ${LEX} ${LFLAGS} -o$@ $< V3Lexer.yy.cpp: V3Lexer_pregen.yy.cpp $(FLEXFIX) $(PERL) $(FLEXFIX) V3Lexer <$< >$@ V3PreLex_pregen.yy.cpp: V3PreLex.l $(HEADERS) ${LEX} --version ${LEX} ${LFLAGS} -o$@ $< V3PreLex.yy.cpp: V3PreLex_pregen.yy.cpp $(FLEXFIX) $(PERL) $(FLEXFIX) V3PreLex <$< >$@ .SUFFIXES: ###################################################################### ###################################################################### DEPS := $(wildcard *.d) ifneq ($(DEPS),) include $(DEPS) endif verilator-3.916/src/V3Cdc.cpp0000664000177100017500000006632413205574202015730 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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) { *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) { 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 explicit 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) { UINFO(4," SCOPE "<iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstActive* nodep) { // 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) { if (m_scopep) { if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block"); AstVarScope* varscp = nodep->varScopep(); if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp"); 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) { // 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) { iterateNewStmt(nodep); } virtual void visit(AstAlwaysPublic* nodep) { // CDC doesn't care about public variables } virtual void visit(AstCFunc* nodep) { iterateNewStmt(nodep); } virtual void visit(AstSenGate* nodep) { // 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) { iterateNewStmt(nodep); } virtual void visit(AstAssignW* nodep) { iterateNewStmt(nodep); } // Math that shouldn't cause us to clear hazard virtual void visit(AstConst* nodep) { } virtual void visit(AstReplicate* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstConcat* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstNot* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstSel* nodep) { if (!nodep->lsbp()->castConst()) setNodeHazard(nodep); nodep->iterateChildren(*this); } virtual void visit(AstNodeSel* nodep) { if (!nodep->bitp()->castConst()) setNodeHazard(nodep); nodep->iterateChildren(*this); } // Ignores virtual void visit(AstInitial* nodep) { } virtual void visit(AstTraceInc* nodep) { } virtual void visit(AstCoverToggle* nodep) { } virtual void visit(AstNodeDType* nodep) { } //-------------------- // Default virtual void visit(AstNodeMath* nodep) { setNodeHazard(nodep); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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) { UINFO(4," MOD "<iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCFunc* nodep) { 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) { visitStmt(nodep); } // Operators virtual void visit(AstNodeTermop* nodep) { } virtual void visit(AstNodeMath* nodep) { // 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) { needNonStaticFunc(nodep); nodep->iterateChildren(*this); } virtual void visit(AstUCStmt* nodep) { needNonStaticFunc(nodep); visitStmt(nodep); } //-------------------- // Default: Just iterate virtual void visit(AstVar* nodep) {} // Don't hit varrefs under vars virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit DepthVisitor(AstNetlist* nodep) { m_modp=NULL; m_funcp=NULL; m_stmtp=NULL; m_depth=0; m_maxdepth=0; // nodep->accept(*this); } virtual ~DepthVisitor() {} }; //###################################################################### // Depth class functions void V3Depth::depthAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.916/src/V3AstNodes.h0000664000177100017500000077431613205623137016435 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ast node structure // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3ASTNODES_H_ #define _V3ASTNODES_H_ 1 #ifndef _V3AST_H_ #error "Use V3Ast.h as the include" #endif //###################################################################### // Standard defines for all AstNode final classes #define ASTNODE_NODE_FUNCS(name) \ virtual ~Ast ##name() {} \ virtual AstType type() const { return AstType::at ## name; } \ virtual AstNode* clone() { return new Ast ##name (*this); } \ virtual void accept(AstNVisitor& v) { v.visit(this); } \ Ast ##name * cloneTree(bool cloneNext) { return static_cast(AstNode::cloneTree(cloneNext)); } \ Ast ##name * clonep() const { return static_cast(AstNode::clonep()); } //###################################################################### //=== Ast* : Specific types // Netlist interconnect class AstConst : public AstNodeMath { // A constant private: V3Number m_num; // Constant value public: AstConst(FileLine* fl, const V3Number& num) :AstNodeMath(fl) ,m_num(num) { if (m_num.isDouble()) { dtypeSetDouble(); } else if (m_num.isString()) { dtypeSetString(); } else { dtypeSetLogicSized(m_num.width(), m_num.sized()?0:m_num.widthMin(), m_num.isSigned() ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); } } AstConst(FileLine* fl, uint32_t num) :AstNodeMath(fl) ,m_num(V3Number(fl,32,num)) { dtypeSetLogicSized(m_num.width(), m_num.sized()?0:m_num.widthMin(), AstNumeric::UNSIGNED); } class Unsized32 {}; // for creator type-overload selection AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value :AstNodeMath(fl) ,m_num(V3Number(fl,32,num)) { m_num.width(32,false); dtypeSetLogicSized(32,m_num.widthMin(), AstNumeric::UNSIGNED); } class Signed32 {}; // for creator type-overload selection AstConst(FileLine* fl, Signed32, int32_t num) // Signed 32-bit integer of specified value :AstNodeMath(fl) ,m_num(V3Number(fl,32,num)) { m_num.width(32,32); dtypeSetLogicSized(32,m_num.widthMin(), AstNumeric::SIGNED); } class RealDouble {}; // for creator type-overload selection AstConst(FileLine* fl, RealDouble, double num) :AstNodeMath(fl) ,m_num(V3Number(fl,64)) { m_num.setDouble(num); dtypeSetDouble(); } class String {}; // for creator type-overload selection AstConst(FileLine* fl, String, const string& num) :AstNodeMath(fl) ,m_num(V3Number(V3Number::String(), fl, num)) { dtypeSetString(); } class LogicFalse {}; AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, know the dtype should be a logic of size 1 :AstNodeMath(fl) ,m_num(V3Number(fl,1,0)) { dtypeSetLogicBool(); } class LogicTrue {}; AstConst(FileLine* fl, LogicTrue) // Shorthand const 1, know the dtype should be a logic of size 1 :AstNodeMath(fl) ,m_num(V3Number(fl,1,1)) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Const) 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(const AstNode* samep) const { const AstConst* sp = static_cast(samep); return num().isCaseEq(sp->num()); } virtual int instrCount() const { return widthInstrs(); } bool isEqAllOnes() const { return num().isEqAllOnes(width()); } bool isEqAllOnesV() const { return num().isEqAllOnes(widthMinV()); } }; class AstRange : public AstNode { // Range specification, for use under variables and cells private: bool m_littleEndian:1; // Bit vector is little endian public: AstRange(FileLine* fl, AstNode* msbp, AstNode* lsbp) :AstNode(fl) { m_littleEndian = false; setOp2p(msbp); setOp3p(lsbp); } AstRange(FileLine* fl, int msb, int lsb) :AstNode(fl) { m_littleEndian = false; setOp2p(new AstConst(fl,msb)); setOp3p(new AstConst(fl,lsb)); } AstRange(FileLine* fl, const VNumRange& range) :AstNode(fl) { m_littleEndian = range.littleEndian(); setOp2p(new AstConst(fl,range.hi())); setOp3p(new AstConst(fl,range.lo())); } ASTNODE_NODE_FUNCS(Range) AstNode* msbp() const { return op2p(); } // op2 = Msb expression AstNode* lsbp() const { return op3p(); } // 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; } int leftConst() const { AstConst* constp=leftp()->castConst(); return (constp?constp->toSInt():0); } int rightConst() const { AstConst* constp=rightp()->castConst(); return (constp?constp->toSInt():0); } int leftToRightInc() const { return littleEndian()?1:-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(const AstNode* samep) const { return true; } }; class AstGatePin : public AstNodeMath { // Possibly expand a gate primitive input pin value to match the range of the gate primitive public: AstGatePin(FileLine* fl, AstNode* lhsp, AstRange* rangep) : AstNodeMath(fl) { setOp1p(lhsp); setOp2p(rangep); } ASTNODE_NODE_FUNCS(GatePin) virtual string emitVerilog() { return "%l"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } AstNode* exprp() const { return op1p(); } // op1 = Pin expression AstRange* rangep() const { return op2p()->castRange(); } // op2 = Range of pin }; //###################################################################### //==== Data Types class AstParamTypeDType : public AstNodeDType { // Parents: MODULE // A parameter type statement; much like a var or typedef private: AstVarType m_varType; // Type of variable (for localparam vs. param) string m_name; // Name of variable public: AstParamTypeDType(FileLine* fl, AstVarType type, const string& name, VFlagChildDType, AstNodeDType* dtp) : AstNodeDType(fl), m_varType(type), m_name(name) { childDTypep(dtp); // Only for parser dtypep(NULL); // V3Width will resolve } ASTNODE_NODE_FUNCS(ParamTypeDType) AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); } virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); } virtual bool similarDType(AstNodeDType* samep) const { AstParamTypeDType* sp = samep->castParamTypeDType(); return (sp && this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp())); } virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); } // 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; } AstVarType varType() const { return m_varType; } // * = Type of variable bool isParam() const { return true; } bool isGParam() const { return (varType()==AstVarType::GPARAM); } }; class AstTypedef : public AstNode { private: string m_name; bool m_attrPublic; string m_tag; // Holds the string of the verilator tag -- used in XML output. public: AstTypedef(FileLine* fl, const string& name, AstNode* attrsp, VFlagChildDType, AstNodeDType* dtp) : AstNode(fl), m_name(name) { childDTypep(dtp); // Only for parser addAttrsp(attrsp); dtypep(NULL); // V3Width will resolve m_attrPublic = false; } ASTNODE_NODE_FUNCS(Typedef) virtual void dump(ostream& str); AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } void addAttrsp(AstNode* nodep) { addNOp4p(nodep); } AstNode* attrsp() const { return op4p(); } // op4 = Attributes during early parse // METHODS virtual string name() const { return m_name; } virtual bool maybePointedTo() const { return true; } virtual bool hasDType() const { return true; } void name(const string& flag) { m_name = flag; } bool attrPublic() const { return m_attrPublic; } void attrPublic(bool flag) { m_attrPublic = flag; } virtual void tag(const string& text) { m_tag = text;} virtual string tag() const { return m_tag; } }; class AstTypedefFwd : public AstNode { // Forward declaration of a type; stripped after netlist parsing is complete private: string m_name; public: AstTypedefFwd(FileLine* fl, const string& name) : AstNode(fl), m_name(name) {} ASTNODE_NODE_FUNCS(TypedefFwd) // METHODS virtual string name() const { return m_name; } }; class AstDefImplicitDType : public AstNodeDType { // For parsing enum/struct/unions that are declared with a variable rather than typedef // This allows "var enum {...} a,b" to share the enum definition for both variables // After link, these become typedefs private: string m_name; void* m_containerp; // In what scope is the name unique, so we can know what are duplicate definitions (arbitrary value) int m_uniqueNum; public: AstDefImplicitDType(FileLine* fl, const string& name, void* containerp, VFlagChildDType, AstNodeDType* dtp) : AstNodeDType(fl), m_name(name), m_containerp(containerp) { childDTypep(dtp); // Only for parser dtypep(NULL); // V3Width will resolve m_uniqueNum = uniqueNumInc(); } ASTNODE_NODE_FUNCS(DefImplicitDType) virtual bool same(const AstNode* samep) const { const AstDefImplicitDType* sp = static_cast(samep); return m_uniqueNum == sp->m_uniqueNum; } virtual bool similarDType(AstNodeDType* samep) const { return type()==samep->type() && same(samep); } 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); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } void* containerp() const { return m_containerp; } // METHODS AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); } virtual string name() const { return m_name; } void name(const string& flag) { m_name = flag; } }; class AstPackArrayDType : public AstNodeArrayDType { // Array data type, ie "some_dtype var_name [2:0]" // Children: DTYPE (moved to refDTypep() in V3Width) // Children: RANGE (array bounds) public: AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep) : AstNodeArrayDType(fl) { childDTypep(dtp); // Only for parser refDTypep(NULL); setOp2p(rangep); dtypep(NULL); // V3Width will resolve int width = subDTypep()->width() * rangep->elementsConst(); widthForce(width,width); } AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep) : AstNodeArrayDType(fl) { refDTypep(dtp); setOp2p(rangep); dtypep(this); int width = subDTypep()->width() * rangep->elementsConst(); widthForce(width,width); } ASTNODE_NODE_FUNCS(PackArrayDType) }; class AstUnpackArrayDType : public AstNodeArrayDType { // Array data type, ie "some_dtype var_name [2:0]" // Children: DTYPE (moved to refDTypep() in V3Width) // Children: RANGE (array bounds) public: AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep) : AstNodeArrayDType(fl) { childDTypep(dtp); // Only for parser refDTypep(NULL); setOp2p(rangep); dtypep(NULL); // V3Width will resolve // For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type widthFromSub(subDTypep()); } AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep) : AstNodeArrayDType(fl) { refDTypep(dtp); setOp2p(rangep); dtypep(this); // For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type widthFromSub(subDTypep()); } ASTNODE_NODE_FUNCS(UnpackArrayDType) }; class AstBasicDType : public AstNodeDType { // Builtin atomic/vectored data type // Children: RANGE (converted to constant in V3Width) private: struct Members { AstBasicDTypeKwd m_keyword; // (also in VBasicTypeKey) What keyword created basic type VNumRange m_nrange; // (also in VBasicTypeKey) Numeric msb/lsb (if non-opaque keyword) bool operator== (const Members& rhs) const { return rhs.m_keyword == m_keyword && rhs.m_nrange == m_nrange; } } m; // See also in AstNodeDtype: m_width, m_widthMin, m_numeric(issigned) public: AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, VSignedState signst=signedst_NOSIGN) : AstNodeDType(fl) { init(kwd, AstNumeric(signst), 0, -1, NULL); } AstBasicDType(FileLine* fl, VFlagLogicPacked, int wantwidth) : AstNodeDType(fl) { init(AstBasicDTypeKwd::LOGIC, AstNumeric::NOSIGN, wantwidth, -1, NULL); } AstBasicDType(FileLine* fl, VFlagBitPacked, int wantwidth) : AstNodeDType(fl) { init(AstBasicDTypeKwd::BIT, AstNumeric::NOSIGN, wantwidth, -1, NULL); } AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstNumeric numer, int wantwidth, int widthmin) : AstNodeDType(fl) { init(kwd, numer, wantwidth, widthmin, NULL); } AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstNumeric numer, VNumRange range, int widthmin) : AstNodeDType(fl) { init(kwd, numer, range.elements(), widthmin, NULL); m.m_nrange = range; // as init() presumes lsb==0, but range.lsb() might not be } // See also addRange in verilog.y private: void init(AstBasicDTypeKwd kwd, AstNumeric numer, int wantwidth, int wantwidthmin, AstRange* rangep) { // wantwidth=0 means figure it out, but if a widthmin is >=0 // we allow width 0 so that {{0{x}},y} works properly // wantwidthmin=-1: default, use wantwidth if it is non zero m.m_keyword = kwd; // Implicitness: // "parameter X" is implicit and sized from initial value, "parameter reg x" not if (keyword()==AstBasicDTypeKwd::LOGIC_IMPLICIT) { if (rangep || wantwidth) m.m_keyword = AstBasicDTypeKwd::LOGIC; } if (numer == AstNumeric::NOSIGN) { if (keyword().isSigned()) numer = AstNumeric::SIGNED; else if (keyword().isUnsigned()) numer = AstNumeric::UNSIGNED; } numeric(numer); if (!rangep && (wantwidth || wantwidthmin>=0)) { // Constant width if (wantwidth>1) m.m_nrange.init(wantwidth-1, 0, false); int wmin = wantwidthmin>=0 ? wantwidthmin : wantwidth; widthForce(wantwidth, wmin); } else if (!rangep) { // Set based on keyword properties // V3Width will pull from this width if (keyword().width() > 1 && !isOpaque()) { m.m_nrange.init(keyword().width()-1, 0, false); } widthForce(keyword().width(), keyword().width()); } else { widthForce(rangep->elementsConst(), rangep->elementsConst()); // Maybe unknown if parameters underneath it } setNOp1p(rangep); dtypep(this); } public: ASTNODE_NODE_FUNCS(BasicDType) virtual void dump(ostream& str); virtual V3Hash sameHash() const { return V3Hash(V3Hash(m.m_keyword), V3Hash(m.m_nrange.hi())); } virtual bool same(const AstNode* samep) const { // width/widthMin/numeric compared elsewhere const AstBasicDType* sp = static_cast(samep); return m == sp->m; } virtual bool similarDType(AstNodeDType* samep) const { return type()==samep->type() && same(samep); } 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(signst); else if (signst==signedst_SIGNED) numeric(signst); } // METHODS virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... AstBasicDTypeKwd keyword() const { return m.m_keyword; } // Avoid using - use isSomething accessors instead bool isBitLogic() const { return keyword().isBitLogic(); } bool isDouble() const { return keyword().isDouble(); } bool isOpaque() const { return keyword().isOpaque(); } bool isString() const { return keyword().isString(); } bool isSloppy() const { return keyword().isSloppy(); } bool isZeroInit() const { return keyword().isZeroInit(); } bool isRanged() const { return rangep() || m.m_nrange.ranged(); } const VNumRange& nrange() const { return m.m_nrange; } // Generally the msb/lsb/etc funcs should be used instead int msb() const { return (rangep() ? rangep()->msbConst() : m.m_nrange.hi()); } int lsb() const { return (rangep() ? rangep()->lsbConst() : m.m_nrange.lo()); } int left() const { return littleEndian()?lsb():msb(); } // How to show a declaration int right() const { return littleEndian()?msb():lsb(); } bool littleEndian() const { return (rangep() ? rangep()->littleEndian() : m.m_nrange.littleEndian()); } bool implicit() const { return keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT; } VNumRange declRange() const { return isRanged() ? VNumRange(msb(), lsb(), littleEndian()) : VNumRange(); } void cvtRangeConst() { // Convert to smaller represenation if (rangep() && rangep()->msbp()->castConst() && rangep()->lsbp()->castConst()) { m.m_nrange.init(rangep()->msbConst(), rangep()->lsbConst(), rangep()->littleEndian()); rangep()->unlinkFrBackWithNext()->deleteTree(); rangep(NULL); } } }; class AstConstDType : public AstNodeDType { // const data type, ie "const some_dtype var_name [2:0]" // ConstDType are removed in V3LinkLValue and become AstVar::isConst. // When more generic types are supported AstConstDType will be propagated further. private: AstNodeDType* m_refDTypep; // Inherit from this base data type public: AstConstDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp) : AstNodeDType(fl) { childDTypep(dtp); // Only for parser refDTypep(NULL); // V3Width will resolve dtypep(NULL); // V3Width will resolve widthFromSub(subDTypep()); } ASTNODE_NODE_FUNCS(ConstDType) 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(); }} virtual bool same(const AstNode* samep) const { const AstConstDType* sp = static_cast(samep); return (m_refDTypep == sp->m_refDTypep); } virtual bool similarDType(AstNodeDType* samep) const { return skipRefp()->similarDType(samep->skipRefp()); } 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); } virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } // METHODS virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } }; class AstIfaceRefDType : public AstNodeDType { // Reference to an interface, either for a port, or inside parent cell private: string m_cellName; // "" = no cell, such as when connects to 'input' iface string m_ifaceName; // Interface name string m_modportName; // "" = no modport AstIface* m_ifacep; // Pointer to interface; note cellp() should override AstCell* m_cellp; // When exact parent cell known; not a guess AstModport* m_modportp; // NULL = unlinked or no modport public: AstIfaceRefDType(FileLine* fl, const string& cellName, const string& ifaceName) : AstNodeDType(fl), m_cellName(cellName), m_ifaceName(ifaceName), m_modportName(""), m_ifacep(NULL), m_cellp(NULL), m_modportp(NULL) { } AstIfaceRefDType(FileLine* fl, const string& cellName, const string& ifaceName, const string& modport) : AstNodeDType(fl), m_cellName(cellName), m_ifaceName(ifaceName), m_modportName(modport), m_ifacep(NULL), m_cellp(NULL), m_modportp(NULL) { } ASTNODE_NODE_FUNCS(IfaceRefDType) // METHODS virtual const char* broken() const; virtual void dump(ostream& str=cout); virtual void dumpSmall(ostream& str); virtual void cloneRelink(); virtual AstBasicDType* basicp() const { return NULL; } virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual bool similarDType(AstNodeDType* samep) const { return this==samep; } virtual int widthAlignBytes() const { return 1; } virtual int widthTotalBytes() const { return 1; } string cellName() const { return m_cellName; } void cellName(const string& name) { m_cellName=name; } string ifaceName() const { return m_ifaceName; } void ifaceName(const string& name) { m_ifaceName=name; } string modportName() const { return m_modportName; } void modportName(const string& name) { m_modportName=name; } AstIface* ifaceViaCellp() const; // Use cellp or ifacep AstIface* ifacep() const { return m_ifacep; } void ifacep(AstIface* nodep) { m_ifacep=nodep; } AstCell* cellp() const { return m_cellp; } void cellp(AstCell* nodep) { m_cellp=nodep; } AstModport* modportp() const { return m_modportp; } void modportp(AstModport* modportp) { m_modportp=modportp; } bool isModport() { return !m_modportName.empty(); } }; class AstRefDType : public AstNodeDType { private: AstNodeDType* m_refDTypep; // data type pointed to, BELOW the AstTypedef string m_name; // Name of an AstTypedef AstPackage* m_packagep; // Package hierarchy public: AstRefDType(FileLine* fl, const string& name) : AstNodeDType(fl), m_refDTypep(NULL), m_name(name), m_packagep(NULL) {} AstRefDType(FileLine* fl, AstNodeDType* defp) : AstNodeDType(fl), m_refDTypep(defp), m_packagep(NULL) { dtypeFrom(defp->dtypep()); widthFromSub(subDTypep()); } ASTNODE_NODE_FUNCS(RefDType) // 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(); }} virtual bool same(const AstNode* samep) const { const AstRefDType* asamep = static_cast(samep); return (m_refDTypep == asamep->m_refDTypep && m_name == asamep->m_name && m_packagep == asamep->m_packagep); } virtual bool similarDType(AstNodeDType* samep) const { return skipRefp()->similarDType(samep->skipRefp()); } virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(m_packagep)); } virtual void dump(ostream& str=cout); virtual string name() const { return m_name; } virtual AstBasicDType* basicp() const { return subDTypep() ? subDTypep()->basicp() : NULL; } virtual AstNodeDType* skipRefp() const { // Skip past both the Ref and the Typedef if (defp()) return defp()->skipRefp(); else { v3fatalSrc("Typedef not linked"); return NULL; } } virtual AstNodeDType* skipRefToConstp() const { if (defp()) return defp()->skipRefToConstp(); else { v3fatalSrc("Typedef not linked"); return NULL; } } virtual AstNodeDType* skipRefToEnump() const { if (defp()) return defp()->skipRefToEnump(); else { v3fatalSrc("Typedef not linked"); return NULL; } } virtual int widthAlignBytes() const { return dtypeSkipRefp()->widthAlignBytes(); } virtual int widthTotalBytes() const { return dtypeSkipRefp()->widthTotalBytes(); } void name(const string& flag) { m_name = flag; } AstNodeDType* dtypeSkipRefp() const { return defp()->skipRefp(); } // op1 = Range of variable AstNodeDType* defp() const { return m_refDTypep; } // Code backward compatibility name for refDTypep AstNodeDType* refDTypep() const { return m_refDTypep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep=nodep; } virtual AstNodeDType* virtRefDTypep() const { return refDTypep(); } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } virtual AstNodeDType* subDTypep() const { return m_refDTypep; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; class AstStructDType : public AstNodeClassDType { public: AstStructDType(FileLine* fl, AstNumeric numericUnpack) : AstNodeClassDType(fl,numericUnpack) {} ASTNODE_NODE_FUNCS(StructDType) virtual string verilogKwd() const { return "struct"; }; }; class AstUnionDType : public AstNodeClassDType { public: //UNSUP: bool isTagged; AstUnionDType(FileLine* fl, AstNumeric numericUnpack) : AstNodeClassDType(fl,numericUnpack) {} ASTNODE_NODE_FUNCS(UnionDType) virtual string verilogKwd() const { return "union"; }; }; class AstMemberDType : public AstNodeDType { // A member of a struct/union // PARENT: AstClassDType private: AstNodeDType* m_refDTypep; // Elements of this type (after widthing) string m_name; // Name of variable string m_tag; // Holds the string of the verilator tag -- used in XML output. 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) 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); } virtual 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 bool similarDType(AstNodeDType* samep) const { return this==samep; } // virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType) AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType) virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); } virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... // METHODS virtual void name(const string& name) { m_name = name; } virtual void tag(const string& text) { m_tag = text;} virtual string tag() const { return m_tag; } int lsb() const { return m_lsb; } void lsb(int lsb) { m_lsb=lsb; } }; class AstEnumItem : public AstNode { private: string m_name; public: // Parents: ENUM AstEnumItem(FileLine* fl, const string& name, AstNode* rangep, AstNode* initp) : AstNode(fl), m_name(name) { addNOp1p(rangep); addNOp2p(initp); } ASTNODE_NODE_FUNCS(EnumItem) virtual string name() const { return m_name; } virtual bool maybePointedTo() const { return true; } virtual bool hasDType() const { return true; } void name(const string& flag) { m_name = flag; } AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range for name appending void rangep(AstNode* nodep) { addOp1p(nodep); } AstNode* valuep() const { return op2p(); } // op2 = Value void valuep(AstNode* nodep) { addOp2p(nodep); } }; class AstEnumItemRef : public AstNodeMath { private: AstEnumItem* m_itemp; // [AfterLink] Pointer to item AstPackage* m_packagep; // Package hierarchy public: AstEnumItemRef(FileLine* fl, AstEnumItem* itemp, AstPackage* packagep) : AstNodeMath(fl), m_itemp(itemp), m_packagep(packagep) { dtypeFrom(m_itemp); } ASTNODE_NODE_FUNCS(EnumItemRef) 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(const AstNode* samep) const { const AstEnumItemRef* sp = static_cast(samep); return itemp() == sp->itemp(); } AstEnumItem* itemp() const { return m_itemp; } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; class AstEnumDType : public AstNodeDType { // Parents: TYPEDEF/MODULE // Children: ENUMVALUEs private: AstNodeDType* m_refDTypep; // Elements are of this type after V3Width int m_uniqueNum; public: AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* itemsp) : AstNodeDType(fl) { childDTypep(dtp); // Only for parser refDTypep(NULL); addNOp2p(itemsp); dtypep(NULL); // V3Width will resolve widthFromSub(subDTypep()); m_uniqueNum = uniqueNumInc(); } ASTNODE_NODE_FUNCS(EnumDType) 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(); }} virtual bool same(const AstNode* samep) const { const AstEnumDType* sp = static_cast(samep); return m_uniqueNum == sp->m_uniqueNum; } virtual bool similarDType(AstNodeDType* samep) const { return this==samep; } 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); } virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } AstEnumItem* itemsp() const { return op2p()->castEnumItem(); } // op2 = AstEnumItem's void addValuesp(AstNode* nodep) { addOp2p(nodep); } // METHODS virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } }; class AstParseTypeDType : public AstNodeDType { // Parents: VAR // During parsing, this indicates the type of a parameter is a "parameter type" // e.g. the data type is a container of any data type public: explicit AstParseTypeDType(FileLine* fl) : AstNodeDType(fl) {} ASTNODE_NODE_FUNCS(ParseTypeDType) AstNodeDType* dtypep() const { return NULL; } // METHODS virtual bool similarDType(AstNodeDType* samep) const { return this==samep; } virtual AstBasicDType* basicp() const { return NULL; } virtual AstNodeDType* skipRefp() const { return NULL; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return 0; } virtual int widthTotalBytes() const { return 0; } }; //###################################################################### class AstArraySel : public AstNodeSel { // Parents: math|stmt // Children: varref|arraysel, math private: 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) { init(fromp); } AstArraySel(FileLine* fl, AstNode* fromp, int bit) :AstNodeSel(fl, fromp, new AstConst(fl,bit)) { init(fromp); } ASTNODE_NODE_FUNCS(ArraySel) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstArraySel(this->fileline(), lhsp, rhsp); } 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 true; } // esp for V3Const::ifSameAssign virtual bool isPredictOptimizable() const { return false; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } virtual int instrCount() const { return widthInstrs(); } // Special operators static AstNode* baseFromp(AstNode* nodep); ///< What is the base variable (or const) this dereferences? }; class AstWordSel : public AstNodeSel { // Select a single word from a multi-word wide value public: AstWordSel(FileLine* fl, AstNode* fromp, AstNode* bitp) :AstNodeSel(fl, fromp, bitp) { dtypeSetUInt32(); // Always used on IData arrays so returns word entities } ASTNODE_NODE_FUNCS(WordSel) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstWordSel(this->fileline(), lhsp, rhsp); } 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(const AstNode* samep) const { return true; } }; class AstSelExtract : public AstNodePreSel { // Range extraction, gets replaced with AstSel public: AstSelExtract(FileLine* fl, AstNode* fromp, AstNode* msbp, AstNode* lsbp) : AstNodePreSel(fl, fromp, msbp, lsbp) {} ASTNODE_NODE_FUNCS(SelExtract) AstNode* msbp() const { return rhsp(); } AstNode* lsbp() const { return thsp(); } }; class AstSelBit : public AstNodePreSel { // Single bit range extraction, perhaps with non-constant selection or array selection // Gets replaced during link with AstArraySel or AstSel public: AstSelBit(FileLine* fl, AstNode* fromp, AstNode* bitp) :AstNodePreSel(fl, fromp, bitp, NULL) { if (v3Global.assertDTypesResolved()) { v3fatalSrc("not coded to create after dtypes resolved"); } } ASTNODE_NODE_FUNCS(SelBit) AstNode* bitp() const { return rhsp(); } }; class AstSelPlus : public AstNodePreSel { // +: range extraction, perhaps with non-constant selection // Gets replaced during link with AstSel public: AstSelPlus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp) :AstNodePreSel(fl, fromp, bitp, widthp) {} ASTNODE_NODE_FUNCS(SelPlus) AstNode* bitp() const { return rhsp(); } AstNode* widthp() const { return thsp(); } }; class AstSelMinus : public AstNodePreSel { // -: range extraction, perhaps with non-constant selection // Gets replaced during link with AstSel public: AstSelMinus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp) :AstNodePreSel(fl, fromp, bitp, widthp) {} ASTNODE_NODE_FUNCS(SelMinus) AstNode* bitp() const { return rhsp(); } AstNode* widthp() const { return thsp(); } }; class AstSel : public AstNodeTriop { // Multiple bit range extraction // Parents: math|stmt // Children: varref|arraysel, math, constant math // Tempting to have an lvalue() style method here as LHS selects are quite // different, but that doesn't play well with V3Inst and bidirects which don't know direction private: VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid int m_declElWidth; // If a packed array, the number of bits per element public: AstSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, AstNode* widthp) :AstNodeTriop(fl, fromp, lsbp, widthp) { m_declElWidth = 1; if (widthp->castConst()) { dtypeSetLogicSized(widthp->castConst()->toUInt(), widthp->castConst()->toUInt(), AstNumeric::UNSIGNED); } } AstSel(FileLine* fl, AstNode* fromp, int lsb, int bitwidth) :AstNodeTriop(fl, fromp, new AstConst(fl,lsb), new AstConst(fl,bitwidth)) { m_declElWidth = 1; dtypeSetLogicSized(bitwidth,bitwidth,AstNumeric::UNSIGNED); } ASTNODE_NODE_FUNCS(Sel) 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(const AstNode*) const { return true; } virtual int instrCount() const { return widthInstrs()*(lsbp()->castConst()?3:10); } AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing) AstNode* lsbp() const { return op2p(); } // op2 = Msb selection expression AstNode* widthp() const { return op3p(); } // op3 = Width int widthConst() const { return widthp()->castConst()->toSInt(); } int lsbConst() const { return lsbp()->castConst()->toSInt(); } int msbConst() const { return lsbConst()+widthConst()-1; } VNumRange& declRange() { return m_declRange; } void declRange(const VNumRange& flag) { m_declRange = flag; } int declElWidth() const { return m_declElWidth; } void declElWidth(int flag) { m_declElWidth = flag; } }; class AstSliceSel : public AstNodeTriop { // Multiple array element extraction // Parents: math|stmt // Children: varref|arraysel, math, constant math private: VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid public: AstSliceSel(FileLine* fl, AstNode* fromp, const VNumRange& declRange) : AstNodeTriop(fl, fromp, new AstConst(fl, declRange.lo()), new AstConst(fl, declRange.elements())) , m_declRange(declRange) { } ASTNODE_NODE_FUNCS(SliceSel) virtual void dump(ostream& str); virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& lo, const V3Number& width) { V3ERROR_NA; } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } // Removed before EmitC virtual bool cleanOut() { return false; } virtual bool cleanLhs() { return false; } 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(const AstNode*) const { return true; } virtual int instrCount() const { return 10; } // Removed before matters AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing) // For widthConst()/loConst etc, see declRange().elements() and other VNumRange methods VNumRange& declRange() { return m_declRange; } void declRange(const VNumRange& flag) { m_declRange = flag; } }; class AstMemberSel : public AstNodeMath { // Parents: math|stmt // Children: varref|arraysel, math private: // Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it string m_name; public: AstMemberSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name) : AstNodeMath(fl), m_name(name) { setOp1p(fromp); dtypep(NULL); // V3Width will resolve } AstMemberSel(FileLine* fl, AstNode* fromp, AstMemberDType* dtp) : AstNodeMath(fl) { setOp1p(fromp); dtypep(dtp); m_name = dtp->name(); } ASTNODE_NODE_FUNCS(MemberSel) 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(const AstNode* samep) const { return true; } // dtype comparison does it all for us virtual int instrCount() const { return widthInstrs(); } AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing) void fromp(AstNode* nodep) { setOp1p(nodep); } }; class AstMethodSel : public AstNode { // A reference to a member task (or function) // We do not support generic member calls yet, so this is only enough to make built-in methods work private: string m_name; // Name of variable public: AstMethodSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name, AstNode* pinsp) : AstNode(fl), m_name(name) { setOp1p(fromp); dtypep(NULL); // V3Width will resolve addNOp2p(pinsp); } AstMethodSel(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp) :AstNode(fl), m_name(name) { setOp1p(fromp); addNOp2p(pinsp); } ASTNODE_NODE_FUNCS(MethodSel) virtual string name() const { return m_name; } // * = Var name virtual void name(const string& name) { m_name = name; } AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing) void fromp(AstNode* nodep) { setOp1p(nodep); } AstNode* pinsp() const { return op2p(); } // op2 = Pin interconnection list void addPinsp(AstNode* nodep) { addOp2p(nodep); } }; class AstVar : public AstNode { // A variable (in/out/wire/reg/param) inside a module private: string m_name; // Name of variable string m_origName; // Original name before dot addition string m_tag; // Holds the string of the verilator tag -- used in XML output. AstVarType m_varType; // Type of variable bool m_input:1; // Input or inout bool m_output:1; // Output or inout bool m_tristate:1; // Inout or triwire or trireg bool m_declOutput:1; // Inout or output before tristate resolution bool m_primaryIO:1; // In/out to top level (or directly assigned from same) bool m_sc:1; // SystemC variable bool m_scClocked:1; // SystemC sc_clk<> needed bool m_scSensitive:1;// SystemC sensitive() needed bool m_sigPublic:1; // User C code accesses this signal or is top signal bool m_sigModPublic:1;// User C code accesses this signal and module bool m_sigUserRdPublic:1; // User C code accesses this signal, read only bool m_sigUserRWPublic:1; // User C code accesses this signal, read-write bool m_usedClock:1; // Signal used as a clock bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup) bool m_usedLoopIdx:1; // Variable subject of for unrolling bool m_funcLocal:1; // Local variable for a function bool m_funcReturn:1; // Return variable for a function bool m_attrClockEn:1;// User clock enable attribute bool m_attrScBv:1; // User force bit vector attribute bool m_attrIsolateAssign:1;// User isolate_assignments attribute bool m_attrSFormat:1;// User sformat attribute bool m_fileDescr:1; // File descriptor bool m_isConst:1; // Table contains constant data bool m_isStatic:1; // Static variable bool m_isPulldown:1; // Tri0 bool m_isPullup:1; // Tri1 bool m_isIfaceParent:1; // dtype is reference to interface present in this module bool m_noSubst:1; // Do not substitute out references bool m_trace:1; // Trace this variable AstVarAttrClocker m_attrClocker; void init() { m_input=false; m_output=false; m_tristate=false; m_declOutput=false; m_primaryIO=false; m_sc=false; m_scClocked=false; m_scSensitive=false; m_usedClock=false; m_usedParam=false; m_usedLoopIdx=false; m_sigPublic=false; m_sigModPublic=false; m_sigUserRdPublic=false; m_sigUserRWPublic=false; m_funcLocal=false; m_funcReturn=false; m_attrClockEn=false; m_attrScBv=false; m_attrIsolateAssign=false; m_attrSFormat=false; m_fileDescr=false; m_isConst=false; m_isStatic=false; m_isPulldown=false; m_isPullup=false; m_isIfaceParent=false; m_attrClocker=AstVarAttrClocker::CLOCKER_UNKNOWN; m_noSubst=false; m_trace=false; } public: AstVar(FileLine* fl, AstVarType type, const string& name, VFlagChildDType, AstNodeDType* dtp) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); childDTypep(dtp); // Only for parser dtypep(NULL); // V3Width will resolve } AstVar(FileLine* fl, AstVarType type, const string& name, AstNodeDType* dtp) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); UASSERT(dtp,"AstVar created with no dtype"); dtypep(dtp); } AstVar(FileLine* fl, AstVarType type, const string& name, VFlagLogicPacked, int wantwidth) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED); } AstVar(FileLine* fl, AstVarType type, const string& name, VFlagBitPacked, int wantwidth) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED); } AstVar(FileLine* fl, AstVarType type, const string& name, AstVar* examplep) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); if (examplep->childDTypep()) { childDTypep(examplep->childDTypep()->cloneTree(true)); } dtypeFrom(examplep); } ASTNODE_NODE_FUNCS(Var) virtual void dump(ostream& str); virtual string name() const { return m_name; } // * = Var name virtual bool hasDType() const { return true; } virtual bool maybePointedTo() const { return true; } string origName() const { return m_origName; } // * = Original name void origName(const string& name) { m_origName = name; } AstVarType varType() const { return m_varType; } // * = Type of variable void varType(AstVarType type) { m_varType = type; } void varType2Out() { m_tristate=0; m_input=0; m_output=1; } void varType2In() { m_tristate=0; m_input=1; m_output=0; } string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv string cPubArgType(bool named, bool forReturn) const; // Return C /*public*/ type for argument: bool, uint32_t, uint64_t, etc. string dpiArgType(bool named, bool forReturn) const; // Return DPI-C type for argument string vlArgType(bool named, bool forReturn, bool forFunc) const; // Return Verilator internal type for argument: CData, SData, IData, WData string vlEnumType() const; // Return VerilatorVarType: VLVT_UINT32, etc string vlEnumDir() const; // Return VerilatorVarDir: VLVD_INOUT, etc void combineType(AstVarType type); AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType) AstNode* valuep() const { return op3p(); } // 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(); } // op4 = Attributes during early parse void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } void attrClockEn(bool flag) { m_attrClockEn = flag; } void attrClocker(AstVarAttrClocker flag) { m_attrClocker = flag; } void attrFileDescr(bool flag) { m_fileDescr = flag; } void attrScClocked(bool flag) { m_scClocked = flag; } void attrScBv(bool flag) { m_attrScBv = flag; } void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; } void attrSFormat(bool flag) { m_attrSFormat = flag; } void usedClock(bool flag) { m_usedClock = flag; } void usedParam(bool flag) { m_usedParam = flag; } void usedLoopIdx(bool flag) { m_usedLoopIdx = flag; } void sigPublic(bool flag) { m_sigPublic = flag; } void sigModPublic(bool flag) { m_sigModPublic = flag; } void sigUserRdPublic(bool flag) { m_sigUserRdPublic = flag; if (flag) sigPublic(true); } void sigUserRWPublic(bool flag) { m_sigUserRWPublic = flag; if (flag) sigUserRdPublic(true); } void sc(bool flag) { m_sc = flag; } void scSensitive(bool flag) { m_scSensitive = flag; } void primaryIO(bool flag) { m_primaryIO = flag; } void isConst(bool flag) { m_isConst = flag; } void isStatic(bool flag) { m_isStatic = flag; } void isIfaceParent(bool flag) { m_isIfaceParent = flag; } void funcLocal(bool flag) { m_funcLocal = flag; } void funcReturn(bool flag) { m_funcReturn = flag; } void noSubst(bool flag) { m_noSubst=flag; } bool noSubst() const { return m_noSubst; } void trace(bool flag) { m_trace=flag; } // METHODS virtual void name(const string& name) { m_name = name; } virtual void tag(const string& text) { m_tag = text;} virtual string tag() const { return m_tag; } virtual string directionName() const { return (isInout() ? "inout" : isInput() ? "input" : isOutput() ? "output" : varType().ascii()); } bool isInput() const { return m_input; } bool isOutput() const { return m_output; } bool isInOnly() const { return m_input && !m_output; } bool isOutOnly() const { return m_output && !m_input; } bool isInout() const { return m_input && m_output; } bool isTristate() const { return m_tristate; } bool isDeclOutput() const { return m_declOutput; } bool isPrimaryIO() const { return m_primaryIO; } bool isPrimaryIn() const { return isPrimaryIO() && isInput(); } bool isIO() const { return (m_input||m_output); } bool isIfaceRef() const { return (varType()==AstVarType::IFACEREF); } bool isIfaceParent() const { return m_isIfaceParent; } bool isSignal() const { return varType().isSignal(); } bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP || varType()==AstVarType::STMTTEMP || varType()==AstVarType::XTEMP); } bool isToggleCoverable() const { return ((isIO() || isSignal()) && (isIO() || isBitLogic()) // Wrapper would otherwise duplicate wrapped module's coverage && !isSc() && !isPrimaryIO() && !isConst()); } bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); } bool isMovableToBlock() const { return (varType()==AstVarType::BLOCKTEMP || isFuncLocal()); } bool isXTemp() const { return (varType()==AstVarType::XTEMP); } bool isParam() const { return (varType()==AstVarType::LPARAM || varType()==AstVarType::GPARAM); } bool isGParam() const { return (varType()==AstVarType::GPARAM); } bool isGenVar() const { return (varType()==AstVarType::GENVAR); } bool isBitLogic() const { AstBasicDType* bdtypep = basicp(); return bdtypep && bdtypep->isBitLogic(); } bool isUsedClock() const { return m_usedClock; } bool isUsedParam() const { return m_usedParam; } bool isUsedLoopIdx() const { return m_usedLoopIdx; } bool isSc() const { return m_sc; } bool isScQuad() const; bool isScBv() const; bool isScUint() const; bool isScBigUint() const; bool isScSensitive() const { return m_scSensitive; } bool isSigPublic() const; bool isSigModPublic() const { return m_sigModPublic; } bool isSigUserRdPublic() const { return m_sigUserRdPublic; } bool isSigUserRWPublic() const { return m_sigUserRWPublic; } bool isTrace() const { return m_trace; } bool isConst() const { return m_isConst; } bool isStatic() const { return m_isStatic; } bool isFuncLocal() const { return m_funcLocal; } bool isFuncReturn() const { return m_funcReturn; } bool isPullup() const { return m_isPullup; } bool isPulldown() const { return m_isPulldown; } bool attrClockEn() const { return m_attrClockEn; } bool attrScBv() const { return m_attrScBv; } bool attrFileDescr() const { return m_fileDescr; } bool attrScClocked() const { return m_scClocked; } bool attrSFormat() const { return m_attrSFormat; } bool attrIsolateAssign() const { return m_attrIsolateAssign; } AstVarAttrClocker attrClocker() const { return m_attrClocker; } virtual string verilogKwd() const; void propagateAttrFrom(AstVar* fromp) { // This is getting connected to fromp; keep attributes // Note the method below too if (fromp->attrClockEn()) attrClockEn(true); if (fromp->attrFileDescr()) attrFileDescr(true); if (fromp->attrIsolateAssign()) attrIsolateAssign(true); } bool gateMultiInputOptimizable() const { // Ok to gate optimize; must return false if propagateAttrFrom would do anything return (!attrClockEn() && !isUsedClock()); } void combineType(AstVar* typevarp) { // This is same as typevarp (for combining input & reg decls) propagateAttrFrom(typevarp); combineType(typevarp->varType()); if (typevarp->isSigPublic()) sigPublic(true); if (typevarp->isSigModPublic()) sigModPublic(true); if (typevarp->isSigUserRdPublic()) sigUserRdPublic(true); if (typevarp->isSigUserRWPublic()) sigUserRWPublic(true); if (typevarp->attrScClocked()) attrScClocked(true); } void inlineAttrReset(const string& name) { m_input=m_output=false; m_name = name; if (varType()==AstVarType::INOUT) m_varType = AstVarType::TRIWIRE; if (varType()==AstVarType::INPUT || varType()==AstVarType::OUTPUT) m_varType = AstVarType::WIRE; } static AstVar* scVarRecurse(AstNode* nodep); }; class AstDefParam : public AstNode { // A defparam assignment // Parents: MODULE // Children: math private: string m_name; // Name of variable getting set string m_path; // Dotted cellname to set parameter of public: AstDefParam(FileLine* fl, const string& path, const string& name, AstNode* rhsp) : AstNode(fl) { setOp1p(rhsp); m_name = name; m_path = path; } virtual string name() const { return m_name; } // * = Scope name ASTNODE_NODE_FUNCS(DefParam) virtual bool cleanRhs() { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode*) const { return true; } AstNode* rhsp() const { return op1p(); } // op1 = Assign from string path() const { return m_path; } }; class AstImplicit : public AstNode { // Create implicit wires and do nothing else, for gates that are ignored // Parents: MODULE public: AstImplicit(FileLine* fl, AstNode* exprsp) : AstNode(fl) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(Implicit) AstNode* exprsp() const { return op1p(); } // op1 = Assign from }; class AstScope : public AstNode { // A particular usage of a cell // Parents: MODULE // Children: NODEBLOCK private: // An AstScope->name() is special: . indicates an uninlined scope, __DOT__ an inlined scope string m_name; // Name AstScope* m_aboveScopep; // Scope above this one in the hierarchy (NULL if top) AstCell* m_aboveCellp; // Cell above this in the hierarchy (NULL if top) AstNodeModule* m_modp; // Module scope corresponds to public: AstScope(FileLine* fl, AstNodeModule* modp, const string& name, AstScope* aboveScopep, AstCell* aboveCellp) :AstNode(fl) ,m_name(name) ,m_aboveScopep(aboveScopep) ,m_aboveCellp(aboveCellp), m_modp(modp) {} ASTNODE_NODE_FUNCS(Scope) 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(); } // op1 = AstVarScope's void addActivep(AstNode* nodep) { addOp2p(nodep); } AstNode* blocksp() const { return op2p(); } // op2 = Block names void addFinalClkp(AstNode* nodep) { addOp3p(nodep); } AstNode* finalClksp() const { return op3p(); } // op3 = Final assigns for clock correction AstScope* aboveScopep() const { return m_aboveScopep; } AstCell* aboveCellp() const { return m_aboveCellp; } bool isTop() const { return aboveScopep()==NULL; } // At top of hierarchy }; class AstTopScope : public AstNode { // In the top level netlist, a complete scope tree // There may be two of these, when we support "rare" and "usual" splitting // Parents: topMODULE // Children: SCOPEs public: AstTopScope(FileLine* fl, AstScope* ascopep) :AstNode(fl) {addNOp2p(ascopep);} ASTNODE_NODE_FUNCS(TopScope) AstNode* stmtsp() const { return op1p(); } void addStmtsp(AstNode* nodep) { addOp1p(nodep); } AstScope* scopep() const { return op2p()->castScope(); } // op1 = AstVarScope's }; class AstVarScope : public AstNode { // A particular scoped usage of a variable // That is, as a module is used under multiple cells, we get a different varscope for each var in the module // Parents: MODULE // Children: none private: AstScope* m_scopep; // Scope variable is underneath AstVar* m_varp; // [AfterLink] Pointer to variable itself bool m_circular:1; // Used in circular ordering dependency, need change detect bool m_trace:1; // Tracing is turned on for this scope public: AstVarScope(FileLine* fl, AstScope* scopep, AstVar* varp) :AstNode(fl) , m_scopep(scopep), m_varp(varp) { m_circular = false; m_trace = true; dtypeFrom(varp); } ASTNODE_NODE_FUNCS(VarScope) virtual void cloneRelink() { if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); UASSERT(m_scopep->clonep(), "No clone cross link: "<clonep(); }} virtual const char* broken() const { BROKEN_RTN(m_varp && !m_varp->brokeExists()); BROKEN_RTN(m_scopep && !m_scopep->brokeExists()); return NULL; } virtual bool maybePointedTo() const { return true; } virtual string name() const {return scopep()->name()+"->"+varp()->name();} // * = Var name virtual void dump(ostream& str); virtual bool hasDType() const { return true; } AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable AstScope* scopep() const { return m_scopep; } // Pointer to scope it's under AstNode* valuep() const { return op1p(); } // op1 = Calculation of value of variable, NULL=complicated void valuep(AstNode* valuep) { addOp1p(valuep); } bool isCircular() const { return m_circular; } void circular(bool flag) { m_circular = flag; } bool isTrace() const { return m_trace; } void trace(bool flag) { m_trace = flag; } }; class AstVarRef : public AstNodeVarRef { // A reference to a variable (lvalue or rvalue) public: AstVarRef(FileLine* fl, const string& name, bool lvalue) :AstNodeVarRef(fl, name, NULL, lvalue) {} AstVarRef(FileLine* fl, AstVar* varp, bool lvalue) // This form only allowed post-link :AstNodeVarRef(fl, varp->name(), varp, lvalue) {} // because output/wire compression may lead to deletion of AstVar's AstVarRef(FileLine* fl, AstVarScope* varscp, bool lvalue) // This form only allowed post-link :AstNodeVarRef(fl, varscp->varp()->name(), varscp->varp(), lvalue) { // because output/wire compression may lead to deletion of AstVar's varScopep(varscp); } ASTNODE_NODE_FUNCS(VarRef) virtual void dump(ostream& str); virtual V3Hash sameHash() const { return V3Hash(V3Hash(varp()->name()),V3Hash(hiername())); } virtual bool same(const AstNode* samep) const { return same(static_cast(samep)); } inline bool same(const AstVarRef* samep) const { if (varScopep()) return (varScopep()==samep->varScopep() && lvalue()==samep->lvalue()); else return (hiername()==samep->hiername() && varp()->name()==samep->varp()->name() && lvalue()==samep->lvalue()); } inline bool sameNoLvalue(AstVarRef* samep) const { if (varScopep()) return (varScopep()==samep->varScopep()); else return (hiername()==samep->hiername() && varp()->name()==samep->varp()->name()); } virtual int instrCount() const { return widthInstrs()*(lvalue()?1:instrCountLd()); } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } }; class AstVarXRef : public AstNodeVarRef { // A VarRef to something in another module before AstScope. // Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope private: string m_dotted; // Scope name to connected to string m_inlinedDots; // Dotted hierarchy flattened out public: AstVarXRef(FileLine* fl, const string& name, const string& dotted, bool lvalue) :AstNodeVarRef(fl, name, NULL, lvalue) , m_dotted(dotted) { } AstVarXRef(FileLine* fl, AstVar* varp, const string& dotted, bool lvalue) :AstNodeVarRef(fl, varp->name(), varp, lvalue) , m_dotted(dotted) { dtypeFrom(varp); } ASTNODE_NODE_FUNCS(VarXRef) virtual void dump(ostream& str); string dotted() const { return m_dotted; } void dotted(const string& dotted) { m_dotted = 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(const AstNode* samep) const { const AstVarXRef* asamep = static_cast(samep); return (hiername() == asamep->hiername() && varp() == asamep->varp() && name() == asamep->name() && dotted() == asamep->dotted()); } }; class AstPin : public AstNode { // A pin on a cell private: int m_pinNum; // Pin number string m_name; // Pin name, or "" for number based interconnect AstVar* m_modVarp; // Input/output this pin connects to on submodule. AstParamTypeDType* m_modPTypep; // Param type 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; m_modPTypep = 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; m_modPTypep = NULL; setNOp1p(exprp); } ASTNODE_NODE_FUNCS(Pin) virtual void dump(ostream& str); virtual const char* broken() const { BROKEN_RTN(m_modVarp && !m_modVarp->brokeExists()); BROKEN_RTN(m_modPTypep && !m_modPTypep->brokeExists()); return NULL; } virtual string name() const { return m_name; } // * = Pin name, ""=go by number virtual void name(const string& name) { m_name = name; } virtual string prettyOperatorName() const { return modVarp() ? (modVarp()->directionName()+" port connection '"+modVarp()->prettyName()+"'") : "port connection"; } bool dotStar() const { return name() == ".*"; } // Special fake name for .* connections until linked int pinNum() const { return m_pinNum; } void exprp(AstNode* nodep) { addOp1p(nodep); } AstNode* exprp() const { return op1p(); } // op1 = Expression connected to pin, NULL if unconnected AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable void modVarp(AstVar* nodep) { m_modVarp=nodep; } AstParamTypeDType* modPTypep() const { return m_modPTypep; } // [After Link] Pointer to variable void modPTypep(AstParamTypeDType* nodep) { m_modPTypep=nodep; } bool param() const { return m_param; } void param(bool flag) { m_param=flag; } bool svImplicit() const { return m_svImplicit; } void svImplicit(bool flag) { m_svImplicit=flag; } }; class AstArg : public AstNode { // An argument to a function/task private: string m_name; // Pin name, or "" for number based interconnect public: AstArg(FileLine* fl, const string& name, AstNode* exprp) : AstNode(fl) ,m_name(name) { setNOp1p(exprp); } ASTNODE_NODE_FUNCS(Arg) 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(); } // op1 = Expression connected to pin, NULL if unconnected bool emptyConnectNoNext() const { return !exprp() && name()=="" && !nextp(); } }; class AstModule : public AstNodeModule { // A module declaration public: AstModule(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(Module) virtual string verilogKwd() const { return "module"; } }; class AstNotFoundModule : public AstNodeModule { // A missing module declaration public: AstNotFoundModule(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(NotFoundModule) virtual string verilogKwd() const { return "/*not-found-*/ module"; } }; class AstPackage : public AstNodeModule { // A package declaration public: AstPackage(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(Package) virtual string verilogKwd() const { return "package"; } static string dollarUnitName() { return AstNode::encodeName("$unit"); } bool isDollarUnit() const { return name() == dollarUnitName(); } }; class AstPrimitive : public AstNodeModule { // A primitive declaration public: AstPrimitive(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(Primitive) virtual string verilogKwd() const { return "primitive"; } }; class AstPackageExportStarStar : public AstNode { // A package export *::* declaration public: // cppcheck-suppress noExplicitConstructor AstPackageExportStarStar(FileLine* fl) : AstNode (fl) {} ASTNODE_NODE_FUNCS(PackageExportStarStar) }; class AstPackageExport : public AstNode { private: // A package export declaration string m_name; AstPackage* m_packagep; // Package hierarchy public: AstPackageExport(FileLine* fl, AstPackage* packagep, const string& name) : AstNode (fl), m_name(name), m_packagep(packagep) {} ASTNODE_NODE_FUNCS(PackageExport) 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(); } virtual void dump(ostream& str); virtual string name() const { return m_name; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; class 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) 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(); } virtual void dump(ostream& str); virtual string name() const { return m_name; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; class AstIface : public AstNodeModule { // A module declaration public: AstIface(FileLine* fl, const string& name) : AstNodeModule (fl,name) { } ASTNODE_NODE_FUNCS(Iface) }; class AstModportFTaskRef : public AstNode { // An import/export referenced under a modport // The storage for the function itself is inside the interface/instantiator, thus this is a reference // PARENT: AstModport private: string m_name; // Name of the variable referenced bool m_export; // Type of the function (import/export) AstNodeFTask* m_ftaskp; // Link to the function public: AstModportFTaskRef(FileLine* fl, const string& name, bool isExport) : AstNode(fl), m_name(name), m_export(isExport), m_ftaskp(NULL) { } ASTNODE_NODE_FUNCS(ModportFTaskRef) 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(); } bool isImport() const { return !m_export; } bool isExport() const { return m_export; } AstNodeFTask* ftaskp() const { return m_ftaskp; } // [After Link] Pointer to variable void ftaskp(AstNodeFTask* ftaskp) { m_ftaskp=ftaskp; } }; class AstModportVarRef : public AstNode { // A input/output/etc variable referenced under a modport // The storage for the variable itself is inside the interface, thus this is a reference // PARENT: AstModport private: string m_name; // Name of the variable referenced AstVarType m_type; // Type of the variable (in/out) AstVar* m_varp; // Link to the actual Var public: AstModportVarRef(FileLine* fl, const string& name, AstVarType::en type) : AstNode(fl), m_name(name), m_type(type), m_varp(NULL) { } ASTNODE_NODE_FUNCS(ModportVarRef) 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(); } virtual string name() const { return m_name; } AstVarType varType() const { return m_type; } // * = Type of variable bool isInput() const { return (varType()==AstVarType::INPUT || varType()==AstVarType::INOUT); } bool isOutput() const { return (varType()==AstVarType::OUTPUT || varType()==AstVarType::INOUT); } AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable void varp(AstVar* varp) { m_varp=varp; } }; class AstModport : public AstNode { // A modport in an interface private: string m_name; // Name of the modport public: AstModport(FileLine* fl, const string& name, AstNode* varsp) : AstNode(fl), m_name(name) { addNOp1p(varsp); } virtual string name() const { return m_name; } virtual bool maybePointedTo() const { return true; } ASTNODE_NODE_FUNCS(Modport) AstNode* varsp() const { return op1p(); } // op1 = List of Vars }; class AstCell : public AstNode { // A instantiation cell or interface call (don't know which until link) private: string m_name; // Cell name string m_origName; // Original name before dot addition string m_modName; // Module the cell instances AstNodeModule* m_modp; // [AfterLink] Pointer to module instanced bool m_hasIfaceVar:1; // True if a Var has been created for this cell bool m_recursive:1; // Self-recursive module bool m_trace:1; // Trace this cell public: AstCell(FileLine* fl, const string& instName, const string& modName, AstPin* pinsp, AstPin* paramsp, AstRange* rangep) : AstNode(fl) , m_name(instName), m_origName(instName), m_modName(modName) , m_modp(NULL), m_hasIfaceVar(false), m_recursive(false), m_trace(true) { addNOp1p(pinsp); addNOp2p(paramsp); setNOp3p(rangep); } ASTNODE_NODE_FUNCS(Cell) // No cloneRelink, we presume cloneee's want the same module linkages virtual void dump(ostream& str); virtual const char* broken() const { BROKEN_RTN(m_modp && !m_modp->brokeExists()); return NULL; } virtual bool maybePointedTo() const { return true; } // ACCESSORS virtual string name() const { return m_name; } // * = Cell name virtual void name(const string& name) { m_name = name; } string origName() const { return m_origName; } // * = Original name void origName(const string& name) { m_origName = name; } string modName() const { return m_modName; } // * = Instance name void modName(const string& name) { m_modName = name; } AstPin* pinsp() const { return op1p()->castPin(); } // op1 = List of cell ports AstPin* paramsp() const { return op2p()->castPin(); } // op2 = List of parameter #(##) values AstRange* rangep() const { return op3p()->castRange(); } // op3 = Range of arrayed instants (NULL=not ranged) AstNodeModule* modp() const { return m_modp; } // [AfterLink] = Pointer to module instantiated void addPinsp(AstPin* nodep) { addOp1p(nodep); } void addParamsp(AstPin* nodep) { addOp2p(nodep); } void modp(AstNodeModule* nodep) { m_modp = nodep; } bool hasIfaceVar() const { return m_hasIfaceVar; } void hasIfaceVar(bool flag) { m_hasIfaceVar = flag; } void trace(bool flag) { m_trace=flag; } bool isTrace() const { return m_trace; } void recursive(bool flag) { m_recursive = flag; } bool recursive() const { return m_recursive; } }; class AstCellInline : public AstNode { // A instantiation cell that was removed by inlining // For communication between V3Inline and V3LinkDot only // Children: When 2 levels inlined, other CellInline under this private: string m_name; // Cell name, possibly {a}__DOT__{b}... string m_origModName; // Original name of the module, ignoring name() changes, for dot lookup public: AstCellInline(FileLine* fl, const string& name, const string& origModName) : AstNode(fl) , m_name(name), m_origModName(origModName) {} ASTNODE_NODE_FUNCS(CellInline) virtual void dump(ostream& str); // ACCESSORS virtual string name() const { return m_name; } // * = Cell name string origModName() const { return m_origModName; } // * = modp()->origName() before inlining virtual void name(const string& name) { m_name = name; } }; class AstCellRef : public AstNode { // As-of-yet unlinkable reference into a cell private: string m_name; // Cell name public: AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNode* exprp) : AstNode(fl) , m_name(name) { addNOp1p(cellp); addNOp2p(exprp); } ASTNODE_NODE_FUNCS(CellRef) // ACCESSORS virtual string name() const { return m_name; } // * = Array name AstNode* cellp() const { return op1p(); } // op1 = Cell AstNode* exprp() const { return op2p(); } // op2 = Expression }; class AstCellArrayRef : public AstNode { // As-of-yet unlinkable reference into an array of cells private: string m_name; // Array name public: AstCellArrayRef(FileLine* fl, const string& name, AstNode* selectExprp) : AstNode(fl) , m_name(name) { addNOp1p(selectExprp); } ASTNODE_NODE_FUNCS(CellArrayRef) // ACCESSORS virtual string name() const { return m_name; } // * = Array name AstNode* selp() const { return op1p(); } // op1 = Select expression }; class AstUnlinkedRef : public AstNode { // As-of-yet unlinkable Ref private: string m_name; // Var name public: AstUnlinkedRef(FileLine* fl, AstNode* refp, const string& name, AstNode* crp) : AstNode(fl) , m_name(name) { addNOp1p(refp); addNOp2p(crp); } ASTNODE_NODE_FUNCS(UnlinkedRef) // ACCESSORS virtual string name() const { return m_name; } // * = Var name AstNode* refp() const { return op1p(); } // op1 = VarXRef or AstNodeFTaskRef AstNode* cellrefp() const { return op2p(); } // op2 = CellArrayRef or CellRef }; class AstBind : public AstNode { // Parents: MODULE // Children: CELL private: string m_name; // Binding to name public: AstBind(FileLine* fl, const string& name, AstNode* cellsp) : AstNode(fl) , m_name(name) { if (!cellsp->castCell()) cellsp->v3fatalSrc("Only cells allowed to be bound"); addNOp1p(cellsp); } ASTNODE_NODE_FUNCS(Bind) // ACCESSORS virtual string name() const { return m_name; } // * = Bind Target name virtual void name(const string& name) { m_name = name; } AstNode* cellsp() const { return op1p(); } // op1= cells }; class AstPort : public AstNode { // A port (in/out/inout) on a module private: int m_pinNum; // Pin number string m_name; // Name of pin public: AstPort(FileLine* fl, int pinnum, const string& name) :AstNode(fl) ,m_pinNum(pinnum) ,m_name(name) {} ASTNODE_NODE_FUNCS(Port) 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(); } // op1 = Expression connected to port }; //###################################################################### class AstGenerate : public AstNode { // A Generate/end block // Parents: MODULE // Children: modItems public: AstGenerate(FileLine* fileline, AstNode* stmtsp) : AstNode(fileline) { addNOp1p(stmtsp); } ASTNODE_NODE_FUNCS(Generate) // op1 = Statements AstNode* stmtsp() const { return op1p(); } // op1 = List of statements void addStmtp(AstNode* nodep) { addOp1p(nodep); } }; class AstParseRef : public AstNode { // A reference to a variable, function or task // We don't know which at parse time due to bison constraints // The link stages will replace this with AstVarRef, or AstTaskRef, etc. // Parents: math|stmt // Children: TEXT|DOT|SEL*|TASK|FUNC (or expression under sel) private: AstParseRefExp m_expect; // Type we think it should resolve to string m_name; public: AstParseRef(FileLine* fl, AstParseRefExp expect, const string& name, AstNode* lhsp, AstNodeFTaskRef* ftaskrefp) :AstNode(fl), m_expect(expect), m_name(name) { setNOp1p(lhsp); setNOp2p(ftaskrefp); } ASTNODE_NODE_FUNCS(ParseRef) 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(const AstNode* samep) const { const AstParseRef* asamep = static_cast(samep); return (expect() == asamep->expect() && m_name == asamep->m_name); } virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; } virtual void name(const string& name) { m_name = name; } AstParseRefExp expect() const { return m_expect; } void expect(AstParseRefExp exp) { m_expect=exp; } // op1 = Components AstNode* lhsp() const { return op1p(); } // op1 = List of statements AstNode* ftaskrefp() const { return op2p(); } // op2 = Function/task reference void ftaskrefp(AstNodeFTaskRef* nodep) { setNOp2p(nodep); } // op2 = Function/task reference }; class AstPackageRef : public AstNode { private: AstPackage* m_packagep; // Package hierarchy public: AstPackageRef(FileLine* fl, AstPackage* packagep) : AstNode(fl), m_packagep(packagep) {} ASTNODE_NODE_FUNCS(PackageRef) // 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(); }} virtual bool same(const AstNode* samep) const { return (m_packagep==static_cast(samep)->m_packagep); } virtual V3Hash sameHash() const { return V3Hash(m_packagep); } virtual void dump(ostream& str=cout); AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; class AstDot : public AstNode { // A dot separating paths in an AstXRef, AstFuncRef or AstTaskRef // These are eliminated in the link stage public: AstDot(FileLine* fl, AstNode* lhsp, AstNode* rhsp) :AstNode(fl) { setOp1p(lhsp); setOp2p(rhsp); } ASTNODE_NODE_FUNCS(Dot) static AstNode* newIfPkg(FileLine*fl, AstPackage* packagep, AstNode* rhsp) { // For parser, make only if non-null package if (!packagep) return rhsp; return new AstDot(fl, new AstPackageRef(fl, packagep), rhsp); } virtual void dump(ostream& str); virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; } AstNode* lhsp() const { return op1p(); } AstNode* rhsp() const { return op2p(); } }; //###################################################################### class AstTask : public AstNodeFTask { // A task inside a module public: AstTask(FileLine* fl, const string& name, AstNode* stmtp) :AstNodeFTask(fl, name, stmtp) {} ASTNODE_NODE_FUNCS(Task) }; class AstFunc : public AstNodeFTask { // A function inside a module public: AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp) :AstNodeFTask(fl, name, stmtp) { addNOp1p(fvarsp); } ASTNODE_NODE_FUNCS(Func) virtual bool hasDType() const { return true; } }; class AstTaskRef : public AstNodeFTaskRef { // A reference to a task public: AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp) :AstNodeFTaskRef(fl, namep, pinsp) {} AstTaskRef(FileLine* fl, const string& name, AstNode* pinsp) :AstNodeFTaskRef(fl, name, pinsp) {} ASTNODE_NODE_FUNCS(TaskRef) }; class AstFuncRef : public AstNodeFTaskRef { // A reference to a function public: AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp) :AstNodeFTaskRef(fl, namep, pinsp) {} AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp) :AstNodeFTaskRef(fl, name, pinsp) {} ASTNODE_NODE_FUNCS(FuncRef) virtual bool hasDType() const { return true; } }; class AstDpiExport : public AstNode { // We could put an AstNodeFTaskRef instead of the verilog function name, // however we're not *calling* it, so that seems somehow wrong. // (Probably AstNodeFTaskRef should be renamed AstNodeFTaskCall and have-a AstNodeFTaskRef) private: string m_name; // Name of function string m_cname; // Name of function on c side public: AstDpiExport(FileLine* fl, const string& vname, const string& cname) :AstNode(fl), m_name(vname), m_cname(cname) { } ASTNODE_NODE_FUNCS(DpiExport) virtual string name() const { return m_name; } virtual void name(const string& name) { m_name = name; } string cname() const { return m_cname; } void cname(const string& cname) { m_cname = cname; } }; //###################################################################### class AstSenItem : public AstNodeSenItem { // Parents: SENTREE // Children: (optional) VARREF SENGATE private: AstEdgeType m_edgeType; // Edge type public: class Combo {}; // for creator type-overload selection class Illegal {}; // 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, Illegal) : AstNodeSenItem(fl) { m_edgeType = AstEdgeType::ET_ILLEGAL; } 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) virtual void dump(ostream& str); virtual V3Hash sameHash() const { return V3Hash(edgeType()); } virtual bool same(const AstNode* samep) const { return edgeType()==static_cast(samep)->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 isIllegal() const { return edgeType()==AstEdgeType::ET_ILLEGAL; } virtual bool isSettle() const { return edgeType()==AstEdgeType::ET_SETTLE; } virtual bool isNever() const { return edgeType()==AstEdgeType::ET_NEVER; } bool hasVar() const { return !(isCombo()||isInitial()||isSettle()||isNever()); } }; class AstSenGate : public AstNodeSenItem { // Parents: SENTREE // Children: SENITEM expr // AND as applied to a sensitivity list and a gating expression // Performing this gating is optional; it may be removed by later optimizations public: AstSenGate(FileLine* fl, AstSenItem* sensesp, AstNode* rhsp) : AstNodeSenItem(fl) { dtypeSetLogicBool(); addOp1p(sensesp); setOp2p(rhsp); } ASTNODE_NODE_FUNCS(SenGate) virtual string emitVerilog() { return "(%l) %f&& (%r)"; } AstSenItem* sensesp() const { return op1p()->castSenItem(); } AstNode* rhsp() const { return op2p(); } void sensesp(AstSenItem* nodep) { addOp1p(nodep); } void rhsp(AstNode* nodep) { setOp2p(nodep); } // virtual bool isClocked() const { return true; } virtual bool isCombo() const { return false; } virtual bool isInitial() const { return false; } virtual bool isSettle() const { return false; } virtual bool isNever() const { return false; } }; class AstSenTree : public AstNode { // A list of senitems // Parents: MODULE | SBLOCK // Children: SENITEM list private: bool m_multi; // Created from combo logic by ORing multiple clock domains public: AstSenTree(FileLine* fl, AstNodeSenItem* sensesp) : AstNode(fl), m_multi(false) { addNOp1p(sensesp); } ASTNODE_NODE_FUNCS(SenTree) 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() const; // Includes a clocked statement bool hasSettle() const; // Includes a SETTLE SenItem bool hasInitial() const; // Includes a INITIAL SenItem bool hasCombo() const; // Includes a COMBO SenItem }; class AstAlways : public AstNode { VAlwaysKwd m_keyword; public: AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp) : AstNode(fl), m_keyword(keyword) { addNOp1p(sensesp); addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(Always) // virtual void dump(ostream& str); AstSenTree* sensesp() const { return op1p()->castSenTree(); } // op1 = Sensitivity list AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate void addStmtp(AstNode* nodep) { addOp2p(nodep); } VAlwaysKwd keyword() const { return m_keyword; } // Special accessors bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } }; class AstAlwaysPublic : public AstNodeStmt { // "Fake" sensitivity created by /*verilator public_flat_rw @(edgelist)*/ // Body statements are just AstVarRefs to the public signals public: AstAlwaysPublic(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp) : AstNodeStmt(fl) { addNOp1p(sensesp); addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(AlwaysPublic) virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } // AstSenTree* sensesp() const { return op1p()->castSenTree(); } // op1 = Sensitivity list AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate void addStmtp(AstNode* nodep) { addOp2p(nodep); } // Special accessors bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } }; class AstAlwaysPost : public AstNode { // Like always but post assignments for memory assignment IFs public: AstAlwaysPost(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp) : AstNode(fl) { addNOp1p(sensesp); addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(AlwaysPost) // AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate void addBodysp(AstNode* newp) { addOp2p(newp); } }; class AstAssign : public AstNodeAssign { public: AstAssign(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Assign) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssign(this->fileline(), lhsp, rhsp); } virtual bool brokeLhsMustBeLvalue() const { return true; } }; class AstAssignAlias : public AstNodeAssign { // Like AstAssignW, but a true bidirect interconnection alias // If both sides are wires, there's no LHS vs RHS, public: AstAssignAlias(FileLine* fileline, AstVarRef* lhsp, AstVarRef* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(AssignAlias) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { V3ERROR_NA; return NULL; } virtual bool brokeLhsMustBeLvalue() const { return false; } }; class AstAssignDly : public AstNodeAssign { public: AstAssignDly(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(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 "<="; } virtual bool brokeLhsMustBeLvalue() const { return true; } }; class AstAssignW : public AstNodeAssign { // Like assign, but wire/assign's in verilog, the only setting of the specified variable public: AstAssignW(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) { } ASTNODE_NODE_FUNCS(AssignW) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignW(this->fileline(), lhsp, rhsp); } virtual bool brokeLhsMustBeLvalue() const { return true; } AstAlways* convertToAlways() { AstNode* lhs1p = lhsp()->unlinkFrBack(); AstNode* rhs1p = rhsp()->unlinkFrBack(); AstAlways* newp = new AstAlways (fileline(), VAlwaysKwd::ALWAYS, NULL, new AstAssign (fileline(), lhs1p, rhs1p)); replaceWith(newp); // User expected to then deleteTree(); return newp; } }; class AstAssignVarScope : public AstNodeAssign { // Assign two VarScopes to each other public: AstAssignVarScope(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) { dtypeFrom(rhsp); } ASTNODE_NODE_FUNCS(AssignVarScope) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignVarScope(this->fileline(), lhsp, rhsp); } virtual bool brokeLhsMustBeLvalue() const { return false; } }; class AstPull : public AstNode { private: bool m_direction; public: AstPull(FileLine* fileline, AstNode* lhsp, bool direction) : AstNode(fileline) { setOp1p(lhsp); m_direction = direction; } ASTNODE_NODE_FUNCS(Pull) virtual bool same(const AstNode* samep) const { return direction()==static_cast(samep)->direction(); } void lhsp(AstNode* np) { setOp1p(np); } AstNode* lhsp() const { return op1p(); } // op1 = Assign to uint32_t direction() const { return (uint32_t) m_direction; } }; class AstAssignPre : public AstNodeAssign { // Like Assign, but predelayed assignment requiring special order handling public: AstAssignPre(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(AssignPre) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPre(this->fileline(), lhsp, rhsp); } virtual bool brokeLhsMustBeLvalue() const { return true; } }; class AstAssignPost : public AstNodeAssign { // Like Assign, but predelayed assignment requiring special order handling public: AstAssignPost(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(AssignPost) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPost(this->fileline(), lhsp, rhsp); } virtual bool brokeLhsMustBeLvalue() const { return true; } }; class AstComment : public AstNodeStmt { // Some comment to put into the output stream // Parents: {statement list} // Children: none private: string m_name; // Name of variable public: AstComment(FileLine* fl, const string& name) : AstNodeStmt(fl) , m_name(name) {} ASTNODE_NODE_FUNCS(Comment) virtual string name() const { return m_name; } // * = Var name virtual V3Hash sameHash() const { return V3Hash(); } // Ignore name in comments virtual bool same(const AstNode* samep) const { return true; } // Ignore name in comments }; class AstCond : public AstNodeCond { // Conditional ?: statement // Parents: MATH // Children: MATH public: AstCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) : AstNodeCond(fl, condp, expr1p, expr2p) {} ASTNODE_NODE_FUNCS(Cond) virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) { return new AstCond(this->fileline(), condp, expr1p, expr2p); } }; class AstCondBound : public AstNodeCond { // Conditional ?: statement, specially made for saftey checking of array bounds // Parents: MATH // Children: MATH public: AstCondBound(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) : AstNodeCond(fl, condp, expr1p, expr2p) {} ASTNODE_NODE_FUNCS(CondBound) virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) { return new AstCondBound(this->fileline(), condp, expr1p, expr2p); } }; class AstCoverDecl : public AstNodeStmt { // Coverage analysis point declaration // Parents: {statement list} // Children: none private: AstCoverDecl* m_dataDeclp; // [After V3CoverageJoin] Pointer to duplicate declaration to get data from instead string m_page; string m_text; string m_hier; int m_column; int m_binNum; // Set by V3EmitCSyms to tell final V3Emit what to increment public: AstCoverDecl(FileLine* fl, int column, const string& page, const string& comment) : AstNodeStmt(fl) { m_text = comment; m_page = page; m_column = column; m_binNum = 0; m_dataDeclp = NULL; } ASTNODE_NODE_FUNCS(CoverDecl) 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(); } 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(const AstNode* samep) const { const AstCoverDecl* asamep = static_cast(samep); return (fileline() == asamep->fileline() && hier() == asamep->hier() && comment() == asamep->comment() && column() == asamep->column()); } virtual bool isPredictOptimizable() const { return false; } void dataDeclp(AstCoverDecl* nodep) { m_dataDeclp=nodep; } // dataDecl NULL means "use this one", but often you want "this" to indicate to get data from here AstCoverDecl* dataDeclNullp() const { return m_dataDeclp; } AstCoverDecl* dataDeclThisp() { return dataDeclNullp()?dataDeclNullp():this; } }; class AstCoverInc : public AstNodeStmt { // Coverage analysis point; increment coverage count // Parents: {statement list} // Children: none private: AstCoverDecl* m_declp; // [After V3Coverage] Pointer to declaration public: AstCoverInc(FileLine* fl, AstCoverDecl* declp) : AstNodeStmt(fl) { m_declp = declp; } ASTNODE_NODE_FUNCS(CoverInc) virtual const char* broken() const { BROKEN_RTN(!declp()->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_declp->clonep()) m_declp = m_declp->clonep(); } virtual void dump(ostream& str); virtual int instrCount() const { return 1+2*instrCountLd(); } virtual V3Hash sameHash() const { return V3Hash(declp()); } virtual bool same(const AstNode* samep) const { return declp() == static_cast(samep)->declp(); } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isOutputter() const { return true; } // but isPure() true AstCoverDecl* declp() const { return m_declp; } // Where defined }; class AstCoverToggle : public AstNodeStmt { // Toggle analysis of given signal // Parents: MODULE // Children: AstCoverInc, orig var, change det var public: AstCoverToggle(FileLine* fl, AstCoverInc* incp, AstNode* origp, AstNode* changep) : AstNodeStmt(fl) { setOp1p(incp); setOp2p(origp); setOp3p(changep); } ASTNODE_NODE_FUNCS(CoverToggle) virtual int instrCount() const { return 3+instrCountBranch()+instrCountLd(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return true; } virtual bool isOutputter() const { return false; } // Though the AstCoverInc under this is an outputter // but isPure() true AstCoverInc* incp() const { return op1p()->castCoverInc(); } void incp(AstCoverInc* nodep) { setOp1p(nodep); } AstNode* origp() const { return op2p(); } AstNode* changep() const { return op3p(); } }; class AstGenCase : public AstNodeCase { // Generate Case statement // Parents: {statement list} // exprp Children: MATHs // casesp Children: CASEITEMs public: AstGenCase(FileLine* fileline, AstNode* exprp, AstNode* casesp) : AstNodeCase(fileline, exprp, casesp) { } ASTNODE_NODE_FUNCS(GenCase) }; class AstCase : public AstNodeCase { // Case statement // Parents: {statement list} // exprp Children: MATHs // casesp Children: CASEITEMs private: VCaseType m_casex; // 0=case, 1=casex, 2=casez bool m_fullPragma; // Synthesis full_case bool m_parallelPragma; // Synthesis parallel_case bool m_uniquePragma; // unique case bool m_unique0Pragma; // unique0 case bool m_priorityPragma; // priority case public: AstCase(FileLine* fileline, VCaseType casex, AstNode* exprp, AstNode* casesp) : AstNodeCase(fileline, exprp, casesp) { m_casex=casex; m_fullPragma=false; m_parallelPragma=false; m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false; } ASTNODE_NODE_FUNCS(Case) virtual string verilogKwd() const { return casez()?"casez":casex()?"casex":"case"; } virtual bool same(const AstNode* samep) const { return m_casex==static_cast(samep)->m_casex; } bool casex() const { return m_casex==VCaseType::CT_CASEX; } bool casez() const { return m_casex==VCaseType::CT_CASEZ; } bool caseInside() const { return m_casex==VCaseType::CT_CASEINSIDE; } bool caseSimple() const { return m_casex==VCaseType::CT_CASE; } void caseInsideSet() { m_casex=VCaseType::CT_CASEINSIDE; } bool fullPragma() const { return m_fullPragma; } void fullPragma(bool flag) { m_fullPragma=flag; } bool parallelPragma() const { return m_parallelPragma; } void parallelPragma(bool flag) { m_parallelPragma=flag; } bool uniquePragma() const { return m_uniquePragma; } void uniquePragma(bool flag) { m_uniquePragma=flag; } bool unique0Pragma() const { return m_unique0Pragma; } void unique0Pragma(bool flag) { m_unique0Pragma=flag; } bool priorityPragma() const { return m_priorityPragma; } void priorityPragma(bool flag) { m_priorityPragma=flag; } }; class AstCaseItem : public AstNode { // Single item of a case statement // Parents: CASE // condsp Children: MATH (Null condition used for default block) // bodysp Children: Statements private: bool m_ignoreOverlap; // Default created by assertions; ignore overlaps public: AstCaseItem(FileLine* fileline, AstNode* condsp, AstNode* bodysp) : AstNode(fileline) { addNOp1p(condsp); addNOp2p(bodysp); m_ignoreOverlap = false; } ASTNODE_NODE_FUNCS(CaseItem) virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } AstNode* condsp() const { return op1p(); } // op1= list of possible matching expressions AstNode* bodysp() const { return op2p(); } // op2= what to do void condsp(AstNode* nodep) { setOp1p(nodep); } void addBodysp(AstNode* newp) { addOp2p(newp); } bool isDefault() const { return condsp()==NULL; } bool ignoreOverlap() const { return m_ignoreOverlap; } void ignoreOverlap(bool flag) { m_ignoreOverlap = flag; } }; class AstSFormatF : public AstNode { // Convert format to string, generally under an AstDisplay or AstSFormat // Also used as "real" function for /*verilator sformat*/ functions string m_text; bool m_hidden; // Under display, etc bool m_hasFormat; // Has format code public: class NoFormat {}; AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp) : AstNode(fl), m_text(text), m_hidden(hidden), m_hasFormat(true) { dtypeSetString(); addNOp1p(exprsp); addNOp2p(NULL); } AstSFormatF(FileLine* fl, NoFormat, AstNode* exprsp) : AstNode(fl), m_text(""), m_hidden(true), m_hasFormat(false) { dtypeSetString(); addNOp1p(exprsp); addNOp2p(NULL); } ASTNODE_NODE_FUNCS(SFormatF) virtual string name() const { return m_text; } virtual int instrCount() const { return instrCountPli(); } virtual V3Hash sameHash() const { return V3Hash(text()); } virtual bool hasDType() const { return true; } virtual bool same(const AstNode* samep) const { return text()==static_cast(samep)->text(); } virtual string verilogKwd() const { return "$sformatf"; } void addExprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output AstNode* exprsp() const { return op1p(); } // 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; } void hasFormat(bool flag) { m_hasFormat=flag; } bool hasFormat() const { return m_hasFormat; } }; class AstDisplay : public AstNodeStmt { // Parents: stmtlist // Children: file which must be a varref // Children: SFORMATF to generate print string private: AstDisplayType m_displayType; public: AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp) : AstNodeStmt (fileline) { setOp1p(new AstSFormatF(fileline,text,true,exprsp)); setNOp3p(filep); m_displayType = dispType; } AstDisplay(FileLine* fileline, AstDisplayType dispType, AstNode* filep, AstNode* exprsp) : AstNodeStmt (fileline) { setOp1p(new AstSFormatF(fileline, AstSFormatF::NoFormat(), exprsp)); setNOp3p(filep); m_displayType = dispType; } ASTNODE_NODE_FUNCS(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(const AstNode* samep) const { return displayType()==static_cast(samep)->displayType(); } virtual int instrCount() const { return instrCountPli(); } AstDisplayType displayType() const { return m_displayType; } void displayType(AstDisplayType type) { m_displayType = type; } bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter AstSFormatF* fmtp() const { return op1p()->castSFormatF(); } AstNode* filep() const { return op3p(); } void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); } }; class AstSFormat : public AstNodeStmt { // Parents: statement container // Children: string to load // Children: SFORMATF to generate print string public: AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp) : AstNodeStmt (fileline) { setOp1p(new AstSFormatF(fileline,text,true,exprsp)); setOp3p(lhsp); } ASTNODE_NODE_FUNCS(SFormat) 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(const AstNode* samep) const { return true; } void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter AstSFormatF* fmtp() const { return op1p()->castSFormatF(); } AstNode* lhsp() const { return op3p(); } void lhsp(AstNode* nodep) { setOp3p(nodep); } }; class AstSysIgnore : public AstNodeStmt { // Parents: stmtlist // Children: varrefs or exprs public: AstSysIgnore(FileLine* fileline, AstNode* exprsp) : AstNodeStmt (fileline) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(SysIgnore) 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(); } // op1 = Expressions to output void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output }; class AstFClose : public AstNodeStmt { // Parents: stmtlist // Children: file which must be a varref public: AstFClose(FileLine* fileline, AstNode* filep) : AstNodeStmt (fileline) { setNOp2p(filep); } ASTNODE_NODE_FUNCS(FClose) 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(const AstNode* samep) const { return true; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } }; class AstFOpen : public AstNodeStmt { // Although a system function in IEEE, here a statement which sets the file pointer (MCD) public: AstFOpen(FileLine* fileline, AstNode* filep, AstNode* filenamep, AstNode* modep) : AstNodeStmt (fileline) { setOp1p(filep); setOp2p(filenamep); setOp3p(modep); } ASTNODE_NODE_FUNCS(FOpen) 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(const AstNode* samep) const { return true; } AstNode* filep() const { return op1p(); } AstNode* filenamep() const { return op2p(); } AstNode* modep() const { return op3p(); } }; class AstFFlush : public AstNodeStmt { // Parents: stmtlist // Children: file which must be a varref public: AstFFlush(FileLine* fileline, AstNode* filep) : AstNodeStmt (fileline) { setNOp2p(filep); } ASTNODE_NODE_FUNCS(FFlush) 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(const AstNode* samep) const { return true; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } }; class AstFScanF : public AstNodeMath { // Parents: expr // Children: file which must be a varref // Children: varrefs to load private: string m_text; public: AstFScanF(FileLine* fileline, const string& text, AstNode* filep, AstNode* exprsp) : AstNodeMath (fileline), m_text(text) { addNOp1p(exprsp); setNOp2p(filep); } ASTNODE_NODE_FUNCS(FScanF) 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(const AstNode* samep) const { return text()==static_cast(samep)->text(); } AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text=text; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } }; class AstSScanF : public AstNodeMath { // Parents: expr // Children: file which must be a varref // Children: varrefs to load private: string m_text; public: AstSScanF(FileLine* fileline, const string& text, AstNode* fromp, AstNode* exprsp) : AstNodeMath (fileline), m_text(text) { addNOp1p(exprsp); setOp2p(fromp); } ASTNODE_NODE_FUNCS(SScanF) 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(const AstNode* samep) const { return text()==static_cast(samep)->text(); } AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text=text; } AstNode* fromp() const { return op2p(); } void fromp(AstNode* nodep) { setOp2p(nodep); } }; class AstReadMem : public AstNodeStmt { private: bool m_isHex; // readmemh, not readmemb public: AstReadMem(FileLine* fileline, bool hex, AstNode* filenamep, AstNode* memp, AstNode* lsbp, AstNode* msbp) : AstNodeStmt (fileline), m_isHex(hex) { setOp1p(filenamep); setOp2p(memp); setNOp3p(lsbp); setNOp4p(msbp); } ASTNODE_NODE_FUNCS(ReadMem) 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(const AstNode* samep) const { return isHex()==static_cast(samep)->isHex(); } bool isHex() const { return m_isHex; } AstNode* filenamep() const { return op1p(); } AstNode* memp() const { return op2p(); } AstNode* lsbp() const { return op3p(); } AstNode* msbp() const { return op4p(); } }; class AstSystemT : public AstNodeStmt { // $system used as task public: AstSystemT(FileLine* fileline, AstNode* lhsp) : AstNodeStmt (fileline) { setOp1p(lhsp); } ASTNODE_NODE_FUNCS(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(const AstNode* samep) const { return true; } AstNode* lhsp() const { return op1p(); } }; class AstSystemF : public AstNodeMath { // $system used as function public: AstSystemF(FileLine* fileline, AstNode* lhsp) : AstNodeMath (fileline) { setOp1p(lhsp); } ASTNODE_NODE_FUNCS(SystemF) 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(const AstNode* samep) const { return true; } AstNode* lhsp() const { return op1p(); } }; class AstValuePlusArgs : public AstNodeMath { // Parents: expr // Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs public: AstValuePlusArgs(FileLine* fileline, AstNode* searchp, AstNode* outp) : AstNodeMath (fileline) { setOp1p(searchp); setOp2p(outp); } ASTNODE_NODE_FUNCS(ValuePlusArgs) virtual string verilogKwd() const { return "$value$plusargs"; } virtual string emitVerilog() { return "%f$value$plusargs(%l, %k%r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool cleanOut() { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } AstNode* searchp() const { return op1p(); } // op1 = Search expression void searchp(AstNode* nodep) { setOp1p(nodep); } AstNode* outp() const { return op2p(); } // op2 = Expressions to output void outp(AstNode* nodep) { setOp2p(nodep); } }; class AstTestPlusArgs : public AstNodeMath { // Parents: expr // Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs private: string m_text; public: AstTestPlusArgs(FileLine* fileline, const string& text) : AstNodeMath (fileline), m_text(text) { } ASTNODE_NODE_FUNCS(TestPlusArgs) 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(const AstNode* samep) const { return text() == static_cast(samep)->text(); } string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text=text; } }; class AstGenFor : public AstNodeFor { public: AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp, AstNode* incsp, AstNode* bodysp) : AstNodeFor(fileline, initsp, condp, incsp, bodysp) { } ASTNODE_NODE_FUNCS(GenFor) }; class AstForeach : public AstNodeStmt { public: AstForeach(FileLine* fileline, AstNode* arrayp, AstNode* varsp, AstNode* bodysp) : AstNodeStmt(fileline) { setOp1p(arrayp); addNOp2p(varsp); addNOp4p(bodysp); } ASTNODE_NODE_FUNCS(Foreach) AstNode* arrayp() const { return op1p(); } // op1= array AstNode* varsp() const { return op2p(); } // op2= variable index list AstNode* bodysp() const { return op4p(); } // 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(const AstNode* samep) const { return true; } }; class AstRepeat : public AstNodeStmt { public: AstRepeat(FileLine* fileline, AstNode* countp, AstNode* bodysp) : AstNodeStmt(fileline) { setOp2p(countp); addNOp3p(bodysp); } ASTNODE_NODE_FUNCS(Repeat) AstNode* countp() const { return op2p(); } // op2= condition to continue AstNode* bodysp() const { return op3p(); } // 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(const AstNode* samep) const { return true; } }; class AstWhile : public AstNodeStmt { public: AstWhile(FileLine* fileline, AstNode* condp, AstNode* bodysp, AstNode* incsp=NULL) : AstNodeStmt(fileline) { setOp2p(condp); addNOp3p(bodysp); addNOp4p(incsp); } ASTNODE_NODE_FUNCS(While) AstNode* precondsp() const { return op1p(); } // op1= prepare statements for condition (exec every loop) AstNode* condp() const { return op2p(); } // op2= condition to continue AstNode* bodysp() const { return op3p(); } // op3= body of loop AstNode* incsp() const { return op4p(); } // 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(const AstNode* samep) const { return true; } virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here }; class AstBreak : public AstNodeStmt { public: explicit AstBreak(FileLine* fileline) : AstNodeStmt (fileline) {} ASTNODE_NODE_FUNCS(Break) virtual string verilogKwd() const { return "break"; }; virtual V3Hash sameHash() const { return V3Hash(); } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; class AstContinue : public AstNodeStmt { public: explicit AstContinue(FileLine* fileline) : AstNodeStmt (fileline) {} ASTNODE_NODE_FUNCS(Continue) virtual string verilogKwd() const { return "continue"; }; virtual V3Hash sameHash() const { return V3Hash(); } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; class AstDisable : public AstNodeStmt { private: string m_name; // Name of block public: AstDisable(FileLine* fileline, const string& name) : AstNodeStmt(fileline), m_name(name) {} ASTNODE_NODE_FUNCS(Disable) virtual string name() const { return m_name; } // * = Block name void name(const string& flag) { m_name=flag; } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; class AstReturn : public AstNodeStmt { public: AstReturn(FileLine* fileline, AstNode* lhsp=NULL) : AstNodeStmt (fileline) { setNOp1p(lhsp); } ASTNODE_NODE_FUNCS(Return) virtual string verilogKwd() const { return "return"; }; virtual V3Hash sameHash() const { return V3Hash(); } AstNode* lhsp() const { return op1p(); } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; class AstGenIf : public AstNodeIf { public: AstGenIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp) : AstNodeIf(fileline, condp, ifsp, elsesp) { } ASTNODE_NODE_FUNCS(GenIf) }; class AstIf : public AstNodeIf { private: bool m_uniquePragma; // unique case bool m_unique0Pragma; // unique0 case bool m_priorityPragma; // priority case public: AstIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp=NULL) : AstNodeIf(fileline, condp, ifsp, elsesp) { m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false; } ASTNODE_NODE_FUNCS(If) bool uniquePragma() const { return m_uniquePragma; } void uniquePragma(bool flag) { m_uniquePragma=flag; } bool unique0Pragma() const { return m_unique0Pragma; } void unique0Pragma(bool flag) { m_unique0Pragma=flag; } bool priorityPragma() const { return m_priorityPragma; } void priorityPragma(bool flag) { m_priorityPragma=flag; } }; class AstJumpLabel : public AstNodeStmt { // Jump point declaration // Separate from AstJumpGo; as a declaration can't be deleted // Parents: {statement list} // Children: {statement list, with JumpGo below} private: int m_labelNum; // Set by V3EmitCSyms to tell final V3Emit what to increment public: AstJumpLabel(FileLine* fl, AstNode* stmtsp) : AstNodeStmt(fl) ,m_labelNum(0) { addNOp1p(stmtsp); } virtual int instrCount() const { return 0; } ASTNODE_NODE_FUNCS(JumpLabel) virtual bool maybePointedTo() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } // op1 = Statements AstNode* stmtsp() const { return op1p(); } // op1 = List of statements void addStmtsp(AstNode* nodep) { addNOp1p(nodep); } int labelNum() const { return m_labelNum; } void labelNum(int flag) { m_labelNum=flag; } }; class AstJumpGo : public AstNodeStmt { // Jump point; branch up to the JumpLabel // Parents: {statement list} private: AstJumpLabel* m_labelp; // [After V3Jump] Pointer to declaration public: AstJumpGo(FileLine* fl, AstJumpLabel* labelp) : AstNodeStmt(fl) { m_labelp = labelp; } ASTNODE_NODE_FUNCS(JumpGo) virtual const char* broken() const { BROKEN_RTN(!labelp()->brokeExistsAbove()); return NULL; } virtual void cloneRelink() { if (m_labelp->clonep()) m_labelp = m_labelp->clonep(); } virtual void dump(ostream& str); virtual int instrCount() const { return instrCountBranch(); } virtual V3Hash sameHash() const { return V3Hash(labelp()); } virtual bool same(const AstNode* samep) const { // Also same if identical tree structure all the way down, but hard to detect return labelp() == static_cast(samep)->labelp(); } virtual bool isGateOptimizable() const { return false; } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks AstJumpLabel* labelp() const { return m_labelp; } }; class AstUntilStable : public AstNodeStmt { // Quasi-while loop until given signals are stable // Parents: CFUNC (generally) // Children: VARREF, statements public: AstUntilStable(FileLine* fileline, AstVarRef* stablesp, AstNode* bodysp) : AstNodeStmt(fileline) { addNOp2p(stablesp); addNOp3p(bodysp); } ASTNODE_NODE_FUNCS(UntilStable) AstVarRef* stablesp() const { return op2p()->castVarRef(); } // op2= list of variables that must become stable AstNode* bodysp() const { return op3p(); } // 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(const AstNode* samep) const { return true; } }; class AstChangeXor : public AstNodeBiComAsv { // A comparison to determine change detection, common & must be fast. // Returns 32-bit or 64-bit value where 0 indicates no change. // Parents: OR or LOGOR // Children: VARREF public: AstChangeXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeSetUInt32(); // Always used on, and returns word entities } ASTNODE_NODE_FUNCS(ChangeXor) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstChangeXor(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opChangeXor(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f^ %r)"; } virtual string emitC() { return "VL_CHANGEXOR_%li(%lw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "^"; } virtual bool cleanOut() {return false;} // Lclean && Rclean virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs(); } }; class AstChangeDet : public AstNodeStmt { // A comparison to determine change detection, common & must be fast. private: bool m_clockReq; // Type of detection public: // Null lhs+rhs used to indicate change needed with no spec vars AstChangeDet(FileLine* fl, AstNode* lhsp, AstNode* rhsp, bool clockReq) : AstNodeStmt(fl) { setNOp1p(lhsp); setNOp2p(rhsp); m_clockReq=clockReq; } ASTNODE_NODE_FUNCS(ChangeDet) 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(const AstNode* samep) const { return true; } }; class AstBegin : public AstNode { // A Begin/end named block, only exists shortly after parsing until linking // Parents: statement // Children: statements private: string m_name; // Name of block bool m_unnamed; // Originally unnamed bool m_generate; // Underneath a generate public: // Node that simply puts name into the output stream AstBegin(FileLine* fileline, const string& name, AstNode* stmtsp, bool generate=false) : AstNode(fileline) , m_name(name) { addNOp1p(stmtsp); m_unnamed = (name==""); m_generate = generate; } ASTNODE_NODE_FUNCS(Begin) 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(); } // op1 = List of statements void addStmtsp(AstNode* nodep) { addNOp1p(nodep); } AstNode* genforp() const { return op2p(); } // op2 = GENFOR, if applicable, // might NOT be a GenFor, as loop unrolling replaces with Begin void addGenforp(AstGenFor* nodep) { addOp2p(nodep); } bool unnamed() const { return m_unnamed; } void generate(bool flag) { m_generate = flag; } bool generate() const { return m_generate; } }; class AstInitial : public AstNode { public: AstInitial(FileLine* fl, AstNode* bodysp) : AstNode(fl) { addNOp1p(bodysp); } ASTNODE_NODE_FUNCS(Initial) AstNode* bodysp() const { return op1p(); } // op1 = Expressions to evaluate // Special accessors bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } }; class AstFinal : public AstNode { public: AstFinal(FileLine* fl, AstNode* bodysp) : AstNode(fl) { addNOp1p(bodysp); } ASTNODE_NODE_FUNCS(Final) AstNode* bodysp() const { return op1p(); } // op1 = Expressions to evaluate }; class AstInside : public AstNodeMath { public: AstInside(FileLine* fl, AstNode* exprp, AstNode* itemsp) : AstNodeMath(fl) { addOp1p(exprp); addOp2p(itemsp); dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Inside) AstNode* exprp() const { return op1p(); } // op1 = LHS expression to compare with AstNode* itemsp() const { return op2p(); } // op2 = RHS, possibly a list of expr or AstInsideRange virtual string emitVerilog() { return "%l inside { %r }"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return false; } // NA }; class AstInsideRange : public AstNodeMath { public: AstInsideRange(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeMath(fl) { addOp1p(lhsp); addOp2p(rhsp); } ASTNODE_NODE_FUNCS(InsideRange) AstNode* lhsp() const { return op1p(); } // op1 = LHS AstNode* rhsp() const { return op2p(); } // op2 = RHS virtual string emitVerilog() { return "[%l:%r]"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return false; } // NA }; class AstInitArray : public AstNode { // Set a var to a large list of values // The values must be in sorted order, and not exceed the size of the var's array. // The first value on the initsp() list is for the lo() index of the array. // If default is specified, the vector may be sparse, and not provide each value. // Parents: ASTVAR::init() // Children: CONSTs... deque m_indices; // Which array index each entry in the list is for (if defaultp) public: AstInitArray(FileLine* fl, AstNodeArrayDType* newDTypep, AstNode* defaultp) : AstNode(fl) { dtypep(newDTypep); addNOp1p(defaultp); } ASTNODE_NODE_FUNCS(InitArray) AstNode* defaultp() const { return op1p(); } // op1 = Default if sparse void defaultp(AstNode* newp) { setOp1p(newp); } AstNode* initsp() const { return op2p(); } // op2 = Initial value expressions void addValuep(AstNode* newp) { addIndexValuep(m_indices.size(), newp); } void addIndexValuep(uint32_t index, AstNode* newp) { // Must insert in sorted order if (!m_indices.empty()) UASSERT(index > m_indices.back(), "InitArray adding index <= previous index"); m_indices.push_back(index); addOp2p(newp); } void addFrontValuep(AstNode* newp) { // Add to front of list, e.g. index 0. // e.g. 0:100, 1:101 when addFront(200), get 0:200, 1:100, 2:101 initsp()->addHereThisAsNext(newp); m_indices.push_back(m_indices.size()); } int posIndex(int listPos) { UASSERT (listPos < (int)m_indices.size(), "InitArray past end of indices list"); return m_indices[listPos]; } virtual bool hasDType() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return m_indices == static_cast(samep)->m_indices; } }; class AstPragma : public AstNode { private: AstPragmaType m_pragType; // Type of pragma public: // Pragmas don't result in any output code, they're just flags that affect // other processing in verilator. AstPragma(FileLine* fl, AstPragmaType pragType) : AstNode(fl) { m_pragType = pragType; } ASTNODE_NODE_FUNCS(Pragma) 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(const AstNode* samep) const { return pragType() == static_cast(samep)->pragType(); } }; class AstStop : public AstNodeStmt { public: explicit AstStop(FileLine* fl) : AstNodeStmt(fl) {} ASTNODE_NODE_FUNCS(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(const AstNode* samep) const { return fileline() == samep->fileline(); } }; class AstFinish : public AstNodeStmt { public: explicit AstFinish(FileLine* fl) : AstNodeStmt(fl) {} ASTNODE_NODE_FUNCS(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(const AstNode* samep) const { return fileline() == samep->fileline(); } }; class AstTraceDecl : public AstNodeStmt { // Trace point declaration // Separate from AstTraceInc; as a declaration can't be deleted // Parents: {statement list} // Children: none private: string m_showname; // Name of variable uint32_t m_code; // Trace identifier code; converted to ASCII by trace routines VNumRange m_bitRange; // Property of var the trace details VNumRange m_arrayRange; // Property of var the trace details uint32_t m_codeInc; // Code increment public: AstTraceDecl(FileLine* fl, const string& showname, AstNode* valuep, const VNumRange& bitRange, const VNumRange& arrayRange) : AstNodeStmt(fl) , m_showname(showname), m_bitRange(bitRange), m_arrayRange(arrayRange) { dtypeFrom(valuep); m_code = 0; m_codeInc = ((arrayRange.ranged() ? arrayRange.elements() : 1) * valuep->dtypep()->widthWords()); } virtual int instrCount() const { return 100; } // Large... ASTNODE_NODE_FUNCS(TraceDecl) virtual string name() const { return m_showname; } virtual bool maybePointedTo() const { return true; } virtual bool hasDType() const { return true; } virtual bool same(const AstNode* samep) const { return false; } string showname() const { return m_showname; } // * = Var name // Details on what we're tracing uint32_t code() const { return m_code; } void code(uint32_t code) { m_code=code; } uint32_t codeInc() const { return m_codeInc; } const VNumRange& bitRange() const { return m_bitRange; } const VNumRange& arrayRange() const { return m_arrayRange; } }; class AstTraceInc : public AstNodeStmt { // Trace point; incremental change detect and dump // Parents: {statement list} // Children: incremental value private: AstTraceDecl* m_declp; // [After V3Trace] Pointer to declaration public: AstTraceInc(FileLine* fl, AstTraceDecl* declp, AstNode* valuep) : AstNodeStmt(fl) { dtypeFrom(declp); m_declp = declp; addNOp2p(valuep); } ASTNODE_NODE_FUNCS(TraceInc) virtual const char* broken() const { BROKEN_RTN(!declp()->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_declp->clonep()) m_declp = m_declp->clonep(); } 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(const AstNode* samep) const { return declp() == static_cast(samep)->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(); } // 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(); } }; class AstActive : public AstNode { // Block of code with sensitivity activation // Parents: MODULE | CFUNC // Children: SENTREE, statements private: string m_name; AstSenTree* m_sensesp; public: AstActive(FileLine* fileline, const string& name, AstSenTree* sensesp) : AstNode(fileline) { m_name = name; // Copy it UASSERT(sensesp, "Sensesp required arg"); m_sensesp = sensesp; } ASTNODE_NODE_FUNCS(Active) 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(); UASSERT(m_sensesp, "Bad clone cross link: "<castSenTree(); } // op2 = Combo logic AstNode* stmtsp() const { return op2p(); } void addStmtsp(AstNode* nodep) { addOp2p(nodep); } // METHODS bool hasInitial() const { return m_sensesp->hasInitial(); } bool hasSettle() const { return m_sensesp->hasSettle(); } bool hasClocked() const { return m_sensesp->hasClocked(); } }; class AstAttrOf : public AstNode { private: // Return a value of a attribute, for example a LSB or array LSB of a signal AstAttrType m_attrType; // What sort of extraction public: AstAttrOf(FileLine* fl, AstAttrType attrtype, AstNode* fromp=NULL, AstNode* dimp=NULL) : AstNode(fl) { setNOp1p(fromp); setNOp2p(dimp); m_attrType = attrtype; } ASTNODE_NODE_FUNCS(AttrOf) AstNode* fromp() const { return op1p(); } AstNode* dimp() const { return op2p(); } AstAttrType attrType() const { return m_attrType; } virtual void dump(ostream& str=cout); }; class AstScopeName : public AstNodeMath { // For display %m and DPI context imports // Parents: DISPLAY // Children: TEXT private: bool m_dpiExport; // Is for dpiExport string scopeNameFormatter(AstText* textp) const; string scopePrettyNameFormatter(AstText* textp) const; public: explicit AstScopeName(FileLine* fl) : AstNodeMath(fl), m_dpiExport(false) { dtypeSetUInt64(); } ASTNODE_NODE_FUNCS(ScopeName) virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return m_dpiExport == static_cast(samep)->m_dpiExport; } virtual string emitVerilog() { return ""; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } AstText* scopeAttrp() const { return op1p()->castText(); } void scopeAttrp(AstNode* nodep) { addOp1p(nodep); } AstText* scopeEntrp() const { return op2p()->castText(); } void scopeEntrp(AstNode* nodep) { addOp2p(nodep); } string scopeSymName() const { return scopeNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children string scopeDpiName() const { return scopeNameFormatter(scopeEntrp()); } // Name for DPI import scope string scopePrettySymName() const { return scopePrettyNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children string scopePrettyDpiName() const { return scopePrettyNameFormatter(scopeEntrp()); } // Name for __Vscope variable including children bool dpiExport() const { return m_dpiExport; } void dpiExport(bool flag) { m_dpiExport=flag; } }; class AstUdpTable : public AstNode { public: AstUdpTable(FileLine* fl, AstNode* bodysp) : AstNode(fl) { addNOp1p(bodysp); } ASTNODE_NODE_FUNCS(UdpTable) AstUdpTableLine* bodysp() const { return op1p()->castUdpTableLine(); } // op1 = List of UdpTableLines }; class AstUdpTableLine : public AstNode { string m_text; public: AstUdpTableLine(FileLine* fl, const string& text) : AstNode(fl), m_text(text) {} ASTNODE_NODE_FUNCS(UdpTableLine) virtual string name() const { return m_text; } string text() const { return m_text; } }; //====================================================================== // non-ary ops class AstRand : public AstNodeTermop { // Return a random number, based upon width() private: bool m_reset; // Random reset, versus always random public: AstRand(FileLine* fl, AstNodeDType* dtp, bool reset) : AstNodeTermop(fl) { dtypep(dtp); m_reset=reset; } explicit AstRand(FileLine* fl) : AstNodeTermop(fl), m_reset(false) { } ASTNODE_NODE_FUNCS(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(const AstNode* samep) const { return true; } }; class AstTime : public AstNodeTermop { public: explicit AstTime(FileLine* fl) : AstNodeTermop(fl) { dtypeSetUInt64(); } ASTNODE_NODE_FUNCS(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(const AstNode* samep) const { return true; } }; class AstTimeD : public AstNodeTermop { public: explicit AstTimeD(FileLine* fl) : AstNodeTermop(fl) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(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(const AstNode* samep) const { return true; } }; class AstUCFunc : public AstNodeMath { // User's $c function // Perhaps this should be an AstNodeListop; but there's only one list math right now public: AstUCFunc(FileLine* fl, AstNode* exprsp) : AstNodeMath(fl) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(UCFunc) virtual bool cleanOut() { return false; } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } AstNode* bodysp() const { return op1p(); } // 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(const AstNode* samep) const { return true; } }; //====================================================================== // Unary ops class AstNegate : public AstNodeUniop { public: AstNegate(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Negate) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNegate(lhs); } virtual string emitVerilog() { return "%f(- %l)"; } virtual string emitC() { return "VL_NEGATE_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return true;} }; class AstNegateD : public AstNodeUniop { public: AstNegateD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(NegateD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNegateD(lhs); } virtual string emitVerilog() { return "%f(- %l)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "-"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstRedAnd : public AstNodeUniop { public: AstRedAnd(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(RedAnd) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedAnd(lhs); } virtual string emitVerilog() { return "%f(& %l)"; } virtual string emitC() { return "VL_REDAND_%nq%lq(%nw,%lw, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} }; class AstRedOr : public AstNodeUniop { public: AstRedOr(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(RedOr) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedOr(lhs); } virtual string emitVerilog() { return "%f(| %l)"; } virtual string emitC() { return "VL_REDOR_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} }; class AstRedXor : public AstNodeUniop { public: AstRedXor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(RedXor) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXor(lhs); } virtual string emitVerilog() { return "%f(^ %l)"; } virtual string emitC() { return "VL_REDXOR_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {int w = lhsp()->width(); return (w!=1 && w!=2 && w!=4 && w!=8 && w!=16); } virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return 1+V3Number::log2b(width()); } }; class AstRedXnor : public AstNodeUniop { // AstRedXnors are replaced with AstRedXors in V3Const. public: AstRedXnor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(RedXnor) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXnor(lhs); } virtual string emitVerilog() { return "%f(~^ %l)"; } virtual string emitC() { v3fatalSrc("REDXNOR should have became REDXOR"); return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return 1+V3Number::log2b(width()); } }; class AstLogNot : public AstNodeUniop { public: AstLogNot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogNot) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opLogNot(lhs); } virtual string emitVerilog() { return "%f(! %l)"; } virtual string emitC() { return "VL_LOGNOT_%nq%lq(%nw,%lw, %P, %li)"; } virtual string emitSimpleOperator() { return "!"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} }; class AstNot : public AstNodeUniop { public: AstNot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Not) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNot(lhs); } virtual string emitVerilog() { return "%f(~ %l)"; } virtual string emitC() { return "VL_NOT_%lq(%lW, %P, %li)"; } virtual string emitSimpleOperator() { return "~"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return true;} }; class AstExtend : public AstNodeUniop { // Expand a value into a wider entity by 0 extension. Width is implied from nodep->width() public: AstExtend(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} AstExtend(FileLine* fl, AstNode* lhsp, int width) : AstNodeUniop(fl, lhsp) { dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); } ASTNODE_NODE_FUNCS(Extend) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); } virtual string emitVerilog() { return "%l"; } virtual string emitC() { return "VL_EXTEND_%nq%lq(%nw,%lw, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts virtual int instrCount() const { return 0; } }; class AstExtendS : public AstNodeUniop { // Expand a value into a wider entity by sign extension. Width is implied from nodep->width() public: AstExtendS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} AstExtendS(FileLine* fl, AstNode* lhsp, int width) : AstNodeUniop(fl, lhsp) { // Important that widthMin be correct, as opExtend requires it after V3Expand dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); } ASTNODE_NODE_FUNCS(ExtendS) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opExtendS(lhs, lhsp()->widthMinV()); } virtual string emitVerilog() { return "%l"; } virtual string emitC() { return "VL_EXTENDS_%nq%lq(%nw,%lw, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts virtual int instrCount() const { return 0; } virtual bool signedFlavor() const { return true; } }; class AstSigned : public AstNodeUniop { // $signed(lhs) public: AstSigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { if (v3Global.assertDTypesResolved()) { v3fatalSrc("not coded to create after dtypes resolved"); } } ASTNODE_NODE_FUNCS(Signed) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); } virtual string emitVerilog() { return "%f$signed(%l)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return true;} // Eliminated before matters virtual int instrCount() const { return 0; } }; class AstUnsigned : public AstNodeUniop { // $unsigned(lhs) public: AstUnsigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { if (v3Global.assertDTypesResolved()) { v3fatalSrc("not coded to create after dtypes resolved"); } } ASTNODE_NODE_FUNCS(Unsigned) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); } virtual string emitVerilog() { return "%f$unsigned(%l)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return true;} // Eliminated before matters virtual int instrCount() const { return 0; } }; class AstRToIS : public AstNodeUniop { // $rtoi(lhs) public: AstRToIS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetSigned32(); } ASTNODE_NODE_FUNCS(RToIS) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRToIS(lhs); } virtual string emitVerilog() { return "%f$rtoi(%l)"; } virtual string emitC() { return "VL_RTOI_I_D(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstRToIRoundS : public AstNodeUniop { public: AstRToIRoundS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetSigned32(); } ASTNODE_NODE_FUNCS(RToIRoundS) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRToIRoundS(lhs); } virtual string emitVerilog() { return "%f$rtoi_rounded(%l)"; } virtual string emitC() { return "VL_RTOIROUND_I_D(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstIToRD : public AstNodeUniop { public: AstIToRD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(IToRD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIToRD(lhs); } virtual string emitVerilog() { return "%f$itor(%l)"; } virtual string emitC() { return "VL_ITOR_D_I(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstRealToBits : public AstNodeUniop { public: AstRealToBits(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetUInt64(); } ASTNODE_NODE_FUNCS(RealToBits) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRealToBits(lhs); } virtual string emitVerilog() { return "%f$realtobits(%l)"; } virtual string emitC() { return "VL_CVT_Q_D(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstBitsToRealD : public AstNodeUniop { public: AstBitsToRealD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(BitsToRealD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opBitsToRealD(lhs); } virtual string emitVerilog() { return "%f$bitstoreal(%l)"; } virtual string emitC() { return "VL_CVT_D_Q(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstCLog2 : public AstNodeUniop { public: AstCLog2(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(CLog2) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCLog2(lhs); } virtual string emitVerilog() { return "%f$clog2(%l)"; } virtual string emitC() { return "VL_CLOG2_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*16; } }; class AstCountOnes : public AstNodeUniop { // Number of bits set in vector public: AstCountOnes(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(CountOnes) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCountOnes(lhs); } virtual string emitVerilog() { return "%f$countones(%l)"; } virtual string emitC() { return "VL_COUNTONES_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*16; } }; class AstIsUnknown : public AstNodeUniop { // True if any unknown bits public: AstIsUnknown(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(IsUnknown) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIsUnknown(lhs); } virtual string emitVerilog() { return "%f$isunknown(%l)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} }; class AstOneHot : public AstNodeUniop { // True if only single bit set in vector public: AstOneHot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(OneHot) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot(lhs); } virtual string emitVerilog() { return "%f$onehot(%l)"; } virtual string emitC() { return "VL_ONEHOT_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*4; } }; class AstOneHot0 : public AstNodeUniop { // True if only single bit, or no bits set in vector public: AstOneHot0(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(OneHot0) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot0(lhs); } virtual string emitVerilog() { return "%f$onehot0(%l)"; } virtual string emitC() { return "VL_ONEHOT0_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*3; } }; class AstCast : public AstNode { // Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc public: AstCast(FileLine* fl, AstNode* lhsp, AstNodeDType* dtp) : AstNode(fl) { setOp1p(lhsp); setOp2p(dtp); dtypeFrom(dtp); } ASTNODE_NODE_FUNCS(Cast) virtual bool hasDType() const { return true; } virtual string emitVerilog() { return "((%d)'(%l))"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} AstNode* lhsp() const { return op1p(); } AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op2p()->castNodeDType(); } }; class AstCastParse : public AstNode { // Cast to appropriate type, where we haven't determined yet what the data type is public: AstCastParse(FileLine* fl, AstNode* lhsp, AstNode* dtp) : AstNode(fl) { setOp1p(lhsp); setOp2p(dtp); } ASTNODE_NODE_FUNCS(CastParse) virtual string emitVerilog() { return "((%d)'(%l))"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} AstNode* lhsp() const { return op1p(); } AstNode* dtp() const { return op2p(); } }; class AstCastSize : public AstNode { // Cast to specific size; signed/twostate inherited from lower element per IEEE public: AstCastSize(FileLine* fl, AstNode* lhsp, AstConst* rhsp) : AstNode(fl) { setOp1p(lhsp); setOp2p(rhsp); } ASTNODE_NODE_FUNCS(CastSize) // No hasDType because widthing removes this node before the hasDType check virtual string emitVerilog() { return "((%r)'(%l))"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} AstNode* lhsp() const { return op1p(); } AstNode* rhsp() const { return op2p(); } }; class AstCCast : public AstNodeUniop { // Cast to C-based data type private: int m_size; public: AstCCast(FileLine* fl, AstNode* lhsp, int setwidth, int minwidth=-1) : AstNodeUniop(fl, lhsp) { m_size=setwidth; if (setwidth) { if (minwidth==-1) minwidth=setwidth; dtypeSetLogicSized(setwidth,minwidth,AstNumeric::UNSIGNED); } } AstCCast(FileLine* fl, AstNode* lhsp, AstNode* typeFromp) : AstNodeUniop(fl, lhsp) { dtypeFrom(typeFromp); m_size=width(); } ASTNODE_NODE_FUNCS(CCast) 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(const AstNode* samep) const { return size() == static_cast(samep)->size(); } virtual void dump(ostream& str=cout); // int size() const { return m_size; } }; class AstCvtPackString : public AstNodeUniop { // Convert to Verilator Packed String (aka verilog "string") public: AstCvtPackString(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetString(); } // Really, width should be dtypep -> STRING ASTNODE_NODE_FUNCS(CvtPackString) 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(const AstNode* samep) const { return true; } }; class AstFEof : public AstNodeUniop { public: AstFEof(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(FEof) virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; } virtual string emitVerilog() { return "%f$feof(%l)"; } virtual string emitC() { return "(%li ? feof(VL_CVT_I_FP(%li)) : true)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*16; } virtual bool isPure() const { return false; } // SPECIAL: $display has 'visual' ordering AstNode* filep() const { return lhsp(); } }; class AstFGetC : public AstNodeUniop { public: AstFGetC(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(FGetC) virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; } virtual string emitVerilog() { return "%f$fgetc(%l)"; } // Non-existent filehandle returns EOF virtual string emitC() { return "(%li ? fgetc(VL_CVT_I_FP(%li)) : -1)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*64; } virtual bool isPure() const { return false; } // SPECIAL: $display has 'visual' ordering AstNode* filep() const { return lhsp(); } }; class AstCeilD : public AstNodeUniop { public: AstCeilD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(CeilD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(ceil(lhs.toDouble())); } virtual string emitVerilog() { return "%f$ceil(%l)"; } virtual string emitC() { return "ceil(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstExpD : public AstNodeUniop { public: AstExpD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(ExpD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(exp(lhs.toDouble())); } virtual string emitVerilog() { return "%f$exp(%l)"; } virtual string emitC() { return "exp(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstFloorD : public AstNodeUniop { public: AstFloorD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(FloorD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(floor(lhs.toDouble())); } virtual string emitVerilog() { return "%f$floor(%l)"; } virtual string emitC() { return "floor(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstLogD : public AstNodeUniop { public: AstLogD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(LogD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(log(lhs.toDouble())); } virtual string emitVerilog() { return "%f$ln(%l)"; } virtual string emitC() { return "log(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstLog10D : public AstNodeUniop { public: AstLog10D(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(Log10D) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(log10(lhs.toDouble())); } virtual string emitVerilog() { return "%f$log10(%l)"; } virtual string emitC() { return "log10(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstSqrtD : public AstNodeUniop { public: AstSqrtD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(SqrtD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(sqrt(lhs.toDouble())); } virtual string emitVerilog() { return "%f$sqrt(%l)"; } virtual string emitC() { return "sqrt(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; //====================================================================== // Binary ops class AstLogOr : public AstNodeBiop { public: AstLogOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogOr) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLogOr(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogOr(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f|| %r)"; } virtual string emitC() { return "VL_LOGOR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "||"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } }; class AstLogAnd : public AstNodeBiop { public: AstLogAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogAnd) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLogAnd(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogAnd(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f&& %r)"; } virtual string emitC() { return "VL_LOGAND_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "&&"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } }; class AstLogIf : public AstNodeBiop { public: AstLogIf(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogIf) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLogIf(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogIf(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f-> %r)"; } virtual string emitC() { return "VL_LOGIF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "->"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } }; class AstLogIff : public AstNodeBiCom { public: AstLogIff(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogIff) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLogIff(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogIff(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<-> %r)"; } virtual string emitC() { return "VL_LOGIFF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "<->"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } }; class AstOr : public AstNodeBiComAsv { public: AstOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Or) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstOr(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opOr(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f| %r)"; } virtual string emitC() { return "VL_OR_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "|"; } virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean && Rclean virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstAnd : public AstNodeBiComAsv { public: AstAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(And) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAnd(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAnd(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f& %r)"; } virtual string emitC() { return "VL_AND_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "&"; } virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean || Rclean virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstXor : public AstNodeBiComAsv { public: AstXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Xor) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstXor(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXor(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f^ %r)"; } virtual string emitC() { return "VL_XOR_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "^"; } virtual bool cleanOut() {return false;} // Lclean && Rclean virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstXnor : public AstNodeBiComAsv { public: AstXnor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Xnor) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstXnor(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXnor(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f^ ~ %r)"; } virtual string emitC() { return "VL_XNOR_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "^ ~"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} }; class AstEq : public AstNodeBiCom { public: AstEq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Eq) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEq(this->fileline(), lhsp, rhsp); } static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstEq/AstEqD virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f== %r)"; } virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstEqD : public AstNodeBiCom { public: AstEqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(EqD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEqD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f== %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstEqN : public AstNodeBiCom { public: AstEqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(EqN) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqN(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEqN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f== %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstNeq : public AstNodeBiCom { public: AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Neq) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeq(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!= %r)"; } virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstNeqD : public AstNodeBiCom { public: AstNeqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(NeqD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeqD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeqD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstNeqN : public AstNodeBiCom { public: AstNeqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(NeqN) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeqN(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeqN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstLt : public AstNodeBiop { public: AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Lt) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLt(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLt(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f< %r)"; } virtual string emitC() { return "VL_LT_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "<"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstLtD : public AstNodeBiop { public: AstLtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LtD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLtD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f< %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "<"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstLtS : public AstNodeBiop { public: AstLtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LtS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLtS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f< %r)"; } virtual string emitC() { return "VL_LTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstLtN : public AstNodeBiop { public: AstLtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LtN) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLtN(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f< %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "<"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstGt : public AstNodeBiop { public: AstGt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Gt) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGt(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGt(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f> %r)"; } virtual string emitC() { return "VL_GT_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ">"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstGtD : public AstNodeBiop { public: AstGtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GtD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGtD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f> %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return ">"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstGtS : public AstNodeBiop { public: AstGtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GtS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGtS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f> %r)"; } virtual string emitC() { return "VL_GTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstGtN : public AstNodeBiop { public: AstGtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GtN) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGtN(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f> %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return ">"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstGte : public AstNodeBiop { public: AstGte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Gte) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGte(this->fileline(), lhsp, rhsp); } static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstGte/AstGteS/AstGteD virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGte(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>= %r)"; } virtual string emitC() { return "VL_GTE_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ">="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstGteD : public AstNodeBiop { public: AstGteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GteD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGteD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return ">="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstGteS : public AstNodeBiop { public: AstGteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GteS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGteS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>= %r)"; } virtual string emitC() { return "VL_GTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstGteN : public AstNodeBiop { public: AstGteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GteN) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGteN(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return ">="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstLte : public AstNodeBiop { public: AstLte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Lte) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLte(this->fileline(), lhsp, rhsp); } static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstLte/AstLteS/AstLteD virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLte(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<= %r)"; } virtual string emitC() { return "VL_LTE_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "<="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstLteD : public AstNodeBiop { public: AstLteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LteD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLteD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "<="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstLteS : public AstNodeBiop { public: AstLteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LteS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLteS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<= %r)"; } virtual string emitC() { return "VL_LTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstLteN : public AstNodeBiop { public: AstLteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LteN) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLteN(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "<="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstShiftL : public AstNodeBiop { public: AstShiftL(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0) : AstNodeBiop(fl, lhsp, rhsp) { if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(ShiftL) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstShiftL(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftL(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<< %r)"; } virtual string emitC() { return "VL_SHIFTL_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "<<"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} }; class AstShiftR : public AstNodeBiop { public: AstShiftR(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0) : AstNodeBiop(fl, lhsp, rhsp) { if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(ShiftR) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstShiftR(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftR(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>> %r)"; } virtual string emitC() { return "VL_SHIFTR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ">>"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} // LHS size might be > output size, so don't want to force size }; class AstShiftRS : public AstNodeBiop { // Shift right with sign extension, >>> operator // Output data type's width determines which bit is used for sign extension public: AstShiftRS(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0) : AstNodeBiop(fl, lhsp, rhsp) { // Important that widthMin be correct, as opExtend requires it after V3Expand if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::SIGNED); } } ASTNODE_NODE_FUNCS(ShiftRS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstShiftRS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftRS(lhs,rhs,lhsp()->widthMinV()); } virtual string emitVerilog() { return "%k(%l %f>>> %r)"; } virtual string emitC() { return "VL_SHIFTRS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstAdd : public AstNodeBiComAsv { public: AstAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Add) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAdd(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAdd(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f+ %r)"; } virtual string emitC() { return "VL_ADD_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "+"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} }; class AstAddD : public AstNodeBiComAsv { public: AstAddD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(AddD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAddD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAddD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f+ %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "+"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstSub : public AstNodeBiop { public: AstSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Sub) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstSub(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSub(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f- %r)"; } virtual string emitC() { return "VL_SUB_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "-"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} }; class AstSubD : public AstNodeBiop { public: AstSubD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(SubD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstSubD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSubD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f- %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "-"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstMul : public AstNodeBiComAsv { public: AstMul(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Mul) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstMul(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMul(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f* %r)"; } virtual string emitC() { return "VL_MUL_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "*"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountMul(); } }; class AstMulD : public AstNodeBiComAsv { public: AstMulD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(MulD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstMulD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f* %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "*"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstMulS : public AstNodeBiComAsv { public: AstMulS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(MulS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstMulS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f* %r)"; } virtual string emitC() { return "VL_MULS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountMul(); } virtual bool signedFlavor() const { return true; } }; class AstDiv : public AstNodeBiop { public: AstDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Div) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstDiv(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDiv(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f/ %r)"; } virtual string emitC() { return "VL_DIV_%nq%lq%rq(%lw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountDiv(); } }; class AstDivD : public AstNodeBiop { public: AstDivD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(DivD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstDivD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f/ %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "/"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDoubleDiv(); } virtual bool doubleFlavor() const { return true; } }; class AstDivS : public AstNodeBiop { public: AstDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(DivS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstDivS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f/ %r)"; } virtual string emitC() { return "VL_DIVS_%nq%lq%rq(%lw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountDiv(); } virtual bool signedFlavor() const { return true; } }; class AstModDiv : public AstNodeBiop { public: AstModDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(ModDiv) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstModDiv(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDiv(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f%% %r)"; } virtual string emitC() { return "VL_MODDIV_%nq%lq%rq(%lw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountDiv(); } }; class AstModDivS : public AstNodeBiop { public: AstModDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(ModDivS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstModDivS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDivS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f%% %r)"; } virtual string emitC() { return "VL_MODDIVS_%nq%lq%rq(%lw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountDiv(); } virtual bool signedFlavor() const { return true; } }; class AstPow : public AstNodeBiop { public: AstPow(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Pow) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPow(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPow(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "VL_POW_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*instrCountMul()*10; } }; class AstPowD : public AstNodeBiop { public: AstPowD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(PowD) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPowD(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "pow(%li,%ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDoubleDiv()*5; } virtual bool doubleFlavor() const { return true; } }; class AstPowSU : public AstNodeBiop { public: AstPowSU(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(PowSU) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPowSU(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowSU(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,0)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*instrCountMul()*10; } virtual bool signedFlavor() const { return true; } }; class AstPowSS : public AstNodeBiop { public: AstPowSS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(PowSS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPowSS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowSS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,1)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*instrCountMul()*10; } virtual bool signedFlavor() const { return true; } }; class AstPowUS : public AstNodeBiop { public: AstPowUS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(PowUS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPowUS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowUS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 0,1)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*instrCountMul()*10; } virtual bool signedFlavor() const { return true; } }; class AstEqCase : public AstNodeBiCom { public: AstEqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(EqCase) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqCase(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseEq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f=== %r)"; } virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstNeqCase : public AstNodeBiCom { public: AstNeqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(NeqCase) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeqCase(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseNeq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!== %r)"; } virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstEqWild : public AstNodeBiop { // Note wildcard operator rhs differs from lhs public: AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(EqWild) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqWild(this->fileline(), lhsp, rhsp); } static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstEqWild/AstEqD virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f==? %r)"; } virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstNeqWild : public AstNodeBiop { public: AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(NeqWild) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeqWild(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildNeq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!=? %r)"; } virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstConcat : public AstNodeBiop { // If you're looking for {#{}}, see AstReplicate public: AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { if (lhsp->dtypep() && rhsp->dtypep()) { dtypeSetLogicSized(lhsp->dtypep()->width()+rhsp->dtypep()->width(), lhsp->dtypep()->width()+rhsp->dtypep()->width(), AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(Concat) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstConcat(this->fileline(), lhsp, rhsp); } virtual string emitVerilog() { return "%f{%l, %k%r}"; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcat(lhs,rhs); } virtual string emitC() { return "VL_CONCAT_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } }; class AstConcatN : public AstNodeBiop { // String concatenate public: AstConcatN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetString(); } ASTNODE_NODE_FUNCS(ConcatN) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstConcatN(this->fileline(), lhsp, rhsp); } virtual string emitVerilog() { return "%f{%l, %k%r}"; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcatN(lhs,rhs); } virtual string emitC() { return "VL_CONCATN_NNN(%li, %ri)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstReplicate : public AstNodeBiop { // Also used as a "Uniop" flavor of Concat, e.g. "{a}" // Verilog {rhs{lhs}} - Note rhsp() is the replicate value, not the lhsp() private: void init() { if (lhsp()) { if (AstConst* constp=rhsp()->castConst()) { dtypeSetLogicSized(lhsp()->width()*constp->toUInt(), lhsp()->width()*constp->toUInt(), AstNumeric::UNSIGNED); } } } public: AstReplicate(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { init(); } AstReplicate(FileLine* fl, AstNode* lhsp, uint32_t repCount) : AstNodeBiop(fl, lhsp, new AstConst(fl, repCount)) { init(); } ASTNODE_NODE_FUNCS(Replicate) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstReplicate(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opRepl(lhs,rhs); } virtual string emitVerilog() { return "%f{%r{%k%l}}"; } virtual string emitC() { return "VL_REPLICATE_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } }; class AstReplicateN : public AstNodeBiop { // String replicate private: void init() { dtypeSetString(); } public: AstReplicateN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { init(); } AstReplicateN(FileLine* fl, AstNode* lhsp, uint32_t repCount) : AstNodeBiop(fl, lhsp, new AstConst(fl, repCount)) { init(); } ASTNODE_NODE_FUNCS(ReplicateN) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstReplicateN(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opReplN(lhs,rhs); } virtual string emitVerilog() { return "%f{%r{%k%l}}"; } virtual string emitC() { return "VL_REPLICATEN_NN%rq(0,0,%rw, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } virtual bool stringFlavor() const { return true; } }; class AstStreamL : public AstNodeStream { // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp() public: AstStreamL(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStream(fl, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(StreamL) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstStreamL(this->fileline(), lhsp, rhsp); } virtual string emitVerilog() { return "%f{ << %r %k{%l} }"; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opStreamL(lhs,rhs); } virtual string emitC() { return "VL_STREAML_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } }; class AstStreamR : public AstNodeStream { // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp() public: AstStreamR(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStream(fl, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(StreamR) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstStreamR(this->fileline(), lhsp, rhsp); } virtual string emitVerilog() { return "%f{ >> %r %k{%l} }"; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAssign(lhs); } virtual string emitC() { return isWide() ? "VL_ASSIGN_W(%nw, %P, %li)" : "%li"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } }; class AstBufIf1 : public AstNodeBiop { // lhs is enable, rhs is data to drive // Note unlike the Verilog bufif1() UDP, this allows any width; each lhsp bit enables respective rhsp bit public: AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(BufIf1) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstBufIf1(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opBufIf1(lhs,rhs); } virtual string emitVerilog() { return "bufif(%r,%l)"; } virtual string emitC() { V3ERROR_NA; return "";} // Lclean || Rclean virtual string emitSimpleOperator() { V3ERROR_NA; return "";} // Lclean || Rclean virtual bool cleanOut() {V3ERROR_NA; return "";} // Lclean || Rclean virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstFGetS : public AstNodeBiop { public: AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(FGetS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstFGetS(this->fileline(), lhsp, rhsp); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; } virtual string emitVerilog() { return "%f$fgets(%l,%r)"; } virtual string emitC() { return "VL_FGETS_%nqX%rq(%lw, %P, &(%li), %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*64; } AstNode* strgp() const { return lhsp(); } AstNode* filep() const { return rhsp(); } }; class AstPattern : public AstNodeMath { // Verilog '{a,b,c,d...} // Parents: AstNodeAssign, AstPattern, ... // Children: expression, AstPattern, AstPatReplicate public: AstPattern(FileLine* fl, AstNode* itemsp) : AstNodeMath(fl) { addNOp2p(itemsp); } ASTNODE_NODE_FUNCS(Pattern) 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); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc }; class AstPatMember : public AstNodeMath { // Verilog '{a} or '{a{b}} // Parents: AstPattern // Children: expression, AstPattern, replication count private: bool m_default; public: AstPatMember(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* repp) : AstNodeMath(fl) { addOp1p(lhsp), setNOp2p(keyp), setNOp3p(repp); m_default = false; } ASTNODE_NODE_FUNCS(PatMember) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; } virtual string emitVerilog() { return lhssp()?"%f{%r{%k%l}}":"%l"; } virtual string emitC() { V3ERROR_NA; return "";} virtual string emitSimpleOperator() { V3ERROR_NA; return "";} virtual bool cleanOut() {V3ERROR_NA; return "";} virtual int instrCount() const { return widthInstrs()*2; } AstNode* lhssp() const { return op1p(); } // op1 = expression to assign or another AstPattern (list if replicated) AstNode* keyp() const { return op2p(); } // op2 = assignment key (Const, id Text) AstNode* repp() const { return op3p(); } // op3 = replication count, or NULL for count 1 bool isDefault() const { return m_default; } void isDefault(bool flag) { m_default = flag; } }; //====================================================================== // SysVerilog assertions class AstVAssert : public AstNodeStmt { // Verilog Assertion // Parents: {statement list} // Children: expression, if pass statements, if fail statements public: AstVAssert(FileLine* fl, AstNode* propp, AstNode* passsp, AstNode* failsp) : AstNodeStmt(fl) { addOp1p(propp); addNOp2p(passsp); addNOp3p(failsp); } ASTNODE_NODE_FUNCS(VAssert) virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } AstNode* propp() const { return op1p(); } // op1 = property AstNode* passsp() const { return op2p(); } // op2 = if passes AstNode* failsp() const { return op3p(); } // op3 = if fails }; //====================================================================== // Assertions class AstClocking : public AstNode { // Set default clock region // Parents: MODULE // Children: Assertions public: AstClocking(FileLine* fl, AstNodeSenItem* sensesp, AstNode* bodysp) : AstNode(fl) { addOp1p(sensesp); addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(Clocking) AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list AstNode* bodysp() const { return op2p(); } // op2 = Body }; //====================================================================== // PSL class AstPslClocked : public AstNode { // A clocked property // Parents: ASSERT|COVER (property) // Children: SENITEM, Properties public: AstPslClocked(FileLine* fl, AstNodeSenItem* sensesp, AstNode* disablep, AstNode* propp) : AstNode(fl) { addNOp1p(sensesp); addNOp2p(disablep); addOp3p(propp); } ASTNODE_NODE_FUNCS(PslClocked) virtual bool hasDType() const { return true; } // Used under PslCover, which expects a bool child AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list AstNode* disablep() const { return op2p(); } // op2 = disable AstNode* propp() const { return op3p(); } // op3 = property }; class AstPslCover : public AstNodeStmt { // Psl Cover // Parents: {statement list} // Children: expression, report string private: string m_name; // Name to report public: AstPslCover(FileLine* fl, AstNode* propp, AstNode* stmtsp, const string& name="") : AstNodeStmt(fl) , m_name(name) { addOp1p(propp); addNOp4p(stmtsp); } ASTNODE_NODE_FUNCS(PslCover) virtual string name() const { return m_name; } // * = Var name virtual V3Hash sameHash() const { return V3Hash(name()); } virtual bool same(const AstNode* samep) const { return samep->name() == name(); } virtual void name(const string& name) { m_name = name; } AstNode* propp() const { return op1p(); } // op1 = property AstSenTree* sentreep() const { return op2p()->castSenTree(); } // op2 = clock domain void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain AstNode* coverincp() const { return op3p(); } // op3 = coverage node void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node AstNode* stmtsp() const { return op4p(); } // op4 = statements }; //====================================================================== // Text based nodes class AstText : public AstNodeText { private: bool m_tracking; // When emit, it's ok to parse the string to do indentation public: AstText(FileLine* fl, const string& textp, bool tracking=false) : AstNodeText(fl, textp), m_tracking(tracking) {} ASTNODE_NODE_FUNCS(Text) void tracking(bool flag) { m_tracking = flag; } bool tracking() const { return m_tracking; } }; class AstScCtor : public AstNodeText { public: AstScCtor(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScCtor) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScDtor : public AstNodeText { public: AstScDtor(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScDtor) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScHdr : public AstNodeText { public: AstScHdr(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScHdr) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScImp : public AstNodeText { public: AstScImp(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScImp) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScImpHdr : public AstNodeText { public: AstScImpHdr(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScImpHdr) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScInt : public AstNodeText { public: AstScInt(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScInt) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstUCStmt : public AstNodeStmt { // User $c statement public: AstUCStmt(FileLine* fl, AstNode* exprsp) : AstNodeStmt(fl) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(UCStmt) AstNode* bodysp() const { return op1p(); } // 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(const AstNode* samep) const { return true; } }; //====================================================================== // Emit C nodes class AstCFile : public AstNode { // C++ output file // Parents: NETLIST // Children: nothing yet private: string m_name; ///< Filename bool m_slow:1; ///< Compile w/o optimization bool m_source:1; ///< Source file (vs header file) bool m_support:1; ///< Support file (non systemc) public: AstCFile(FileLine* fl, const string& name) : AstNode(fl) { m_name = name; m_slow = false; m_source = false; m_support = false; } ASTNODE_NODE_FUNCS(CFile) virtual string name() const { return m_name; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } virtual void dump(ostream& str=cout); bool slow() const { return m_slow; } void slow(bool flag) { m_slow = flag; } bool source() const { return m_source; } void source(bool flag) { m_source = flag; } bool support() const { return m_support; } void support(bool flag) { m_support = flag; } }; class AstCFunc : public AstNode { // C++ function // Parents: MODULE/SCOPE // Children: VAR/statements private: AstCFuncType m_funcType; AstScope* m_scopep; string m_name; string m_cname; // C name, for dpiExports string m_rtnType; // void, bool, or other return type string m_argTypes; string m_ifdef; // #ifdef symbol around this function bool m_dontCombine:1; // V3Combine shouldn't compare this func tree, it's special bool m_skipDecl:1; // Don't declare it bool m_declPrivate:1; // Declare it private bool m_formCallTree:1; // Make a global function to call entire tree of functions bool m_slow:1; // Slow routine, called once or just at init time bool m_funcPublic:1; // From user public task/function bool m_isInline:1; // Inline function bool m_isStatic:1; // Function is declared static (no this) bool m_symProlog:1; // Setup symbol table for later instructions bool m_entryPoint:1; // User may call into this top level function bool m_pure:1; // Pure function bool m_dpiExport:1; // From dpi export bool m_dpiExportWrapper:1; // From dpi export; static function with dispatch table bool m_dpiImport:1; // From dpi import public: AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType="") : AstNode(fl) { m_funcType = AstCFuncType::FT_NORMAL; m_scopep = scopep; m_name = name; m_rtnType = rtnType; m_dontCombine = false; m_skipDecl = false; m_declPrivate = false; m_formCallTree = false; m_slow = false; m_funcPublic = false; m_isInline = false; m_isStatic = true; // Note defaults to static, later we see where thisp is needed m_symProlog = false; m_entryPoint = false; m_pure = false; m_dpiExport = false; m_dpiExportWrapper = false; m_dpiImport = false; } ASTNODE_NODE_FUNCS(CFunc) 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(const AstNode* samep) const { const AstCFunc* asamep = static_cast(samep); return ((funcType() == asamep->funcType()) && (rtnTypeVoid() == asamep->rtnTypeVoid()) && (argTypes() == asamep->argTypes()) && (!(dpiImport() || dpiExport()) || name() == asamep->name())); } // virtual void name(const string& name) { m_name = name; } virtual int instrCount() const { return dpiImport() ? instrCountDpi() : 0; } void cname(const string& name) { m_cname = name; } string cname() const { return m_cname; } AstScope* scopep() const { return m_scopep; } void scopep(AstScope* nodep) { m_scopep = nodep; } string rtnTypeVoid() const { return ((m_rtnType=="") ? "void" : m_rtnType); } bool dontCombine() const { return m_dontCombine || funcType()!=AstCFuncType::FT_NORMAL; } void dontCombine(bool flag) { m_dontCombine = flag; } bool dontInline() const { return dontCombine() || slow() || skipDecl() || funcPublic(); } bool skipDecl() const { return m_skipDecl; } void skipDecl(bool flag) { m_skipDecl = flag; } bool declPrivate() const { return m_declPrivate; } void declPrivate(bool flag) { m_declPrivate = flag; } bool formCallTree() const { return m_formCallTree; } void formCallTree(bool flag) { m_formCallTree = flag; } bool slow() const { return m_slow; } void slow(bool flag) { m_slow = flag; } bool funcPublic() const { return m_funcPublic; } void funcPublic(bool flag) { m_funcPublic = flag; } void argTypes(const string& str) { m_argTypes = str; } string argTypes() const { return m_argTypes; } void ifdef(const string& str) { m_ifdef = str; } string ifdef() const { return m_ifdef; } void funcType(AstCFuncType flag) { m_funcType = flag; } AstCFuncType funcType() const { return m_funcType; } bool isInline() const { return m_isInline; } void isInline(bool flag) { m_isInline = flag; } bool isStatic() const { return m_isStatic; } void isStatic(bool flag) { m_isStatic = flag; } bool symProlog() const { return m_symProlog; } void symProlog(bool flag) { m_symProlog = flag; } bool entryPoint() const { return m_entryPoint; } void entryPoint(bool flag) { m_entryPoint = flag; } bool pure() const { return m_pure; } void pure(bool flag) { m_pure = flag; } bool dpiExport() const { return m_dpiExport; } void dpiExport(bool flag) { m_dpiExport = flag; } bool dpiExportWrapper() const { return m_dpiExportWrapper; } void dpiExportWrapper(bool flag) { m_dpiExportWrapper = flag; } bool dpiImport() const { return m_dpiImport; } void dpiImport(bool flag) { m_dpiImport = flag; } // // If adding node accessors, see below emptyBody AstNode* argsp() const { return op1p(); } void addArgsp(AstNode* nodep) { addOp1p(nodep); } AstNode* initsp() const { return op2p(); } void addInitsp(AstNode* nodep) { addOp2p(nodep); } AstNode* stmtsp() const { return op3p(); } void addStmtsp(AstNode* nodep) { addOp3p(nodep); } AstNode* finalsp() const { return op4p(); } void addFinalsp(AstNode* nodep) { addOp4p(nodep); } // Special methods bool emptyBody() const { return argsp()==NULL && initsp()==NULL && stmtsp()==NULL && finalsp()==NULL; } }; class AstCCall : public AstNodeStmt { // C++ function call // Parents: Anything above a statement // Children: Args to the function private: AstCFunc* m_funcp; string m_hiername; string m_argTypes; public: AstCCall(FileLine* fl, AstCFunc* funcp, AstNode* argsp=NULL) : AstNodeStmt(fl) { m_funcp = funcp; addNOp1p(argsp); } AstCCall(AstCCall* oldp, AstCFunc* funcp) // Replacement form for V3Combine // Note this removes old attachments from the oldp : AstNodeStmt(oldp->fileline()) { m_funcp = funcp; m_hiername = oldp->hiername(); m_argTypes = oldp->argTypes(); if (oldp->argsp()) addNOp1p(oldp->argsp()->unlinkFrBackWithNext()); } ASTNODE_NODE_FUNCS(CCall) virtual void dump(ostream& str=cout); virtual void cloneRelink() { if (m_funcp && m_funcp->clonep()) { m_funcp = m_funcp->clonep(); }} 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(const AstNode* samep) const { const AstCCall* asamep = static_cast(samep); return (funcp() == asamep->funcp() && argTypes() == asamep->argTypes()); } AstNode* exprsp() const { return op1p(); } // 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(); } void addArgsp(AstNode* nodep) { addOp1p(nodep); } }; class AstCReturn : public AstNodeStmt { // C++ return from a function // Parents: CFUNC/statement // Children: Math public: AstCReturn(FileLine* fl, AstNode* lhsp) : AstNodeStmt(fl) { setOp1p(lhsp); } ASTNODE_NODE_FUNCS(CReturn) virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } // AstNode* lhsp() const { return op1p(); } }; class AstCMath : public AstNodeMath { private: bool m_cleanOut; public: // Emit C textual math function (like AstUCFunc) AstCMath(FileLine* fl, AstNode* exprsp) : AstNodeMath(fl), m_cleanOut(true) { addOp1p(exprsp); dtypeFrom(exprsp); } AstCMath(FileLine* fl, const string& textStmt, int setwidth, bool cleanOut=true) : AstNodeMath(fl), m_cleanOut(cleanOut) { addNOp1p(new AstText(fl, textStmt, true)); if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(CMath) 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(const AstNode* samep) const { return true; } void addBodysp(AstNode* nodep) { addNOp1p(nodep); } AstNode* bodysp() const { return op1p(); } // op1= expressions to print }; class AstCReset : public AstNodeStmt { //Reset variable at startup public: AstCReset(FileLine* fl, AstNode* exprsp) : AstNodeStmt(fl) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(CReset) virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } AstVarRef* varrefp() const { return op1p()->castVarRef(); } // op1= varref to reset }; class AstCStmt : public AstNodeStmt { // Emit C statement public: AstCStmt(FileLine* fl, AstNode* exprsp) : AstNodeStmt(fl) { addNOp1p(exprsp); } AstCStmt(FileLine* fl, const string& textStmt) : AstNodeStmt(fl) { addNOp1p(new AstText(fl, textStmt, true)); } ASTNODE_NODE_FUNCS(CStmt) virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } void addBodysp(AstNode* nodep) { addNOp1p(nodep); } AstNode* bodysp() const { return op1p(); } // op1= expressions to print }; //###################################################################### // Right below top class AstTypeTable : public AstNode { // Container for hash of standard data types // Children: NODEDTYPEs typedef map,AstBasicDType*> LogicMap; AstBasicDType* m_basicps[AstBasicDTypeKwd::_ENUM_MAX]; // enum { IDX0_LOGIC, IDX0_BIT, _IDX0_MAX }; LogicMap m_logicMap[_IDX0_MAX][AstNumeric::_ENUM_MAX]; // uses above IDX enums // typedef map DetailedMap; DetailedMap m_detailedMap; public: explicit AstTypeTable(FileLine* fl) : AstNode(fl) { for (int i=0; icastNodeDType();} // op1 = List of dtypes void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); } AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd); AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, int widthMin, AstNumeric numeric); AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, VNumRange range, int widthMin, AstNumeric numeric); AstBasicDType* findInsertSameDType(AstBasicDType* nodep); void clearCache(); void repairCache(); virtual void dump(ostream& str=cout); }; //###################################################################### // Top class AstNetlist : public AstNode { // All modules are under this single top node. // Parents: none // Children: MODULEs & CFILEs private: AstTypeTable* m_typeTablep; // Reference to top type table, for faster lookup AstPackage* m_dollarUnitPkgp; public: AstNetlist() : AstNode(new FileLine("AstRoot",0)) { m_typeTablep = NULL; m_dollarUnitPkgp = NULL; } ASTNODE_NODE_FUNCS(Netlist) 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.916/src/VlcTop.cpp0000664000177100017500000002067113205574202016230 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: top implementation // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "V3Error.h" #include "V3Os.h" #include "VlcOptions.h" #include "VlcTop.h" #include #include #include //###################################################################### void VlcTop::readCoverage(const string& filename, bool nonfatal) { UINFO(2,"readCoverage "<= VlcBuckets::sufficient()) { points().pointNumber(pointnum).testsCoveringInc(); testp->buckets().addData(pointnum, hits); } } } } } void VlcTop::writeCoverage(const string& filename) { UINFO(2,"writeCoverage "<second); os <<"C '"<computrons() != rhsp->computrons()) { return lhsp->computrons() < rhsp->computrons(); } return lhsp->bucketsCovered() > rhsp->bucketsCovered(); } }; void VlcTop::rank() { UINFO(2,"rank...\n"); vluint64_t nextrank=1; // Sort by computrons, so fast tests get selected first vector bytime; for (VlcTests::ByName::iterator it=m_tests.begin(); it!=m_tests.end(); ++it) { VlcTest* testp = *it; if (testp->bucketsCovered()) { // else no points, so can't help us bytime.push_back(*it); } } sort(bytime.begin(), bytime.end(), CmpComputrons()); // Sort the vector VlcBuckets remaining; for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) { VlcPoint* pointp = &points().pointNumber(it->second); // If any tests hit this point, then we'll need to cover it. if (pointp->testsCovering()) { remaining.addData(pointp->pointNum(), 1); } } // Additional Greedy algorithm // O(n^2) Ouch. Probably the thing to do is randomize the order of data // then hierarchically solve a small subset of tests, and take resulting // solution and move up to larger subset of tests. (Aka quick sort.) while (1) { if (debug()) { UINFO(9,"Left on iter"<::iterator it=bytime.begin(); it!=bytime.end(); ++it) { VlcTest* testp = *it; if (!testp->rank()) { vluint64_t remain = testp->buckets().dataPopCount(remaining); if (remain > bestRemain) { bestTestp = testp; bestRemain = remain; } } } if (VlcTest* testp = bestTestp) { testp->rank(nextrank++); testp->rankPoints(bestRemain); remaining.orData(bestTestp->buckets()); } else { break; // No test covering more stuff found } } } //###################################################################### void VlcTop::annotateCalc() { // Calculate per-line information into filedata structure for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) { const VlcPoint& point = m_points.pointNumber(it->second); string filename = point.filename(); int lineno = point.lineno(); if (filename!="" && lineno!=0) { int column = point.column(); VlcSource& source = sources().findNewSource(filename); string threshStr = point.thresh(); unsigned thresh = (threshStr!="") ? atoi(threshStr.c_str()) : opt.annotateMin(); bool ok = (point.count() >= thresh); UINFO(9, "AnnoCalc count "<second; //UINFO(1,"Source "<second; for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) { VlcSourceCount& col = cit->second; //UINFO(0,"Source "<second; if (!source.needed()) continue; string filename = source.name(); string outfilename = dirname+"/"+V3Os::filenameNonDir(filename); UINFO(1,"annotateOutputFile "< "<second; for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) { VlcSourceCount& col = cit->second; //UINFO(0,"Source "< #include #include #include #include #include #include #include "V3Global.h" #include "V3String.h" #include "V3EmitXml.h" #include "V3EmitCBase.h" //###################################################################### // Emit statements and math operators class EmitXmlFileVisitor : public AstNVisitor { // NODE STATE //Entire netlist: // AstNode::user1 -> uint64_t, number to connect crossrefs // MEMBERS V3OutFile* m_ofp; uint64_t m_id; // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // Outfile methods V3OutFile* ofp() const { return m_ofp; } virtual void puts(const string& str) { ofp()->puts(str); } virtual void putbs(const string& str) { ofp()->putbs(str); } virtual void putfs(AstNode*, const string& str) { putbs(str); } virtual void putqs(AstNode*, const string& str) { putbs(str); } virtual void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); } virtual void putsQuoted(const string& str) { // Quote \ and " for use inside C programs // Don't use to quote a filename for #include - #include doesn't \ escape. // Duplicate in V3File - here so we can print to string putsNoTracking("\""); putsNoTracking(V3Number::quoteNameControls(str)); putsNoTracking("\""); } // XML methods void outputId(AstNode* nodep) { if (!nodep->user1()) { nodep->user1(++m_id); } puts("\""+cvtToStr(nodep->user1())+"\""); } void outputTag(AstNode* nodep, string tag) { if (tag=="") tag = VString::downcase(nodep->typeName()); puts("<"+tag+" "+nodep->fileline()->xml()); if (nodep->castNodeDType()) { puts(" id="); outputId(nodep); } if (nodep->name()!="") { puts(" name="); putsQuoted(nodep->prettyName()); } if (nodep->tag()!="") { puts(" tag="); putsQuoted(nodep->tag()); } if (AstNodeDType* dtp = nodep->castNodeDType()) { if (dtp->subDTypep()) { puts(" sub_dtype_id="); outputId(dtp->subDTypep()->skipRefp()); } } else { if (nodep->dtypep()) { puts(" dtype_id="); outputId(nodep->dtypep()->skipRefp()); } } } 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) { puts("\n"); nodep->iterateChildren(*this); puts("\n"); } virtual void visit(AstNodeModule* nodep) { 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) { outputTag(nodep, "instance"); // IEEE: vpiInstance puts(" defName="); putsQuoted(nodep->modName()); // IEEE vpiDefName outputChildrenEnd(nodep, "instance"); } virtual void visit(AstPin* nodep) { // 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) { outputTag(nodep, "contassign"); // IEEE: vpiContAssign outputChildrenEnd(nodep, "contassign"); } // Data types virtual void visit(AstBasicDType* nodep) { outputTag(nodep, "basicdtype "); if (nodep->isRanged()) { puts(" left=\""+cvtToStr(nodep->left())+"\""); puts(" right=\""+cvtToStr(nodep->right())+"\""); } puts("/>\n"); } // Default virtual void visit(AstNode* nodep) { outputTag(nodep, ""); outputChildrenEnd(nodep, ""); } public: EmitXmlFileVisitor(AstNode* nodep, V3OutFile* ofp) { m_ofp = ofp; m_id = 0; nodep->accept(*this); } virtual ~EmitXmlFileVisitor() {} }; //###################################################################### // 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.916/src/V3Descope.cpp0000664000177100017500000002732613205574202016620 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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_modSingleton; // m_modp is only instanced once bool m_needThis; // Make function non-static 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; } static bool modIsSingleton(AstNodeModule* modp) { // True iff there's exactly one instance of this module in the design. int instances = 0; for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) { if (stmtp->castScope()) { if (++instances > 1) { return false; } } } return (instances == 1); } // Construct the best prefix to reference an object in 'scopep' // from a CFunc in 'm_scopep'. Result may be relative // ("this->[...]") or absolute ("vlTOPp->[...]"). // // Using relative references allows V3Combine'ing // code across multiple instances of the same module. // // Sets 'hierThisr' true if the object is local to this scope // (and could be made into a function-local later in V3Localize), // false if the object is in another scope. string descopedName(const AstScope* scopep, bool& hierThisr, const AstVar* varp=NULL) { UASSERT(scopep, "Var/Func not scoped\n"); hierThisr = (scopep == m_scopep); // It's possible to disable relative references. This is a concession // to older compilers (gcc < 4.5.x) that don't understand __restrict__ // well and emit extra ld/st to guard against pointer aliasing // when this-> and vlTOPp-> are mixed in the same function. // // "vlTOPp" is declared "restrict" so better compilers understand // that it won't alias with "this". bool relativeRefOk = v3Global.opt.relativeCFuncs(); // Use absolute refs in top-scoped routines, keep them static. // The DPI callback registration depends on representing top-level // static routines as plain function pointers. That breaks if those // become true OO routines. // // V3Combine wouldn't likely be able to combine top-level // routines anyway, so there's no harm in keeping these static. if (m_modp->isTop()) { relativeRefOk = false; } // Use absolute refs if this scope is the only instance of the module. // Saves a bit of overhead on passing the 'this' pointer, and there's no // need to be nice to V3Combine when we have only a single instance. // The risk that this prevents combining identical logic from differently- // named but identical modules seems low. if (m_modSingleton) { relativeRefOk = false; } if (varp && varp->isFuncLocal()) { hierThisr = true; return ""; // Relative to function, not in this } else if (relativeRefOk && scopep == m_scopep) { m_needThis = true; return "this->"; } else if (relativeRefOk && scopep->aboveScopep() && scopep->aboveScopep()==m_scopep) { // 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); } m_needThis = true; return name+"->"; } else { // Reference to something elsewhere, or relative refences // are disabled. Use global variable UINFO(8," Descope "<name()<name()<aboveScopep()) { // Top // We could also return "vlSymsp->TOPp->" here, but GCC would // suspect aliases. return "vlTOPp->"; } 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()) { AstNode* newp = new AstVarRef(portp->fileline(), portp, portp->isOutput()); if (argsp) argsp = argsp->addNextNull(newp); else argsp = newp; } } } 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_WARNING, // 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) { m_modp = nodep; m_modFuncs.clear(); m_modSingleton = modIsSingleton(m_modp); nodep->iterateChildren(*this); makePublicFuncWrappers(); m_modp = NULL; } virtual void visit(AstScope* nodep) { m_scopep = nodep; nodep->iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstVarScope* nodep) { // Delete the varscope when we're finished nodep->unlinkFrBack(); pushDeletep(nodep); } virtual void visit(AstNodeVarRef* nodep) { 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) { //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) { if (!nodep->user1()) { m_needThis = false; nodep->iterateChildren(*this); nodep->user1(true); if (m_needThis) { nodep->isStatic(false); } // 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*) {} virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit DescopeVisitor(AstNetlist* nodep) : m_modp(NULL), m_scopep(NULL), m_modSingleton(false), m_needThis(false) { nodep->accept(*this); } virtual ~DescopeVisitor() {} }; //###################################################################### // Descope class functions void V3Descope::descopeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Broken.cpp0000664000177100017500000002347213205574202016454 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Broken's Transformations: // // Entire netlist // Mark all nodes // Check all links point to marked nodes // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include VL_INCLUDE_UNORDERED_MAP #include "V3Global.h" #include "V3Broken.h" #include "V3Ast.h" // This visitor does not edit nodes, and is called at error-exit, so should use constant iterators #include "V3AstConstOnly.h" //###################################################################### class BrokenTable : public AstNVisitor { // Table of brokenExists node pointers private: // MEMBERS // For each node, we keep if it exists or not. typedef vl_unordered_map NodeMap; // Performance matters (when --debug) static NodeMap s_nodes; // Set of all nodes that exist // BITMASK enum { FLAG_ALLOCATED = 0x01 }; // new() and not delete()ed enum { FLAG_IN_TREE = 0x02 }; // Is in netlist tree enum { FLAG_LINKABLE = 0x04 }; // Is in netlist tree, can be linked to enum { FLAG_LEAKED = 0x08 }; // Known to have been leaked enum { FLAG_UNDER_NOW = 0x10 }; // Is in tree as parent of current node public: // METHODS static void deleted(const AstNode* nodep) { // Called by operator delete on any node - only if VL_LEAK_CHECKS if (debug()>=9) cout<<"-nodeDel: "<<(void*)(nodep)<second & FLAG_ALLOCATED)) { ((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted"); } if (iter!=s_nodes.end()) s_nodes.erase(iter); } #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4 // GCC 4.4.* compiler warning bug, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39390 # pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif 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)) { nodep->v3fatalSrc("Newing AstNode object that is already allocated"); } if (iter == s_nodes.end()) { int flags = FLAG_ALLOCATED; // This int needed to appease GCC 4.1.2 s_nodes.insert(make_pair(nodep,flags)); } } static void setUnder(const AstNode* nodep, bool flag) { // Called by BrokenCheckVisitor when each node entered/exited if (!okIfLinkedTo(nodep)) return; NodeMap::iterator iter = s_nodes.find(nodep); if (iter!=s_nodes.end()) { iter->second &= ~FLAG_UNDER_NOW; if (flag) iter->second |= FLAG_UNDER_NOW; } } static void addInTree(AstNode* nodep, bool linkable) { #ifndef VL_LEAK_CHECKS if (!linkable) return; // save some time, else the map will get huge! #endif NodeMap::iterator iter = s_nodes.find(nodep); if (iter == s_nodes.end()) { #ifdef VL_LEAK_CHECKS nodep->v3fatalSrc("AstNode is in tree, but not allocated"); #endif } else { if (!(iter->second & FLAG_ALLOCATED)) { #ifdef VL_LEAK_CHECKS nodep->v3fatalSrc("AstNode is in tree, but not allocated"); #endif } if (iter->second & FLAG_IN_TREE) { nodep->v3fatalSrc("AstNode is already in tree at another location"); } } 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 // METHODS void processAndIterate(AstNode* nodep) { BrokenTable::addInTree(nodep, nodep->maybePointedTo()); nodep->iterateChildrenConst(*this); } // VISITORS virtual void visit(AstNode* nodep) { processAndIterate(nodep); } public: // CONSTUCTORS explicit BrokenMarkVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~BrokenMarkVisitor() {} }; //###################################################################### // Broken state, as a visitor of each AstNode class BrokenCheckVisitor : public AstNVisitor { private: void checkWidthMin(AstNode* nodep) { if (nodep->width() != nodep->widthMin() && v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH) { nodep->v3fatalSrc("Width != WidthMin"); } } void processAndIterate(AstNode* nodep) { BrokenTable::setUnder(nodep,true); if (const char* whyp=nodep->broken()) { nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<dtypep()) { if (!nodep->dtypep()->brokeExists()) { nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep()); } else if (!nodep->dtypep()->castNodeDType()) { nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); } } if (v3Global.assertDTypesResolved()) { if (nodep->hasDType()) { if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype on node with hasDType(): "<prettyTypeName()); } else { if (nodep->dtypep()) nodep->v3fatalSrc("DType on node without hasDType(): "<prettyTypeName()); } if (nodep->getChildDTypep()) nodep->v3fatalSrc("childDTypep() non-null on node after should have removed"); if (AstNodeDType* dnodep = nodep->castNodeDType()) checkWidthMin(dnodep); } checkWidthMin(nodep); nodep->iterateChildrenConst(*this); BrokenTable::setUnder(nodep,false); } virtual void visit(AstNodeAssign* nodep) { processAndIterate(nodep); if (v3Global.assertDTypesResolved() && nodep->brokeLhsMustBeLvalue() && nodep->lhsp()->castNodeVarRef() && !nodep->lhsp()->castNodeVarRef()->lvalue()) { nodep->v3fatalSrc("Assignment LHS is not an lvalue"); } } virtual void visit(AstNode* nodep) { processAndIterate(nodep); } public: // CONSTUCTORS explicit 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) { if (nodep->lvalue() && !m_splitVscp && nodep->varp()->attrIsolateAssign()) { m_splitVscp = nodep->varScopep(); } } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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) { 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) { // 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) {} virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit SplitAsVisitor(AstNetlist* nodep) { m_splitVscp = NULL; AstNode::user1ClearTree(); // user1p() used on entire tree nodep->accept(*this); } virtual ~SplitAsVisitor() { V3Stats::addStat("Optimizations, isolate_assignments blocks", m_statSplits); } }; //###################################################################### // SplitAs class functions void V3SplitAs::splitAsAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Cast.h0000664000177100017500000000226213205574202015565 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add C++ casts across expression size changes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CAST_H_ #define _V3CAST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Cast { public: static void castAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3Dead.h0000664000177100017500000000271613205574202015534 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Dead branch elimination // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3DEAD_H_ #define _V3DEAD_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Dead { public: // Modules, no vars/dtypes static void deadifyModules(AstNetlist* nodep); // Modules, Data types static void deadifyDTypes(AstNetlist* nodep); static void deadifyDTypesScoped(AstNetlist* nodep); // Everything that's possible static void deadifyAll(AstNetlist* nodep); static void deadifyAllScoped(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/vlcovgen0000775000177100017500000000776413205574202016076 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### #require 5.006_001; use Getopt::Long; use IO::File; use Pod::Usage; use strict; use vars qw ($Debug); our @Items; #====================================================================== # main $Debug = 0; my $Opt_Srcdir = "."; Getopt::Long::config ("pass_through", "no_auto_abbrev"); if (! GetOptions ( "help" => \&usage, "debug" => sub { $Debug = 1; }, "srcdir=s" => \$Opt_Srcdir, "<>" => sub { die "%Error: Unknown parameter: $_[0],"; }, )) { usage(); } read_keys("$Opt_Srcdir/../include/verilated_cov_key.h"); lint(); write_keys("$Opt_Srcdir/../include/verilated_cov_key.h"); #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } ####################################################################### sub read_keys { my $filename = shift; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename,"; while (defined (my $line = $fh->getline())) { $line =~ s/\/\/.*$//; next if $line =~ /^\s*$/; if ($line =~ /^\s*VLCOVGEN_ITEM/) { $line =~ /^\s*VLCOVGEN_ITEM *\( *"([^"]+)" *\)/ or die "%Error: $filename:$.: Misformed VLCOVGEN_ITEM line,"; my @data; my $code = "\@data = ($1);"; eval $code; die "%Error: $filename:$.: Parsing '$code': $@," if $@; push @Items, {@data}; } } } ####################################################################### sub lint { my %shorts; my $ok = 1; foreach my $itemref (@Items) { if ($shorts{$itemref->{short}}) { warn "%Error: Duplicate short code: $itemref->{short},"; $ok = 0; } $shorts{$itemref->{short}} = 1; } return $ok; } sub write_keys { my $filename = shift; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; my @in; my @out; my $deleting; while (defined(my $line = $fh->getline)) { push @in, $line; if ($line =~ /VLCOVGEN_CIK_AUTO_EDIT_BEGIN/) { $deleting = 1; push @out, $line; foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) { push @out, sprintf("#define VL_CIK_%s \"%s\"\n", uc $keyref->{name}, $keyref->{short}); } } elsif ($line =~ /VLCOVGEN_SHORT_AUTO_EDIT_BEGIN/) { $deleting = 1; push @out, $line; foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) { push @out, sprintf("\tif (key == \"%s\") return VL_CIK_%s;\n", $keyref->{name}, uc $keyref->{name}); } } elsif ($line =~ /VLCOVGEN_.*AUTO_EDIT_END/) { $deleting = 0; push @out, $line; } elsif ($deleting) { } else { push @out, $line; } } $fh->close; my $ok = join("", @out) eq join("", @in); if (!$ok) { my $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename\n"; $fh->print(join "", @out); $fh->close; } } ####################################################################### __END__ =pod =head1 NAME vlcovgen - Generate verilated_cov headers to reduce C++ code duplication =head1 SYNOPSIS (called from make rules) vlcovgen =head1 DESCRIPTION Generates several files for Verilator compilations. =head1 ARGUMENTS =over 4 =item --help Displays this message and program version and exits. =back =head1 DISTRIBUTION Copyright 2002-2017 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify it under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO =cut ###################################################################### ### Local Variables: ### compile-command: "./vlcovgen --srcdir ." ### End: verilator-3.916/src/V3PreShell.h0000664000177100017500000000317513205574202016415 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Preprocessing wrapper program // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3PRESHELL_H_ #define _V3PRESHELL_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3FileLine.h" class V3ParseImp; class V3InFilter; //============================================================================ class V3PreShell { // Static class for calling preprocessor public: static void boot(char** env); static bool preproc(FileLine* fileline, const string& module, V3InFilter* filterp, V3ParseImp* parsep, const string& errmsg); static void preprocInclude(FileLine* fileline, const string& module); static string dependFiles() { return ""; } // Perl only static void defineCmdLine(const string& name, const string& value); static void undef(const string& name); }; #endif // Guard verilator-3.916/src/V3LinkJump.cpp0000664000177100017500000002271213205574202016761 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3LinkJump's Transformations: // // Each module: // Look for BEGINs // BEGIN(VAR...) -> VAR ... {renamed} // FOR -> WHILEs // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3LinkJump.h" #include "V3Ast.h" //###################################################################### class LinkJumpVisitor : public AstNVisitor { private: // TYPES typedef vector BeginStack; // STATE AstNodeModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Current function/task AstWhile* m_loopp; // Current loop bool m_loopInc; // In loop increment int m_repeatNum; // Repeat counter BeginStack m_beginStack; // All begin blocks above current node // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } AstJumpLabel* findAddLabel(AstNode* nodep, bool endOfIter) { // Put label under given node, and if WHILE optionally at end of iteration UINFO(4,"Create label for "<castJumpLabel()) return nodep->castJumpLabel(); // Done AstNode* underp = NULL; bool under_and_next = true; if (nodep->castBegin()) underp = nodep->castBegin()->stmtsp(); else if (nodep->castNodeFTask()) underp = nodep->castNodeFTask()->stmtsp(); else if (nodep->castWhile()) { if (endOfIter) { // Note we jump to end of bodysp; a FOR loop has its increment under incsp() which we don't skip underp = nodep->castWhile()->bodysp(); } else { underp = nodep; under_and_next=false; // IE we skip the entire while } } else { nodep->v3fatalSrc("Unknown jump point for break/disable/continue"); return NULL; } // Skip over variables as we'll just move them in a momement // Also this would otherwise prevent us from using a label twice // see t_func_return test. while (underp && underp->castVar()) underp = underp->nextp(); if (underp) UINFO(5," Underpoint is "<v3fatalSrc("Break/disable/continue not under expected statement"); return NULL; } else if (underp->castJumpLabel()) { return underp->castJumpLabel(); } else { // Move underp stuff to be under a new label AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), NULL); AstNRelinker repHandle; if (under_and_next) underp->unlinkFrBackWithNext(&repHandle); else underp->unlinkFrBack(&repHandle); repHandle.relink(labelp); labelp->addStmtsp(underp); // Keep any AstVars under the function not under the new JumpLabel for (AstNode* nextp, *varp=underp; varp; varp = nextp) { nextp = varp->nextp(); if (varp->castVar()) { labelp->addPrev(varp->unlinkFrBack()); } } return labelp; } } // VISITORS virtual void visit(AstNodeModule* nodep) { if (nodep->dead()) return; m_modp = nodep; m_repeatNum = 0; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstNodeFTask* nodep) { m_ftaskp = nodep; nodep->iterateChildren(*this); m_ftaskp = NULL; } virtual void visit(AstBegin* nodep) { UINFO(8," "<iterateChildren(*this); m_beginStack.pop_back(); } virtual void visit(AstRepeat* nodep) { // 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(); VL_DANGLING(nodep); } virtual void visit(AstWhile* nodep) { // 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) { 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); VL_DANGLING(nodep); } virtual void visit(AstBreak* nodep) { 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); VL_DANGLING(nodep); } virtual void visit(AstContinue* nodep) { 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); VL_DANGLING(nodep); } virtual void visit(AstDisable* nodep) { 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); VL_DANGLING(nodep); //if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout," labelo: "); } } virtual void visit(AstVarRef* nodep) { if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true); } virtual void visit(AstConst* nodep) {} virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit LinkJumpVisitor(AstNetlist* nodep) { m_modp = NULL; m_ftaskp = NULL; m_loopp = NULL; m_loopInc = false; m_repeatNum = 0; nodep->accept(*this); } virtual ~LinkJumpVisitor() {} }; //###################################################################### // Task class functions void V3LinkJump::linkJump(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Branch.h0000664000177100017500000000226313205574202016071 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Branch prediction // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3BRANCH_H_ #define _V3BRANCH_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Branch { public: // CONSTRUCTORS static void branchAll(AstNetlist* rootp); }; #endif // Guard verilator-3.916/src/V3EmitCBase.h0000664000177100017500000000754213205574202016475 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EMITCBASE_H_ #define _V3EMITCBASE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3File.h" #include "V3Ast.h" //###################################################################### // Base Visitor class -- holds output file pointer class EmitCBaseVisitor : public AstNVisitor { public: // STATE V3OutCFile* m_ofp; // METHODS V3OutCFile* ofp() const { return m_ofp; } void puts(const string& str) { ofp()->puts(str); } void putbs(const string& str) { ofp()->putbs(str); } void putsDecoration(const string& str) { if (v3Global.opt.decoration()) puts(str); } void putsQuoted(const string& str) { ofp()->putsQuoted(str); } bool optSystemC() { return v3Global.opt.systemC(); } static string symClassName() { return v3Global.opt.prefix()+"__Syms"; } static string symClassVar() { return symClassName()+"* __restrict vlSymsp"; } static string symTopAssign() { return v3Global.opt.prefix()+"* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;"; } static string modClassName(AstNodeModule* modp) { // Return name of current module being processed if (modp->isTop()) { return v3Global.opt.prefix(); } else { return v3Global.opt.modPrefix() + "_" + modp->name(); } } static string topClassName() { // Return name of top wrapper module return v3Global.opt.prefix(); } AstCFile* newCFile(const string& filename, bool slow, bool source) { AstCFile* cfilep = new AstCFile(v3Global.rootp()->fileline(), filename); cfilep->slow(slow); cfilep->source(source); v3Global.rootp()->addFilesp(cfilep); return cfilep; } string cFuncArgs(AstCFunc* nodep) { // Return argument list for given C function string args = nodep->argTypes(); // Might be a user function with argument list. for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && !portp->isFuncReturn()) { if (args != "") args+= ", "; if (nodep->dpiImport() || nodep->dpiExportWrapper()) args += portp->dpiArgType(true,false); else if (nodep->funcPublic()) args += portp->cPubArgType(true,false); else args += portp->vlArgType(true,false,true); } } } return args; } // CONSTRUCTORS EmitCBaseVisitor() { m_ofp = NULL; } virtual ~EmitCBaseVisitor() {} }; //###################################################################### // Count operations under the given node, as a visitor of each AstNode class EmitCBaseCounterVisitor : public AstNVisitor { private: // STATE int m_count; // Number of statements // VISITORS virtual void visit(AstNode* nodep) { m_count++; nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit EmitCBaseCounterVisitor(AstNode* nodep) { m_count = 0; nodep->accept(*this); } virtual ~EmitCBaseCounterVisitor() {} int count() const { return m_count; } }; #endif // guard verilator-3.916/src/V3Simulate.h0000664000177100017500000007771713205574202016477 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 #include //============================================================================ //###################################################################### // Simulate class functions class SimulateStackNode { public: // MEMBERS AstFuncRef* m_funcp; V3TaskConnects* m_tconnects; // CONSTRUCTORS SimulateStackNode(AstFuncRef* funcp, V3TaskConnects* tconnects): m_funcp(funcp), m_tconnects(tconnects) {} ~SimulateStackNode() {} }; 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 deque m_callStack; ///< Call stack for verbose error messages // Cleanup // V3Numbers that represents strings are a bit special and the API for V3Number does not allow changing them. deque m_stringNumbersp; // List of allocated string numbers // 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; } // Potentially very slow, intended for debugging string prettyNumber(V3Number* nump, AstNodeDType* dtypep) { if (AstRefDType* refdtypep = dtypep->castRefDType()) { dtypep = refdtypep->skipRefp(); } if (AstStructDType* stp = dtypep->castStructDType()) { if (stp->packed()) { ostringstream out; out<<"'{"; for (AstMemberDType* itemp = stp->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) { int width = itemp->width(); int lsb = itemp->lsb(); int msb = lsb + width - 1; V3Number fieldNum = V3Number(nump->fileline(), width); fieldNum.opSel(*nump, msb, lsb); out<name()<<": "; if (AstNodeDType * childTypep = itemp->subDTypep()) { out<nextp()) out<<", "; } out<<"}"; return out.str(); } } else if (AstPackArrayDType * arrayp = dtypep->castPackArrayDType()) { if (AstNodeDType * childTypep = arrayp->subDTypep()) { ostringstream out; out<<"["; int arrayElements = arrayp->elementsConst(); for (int element = 0; element < arrayElements; ++element) { int width = childTypep->width(); int lsb = width * element; int msb = lsb + width - 1; V3Number fieldNum = V3Number(nump->fileline(), width); fieldNum.opSel(*nump, msb, lsb); int arrayElem = arrayp->lsb() + element; out<ascii(); } // 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: "<::iterator it=m_callStack.begin(); it !=m_callStack.end(); ++it) { AstFuncRef* funcp = (*it)->m_funcp; stack<<"\nCalled from:\n"<fileline()<<" "<prettyName()<<"() with parameters:"; V3TaskConnects* tconnects = (*it)->m_tconnects; for (V3TaskConnects::iterator conIt = tconnects->begin(); conIt != tconnects->end(); ++conIt) { AstVar* portp = conIt->first; AstNode* pinp = conIt->second->exprp(); AstNodeDType* dtypep = pinp->dtypep(); stack<<"\n "<prettyName()<<" = "<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((void*)nump); } inline void setOutNumber(AstNode* nodep, const V3Number* nump) { UINFO(9," set num "<<*nump<<" on "<user2p((void*)nump); } void checkNodeInfo(AstNode* nodep) { if (m_checkOnly) { m_instrCount += nodep->instrCount(); m_dataCount += nodep->width(); } if (!nodep->isPredictOptimizable()) { //UINFO(9," !predictopt "<prettyTypeName()<varScopep(); else vscp = nodep->varp(); if (!vscp) nodep->v3fatalSrc("Not linked"); return vscp; } int unrollCount() { return m_params ? v3Global.opt.unrollCount()*16 : v3Global.opt.unrollCount(); } bool jumpingOver(AstNode* nodep) { // True to jump over this node - all visitors must call this up front return (m_jumpp && m_jumpp->labelp()!=nodep); } void assignOutNumber(AstNodeAssign* nodep, AstNode* vscp, const V3Number* nump) { // Don't do setNumber, as value isn't yet visible to following statements if (nodep->castAssignDly()) { // Don't do setNumber, as value isn't yet visible to following statements newOutNumber(vscp)->opAssign(*nump); } else { newNumber(vscp)->opAssign(*nump); newOutNumber(vscp)->opAssign(*nump); } } // VISITORS virtual void visit(AstAlways* nodep) { if (jumpingOver(nodep)) return; checkNodeInfo(nodep); nodep->iterateChildren(*this); } virtual void visit(AstSenTree* nodep) { // Sensitivities aren't inputs per se; we'll keep our tree under the same sens. } virtual void visit(AstVarRef* nodep) { if (jumpingOver(nodep)) return; if (!optimizable()) return; // Accelerate nodep->varp()->iterateChildren(*this); 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() && !nodep->varp()->dtypeSkipRefp()->castPackArrayDType() && !nodep->varp()->dtypeSkipRefp()->castStructDType()) 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(); V3Number* nump = isConst ? fetchNumberNull(nodep->varp()->valuep()) : NULL; if (isConst && nump) { // Propagate PARAM constants for constant function analysis if (!m_checkOnly && optimizable()) { newNumber(vscp)->opAssign(*nump); } } 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) { 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) { 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) { 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) { checkNodeInfo(nodep); if (!m_checkOnly && optimizable()) { setNumber(nodep, &(nodep->num())); } } virtual void visit(AstEnumItemRef* nodep) { checkNodeInfo(nodep); if (!nodep->itemp()) nodep->v3fatalSrc("Not linked"); if (!m_checkOnly && optimizable()) { AstNode* valuep = nodep->itemp()->valuep(); if (valuep) { valuep->iterateAndNext(*this); if (optimizable()) { newNumber(nodep)->opAssign(*fetchNumber(valuep)); } } else { clearOptimizable(nodep, "No value found for enum item"); } } } virtual void visit(AstNodeUniop* nodep) { 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) { 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) { 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) { // Need to short circuit if (!optimizable()) return; // Accelerate checkNodeInfo(nodep); if (m_checkOnly) { nodep->iterateChildren(*this); } else { nodep->lhsp()->accept(*this); if (optimizable()) { 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) { // Need to short circuit if (!optimizable()) return; // Accelerate checkNodeInfo(nodep); if (m_checkOnly) { nodep->iterateChildren(*this); } else { nodep->lhsp()->accept(*this); if (optimizable()) { 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) { // 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 (optimizable()) { 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) { // 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 (optimizable()) { 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())); } } } } void handleAssignSel(AstNodeAssign* nodep, AstSel* selp) { AstVarRef* varrefp = NULL; V3Number lsb = V3Number(nodep->fileline()); nodep->rhsp()->iterateAndNext(*this); // Value to assign handleAssignSelRecurse(nodep, selp, varrefp/*ref*/, lsb/*ref*/, 0); if (!m_checkOnly && optimizable()) { if (!varrefp) nodep->v3fatalSrc("Indicated optimizable, but no variable found on RHS of select"); AstNode* vscp = varOrScope(varrefp); V3Number outnum = V3Number(nodep->fileline()); if (V3Number* vscpnump = fetchOutNumberNull(vscp)) { outnum = *vscpnump; } else if (V3Number* vscpnump = fetchNumberNull(vscp)) { outnum = *vscpnump; } else { // Assignment to unassigned variable, all bits are X or 0 outnum = V3Number(nodep->fileline(), varrefp->varp()->widthMin()); if (varrefp->varp()->basicp() && varrefp->varp()->basicp()->isZeroInit()) { outnum.setAllBits0(); } else { outnum.setAllBitsX(); } } outnum.opSelInto(*fetchNumber(nodep->rhsp()), lsb, selp->widthConst()); assignOutNumber(nodep, vscp, &outnum); } } void handleAssignSelRecurse (AstNodeAssign* nodep, AstSel* selp, AstVarRef*& outVarrefpRef, V3Number& lsbRef, int depth) { // Recurse down to find final variable being set (outVarrefp), with value to write on nodep->rhsp() checkNodeInfo(selp); selp->lsbp()->iterateAndNext(*this); // Bit index if (AstVarRef* varrefp = selp->fromp()->castVarRef()) { outVarrefpRef = varrefp; lsbRef = *fetchNumber(selp->lsbp()); return; // And presumably still optimizable() } else if (AstSel* subselp = selp->lhsp()->castSel()) { V3Number sublsb = V3Number(nodep->fileline()); handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb/*ref*/, depth+1); if (optimizable()) { lsbRef = sublsb; lsbRef.opAdd(sublsb, *fetchNumber(selp->lsbp())); } } else { clearOptimizable(nodep, "Select LHS isn't simple variable"); } } virtual void visit(AstNodeAssign* nodep) { if (jumpingOver(nodep)) return; if (!optimizable()) return; // Accelerate if (nodep->castAssignDly()) { if (m_anyAssignComb) clearOptimizable(nodep, "Mix of dly/non-dly assigns"); m_anyAssignDly = true; m_inDlyAssign = true; } else { if (m_anyAssignDly) clearOptimizable(nodep, "Mix of dly/non-dly assigns"); m_anyAssignComb = true; } if (AstSel* selp = nodep->lhsp()->castSel()) { if (!m_params) { clearOptimizable(nodep, "LHS has select"); return; } handleAssignSel(nodep, selp); } else if (!nodep->lhsp()->castVarRef()) { clearOptimizable(nodep, "LHS isn't simple variable"); } else if (m_checkOnly) { nodep->iterateChildren(*this); } else if (optimizable()) { nodep->rhsp()->iterateAndNext(*this); if (optimizable()) { AstNode* vscp = varOrScope(nodep->lhsp()->castVarRef()); assignOutNumber(nodep, vscp, fetchNumber(nodep->rhsp())); } } m_inDlyAssign = false; } virtual void visit(AstBegin* nodep) { checkNodeInfo(nodep); nodep->iterateChildren(*this); } virtual void visit(AstNodeCase* nodep) { 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) { // Real handling is in AstNodeCase if (jumpingOver(nodep)) return; checkNodeInfo(nodep); nodep->iterateChildren(*this); } virtual void visit(AstComment*) {} virtual void visit(AstJumpGo* nodep) { 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) { // 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) { if (jumpingOver(nodep)) return; if (!optimizable()) return; // Accelerate UINFO(5," FUNCREF "<taskp()->castNodeFTask(); if (!funcp) nodep->v3fatalSrc("Not linked"); if (m_params) { V3Width::widthParamsEdit(funcp); } VL_DANGLING(funcp); // 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)); } } } SimulateStackNode stackNode(nodep, &tconnects); m_callStack.push_front(&stackNode); // Evaluate the function funcp->accept(*this); m_callStack.pop_front(); 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) { if (jumpingOver(nodep)) return; if (!m_params) { badNodeType(nodep); return; } } virtual void visit(AstScopeName *nodep) { if (jumpingOver(nodep)) return; if (!m_params) { badNodeType(nodep); return; } // Ignore } virtual void visit(AstSFormatF *nodep) { if (jumpingOver(nodep)) return; if (!optimizable()) return; // Accelerate nodep->iterateChildren(*this); if (m_params) { AstNode* nextArgp = nodep->exprsp(); string result = ""; string format = nodep->text(); string::const_iterator pos = format.begin(); bool inPct = false; for (; pos != format.end(); ++pos) { if (!inPct && pos[0] == '%') { inPct = true; } else if (!inPct) { // Normal text result += *pos; } else { // Format character inPct = false; if (V3Number::displayedFmtLegal(tolower(pos[0]))) { AstNode* argp = nextArgp; nextArgp = nextArgp->nextp(); V3Number* nump = fetchNumberNull(argp); if (!nump) { clearOptimizable(nodep, "Argument for $display like statement is not constant"); break; } string format = string("%") + pos[0]; result += nump->displayed(nodep->fileline(), format); } else { switch (tolower(pos[0])) { case '%': result += "%"; break; case 'm': // This happens prior to AstScope so we don't know the scope name. Leave the %m in place. result += "%m"; break; default: clearOptimizable(nodep, "Unknown $display-like format code."); break; } } } } V3Number* resultNump = new V3Number(V3Number::String(), nodep->fileline(), result); setNumber(nodep, resultNump); m_stringNumbersp.push_back(resultNump); } } virtual void visit(AstDisplay *nodep) { if (jumpingOver(nodep)) return; if (!optimizable()) return; // Accelerate nodep->iterateChildren(*this); if (m_params) { V3Number* textp = fetchNumber(nodep->fmtp()); switch (nodep->displayType()) { case AstDisplayType::DT_DISPLAY: // FALLTHRU case AstDisplayType::DT_INFO: v3warn(USERINFO, textp->toString()); break; case AstDisplayType::DT_ERROR: v3warn(USERERROR, textp->toString()); break; case AstDisplayType::DT_WARNING: v3warn(USERWARN, textp->toString()); break; case AstDisplayType::DT_FATAL: v3warn(USERFATAL, textp->toString()); break; case AstDisplayType::DT_WRITE: // FALLTHRU default: clearOptimizable(nodep, "Unexpected display type"); } } } // default // These types are definately not reducable // AstCoverInc, AstArraySel, AstFinish, // AstRand, AstTime, AstUCFunc, AstCCall, AstCStmt, AstUCStmt virtual void visit(AstNode* nodep) { 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 mainCheckTree (AstNode* nodep) { setMode(false/*scoped*/,true/*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); } for (deque::iterator it = m_stringNumbersp.begin(); it != m_stringNumbersp.end(); ++it) { delete (*it); } m_stringNumbersp.clear(); m_numFreeps.clear(); m_numAllps.clear(); } }; #endif // Guard verilator-3.916/src/V3Undriven.cpp0000664000177100017500000003355613205623251017031 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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: // // Netlist: // 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 explicit UndrivenVarEntry (AstVar* varp) { // Construction for when a var is used UINFO(9, "create "<width()*FLAGS_PER_BIT); for (int i=0; iwidth()*FLAGS_PER_BIT; i++) { m_flags[i] = false; } } ~UndrivenVarEntry() {} private: // METHODS inline bool bitNumOk(int bit) const { return bit>=0 && (bit*FLAGS_PER_BIT < (int)m_flags.size()); } inline bool usedFlag(int bit) const { return m_usedWhole || m_flags[bit*FLAGS_PER_BIT + FLAG_USED]; } inline bool drivenFlag(int bit) const { return m_drivenWhole || m_flags[bit*FLAGS_PER_BIT + FLAG_DRIVEN]; } enum BitNamesWhich { BN_UNUSED, BN_UNDRIVEN, BN_BOTH }; string bitNames(BitNamesWhich which) { string bits=""; bool prev = false; int msb = 0; // bit==-1 loops below; we do one extra iteration so end with prev=false for (int bit=(m_flags.size()/FLAGS_PER_BIT)-1; bit >= -1; --bit) { if (bit>=0 && ((which == BN_UNUSED && !usedFlag(bit) && drivenFlag(bit)) || (which == BN_UNDRIVEN && usedFlag(bit) && !drivenFlag(bit)) || (which == BN_BOTH && !usedFlag(bit) && !drivenFlag(bit)))) { if (!prev) { prev=true; msb = bit; } } else if (prev) { AstBasicDType* bdtypep = m_varp->basicp(); int lsb = bit+1; if (bits != "") bits += ","; if (lsb==msb) { bits += cvtToStr(lsb+bdtypep->lsb()); } else { if (bdtypep->littleEndian()) { bits += cvtToStr(lsb+bdtypep->lsb())+":"+cvtToStr(msb+bdtypep->lsb()); } else { bits += cvtToStr(msb+bdtypep->lsb())+":"+cvtToStr(lsb+bdtypep->lsb()); } } prev = false; } } return "["+bits+"]"; } public: void usedWhole() { UINFO(9, "set u[*] "<name()<name()<name()<name()<prettyName(); return VString::wildmatch(prettyName.c_str(), regexp.c_str()); } void reportViolations() { // Combine bits into overall state AstVar* nodep = m_varp; if (!nodep->isParam() && !nodep->isGenVar()) { bool allU=true; bool allD=true; bool anyU=m_usedWhole; bool anyD=m_drivenWhole; bool anyUnotD=false; bool anyDnotU=false; bool anynotDU=false; for (unsigned bit=0; bitisIfaceRef()) { // For interface top level we don't do any tracking // Ideally we'd report unused instance cells, but presumably a signal inside one // would get reported as unused } else if (allU && allD) { // It's fine } else if (!anyD && !anyU) { // UNDRIVEN is considered more serious - as is more likely a bug, // thus undriven+unused bits get UNUSED warnings, as they're not as buggy. if (!unusedMatch(nodep)) { nodep->v3warn(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 // Netlist: // AstVar::user1p -> UndrivenVar* for usage var, 0=not set yet AstUser1InUse m_inuser1; // Each always: // AstNode::user2p -> UndrivenVar* for usage var, 0=not set yet AstUser2InUse m_inuser2; // STATE vector m_entryps[3]; // Nodes to delete when we are finished bool m_inBBox; // In black box; 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(AstNodeVarRef* nodep) { AstVar* varp = nodep->varp(); if (!varp->isParam() && !varp->isGenVar() && !varp->isUsedLoopIdx() && !m_inBBox // We may have falsely considered a SysIgnore as a driver && !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) { 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) { // Arrays are rarely constant assigned, so for now we punt and do all entries nodep->iterateChildren(*this); } virtual void visit(AstSliceSel* nodep) { // Arrays are rarely constant assigned, so for now we punt and do all entries nodep->iterateChildren(*this); } virtual void visit(AstSel* nodep) { AstNodeVarRef* varrefp = nodep->fromp()->castNodeVarRef(); 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_inBBox || 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_inBBox || !varrefp->lvalue()) entryp->usedBit(lsb, nodep->width()); } } else { // else other varrefs handled as unknown mess in AstVarRef nodep->iterateChildren(*this); } } virtual void visit(AstNodeVarRef* nodep) { // 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_inBBox || nodep->lvalue()) { if (usr==2 && m_alwaysp && entryp->isUsedNotDrivenAny()) { UINFO(9," Full bus. Entryp="<<(void*)entryp<drivenWhole(); } if (m_inBBox || !nodep->lvalue() || fdrv) entryp->usedWhole(); } } // Don't know what black boxed calls do, assume in+out virtual void visit(AstSysIgnore* nodep) { bool prevMark = m_inBBox; m_inBBox = true; nodep->iterateChildren(*this); m_inBBox = prevMark; } virtual void visit(AstAlways* nodep) { 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) {} // Coverage artifacts etc shouldn't count as a sink virtual void visit(AstCoverDecl* nodep) {} virtual void visit(AstCoverInc* nodep) {} virtual void visit(AstCoverToggle* nodep) {} virtual void visit(AstTraceDecl* nodep) {} virtual void visit(AstTraceInc* nodep) {} // iterate virtual void visit(AstConst* nodep) {} virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit UndrivenVisitor(AstNetlist* nodep) { m_inBBox = 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 VL_INCLUDE_UNORDERED_SET #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(); } } 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 { vl_unordered_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); } } AstNodeBiop* AstEqWild::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) { if (lhsp->isDouble() && rhsp->isDouble()) { return new AstEqD(fl, lhsp, rhsp); } else { return new AstEqWild(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 if (varType()==AstVarType::WREAL) { return "wreal"; } else { return dtypep()->name(); } } string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const { if (forReturn) named=false; if (forReturn) v3fatalSrc("verilator internal data is never passed as return, but as first argument"); string arg; if (isWide() && isInOnly()) arg += "const "; AstBasicDType* bdtypep = basicp(); bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING; if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) { arg += "const char*"; } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) { arg += "const VerilatedScope*"; } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::DOUBLE) { arg += "double"; } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::FLOAT) { arg += "float"; } else if (strtype) { if (isInOnly()) arg += "const "; arg += "std::string"; } else if (widthMin() <= 8) { arg += "CData"; } else if (widthMin() <= 16) { arg += "SData"; } else if (widthMin() <= VL_WORDSIZE) { arg += "IData"; } else if (isQuad()) { arg += "QData"; } else if (isWide()) { arg += "WData"; // []'s added later } if (isWide() && !strtype) { arg += " (& "+name(); arg += ")["+cvtToStr(widthWords())+"]"; } else { if (forFunc && (isOutput() || (strtype && isInput()))) arg += "&"; if (named) arg += " "+name(); } return arg; } string AstVar::vlEnumType() const { string arg; AstBasicDType* bdtypep = basicp(); bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING; if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) { return "VLVT_PTR"; } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) { return "VLVT_PTR"; } else if (strtype) { arg += "VLVT_STRING"; } else if (widthMin() <= 8) { arg += "VLVT_UINT8"; } else if (widthMin() <= 16) { arg += "VLVT_UINT16"; } else if (widthMin() <= VL_WORDSIZE) { arg += "VLVT_UINT32"; } else if (isQuad()) { arg += "VLVT_UINT64"; } else if (isWide()) { arg += "VLVT_WDATA"; } // else return "VLVT_UNKNOWN" return arg; } string AstVar::vlEnumDir() const { if (isInout()) { return "VLVD_INOUT"; } else if (isInOnly()) { return "VLVD_IN"; } else if (isOutOnly()) { return "VLVD_OUT"; } else { return "VLVD_NODIR"; } } string AstVar::cPubArgType(bool named, bool forReturn) const { if (forReturn) named=false; string arg; if (isWide() && isInOnly()) arg += "const "; if (widthMin() == 1) { arg += "bool"; } else if (widthMin() <= VL_WORDSIZE) { arg += "uint32_t"; } else if (isWide()) { arg += "uint32_t"; // []'s added later } else { arg += "vluint64_t"; } if (isWide()) { if (forReturn) v3error("Unsupported: Public functions with >64 bit outputs; make an output of a public task instead"); arg += " (& "+name(); arg += ")["+cvtToStr(widthWords())+"]"; } else { if (isOutput() && !forReturn) arg += "&"; if (named) arg += " "+name(); } return arg; } string AstVar::dpiArgType(bool named, bool forReturn) const { if (forReturn) named=false; string arg; if (!basicp()) arg = "UNKNOWN"; if (basicp()->isBitLogic()) { if (widthMin() == 1) { arg = "unsigned char"; if (!forReturn && isOutput()) arg += "*"; } else { if (forReturn) { arg = "svBitVecVal"; } else if (isInOnly()) { arg = "const svBitVecVal*"; } else { arg = "svBitVecVal*"; } } } else { arg = basicp()->keyword().dpiType(); if (basicp()->keyword().isDpiUnsignable() && !basicp()->isSigned()) { arg = "unsigned "+arg; } if (!forReturn && isOutput()) arg += "*"; } if (named) arg += " "+name(); return arg; } string AstVar::scType() const { if (isScBigUint()) { return (string("sc_biguint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >> } else if (isScUint()) { return (string("sc_uint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >> } else if (isScBv()) { return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >> } else if (widthMin() == 1) { return "bool"; } else if (widthMin() <= VL_WORDSIZE) { if (widthMin() <= 8 && v3Global.opt.pinsUint8()) { return "uint8_t"; } else if (widthMin() <= 16 && v3Global.opt.pinsUint8()) { return "uint16_t"; } else { return "uint32_t"; } } else { return "vluint64_t"; } } AstVar* AstVar::scVarRecurse(AstNode* nodep) { // See if this is a SC assignment; if so return that type // Historically sc variables are identified by a variable // attribute. TODO it would better be a data type attribute. if (AstVar* anodep = nodep->castVar()) { if (anodep->isSc()) return anodep; else return NULL; } else if (nodep->castVarRef()) { if (nodep->castVarRef()->varp()->isSc()) return nodep->castVarRef()->varp(); else return NULL; } else if (nodep->castArraySel()) { if (nodep->op1p()) if (AstVar* p = scVarRecurse(nodep->op1p())) return p; if (nodep->op2p()) if (AstVar* p = scVarRecurse(nodep->op2p())) return p; if (nodep->op3p()) if (AstVar* p = scVarRecurse(nodep->op3p())) return p; if (nodep->op4p()) if (AstVar* p = scVarRecurse(nodep->op4p())) return p; } return NULL; } AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) { // dimension passed from AstArraySel::dimension // Dimension 0 means the VAR itself, 1 is the closest SEL to the AstVar, // which is the lowest in the dtype list. // ref order: a[1][2][3][4] // Created as: reg [4] a [1][2][3]; // *or* reg a [1][2][3][4]; // // The bit select is optional; used only if "leftover" []'s // SEL: SEL4(SEL3(SEL2(SEL1(VARREF0 a)))) // DECL: VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (DT RANGE3)))) // *or* VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (ARRAYSEL3 (DT)))) // SEL1 needs to select from entire variable which is a pointer to ARRAYSEL0 // TODO this function should be removed in favor of recursing the dtype(), // as that allows for more complicated data types. int dim = 0; UDEBUGONLY(UASSERT(dynamic_cast(this),"this should not be NULL");); 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; UDEBUGONLY(UASSERT(dynamic_cast(this),"this should not be NULL");); 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; UDEBUGONLY(UASSERT(dynamic_cast(this),"this should not be NULL");); 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(); if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep(); if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep(); } 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::scopePrettyNameFormatter(AstText* scopeTextp) const { string out; for (AstText* textp=scopeTextp; 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::scopeNameFormatter(AstText* scopeTextp) const { string out; for (AstText* textp=scopeTextp; 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() const { 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() const { 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() const { 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() const { if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it"); for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) { if (senp->isCombo()) return true; } return false; } void AstTypeTable::clearCache() { // When we mass-change widthMin in V3WidthCommit, we need to correct the table. // Just clear out the maps; the search functions will be used to rebuild the map for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) { m_basicps[i] = NULL; } for (int isbit=0; isbit<_IDX0_MAX; ++isbit) { for (int numer=0; numernextp()) { if (AstBasicDType* bdtypep = nodep->castBasicDType()) { bdtypep->generic(false); } } } void AstTypeTable::repairCache() { // After we mass-change widthMin in V3WidthCommit, we need to correct the table. clearCache(); for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) { if (AstBasicDType* bdtypep = nodep->castBasicDType()) { (void)findInsertSameDType(bdtypep); } } } AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd) { if (m_basicps[kwd]) return m_basicps[kwd]; // AstBasicDType* new1p = new AstBasicDType(fl, kwd); // Because the detailed map doesn't update this map, // check the detailed map for this same node // Also adds this new node to the detailed map AstBasicDType* newp = findInsertSameDType(new1p); if (newp != new1p) new1p->deleteTree(); else addTypesp(newp); // m_basicps[kwd] = newp; return newp; } AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, int widthMin, AstNumeric numeric) { int idx = IDX0_LOGIC; if (kwd == AstBasicDTypeKwd::LOGIC) idx = IDX0_LOGIC; else if (kwd == AstBasicDTypeKwd::BIT) idx = IDX0_BIT; else fl->v3fatalSrc("Bad kwd for findLogicBitDType"); pair widths = make_pair(width,widthMin); LogicMap& mapr = m_logicMap[idx][(int)numeric]; LogicMap::const_iterator it = mapr.find(widths); if (it != mapr.end()) return it->second; // AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin); // Because the detailed map doesn't update this map, // check the detailed map for this same node, and if found update this map // Also adds this new node to the detailed map AstBasicDType* newp = findInsertSameDType(new1p); if (newp != new1p) new1p->deleteTree(); else addTypesp(newp); // mapr.insert(make_pair(widths,newp)); return newp; } AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, VNumRange range, int widthMin, AstNumeric numeric) { AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin); AstBasicDType* newp = findInsertSameDType(new1p); if (newp != new1p) new1p->deleteTree(); else addTypesp(newp); return newp; } AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) { VBasicTypeKey key (nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(), nodep->nrange()); DetailedMap& mapr = m_detailedMap; DetailedMap::const_iterator it = mapr.find(key); if (it != mapr.end()) return it->second; mapr.insert(make_pair(key,nodep)); nodep->generic(true); // No addTypesp; the upper function that called new() is responsible for adding return nodep; } //====================================================================== // Special walking tree inserters void AstNode::addBeforeStmt(AstNode* newp, AstNode*) { if (!backp()) newp->v3fatalSrc("Can't find current statement to addBeforeStmt"); // Look up; virtual call will find where to put it this->backp()->addBeforeStmt(newp, this); } void AstNode::addNextStmt(AstNode* newp, AstNode*) { if (!backp()) newp->v3fatalSrc("Can't find current statement to addBeforeStmt"); // Look up; virtual call will find where to put it this->backp()->addNextStmt(newp, this); } void AstNodeStmt::addBeforeStmt(AstNode* newp, AstNode*) { // Insert newp before current node this->addHereThisAsNext(newp); } void AstNodeStmt::addNextStmt(AstNode* newp, AstNode*) { // Insert newp after current node this->addNextHere(newp); } void AstWhile::addBeforeStmt(AstNode* newp, AstNode* belowp) { // Special, as statements need to be put in different places // Belowp is how we came to recurse up to this point // Preconditions insert first just before themselves (the normal rule for other statement types) if (belowp == precondsp()) { // Must have been first statement in precondsp list, so newp is new first statement belowp->addHereThisAsNext(newp); } else if (belowp == condp()) { // Goes before condition, IE in preconditions addPrecondsp(newp); } else if (belowp == bodysp()) { // Was first statement in body, so new front belowp->addHereThisAsNext(newp); } else { belowp->v3fatalSrc("Doesn't look like this was really under the while"); } } void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) { // Special, as statements need to be put in different places // Belowp is how we came to recurse up to this point // Preconditions insert first just before themselves (the normal rule for other statement types) if (belowp == precondsp()) { // Next in precond list belowp->addNextHere(newp); } else if (belowp == condp()) { // Becomes first statement in body, body may have been empty if (bodysp()) { bodysp()->addHereThisAsNext(newp); } else { addBodysp(newp); } } else if (belowp == bodysp()) { // Next statement in body belowp->addNextHere(newp); } else { belowp->v3fatalSrc("Doesn't look like this was really under the while"); } } //====================================================================== // Per-type Debugging void AstNode::dump(ostream& str) { str<m_backp <<" =editCountLast())?"#>":">") <<" {"<filenameLetters()<lineno()<<"}"; if (user1p()) str<<" u1="<<(void*)user1p(); if (user2p()) str<<" u2="<<(void*)user2p(); if (user3p()) str<<" u3="<<(void*)user3p(); if (user4p()) str<<" u4="<<(void*)user4p(); if (user5p()) str<<" u5="<<(void*)user5p(); if (hasDType()) { if (dtypep()==this) str<<" @dt="<<"this@"; else str<<" @dt="<<(void*)dtypep()<<"@"; // Final @ so less likely to by accident think it's nodep if (AstNodeDType* dtp = dtypep()) { dtp->dumpSmall(str); } } else { // V3Broken will throw an error if (dtypep()) str<<" %Error-dtype-exp=null,got="<<(void*)dtypep(); } if (name()!="") { if (castConst()) str<<" "<AstNode::dump(str); if (keyword() != VAlwaysKwd::ALWAYS) str<<" ["<AstNode::dump(str); str<<" ["<AstNodeDType::dump(str); str<<" kwd="<AstNode::dump(str); str<<" sz"<AstNode::dump(str); if (recursive()) str<<" [RECURSIVE]"; if (modp()) { str<<" -> "; modp()->dump(str); } else { str<<" ->UNLINKED:"<AstNode::dump(str); str<<" -> "<AstNode::dump(str); //str<<" "<AstNode::dump(str); str<<" -> "; if (itemp()) { itemp()->dump(str); } else { str<<"UNLINKED"; } } void AstIfaceRefDType::dump(ostream& str) { this->AstNode::dump(str); if (cellName()!="") { str<<" cell="< "; cellp()->dump(str); } else if (ifacep()) { str<<" -> "; ifacep()->dump(str); } else { str<<" -> UNLINKED"; } } void AstIfaceRefDType::dumpSmall(ostream& str) { this->AstNodeDType::dumpSmall(str); str<<"iface"; } void AstJumpGo::dump(ostream& str) { this->AstNode::dump(str); str<<" -> "; if (labelp()) { labelp()->dump(str); } else { str<<"%Error:UNLINKED"; } } void AstModportFTaskRef::dump(ostream& str) { this->AstNode::dump(str); if (isExport()) str<<" EXPORT"; if (isImport()) str<<" IMPORT"; if (ftaskp()) { str<<" -> "; ftaskp()->dump(str); } else { str<<" -> UNLINKED"; } } void AstModportVarRef::dump(ostream& str) { this->AstNode::dump(str); str<<" "< "; varp()->dump(str); } else { str<<" -> UNLINKED"; } } void AstPin::dump(ostream& str) { this->AstNode::dump(str); if (modVarp()) { str<<" -> "; modVarp()->dump(str); } else { str<<" ->UNLINKED"; } if (svImplicit()) str<<" [.SV]"; } void AstTypedef::dump(ostream& str) { this->AstNode::dump(str); if (attrPublic()) str<<" [PUBLIC]"; } void AstRange::dump(ostream& str) { this->AstNode::dump(str); if (littleEndian()) str<<" [LITTLE]"; } void AstRefDType::dump(ostream& str) { this->AstNodeDType::dump(str); if (defp()) { str<<" -> "; defp()->dump(str); } else { str<<" -> UNLINKED"; } } void AstNodeClassDType::dump(ostream& str) { this->AstNode::dump(str); if (packed()) str<<" [PACKED]"; } void AstNodeDType::dump(ostream& str) { this->AstNode::dump(str); if (generic()) str<<" [GENERIC]"; if (AstNodeDType* dtp = virtRefDTypep()) { str<<" refdt="<<(void*)(dtp); dtp->dumpSmall(str); } } void AstNodeDType::dumpSmall(ostream& str) { str<<"(" <<(generic()?"G/":"") <<((isSigned()&&!isDouble())?"s":"") <<(isNosign()?"n":"") <<(isDouble()?"d":"") <<(isString()?"str":""); if (!isDouble() && !isString()) { str<<"w"<<(widthSized()?"":"u")<AstNodeDType::dumpSmall(str); if (castPackArrayDType()) str<<"p"; else str<<"u"; str<AstNodeDType::dump(str); str<<" "<AstNode::dump(str); str<<" L"<AstNode::dump(str); str<<" -> "<AstNode::dump(str); str<<" -> "<AstNode::dump(str); if (declRange().ranged()) { str<<" decl"<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]"; if (!attrClocker().unknown()) 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.916/src/V3Cdc.h0000664000177100017500000000225513205574202015366 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3TraceDecl.h0000664000177100017500000000224713205574202016524 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves Tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Unroll.h0000664000177100017500000000234613205574202016151 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Split.cpp0000664000177100017500000005313213206352045016323 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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: explicit SplitPliVertex(V3Graph* graphp) : V3GraphVertex(graphp) {} virtual ~SplitPliVertex() {} virtual string name() const { return "*PLI*"; } virtual string dotColor() const { return "green"; } }; class SplitNodeVertex : public V3GraphVertex { AstNode* m_nodep; protected: SplitNodeVertex(V3Graph* graphp, AstNode* nodep) : V3GraphVertex(graphp), m_nodep(nodep) {} virtual ~SplitNodeVertex() {} // Accessors // Do not make accessor for nodep(), It may change due to // reordering a lower block, but we don't repair it virtual string name() const { if (m_nodep->name() == "") { return cvtToStr((void*)m_nodep); } else { return m_nodep->name(); } } }; class SplitLogicVertex : public SplitNodeVertex { uint32_t m_splitColor; // Copied from color() when determined public: SplitLogicVertex(V3Graph* graphp, AstNode* nodep) : SplitNodeVertex(graphp,nodep), m_splitColor(0) {} void splitColor(uint32_t flag) { m_splitColor=flag; } uint32_t splitColor() const { return m_splitColor; } virtual ~SplitLogicVertex() {} virtual string dotColor() const { return "yellow"; } }; class SplitVarStdVertex : public SplitNodeVertex { public: SplitVarStdVertex(V3Graph* graphp, AstNode* nodep) : SplitNodeVertex(graphp,nodep) {} virtual ~SplitVarStdVertex() {} virtual string dotColor() const { return "skyblue"; } }; class SplitVarPostVertex : public SplitNodeVertex { public: SplitVarPostVertex(V3Graph* graphp, AstNode* nodep) : SplitNodeVertex(graphp,nodep) {} virtual ~SplitVarPostVertex() {} virtual string name() const { return (string)"POST "+SplitNodeVertex::name(); } virtual string dotColor() const { return "CadetBlue"; } }; //###################################################################### // Edge types class SplitEdge : public V3GraphEdge { uint32_t m_ignoreInStep; // Step number that if set to, causes this edge to be ignored static uint32_t s_stepNum; // Global step number protected: enum { WEIGHT_NORMAL=10 }; SplitEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=CUTABLE) : V3GraphEdge(graphp, fromp, top, weight, cutable) ,m_ignoreInStep(0) {} virtual ~SplitEdge() {} public: // Iterator for graph functions static void incrementStep() { ++s_stepNum; } bool ignoreThisStep() const { return m_ignoreInStep == s_stepNum; } void setIgnoreThisStep() { m_ignoreInStep = s_stepNum; } virtual bool followScoreboard() const = 0; static bool followScoreboard(const V3GraphEdge* edgep) { const SplitEdge* oedgep = dynamic_cast(edgep); if (!oedgep) v3fatalSrc("Following edge of non-SplitEdge type"); if (oedgep->ignoreThisStep()) return false; return oedgep->followScoreboard(); } static bool followCyclic(const V3GraphEdge* edgep) { const SplitEdge* oedgep = dynamic_cast(edgep); if (!oedgep) v3fatalSrc("Following edge of non-SplitEdge type"); if (oedgep->ignoreThisStep()) return false; return true; } }; uint32_t SplitEdge::s_stepNum = 0; class SplitPostEdge : public SplitEdge { public: SplitPostEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL) {} virtual ~SplitPostEdge() {} virtual bool followScoreboard() const { return false; } virtual string dotColor() const { return "khaki"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; class SplitLVEdge : public SplitEdge { public: SplitLVEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL) {} virtual ~SplitLVEdge() {} virtual bool followScoreboard() const { return true; } virtual string dotColor() const { return "yellowGreen"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; class SplitRVEdge : public SplitEdge { public: SplitRVEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL) {} virtual ~SplitRVEdge() {} virtual bool followScoreboard() const { return true; } virtual string dotColor() const { return "green"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; struct SplitScorebdEdge : public SplitEdge { public: SplitScorebdEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL) {} virtual ~SplitScorebdEdge() {} virtual bool followScoreboard() const { return true; } virtual string dotColor() const { return "blue"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; struct SplitStrictEdge : public SplitEdge { // A strict order, based on the original statement order in the graph // The only non-cutable edge type public: SplitStrictEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL, NOT_CUTABLE) {} virtual ~SplitStrictEdge() {} virtual bool followScoreboard() const { return true; } virtual string dotColor() const { return "blue"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; //###################################################################### // Split class functions class SplitVisitor : public AstNVisitor { private: // NODE STATE // AstVarScope::user1p -> Var SplitNodeVertex* for usage var, 0=not set yet // AstVarScope::user2p -> Var SplitNodeVertex* for delayed assignment var, 0=not set yet // Ast*::user3p -> Statement SplitLogicVertex* (temporary only) // Ast*::user4 -> Current ordering number (reorderBlock usage) AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; AstUser4InUse m_inuser4; // TYPES typedef vector VStack; // STATE bool m_reorder; // Reorder statements vs. just splitting string m_noReorderWhy; // Reason we can't reorder VStack m_stmtStackps; // Current statements being tracked SplitPliVertex* m_pliVertexp; // Element specifying PLI ordering V3Graph m_graph; // Scoreboard of var usages/dependencies bool m_inDly; // Inside ASSIGNDLY V3Double0 m_statSplits; // Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void scoreboardClear() { //VV***** We reset user1p() and user2p on each block!!! m_inDly = false; m_graph.clear(); m_stmtStackps.clear(); m_pliVertexp = NULL; m_noReorderWhy = ""; AstNode::user1ClearTree(); AstNode::user2ClearTree(); AstNode::user3ClearTree(); AstNode::user4ClearTree(); } void scoreboardPli() { // Order all PLI statements with other PLI statements // This insures $display's and such remain in proper order // We don't prevent splitting out other non-pli statements, however. if (!m_pliVertexp) { m_pliVertexp = new SplitPliVertex(&m_graph); // m_graph.clear() will delete it } for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { // Both ways... new SplitScorebdEdge(&m_graph, *it, m_pliVertexp); new SplitScorebdEdge(&m_graph, m_pliVertexp, *it); } } void scoreboardPushStmt(AstNode* nodep) { //UINFO(9," push "<user3p()) nodep->v3fatalSrc("user3p should not be used; cleared in processBlock"); 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"); if (!color) nextp->v3fatalSrc("No node color assigned"); 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(); if (newListp) newListp = newListp->addNext(nextp); else newListp = nextp; } if (splitAlwaysp) { ++m_statSplits; AstAlways* alwaysp = new AstAlways(nodep->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) { UINFO(4," ALW "<=9) nodep->dumpTree(cout," alwIn:: "); scoreboardClear(); processBlock(nodep->bodysp()); if (debug()>=9) nodep->dumpTree(cout," alwOut: "); } virtual void visit(AstNodeIf* nodep) { 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) { m_inDly = true; UINFO(4," ASSIGNDLY "<iterateChildren(*this); m_inDly = false; } virtual void visit(AstVarRef* nodep) { 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) { // **** SPECIAL default type that sets PLI_ORDERING if (!m_stmtStackps.empty() && !nodep->isPure()) { UINFO(9," NotSplittable "<iterateChildren(*this); } public: // CONSTUCTORS SplitVisitor(AstNetlist* nodep, bool reorder) : m_reorder(reorder) { scoreboardClear(); nodep->accept(*this); } virtual ~SplitVisitor() { V3Stats::addStat("Optimizations, Split always", m_statSplits); } }; //###################################################################### // Split class functions void V3Split::splitReorderAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Split::splitAlwaysAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.916/src/VlcOptions.h0000664000177100017500000000514413205574202016564 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Command line options // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCOPTIONS_H_ #define _VLCOPTIONS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "config_rev.h" //###################################################################### // V3Options - Command line options typedef vector VlStringList; typedef set VlStringSet; class VlcOptions { // MEMBERS (general options) string m_annotateOut; // main switch: --annotate I bool m_annotateAll; // main switch: --annotate-all int m_annotateMin; // main switch: --annotate-min I VlStringSet m_readFiles; // main switch: --read bool m_rank; // main switch: --rank bool m_unlink; // main switch: --unlink string m_writeFile; // main switch: --write private: // METHODS void showVersion(bool verbose); bool onoff(const char* sw, const char* arg, bool& flag); public: // CONSTRUCTORS VlcOptions() { m_annotateAll = false; m_annotateMin = 10; m_rank = false; m_unlink = false; } ~VlcOptions() {} void setDebugMode(int level); // METHODS void parseOptsList(int argc, char** argv); void addReadFile(const string& filename); // ACCESSORS (options) const VlStringSet& readFiles() const { return m_readFiles; } string annotateOut() const { return m_annotateOut; } bool annotateAll() const { return m_annotateAll; } int annotateMin() const { return m_annotateMin; } bool rank() const { return m_rank; } bool unlink() const { return m_unlink; } string writeFile() const { return m_writeFile; } // METHODS (from main) static string version(); }; //###################################################################### #endif // guard verilator-3.916/src/V3FileLine.cpp0000664000177100017500000002206213205574202016715 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Error handling // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 VL_INCLUDE_UNORDERED_SET #include "V3Error.h" #include "V3FileLine.h" #ifndef _V3ERROR_NO_GLOBAL_ # include "V3Ast.h" # include "V3Global.h" # include "V3Stats.h" # include "V3Config.h" #endif //###################################################################### // FileLineSingleton class functions const string FileLineSingleton::filenameLetters(int no) { const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number char out[size]; char* op = out+size-1; *--op = '\0'; // We build backwards int num = no; do { *--op = 'a'+num%26; num /= 26; } while (num); return op; } //! Convert filenames to a filenameno //! This lets us assign a nice small identifier for debug messages, but more //! importantly lets us use a 4 byte int instead of 8 byte pointer in every //! FileLine. //! We associate a language with each source file, so we also set the default //! for this. int FileLineSingleton::nameToNumber(const string& filename) { FileNameNumMap::const_iterator it = m_namemap.find(filename); if (VL_LIKELY(it != m_namemap.end())) return it->second; int num = m_names.size(); m_names.push_back(filename); m_languages.push_back(V3LangCode::mostRecent()); m_namemap.insert(make_pair(filename,num)); return num; } //! Support XML output //! Experimental. Updated to also put out the language. void FileLineSingleton::fileNameNumMapDumpXml(ostream& os) { os<<"\n"; for (FileNameNumMap::const_iterator it = m_namemap.begin(); it != m_namemap.end(); ++it) { os<<"second) <<"\" filename=\""<first <<"\" language=\""<second).ascii()<<"\"/>\n"; } os<<"\n"; } //###################################################################### // FileLine class functions FileLine::FileLine(FileLine::EmptySecret) { // Sort of a singleton m_lineno=0; m_filenameno=singleton().nameToNumber("AstRoot"); m_warnOn=0; for (int codei=V3ErrorCode::EC_MIN; codeiascii()<<": "<warnIsOff(code)) { warnOff(code, true); } } } void FileLine::v3errorEnd(ostringstream& str) { if (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"); } ::operator delete(objp); } #endif void FileLine::deleteAllRemaining() { #ifdef VL_LEAK_CHECKS // FileLines are allocated, but never nicely freed, as it's much faster // that way. Unfortunately this makes our leak checking a big mess, so // only when leak checking we'll track them all and cleanup. while (1) { FileLineCheckSet::iterator it=fileLineLeakChecks.begin(); if (it==fileLineLeakChecks.end()) break; delete *it; // Operator delete will remove the iterated object from the list. // Eventually the list will be empty and terminate the loop. } fileLineLeakChecks.clear(); singleton().clear(); #endif } verilator-3.916/src/V3EmitC.h0000664000177100017500000000235613205574202015700 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit C++ code for module tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EMITC_H_ #define _V3EMITC_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3EmitC { public: static void emitc(); static void emitcInlines(); static void emitcSyms(); static void emitcTrace(); }; #endif // Guard verilator-3.916/src/V3Inst.h0000664000177100017500000000255513205574202015615 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity inst domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3INST_H_ #define _V3INST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Inst { public: static void instAll(AstNetlist* nodep); static void dearrayAll(AstNetlist* nodep); static AstAssignW* pinReconnectSimple(AstPin* nodep, AstCell* cellp, AstNodeModule* modp, bool forTristate, bool alwaysCvt=false); }; #endif // Guard verilator-3.916/src/V3SplitAs.h0000664000177100017500000000230713205574202016252 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3SPLITAS_H_ #define _V3SPLITAS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3SplitAs { public: static void splitAsAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3GenClk.cpp0000664000177100017500000001725213205574202016376 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Generated Clock repairs // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // GENCLK TRANSFORMATIONS: // Follow control-flow graph with assignments and var usages // ASSIGNDLY to variable later used as clock requires change detect // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3GenClk.h" #include "V3Ast.h" //###################################################################### // GenClk state, as a visitor of each AstNode class GenClkBaseVisitor : public AstNVisitor { protected: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### // GenClk Read class GenClkRenameVisitor : public GenClkBaseVisitor { private: // NODE STATE // Cleared on top scope // AstVarScope::user2() -> AstVarScope*. Signal replacing activation with // AstVarRef::user3() -> bool. Signal is replaced activation (already done) AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; // STATE AstActive* m_activep; // Inside activate statement AstNodeModule* m_topModp; // Top module AstScope* m_scopetopp; // Scope under TOPSCOPE // METHODS AstVarScope* genInpClk(AstVarScope* vscp) { if (vscp->user2p()) { return vscp->user2p()->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) { 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) { // 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); VL_DANGLING(nodep); } } } virtual void visit(AstActive* nodep) { m_activep = nodep; nodep->sensesp()->iterateChildren(*this); // iterateAndNext? m_activep = NULL; nodep->iterateChildren(*this); } virtual void visit(AstCFunc* nodep) { nodep->iterateChildren(*this); } //----- virtual void visit(AstNode* nodep) { 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 AstCFunc* m_tracingCallp; // Currently tracing a call to this cfunc AstNodeAssign* m_assignp; // Inside assigndly statement AstNodeModule* m_topModp; // Top module // VISITORS virtual void visit(AstTopScope* nodep) { 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) { // Only track the top scopes, not lower level functions if (nodep->isTop()) { m_topModp = nodep; nodep->iterateChildren(*this); } } virtual void visit(AstCCall* nodep) { nodep->iterateChildren(*this); // Enter the function and trace it m_tracingCallp = nodep->funcp(); nodep->funcp()->accept(*this); } virtual void visit(AstCFunc* nodep) { if (m_tracingCallp != nodep) { // Only consider logic within a CFunc when looking // at the call to it, and not when scanning whatever // scope it happens to live beneath. return; } m_tracingCallp = NULL; nodep->iterateChildren(*this); } //---- virtual void visit(AstVarRef* nodep) { // 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) { //UINFO(8,"ASS "<iterateChildren(*this); m_assignp = NULL; } virtual void visit(AstActive* nodep) { UINFO(8,"ACTIVE "<sensesp()->iterateChildren(*this); // iterateAndNext? m_activep = NULL; nodep->iterateChildren(*this); } //----- virtual void visit(AstVar*) {} // Don't want varrefs under it virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit GenClkReadVisitor(AstNetlist* nodep) : m_activep(NULL) , m_tracingCallp(NULL) , m_assignp(NULL) , m_topModp(NULL) { nodep->accept(*this); } virtual ~GenClkReadVisitor() {} }; //###################################################################### // GenClk class functions void V3GenClk::genClkAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3ActiveTop.cpp0000664000177100017500000001343513205574202017130 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity active domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Active's Transformations: // // Note this can be called multiple times. // Across all ACTIVES // SenTrees are now under each ACTIVE statement, we want them global: // Find SenTree in under global TopScope, or create it there // Move SenTree the global SenTree // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3ActiveTop.h" #include "V3Ast.h" #include "V3SenTree.h" #include "V3Const.h" //###################################################################### // Active class functions class ActiveTopVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist // AstNode::user() bool. True if processed // Each call to V3Const::constify // AstNode::user4() Used by V3Const::constify, called below AstUser1InUse m_inuser1; // STATE AstTopScope* m_topscopep; // Top scope for adding sentrees under SenTreeFinder m_finder; // Find global sentree's and add them // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstTopScope* nodep) { m_topscopep = nodep; m_finder.main(m_topscopep); nodep->iterateChildren(*this); m_topscopep = NULL; } virtual void visit(AstNodeModule* nodep) { // 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) { 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(); VL_DANGLING(nodep); 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"); 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) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstAssignAlias* nodep) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstAssignW* nodep) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstAlways* nodep) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstAlwaysPublic* nodep) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstFinal* nodep) { nodep->v3fatalSrc("Node should have been deleted"); } // Empty visitors, speed things up virtual void visit(AstNodeMath* nodep) {} virtual void visit(AstVarScope* nodep) {} //-------------------- virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit ActiveTopVisitor(AstNetlist* nodep) { m_topscopep = NULL; nodep->accept(*this); } virtual ~ActiveTopVisitor() {} }; //###################################################################### // Active class functions void V3ActiveTop::activeTopAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3TraceDecl.cpp0000664000177100017500000002661613205574202017065 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3TraceDecl's Transformations: // Create trace CFUNCs // For each VARSCOPE // If appropriate type of signal, create a TRACE // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3TraceDecl.h" #include "V3EmitCBase.h" #include "V3Stats.h" //###################################################################### // TraceDecl state, as a visitor of each AstNode class TraceDeclVisitor : public EmitCBaseVisitor { private: // NODE STATE // STATE AstScope* m_scopetopp; // Current top scope AstCFunc* m_initFuncp; // Trace function being built AstCFunc* m_initSubFuncp; // Trace function being built (under m_init) int m_initSubStmts; // Number of statements in function AstCFunc* m_fullFuncp; // Trace function being built AstCFunc* m_chgFuncp; // Trace function being built int m_funcNum; // Function number being built AstVarScope* m_traVscp; // Signal being trace constructed AstNode* m_traValuep; // Signal being traced's value to trace in it string m_traShowname; // Signal being traced's component name V3Double0 m_statSigs; // Statistic tracking V3Double0 m_statIgnSigs; // Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } const char* vscIgnoreTrace(AstVarScope* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3Coverage::varIgnoreToggle AstVar* varp = nodep->varp(); if (!varp->isTrace()) { return "Verilator trace_off"; } else if (!nodep->isTrace()) { return "Verilator cell trace_off"; } else if (!v3Global.opt.traceUnderscore()) { string prettyName = varp->prettyName(); if (prettyName.size()>=1 && prettyName[0] == '_') return "Leading underscore"; if (prettyName.find("._") != string::npos) return "Inlined leading underscore"; } return NULL; } AstCFunc* newCFunc(AstCFuncType type, const string& name, bool slow) { AstCFunc* funcp = new AstCFunc(m_scopetopp->fileline(), name, m_scopetopp); funcp->slow(slow); funcp->argTypes(EmitCBaseVisitor::symClassVar()+", "+v3Global.opt.traceClassBase()+"* vcdp, uint32_t code"); funcp->funcType(type); funcp->symProlog(true); m_scopetopp->addActivep(funcp); UINFO(5," Newfunc "<name()+"__"+cvtToStr(++m_funcNum); AstCFunc* funcp = NULL; if (basep->funcType()==AstCFuncType::TRACE_INIT) { funcp = newCFunc(AstCFuncType::TRACE_INIT_SUB, name, basep->slow()); } else { basep->v3fatalSrc("Strange base function type"); } // cppcheck-suppress nullPointer // above fatal prevents it AstCCall* callp = new AstCCall(funcp->fileline(), funcp); callp->argTypes("vlSymsp, vcdp, code"); basep->addStmtsp(callp); return funcp; } void addTraceDecl(const VNumRange& arrayRange, int widthOverride) { // If !=0, is packed struct/array where basicp size misreflects one element VNumRange bitRange; AstBasicDType* bdtypep = m_traValuep->dtypep()->basicp(); if (widthOverride) bitRange = VNumRange(widthOverride-1,0,false); else if (bdtypep) bitRange = bdtypep->nrange(); AstTraceDecl* declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname, m_traValuep, bitRange, arrayRange); UINFO(9,"Decl "< v3Global.opt.outputSplitCTrace()) { m_initSubFuncp = newCFuncSub(m_initFuncp); m_initSubStmts = 0; } m_initSubFuncp->addStmtsp(declp); m_initSubStmts += EmitCBaseCounterVisitor(declp).count(); m_chgFuncp->addStmtsp(new AstTraceInc(m_traVscp->fileline(), declp, m_traValuep->cloneTree(true))); // The full version will get constructed in V3Trace } void addIgnore(const char* why) { ++m_statIgnSigs; m_initSubFuncp->addStmtsp( new AstComment(m_traVscp->fileline(), "Tracing: "+m_traShowname+" // Ignored: "+why)); } // VISITORS virtual void visit(AstTopScope* nodep) { 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) { nodep->iterateChildren(*this); // Avoid updating this if (), instead see varp->isTrace() if (!nodep->varp()->isTemp() && !nodep->varp()->isFuncLocal()) { UINFO(5, " vsc "<varp(); AstScope* scopep = nodep->scopep(); // Compute show name // This code assumes SPTRACEVCDC_VERSION >= 1330; // it uses spaces to separate hierarchy components. m_traShowname = AstNode::vcdName(scopep->name() + " " + varp->name()); if (m_traShowname.substr(0,4) == "TOP ") m_traShowname.replace(0,4,""); if (!m_initSubFuncp) nodep->v3fatalSrc("NULL"); m_traVscp = nodep; m_traValuep = NULL; if (vscIgnoreTrace(nodep)) { addIgnore(vscIgnoreTrace(nodep)); } else { ++m_statSigs; if (nodep->valuep()) m_traValuep = nodep->valuep()->cloneTree(true); else m_traValuep = new AstVarRef(nodep->fileline(), nodep, false); { // Recurse into data type of the signal; the visitors will call addTraceDecl() varp->dtypeSkipRefp()->accept(*this); } // Cleanup if (m_traValuep) { m_traValuep->deleteTree(); m_traValuep=NULL; } } m_traVscp = NULL; m_traValuep = NULL; m_traShowname = ""; } } // VISITORS - Data types when tracing virtual void visit(AstConstDType* nodep) { if (m_traVscp) { nodep->subDTypep()->skipRefp()->accept(*this); } } virtual void visit(AstRefDType* nodep) { if (m_traVscp) { nodep->subDTypep()->skipRefp()->accept(*this); } } virtual void visit(AstUnpackArrayDType* nodep) { // Note more specific dtypes above if (m_traVscp) { if ((int)nodep->arrayUnpackedElements() > v3Global.opt.traceMaxArray()) { addIgnore("Wide memory > --trace-max-array ents"); } else if (nodep->subDTypep()->skipRefp()->castBasicDType() // Nothing lower than this array && m_traVscp->dtypep()->skipRefp() == nodep) { // Nothing above this array // Simple 1-D array, use exising V3EmitC runtime loop rather than unrolling // This will put "(index)" at end of signal name for us addTraceDecl(nodep->declRange(), 0); } else { // Unroll now, as have no other method to get right signal names AstNodeDType* subtypep = nodep->subDTypep()->skipRefp(); for (int i=nodep->lsb(); i<=nodep->msb(); ++i) { string oldShowname = m_traShowname; AstNode* oldValuep = m_traValuep; { m_traShowname += string("(")+cvtToStr(i)+string(")"); m_traValuep = new AstArraySel(nodep->fileline(), m_traValuep->cloneTree(true), i - nodep->lsb()); subtypep->accept(*this); m_traValuep->deleteTree(); m_traValuep = NULL; } m_traShowname = oldShowname; m_traValuep = oldValuep; } } } } virtual void visit(AstPackArrayDType* nodep) { if (m_traVscp) { if (!v3Global.opt.traceStructs()) { // Everything downstream is packed, so deal with as one trace unit // This may not be the nicest for user presentation, but is a much faster way to trace addTraceDecl(VNumRange(), nodep->width()); } else { AstNodeDType* subtypep = nodep->subDTypep()->skipRefp(); for (int i=nodep->lsb(); i<=nodep->msb(); ++i) { string oldShowname = m_traShowname; AstNode* oldValuep = m_traValuep; { m_traShowname += string("(")+cvtToStr(i)+string(")"); m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), (i - nodep->lsb())*subtypep->width(), subtypep->width()); subtypep->accept(*this); m_traValuep->deleteTree(); m_traValuep = NULL; } m_traShowname = oldShowname; m_traValuep = oldValuep; } } } } virtual void visit(AstNodeClassDType* nodep) { if (m_traVscp) { if (nodep->packed() && !v3Global.opt.traceStructs()) { // Everything downstream is packed, so deal with as one trace unit // This may not be the nicest for user presentation, but is a much faster way to trace addTraceDecl(VNumRange(), nodep->width()); } else { if (!nodep->packed()) { addIgnore("Unsupported: Unpacked struct/union"); } else { for (AstMemberDType* itemp = nodep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) { AstNodeDType* subtypep = itemp->subDTypep()->skipRefp(); string oldShowname = m_traShowname; AstNode* oldValuep = m_traValuep; { m_traShowname += string(" ")+itemp->prettyName(); if (nodep->castStructDType()) { m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), itemp->lsb(), subtypep->width()); subtypep->accept(*this); m_traValuep->deleteTree(); m_traValuep = NULL; } else { // Else union, replicate fields subtypep->accept(*this); } } m_traShowname = oldShowname; m_traValuep = oldValuep; } } } } } virtual void visit(AstBasicDType* nodep) { if (m_traVscp) { if (nodep->keyword()==AstBasicDTypeKwd::STRING) { addIgnore("Unsupported: strings"); } else { addTraceDecl(VNumRange(), 0); } } } virtual void visit(AstNodeDType* nodep) { // Note more specific dtypes above if (!m_traVscp) return; addIgnore("Unsupported: data type"); } //-------------------- virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit TraceDeclVisitor(AstNetlist* nodep) { m_scopetopp = NULL; m_initFuncp = NULL; m_initSubFuncp = NULL; m_initSubStmts = 0; m_fullFuncp = NULL; m_chgFuncp = NULL; m_funcNum = 0; m_traVscp = NULL; m_traValuep = NULL; nodep->accept(*this); } virtual ~TraceDeclVisitor() { V3Stats::addStat("Tracing, Traced signals", m_statSigs); V3Stats::addStat("Tracing, Ignored signals", m_statIgnSigs); } }; //###################################################################### // Trace class functions void V3TraceDecl::traceDeclAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Inline.h0000664000177100017500000000224113205574202016106 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Inlining of modules // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3INLINE_H_ #define _V3INLINE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Inline { public: static void inlineAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3Begin.cpp0000664000177100017500000002326513205601572016261 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Removal of named begin blocks // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Begin's Transformations: // // Each module: // Look for BEGINs // BEGIN(VAR...) -> VAR ... {renamed} // FOR -> WHILEs // // There are two scopes; named BEGINs change %m and variable scopes. // Unnamed BEGINs change only variable, not $display("%m") scope. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Begin.h" #include "V3Inst.h" #include "V3Ast.h" //###################################################################### class BeginState { private: // NODE STATE //Entire netlist: // AstNodeFTask::user1 -> bool, 1=processed AstUser1InUse m_inuser1; bool m_anyFuncInBegin; public: BeginState() { m_anyFuncInBegin = false; } ~BeginState() {} void userMarkChanged(AstNode* 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) { m_modp = nodep; m_repeatNum = 0; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstNodeFTask* nodep) { 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) { // 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); VL_DANGLING(nodep); } virtual void visit(AstVar* nodep) { if (m_unnamedScope != "") { // Rename it nodep->name(m_unnamedScope+"__DOT__"+nodep->name()); m_statep->userMarkChanged(nodep); // 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) { UINFO(8," CELL "<userMarkChanged(nodep); // Rename it nodep->name(m_namedScope+"__DOT__"+nodep->name()); UINFO(8," rename to "<name()<unlinkFrBack(); m_modp->addStmtp(nodep); } nodep->iterateChildren(*this); } virtual void visit(AstVarXRef* nodep) { UINFO(9, " VARXREF "<inlinedDots() == "") { nodep->inlinedDots(m_namedScope); UINFO(9, " rescope to "<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) { // 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) { // 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) { 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) { if (nodep->taskp()->user1()) { // It was converted UINFO(9, " relinkFTask "<name(nodep->taskp()->name()); } nodep->iterateChildren(*this); } virtual void visit(AstVarRef* nodep) { if (nodep->varp()->user1()) { // It was converted UINFO(9, " relinVarRef "<name(nodep->varp()->name()); } nodep->iterateChildren(*this); } virtual void visit(AstIfaceRefDType* nodep) { // May have changed cell names // TypeTable is always after all modules, so names are stable UINFO(8," IFACEREFDTYPE "<cellp()) nodep->cellName(nodep->cellp()->name()); UINFO(8," rename to "<iterateChildren(*this); } //-------------------- virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS BeginRelinkVisitor(AstNetlist* nodep, BeginState*) { nodep->accept(*this); } virtual ~BeginRelinkVisitor() {} }; //###################################################################### // Task class functions void V3Begin::debeginAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Scope.cpp0000664000177100017500000003403313205574202016300 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Scope's Transformations: // // For every CELL that references this module, create a // SCOPE // {all blocked statements} // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Scope.h" #include "V3Ast.h" //###################################################################### // Scope class functions class ScopeVisitor : public AstNVisitor { private: // NODE STATE // AstVar::user1p -> AstVarScope replacement for this variable // AstTask::user2p -> AstTask*. Replacement task AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // TYPES typedef map PackageScopeMap; typedef map, AstVarScope*> VarScopeMap; typedef set > VarRefScopeSet; // STATE, inside processing a single module AstNodeModule* m_modp; // Current module AstScope* m_scopep; // Current scope we are building // STATE, for passing down one level of hierarchy (may need save/restore) AstCell* m_aboveCellp; // Cell that instantiates this module AstScope* m_aboveScopep; // Scope that instantiates this scope PackageScopeMap m_packageScopes; // Scopes for each package VarScopeMap m_varScopes; // Varscopes created for each scope and var VarRefScopeSet m_varRefScopes; // Varrefs-in-scopes needing fixup when donw // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void cleanupVarRefs() { for (VarRefScopeSet::iterator it = m_varRefScopes.begin(); it!=m_varRefScopes.end(); ++it) { AstVarRef* nodep = it->first; AstScope* scopep = it->second; if (nodep->packagep()) { PackageScopeMap::iterator it2 = m_packageScopes.find(nodep->packagep()); if (it2==m_packageScopes.end()) nodep->v3fatalSrc("Can't locate package scope"); scopep = it2->second; } VarScopeMap::iterator it3 = m_varScopes.find(make_pair(nodep->varp(), scopep)); if (it3==m_varScopes.end()) nodep->v3fatalSrc("Can't locate varref scope"); AstVarScope* varscp = it3->second; nodep->varScopep(varscp); } } // VISITORS virtual void visit(AstNetlist* nodep) { AstNodeModule* modp = nodep->topModulep(); if (!modp) { nodep->v3error("No root module specified"); return; } // Operate starting at the top of the hierarchy m_aboveCellp = NULL; m_aboveScopep = NULL; modp->accept(*this); cleanupVarRefs(); } virtual void visit(AstNodeModule* nodep) { // Create required blocks and add to module string scopename; if (!m_aboveScopep) scopename = "TOP"; else scopename = m_aboveScopep->name()+"."+m_aboveCellp->name(); UINFO(4," MOD AT "<fileline(), nodep, scopename, m_aboveScopep, m_aboveCellp); if (nodep->castPackage()) m_packageScopes.insert(make_pair(nodep->castPackage(), m_scopep)); // Now for each child cell, iterate the module this cell points to for (AstNode* cellnextp = nodep->stmtsp(); cellnextp; cellnextp=cellnextp->nextp()) { if (AstCell* cellp = cellnextp->castCell()) { AstScope* oldScopep = m_scopep; AstCell* oldAbCellp = m_aboveCellp; AstScope* oldAbScopep = m_aboveScopep; { m_aboveCellp = cellp; m_aboveScopep = m_scopep; AstNodeModule* modp = cellp->modp(); if (!modp) cellp->v3fatalSrc("Unlinked mod"); modp->accept(*this); // Recursive call to visit(AstNodeModule) } // Done, restore vars m_scopep = oldScopep; m_aboveCellp = oldAbCellp; m_aboveScopep = oldAbScopep; } } // Create scope for the current usage of this module UINFO(4," back AT "<isTop()) { AstTopScope* topscp = new AstTopScope(nodep->fileline(), m_scopep); m_modp->addStmtp(topscp); } else { m_modp->addStmtp(m_scopep); } // Copy blocks into this scope // If this is the first usage of the block ever, we can simply move the reference nodep->iterateChildren(*this); // ***Note m_scopep is passed back to the caller of the routine (above) } virtual void visit(AstActive* nodep) { nodep->v3fatalSrc("Actives now made after scoping"); } virtual void visit(AstInitial* nodep) { // 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) { // 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) { // 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) { // 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) { // 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) { // 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) { // 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) { // 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) { // 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) { // 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) { // Make new scope variable // This is called cross-module by AstVar, so we cannot trust any m_ variables if (!nodep->user1p()) { AstVarScope* varscp = new AstVarScope(nodep->fileline(), m_scopep, nodep); UINFO(6," New scope "<isTrace()) varscp->trace(false); nodep->user1p(varscp); if (v3Global.opt.isClocker(varscp->prettyName())) { nodep->attrClocker(AstVarAttrClocker::CLOCKER_YES); } if (v3Global.opt.isNoClocker(varscp->prettyName())) { nodep->attrClocker(AstVarAttrClocker::CLOCKER_NO); } if (!m_scopep) nodep->v3fatalSrc("No scope for var"); m_varScopes.insert(make_pair(make_pair(nodep, m_scopep), varscp)); m_scopep->addVarp(varscp); } } virtual void visit(AstVarRef* nodep) { // VarRef needs to point to VarScope // Make sure variable has made user1p. if (!nodep->varp()) nodep->v3fatalSrc("Unlinked"); if (nodep->varp()->isIfaceRef()) { nodep->varScopep(NULL); } else { // We may have not made the variable yet, and we can't make it now as // the var's referenced package etc might not be created yet. // So push to a list and post-correct m_varRefScopes.insert(make_pair(nodep, m_scopep)); } } virtual void visit(AstScopeName* nodep) { // If there's a %m in the display text, we add a special node that will contain the name() string prefix = (string)("__DOT__")+m_scopep->name(); // TOP and above will be the user's name(). // Note 'TOP.' is stripped by scopePrettyName // To keep correct visual order, must add before other Text's AstNode* afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeAttrp(new AstText(nodep->fileline(), prefix)); if (afterp) nodep->scopeAttrp(afterp); afterp = nodep->scopeEntrp(); if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeEntrp(new AstText(nodep->fileline(), prefix)); if (afterp) nodep->scopeEntrp(afterp); nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep) { // 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) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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) { // 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. // Certain nodes can be referenced later in this pass, notably // an FTaskRef needs to access the FTask to find the cloned task pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep); } } virtual void visit(AstInitial* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstFinal* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstAssignAlias* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstAssignVarScope* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstAssignW* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstAlways* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstAlwaysPublic* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstCoverToggle* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstNodeFTask* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstCFunc* nodep) { movedDeleteOrIterate(nodep); } virtual void visit(AstVarXRef* nodep) { // The crossrefs are dealt with in V3LinkDot nodep->varp(NULL); } virtual void visit(AstNodeFTaskRef* nodep) { // 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()->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) { // The crossrefs are dealt with in V3LinkDot nodep->ftaskp(NULL); nodep->iterateChildren(*this); } //-------------------- // Default virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit ScopeCleanupVisitor(AstNetlist* nodep) { m_scopep = NULL; nodep->accept(*this); } virtual ~ScopeCleanupVisitor() {} }; //###################################################################### // Scope class functions void V3Scope::scopeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3DepthBlock.h0000664000177100017500000000227313205574202016714 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3DEPTHBLOCK_H_ #define _V3DEPTHBLOCK_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3DepthBlock { public: static void depthBlockAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3PreLex.h0000664000177100017500000001737213205574202016102 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilog::Preproc: Internal header for lex interfacing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2000-2017 by Wilson Snyder. This program is free software; // you can redistribute it and/or modify it under the terms of either the // GNU Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // This header provides the interface between the lex proper V3PreLex.l/.cpp // and the class implementation file V3Pre.cpp // It is not intended for user applications. //************************************************************************* #ifndef _VPREPROCLEX_H_ // Guard #define _VPREPROCLEX_H_ 1 #include #include #include "V3Error.h" #include "V3FileLine.h" //====================================================================== class V3PreLex; class V3PreProcImp; // Token codes // If changing, see V3PreProc.cpp's V3PreProcImp::tokenName() #define VP_EOF 0 #define VP_INCLUDE 256 #define VP_IFDEF 257 #define VP_IFNDEF 258 #define VP_ENDIF 259 #define VP_UNDEF 260 #define VP_DEFINE 261 #define VP_ELSE 262 #define VP_ELSIF 263 #define VP_LINE 264 #define VP_UNDEFINEALL 265 #define VP_SYMBOL 300 #define VP_STRING 301 #define VP_DEFVALUE 302 #define VP_COMMENT 303 #define VP_TEXT 304 #define VP_WHITE 305 #define VP_DEFREF 306 #define VP_DEFARG 307 #define VP_ERROR 308 #define VP_DEFFORM 309 #define VP_STRIFY 310 #define VP_BACKQUOTE 311 #define VP_SYMBOL_JOIN 312 #define VP_DEFREF_JOIN 313 #define VP_JOIN 314 #define VP_PSL 350 //====================================================================== // Externs created by flex // We add a prefix so that other lexers/flexers in the same program won't collide. #ifndef yy_create_buffer # define yy_create_buffer V3PreLex_create_buffer # define yy_delete_buffer V3PreLex_delete_buffer # define yy_scan_buffer V3PreLex_scan_buffer # define yy_scan_string V3PreLex_scan_string # define yy_scan_bytes V3PreLex_scan_bytes # define yy_flex_debug V3PreLex_flex_debug # define yy_init_buffer V3PreLex_init_buffer # define yy_flush_buffer V3PreLex_flush_buffer # define yy_load_buffer_state V3PreLex_load_buffer_state # define yy_switch_to_buffer V3PreLex_switch_to_buffer # define yyin V3PreLexin # define yyleng V3PreLexleng # define yylex V3PreLexlex # define yyout V3PreLexout # define yyrestart V3PreLexrestart # define yytext V3PreLextext # define yyerror V3PreLexerror # define yyerrorf V3PreLexerrorf #endif #ifndef yyourleng # define yyourleng V3PreLexourleng # define yyourtext V3PreLexourtext #endif #ifndef YY_BUFFER_STATE struct yy_buffer_state; typedef struct yy_buffer_state *YY_BUFFER_STATE; # define YY_BUF_SIZE 16384 #endif extern int yylex(); extern void yyrestart(FILE*); // Accessors, because flex keeps changing the type of yyleng extern char* yyourtext(); extern size_t yyourleng(); extern void yyourtext(const char* textp, size_t size); // Must call with static YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ); void yy_delete_buffer( YY_BUFFER_STATE b ); //====================================================================== #define KEEPCMT_SUB 2 #define KEEPCMT_EXP 3 //====================================================================== // Entry for each file processed; a stack of entries included class VPreStream { public: FileLine* m_curFilelinep; // Current processing point (see also m_tokFilelinep) V3PreLex* m_lexp; // Lexer, for resource tracking deque m_buffers; // Buffer of characters to process int m_ignNewlines; // Ignore multiline newlines bool m_eof; // "EOF" buffer bool m_file; // Buffer is start of new file int m_termState; // Termination fsm VPreStream(FileLine* fl, V3PreLex* lexp) : m_curFilelinep(fl), m_lexp(lexp), m_ignNewlines(0), m_eof(false), m_file(false), m_termState(0) { lexStreamDepthAdd(1); } ~VPreStream() { lexStreamDepthAdd(-1); } private: void lexStreamDepthAdd(int delta); }; //====================================================================== // Class entry for each per-lexer state class V3PreLex { public: // Used only by V3PreLex.cpp and V3PreProc.cpp V3PreProcImp* m_preimpp; // Preprocessor lexor belongs to stack m_streampStack; // Stack of processing files int m_streamDepth; // Depth of stream processing YY_BUFFER_STATE m_bufferState; // Flex state FileLine* m_tokFilelinep; // Starting position of current token // State to lexer static V3PreLex* s_currentLexp; ///< Current lexing point int m_keepComments; ///< Emit comments in output text int m_keepWhitespace; ///< Emit all whitespace in output text bool m_pedantic; ///< Obey standard; don't Substitute `error // State from lexer int m_formalLevel; // Parenthesis counting inside def formals int m_parenLevel; // Parenthesis counting inside def args bool m_defCmtSlash; // /*...*/ comment in define had \ ending bool m_defQuote; // Definition value inside quote string m_defValue; // Definition value being built. int m_enterExit; // For VL_LINE, the enter/exit level // CONSTRUCTORS V3PreLex(V3PreProcImp* preimpp, FileLine* filelinep) { m_preimpp = preimpp; m_streamDepth = 0; m_keepComments = 0; m_keepWhitespace = 1; m_pedantic = false; m_formalLevel = 0; m_parenLevel = 0; m_defQuote = false; m_defCmtSlash = false; m_tokFilelinep = filelinep; m_enterExit = 0; initFirstBuffer(filelinep); } ~V3PreLex() { while (!m_streampStack.empty()) { delete m_streampStack.top(); m_streampStack.pop(); } yy_delete_buffer(m_bufferState); m_bufferState=NULL; } // Called by V3PreLex.l from lexer VPreStream* curStreamp() { return m_streampStack.top(); } // Can't be empty, "EOF" is on top FileLine* curFilelinep() { return curStreamp()->m_curFilelinep; } void curFilelinep(FileLine* fl) { curStreamp()->m_curFilelinep = fl; } void appendDefValue(const char* textp, size_t len) { m_defValue.append(textp,len); } void lineDirective(const char* textp); void linenoInc() { if (curStreamp()->m_ignNewlines) curStreamp()->m_ignNewlines--; else curFilelinep()->linenoInc(); } // Called by V3PreProc.cpp to inform lexer void pushStateDefArg(int level); void pushStateDefForm(); void pushStateDefValue(); void pushStateIncFilename(); void scanNewFile(FileLine* filelinep); void scanBytes(const string& str); void scanBytesBack(const string& str); size_t inputToLex(char* buf, size_t max_size); /// Called by V3PreProc.cpp to get data from lexer YY_BUFFER_STATE currentBuffer(); int lex(); int currentStartState() const; void dumpSummary(); void dumpStack(); void unused(); // Called by VPreStream void streamDepthAdd(int delta) { m_streamDepth += delta; } int streamDepth() const { return m_streamDepth; } /// Utility static int debug(); static void debug(int level); static string cleanDbgStrg(const string& in); private: string currentUnreadChars(); string endOfStream(bool& againr); void initFirstBuffer(FileLine* filelinep); void scanSwitchStream(VPreStream* streamp); }; inline void VPreStream::lexStreamDepthAdd(int delta) { m_lexp->streamDepthAdd(delta); } #endif // Guard verilator-3.916/src/bisonpre0000775000177100017500000004041713205574202016064 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### require 5.006_001; use Getopt::Long; use IO::File; use Pod::Usage; use strict; use vars qw ($Debug $VERSION); $VERSION = '3.404'; our $Self; #====================================================================== # main our $Opt_Debug; our $Opt_Definitions; our $Opt_File_Prefix; our $Opt_Name_Prefix; our $Opt_Output; our $Opt_Token_Table; our $Opt_Verbose; our $Opt_Yacc = "bison"; our $Opt_Input; autoflush STDOUT 1; autoflush STDERR 1; Getopt::Long::config ("no_auto_abbrev"); if (! GetOptions ( # Local options "help" => \&usage, "version" => sub { print "Version $VERSION\n"; exit(0); }, "yacc=s" => \$Opt_Yacc, # Passed to Bison "t|debug" => sub { $Opt_Debug = 1; }, "b|file-prefix=s" => \$Opt_File_Prefix, "d" => \$Opt_Definitions, "k|token-table" => \$Opt_Token_Table, "o=s" => \$Opt_Output, "p|name-prefix=s" => \$Opt_Name_Prefix, "v|verbose" => \$Opt_Verbose, "<>" => \¶meter, )) { die "%Error: Bad usage, try 'bisonpre --help'\n"; } $Opt_Input or die "bisonpre: %Error: input file not specified\n"; $Opt_Output or die "bisonpre: %Error: --o option is required\n"; process(); #---------------------------------------------------------------------- sub usage { print "Version $VERSION\n"; pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT, -noperldoc=>1); exit (1); } sub parameter { my $param = shift; if (!defined $Opt_Input) { $Opt_Input = $param; } else { die "bisonpre: %Error: Unknown parameter: $param\n"; } } ####################################################################### sub process { remove_outputs(); $Self->{bison_version} = bison_version_check(); my $supports_report = ($Self->{bison_version} >= 2.3); clean_input($Opt_Input, tmp_prefix().".y"); # Run bison my $command = ($Opt_Yacc .($Opt_Debug?" -t":"") .($Opt_Definitions?" -d":"") .($Opt_Token_Table?" -k":"") .($Opt_Verbose?" -v":"") .(($Opt_Verbose && $supports_report)?" --report=itemset --report=lookahead":"") # -p required for GLR parsers; they write to -p basename, not -o .($Opt_Name_Prefix?" -p $Opt_Name_Prefix":"") ." -b ".tmp_prefix() ." -o ".tmp_prefix().".c" ." ".tmp_prefix().".y" ); print " $command\n"; system $command; my $status = $?; if ($status != 0) { remove_outputs(); my $v = bison_version_check(); die "bisonpre: %Error: $Opt_Yacc version $v run failed due to errors\n"; } clean_output(tmp_prefix().".output",output_prefix().".output", 1,0); warning_check(output_prefix().".output"); clean_output(tmp_prefix().".c", output_prefix().".c", 0,1); clean_output(tmp_prefix().".h", output_prefix().".h", 0,1); remove_tmp(); } sub tmp_prefix { return output_prefix()."_pretmp"; } sub output_prefix { my $o; if ($Opt_Output) { (my $o = $Opt_Output) =~ s!\.[^.]*$!!; return $o; } else { return $Opt_File_Prefix.".tab"; } } sub remove_tmp { unlink(tmp_prefix().".c"); # Ok if errors unlink(tmp_prefix().".h"); # Ok if errors unlink(tmp_prefix().".output"); # Ok if errors } sub remove_outputs { remove_tmp(); unlink(output_prefix().".c"); # Ok if errors unlink(output_prefix().".h"); # Ok if errors # We don't remove .output file, as it's useful for debugging errors } sub bison_version_check { my $v = `$Opt_Yacc --version`; if ($v && $v =~ /([0-9]+\.[0-9]+)/) { my $v = $1; ($v >= 1.875) or die "bisonpre: %Error: '$Opt_Yacc' is version $v; version 1.875 or newer is required\n"; return $v; } else { die "bisonpre: %Error: '$Opt_Yacc' is not installed, or not working\n"; } } sub clean_output { my $filename = shift; my $outname = shift || $filename; my $is_output = shift; my $is_c = shift; print " edit $filename $outname\n"; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; my @lines = $fh->getlines; $fh->close; (my $basename = tmp_prefix().".") =~ s!.*/!!; $basename = quotemeta($basename); (my $newbase = $Opt_Input) =~ s!.*/!!; $newbase =~ s/\.y/./; if ($is_output) { my %state_line; my $l=0; foreach my $line (@lines) { $l++; # We add a colon so it's easy to search for the definition $state_line{$1} = $l if $line =~ s/^state (\d+)\s*$/state $1:/; } my @out; foreach my $line (@lines) { if ($line =~ /^State (\d+) (conflicts)/) { chomp $line; $line .= " // line $state_line{$1}" if $state_line{$1}; $line .= "\n"; } push @out, $line; } @lines = @out; @out = (); } if ($is_c) { my %token_values; my $in_en=0; foreach my $line (@lines) { $in_en=1 if $line =~ /enum\s+yytokentype/; $in_en=0 if $line =~ /;/; $token_values{$2} = $1 if $in_en && $line =~ /\b(\S+) = (\d+)/; } my @out; foreach my $line (@lines) { if ($line =~ /BISONPRE_TOKEN_NAMES/) { push @out, $line; foreach my $tv (sort keys %token_values) { push @out, sprintf("\tcase %d: return \"%s\";\n", $tv, $token_values{$tv}); } next; } push @out, $line; } @lines = @out; @out = (); } $fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n"; foreach my $line (@lines) { # Fix filename refs $line =~ s!$basename!$newbase!g; # Fix bison 2.3 and GCC 4.2.1 $line =~ s!\(YY_\("!(YY_((char*)"!g; # Fix bison 2.3 glr-parser warning about yyerrorloc.YYTYPE::yydummy uninit $line =~ s!(YYLTYPE yyerrloc;)!$1 yyerrloc.yydummy=0;/*bisonpre*/!g; $fh->write($line); } $fh->close; } sub warning_check { my $filename = shift; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; while (defined(my $line = $fh->getline)) { if ($line =~ /(conflicts|warning:|^useless)/i) { die "%Error: $filename:$.: $line\n"; } } $fh->close; } ####################################################################### sub clean_input { my $filename = shift; my $outname = shift || $filename; # Can == filename if desired print " edit $filename $outname\n"; $Self->{filename} = $filename; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; my @lines = $fh->getlines; $fh->close; # Find "%tokens:" # Find "rule:" and replace with just "rule:" my %types; my %rules; $Self->{rules} = \%rules; my %tokens; my $last_rule; my $section = 1; { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; # ^/ to prevent comments from matching $line =~ m!^[a-zA-Z0-9_<>]+:[^/]*[a-zA-Z]! and die "%Error: $filename:$l: Move text on rule line to next line: $line\n"; if ($line =~ /^%%/) { $section++; if ($section==2) { $last_rule = undef; } } elsif ($line =~ s/^([a-zA-Z0-9_]+)<(\S*)>:/$1:/) { !$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n"; $types{$2}{$1} = 1; $rules{$1}{name} = $1; $rules{$1}{type} = $2; !$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n"; $last_rule = $1; } elsif ($line =~ /^([a-zA-Z0-9_]+):/) { !$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n"; $rules{$1}{name} = $1; $rules{$1}{type} = ""; !$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n"; $last_rule = $1; } push @lines, $line; # Now clean the line and extract some more info (my $cline = $line) =~ s/\/\/.*$/\n/; (my $rline = $line) =~ s/\/\/.*$/\n/; if ($cline =~ /^\s*;/) { $last_rule or die "%Error: $filename:$l: Stray semicolon\n"; $last_rule = undef; } elsif ($last_rule) { $rules{$last_rule}{rules_and_productions} .= $cline; } if ($cline =~ /^%token\s*<(\S+)>\s*(\S+)/) { !$tokens{$2} or die "%Error: $filename:$l: Redeclaring '$2': $line\n"; $tokens{$2} = $1; } foreach my $tok (split /[^a-zA-Z0-9_]+/, $cline) { if ($last_rule && $tok=~/^[a-zA-Z]/) { #print "TT $last_rule $tok\n"; $rules{$last_rule}{subrules}{$tok} = 1; $rules{$tok}{parentrules}{$last_rule} = 1; } } } } #use Data::Dumper; print Dumper(\%rules); # Replace BISONPRE_VERSION(ver,,...) with expanded list { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; if ($line =~ /BISONPRE_VERSION/) { # 1 3 4 ($line =~ /BISONPRE_VERSION\((\S+)\s*,\s*((\S+)\s*,)?\s*([^\),]+)\)\s*$/) or die "%Error: $filename:$l: Bad form of BISONPRE_VERSION: $line\n"; my $ver=$1; my $ver_max=$3; my $cmd=$4; if ($Self->{bison_version} >= $1 && (!$ver_max || $Self->{bison_version} <= $ver_max)) { $line = $cmd."\n"; } else { $line = "//NOP: $line"; } } push @lines, $line; } } # Replace BISONPRE_NOT(type,...) with expanded list { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; if ($line =~ /BISONPRE_NOT/) { ($line =~ s/BISONPRE_NOT\((\S+)\)\s*({[^}]+})\s*$//) or die "%Error: $filename:$l: Bad form of BISONPRE_NOT: $line\n"; my $endtok = $1; my $action = $2; my @endtoks = split (/,/, $endtok); map { $tokens{$_} or die "%Error: $filename:$l: Can't find definition for token: $_\n" } @endtoks; # Push it all onto one line to avoid error messages changing my $bar = ""; tok: foreach my $tok (sort keys %tokens) { foreach (@endtoks) { next tok if $tok eq $_; } if ($endtok ne $tok) { $line .= "\t$bar $tok $action"; $bar = "|"; } } $line .= "\n"; } push @lines, $line; } } # Replace BISONPRE_COPY(type,{code}) { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; if ($line =~ /BISONPRE_COPY/) { $line = _bisonpre_copy($line,$l,0); } push @lines, $line; } } # Replace ~[x]~ - must be after BISONPRE_COPY expansion { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; $line =~ s/~[a-zA-Z0-9_]+~//g; push @lines, $line; } } # Find "BISONPRE_TYPES" { my @linesin = @lines; @lines=(); my $l=0; my $needmore = 0; foreach my $line (@linesin) { $l++; if ($line =~ m!//BISONPRE_TYPES!) { push @lines, $line; foreach my $type (sort keys %types) { next if !$type; my $line = "%type<$type>\t"; foreach my $rule (sort keys %{$types{$type}}) { $line.=" ".$rule; } $line .= "\n"; push @lines, $line; $needmore++ } } elsif ($needmore) { # Bison doesn't have a #line directive, so we need somewhere to insert into $line =~ s!^\s*//.*$!!; ($line =~ m/^\s*$/) or die "%Error: $filename:$l: Need $needmore more blank lines to insure line numbers are constant\n"; $needmore--; } else { push @lines, $line; } } } $fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n"; foreach my $line (@lines) { $fh->write($line); } $fh->close; } sub _bisonpre_copy { my $text = shift; my $l = shift; my $depth = shift; while ($text =~ /BISONPRE_COPY/) { ($text =~ s/BISONPRE_COPY(_ONCE)?\((\S+)\s*,\s*{([^}]*)}\s*\)/{HERE}/) or die "%Error: $Self->{filename}:$l: Bad form of BISONPRE_NOT: $text\n"; my $once = $1; my $rule = $2; my $code = $3; $Self->{rules}{$rule} or die "%Error: $Self->{filename}:$l: Can't find definition for rule: $rule\n"; if ($depth > 0 && $once) { # _ONCE means don't inherit $text =~ s/\|[ \t]+{HERE}//; # Don't OR in nothing $text =~ s/{HERE}//; } else { # Push it all onto one line to avoid error messages changing my $insert = $Self->{rules}{$rule}{rules_and_productions}; $insert =~ s/^\S+://g; # Strip rule name # Recurse so BISONPRE under B #print "COPY $l code $code\n"; #print "COPY $l in $insert\n"; $_=$insert; eval("$code; \$_;"); $insert = $_; #print "COPY $l out $insert\n"; while ($insert =~ s/[ \t\n]+\n/\n/go) {} while ($insert =~ s/\n/ /go) {} # Optional - preserve line numbering $text =~ s/{HERE}/$insert/; } $depth++; } return $text; } ####################################################################### __END__ =pod =head1 NAME bisonpre - Bison wrapper with pre and post processing =head1 SYNOPSIS bisonpre --yacc bison --debug --verbose --defines X.h -k $< -pX -o X.c =head1 DESCRIPTION Bisonpre is a wrapper for the Bison YACC replacement. Input to Bison is preprocessed with substitution as described below under EXTENSIONS. Output from Bison is checked for additional errors, and corrected to work around various compile warnings. =head1 EXTENSIONS =over 4 =item //BISONPRE_TYPES This is expanded into %type declarations. =item ~[a-z]+~ Any text matching ~[a-z]+~ is removed. This allows optional text to be used only when the rule containing the ~~ is used in a BISONPRE_COPY. =item rule_label: This allows the label declaring a rule to also specify the type of the rule. The type will be inserted where /*BISONPRE_TYPES*/ is encountered. =item BISONPRE_COPY(rule, {code}) Copy the rules and productions from the specified rule, filter through the Perl code provided in the {} and insert here into the output file. =item BISONPRE_COPY_ONCE(rule, {code}) As with BISONPRE_COPY, but if called from underneath another BISONPRE_COPY rule, ignore it. =item BISONPRE_NOT(token[, token...]) Create a rule that matches every token except for those specified. =item BISONPRE_VERSION(ver, cmd) If the bison version is >= the specified version, include the given command. =back =head1 ARGUMENTS =over 4 =item -b file-prefix =item --file-prefix=file-prefix Passed to bison. Specify a prefix to use for all bison output file names. The names are chosen as if the input file were named file-prefix.c. =item -d Passed to bison. Write an extra output file containing macro definitions for the token type names defined in the grammar and the semantic value type YYSTYPE, as well as a few extern variable declarations. If the parser output file is named name.c then this file is named name.h. This output file is essential if you wish to put the definition of yylex in a separate source file, because yylex needs to be able to refer to token type codes and the variable yylval. =item --help Displays this message and program version and exits. =item -k =item --token-table Passed to bison. This switch causes the name.tab.c output to include a list of token names in order by their token numbers; this is defined in the array yytname. Also generated are #defines for YYNTOKENS, YYNNTS, YYNRULES, and YYNSTATES. =item -t =item --debug Passed to bison. In the parser file, define the macro YYDEBUG to 1 if it is not already defined, so that the debugging facilities are compiled. =item -v =item --verbose Passed to bison. Write an extra output file containing verbose descriptions of the parser states and what is done for each type of look-ahead token in that state. This file also describes all the conflicts, both those resolved by operator precedence and the unresolved ones. The file's name is made by removing .tab.c or .c from the parser output file name, and adding .output instead. Therefore, if the input file is foo.y, then the parser file is called foo.tab.c by default. As a consequence, the verbose output file is called foo.output. =item --version Print the version number and exit. =item --yacc Specify the name of the bison executable, defaults to "bison." =back =head1 DISTRIBUTION This is part of the L free Verilog EDA software tool suite. The latest version is available from CPAN and from L. Copyright 2008-2017 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.916/src/V3Order.cpp0000664000177100017500000017644413205574202016317 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Block code ordering // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Order's Transformations: // // Compute near optimal scheduling of always/wire statements // Make a graph of the entire netlist // // Add master "*INPUTS*" vertex. // For inputs on top level // Add vertex for each input var. // Add edge INPUTS->var_vertex // // For seq logic // Add logic_sensitive_vertex for this list of SenItems // Add edge for each sensitive_var->logic_sensitive_vertex // For AssignPre's // Add vertex for this logic // Add edge logic_sensitive_vertex->logic_vertex // Add edge logic_consumed_var_PREVAR->logic_vertex // Add edge logic_vertex->logic_generated_var (same as if comb) // Add edge logic_vertex->generated_var_PREORDER // Cutable dependency to attempt to order dlyed // assignments to avoid saving state, thus we prefer // a <= b ... As the opposite order would // b <= c ... require the old value of b. // For Logic // Add vertex for this logic // Add edge logic_sensitive_vertex->logic_vertex // Add edge logic_generated_var_PREORDER->logic_vertex // This insures the AssignPre gets scheduled before this logic // Add edge logic_vertex->consumed_var_PREVAR // Add edge logic_vertex->consumed_var_POSTVAR // Add edge logic_vertex->logic_generated_var (same as if comb) // For AssignPost's // Add vertex for this logic // Add edge logic_sensitive_vertex->logic_vertex // Add edge logic_consumed_var->logic_vertex (same as if comb) // Add edge logic_vertex->logic_generated_var (same as if comb) // // For comb logic // For comb logic // Add vertex for this logic // Add edge logic_consumed_var->logic_vertex // Add edge logic_vertex->logic_generated_var // Mark it cutable, as circular logic may require // the generated signal to become a primary input again. // // // // Rank the graph starting at INPUTS (see V3Graph) // // Visit the graph's logic vertices in ranked order // For all logic vertices with all inputs already ordered // Make ordered block for this module // For all ^^ in same domain // Move logic to ordered activation // When we have no more choices, we move to the next module // and make a new block. Add that new activation block to the list of calls to make. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include #include #include "V3Global.h" #include "V3File.h" #include "V3Ast.h" #include "V3Graph.h" #include "V3List.h" #include "V3SenTree.h" #include "V3Stats.h" #include "V3EmitCBase.h" #include "V3Const.h" #include "V3Order.h" #include "V3OrderGraph.h" #include "V3EmitV.h" class OrderMoveDomScope; //###################################################################### // Functions for above graph classes void OrderGraph::loopsVertexCb(V3GraphVertex* vertexp) { if (debug()) cout<<"-Info-Loop: "<(vertexp)) { cerr<nodep()->fileline()<<" "<nodep()->typeName()<(vertexp)) { cerr<varScp()->fileline()<<" "<varScp()->prettyName()< m_readyDomScopeE;// List of next ready dom scope V3List m_readyVertices; // Ready vertices with same domain & scope private: bool m_onReadyList; // True if DomScope is already on list of ready dom/scopes const AstSenTree* m_domainp; // Domain all vertices belong to const AstScope* m_scopep; // Scope all vertices belong to typedef pair DomScopeKey; typedef std::map DomScopeMap; static DomScopeMap s_dsMap; // Structure registered for each dom/scope pairing public: OrderMoveDomScope(const AstSenTree* domainp, const AstScope* scopep) : m_onReadyList(false), m_domainp(domainp), m_scopep(scopep) {} OrderMoveDomScope* readyDomScopeNextp() const { return m_readyDomScopeE.nextp(); } const AstSenTree* domainp() const { return m_domainp; } const 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(const AstSenTree* domainp, const AstScope* scopep) { const DomScopeKey key = make_pair(domainp,scopep); DomScopeMap::iterator iter = s_dsMap.find(key); if (iter != s_dsMap.end()) { return iter->second; } else { OrderMoveDomScope* domScopep = new OrderMoveDomScope(domainp, scopep); s_dsMap.insert(make_pair(key, domScopep)); return domScopep; } } string name() const { return (string("MDS:") +" 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"); OrderVarVertex* vertexp = m_vertexp[type]; if (!vertexp) { UINFO(6,"New vertex "<v3fatalSrc("Bad case"); } m_vertexp[type] = vertexp; } else { if (createdp) *createdp=false; } return vertexp; } public: // CONSTRUCTORS OrderUser() { for (int i=0; ivarScp()->varp()->width() > vsv2p->varScp()->varp()->width(); } }; //! Comparator for fanout of vertex struct OrderVarFanoutCmp { bool operator() (OrderVarStdVertex* vsv1p, OrderVarStdVertex* vsv2p) { return vsv1p->fanout() > vsv2p->fanout(); } }; //###################################################################### // The class is used for propagating the clocker attribute for further // avoiding marking clock signals as circular. // Transformation: // while (newClockerMarked) // check all assignments // if RHS is marked as clocker: // mark LHS as clocker as well. // newClockerMarked = true; // // In addition it also check whether clock and data signals are mixed, and // produce a CLKDATA warning if so. // class OrderClkMarkVisitor : public AstNVisitor { private: bool m_hasClk; // flag indicating whether there is clock signal on rhs bool m_inClocked; // Currently inside a sequential block bool m_newClkMarked; // Flag for deciding whether a new run is needed bool m_inAss; // Currently inside of a assignment int m_childClkWidth; // If in hasClk, width of clock signal in child int m_rightClkWidth; // Clk width on the RHS // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual void visit(AstNodeAssign* nodep) { m_hasClk = false; if (AstVarRef* varrefp = nodep->rhsp()->castVarRef()) { this->visit(varrefp); m_rightClkWidth = varrefp->width(); if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { if (m_inClocked) { varrefp->v3warn(CLKDATA, "Clock used as data (on rhs of assignment) in sequential block "<rhsp()->iterateAndNext(*this); m_rightClkWidth = m_childClkWidth; m_inAss = false; } // do the marking if (m_hasClk) { if (nodep->lhsp()->width() > m_rightClkWidth) { nodep->v3warn(CLKDATA, "Clock is assigned to part of data signal "<< nodep->lhsp()<lhsp()->width() <lhsp()->castVarRef(); if (lhsp && (lhsp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_UNKNOWN)) { lhsp->varp()->attrClocker(AstVarAttrClocker::CLOCKER_YES); // mark as clocker m_newClkMarked = true; // enable a further run since new clocker is marked UINFO(5, "node is newly marked as clocker by assignment "<varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { if (m_inClocked) { nodep->v3warn(CLKDATA, "Clock used as data (on rhs of assignment) in sequential block "<prettyName()); } else { m_hasClk = true; m_childClkWidth = nodep->width(); // Pass up UINFO(5, "node is already marked as clocker "<lhsp()->iterateAndNext(*this); int lw = m_childClkWidth; nodep->rhsp()->iterateAndNext(*this); int rw = m_childClkWidth; m_childClkWidth = lw + rw; // Pass up } } virtual void visit(AstNodeSel* nodep) { if (m_inAss) { nodep->iterateChildren(*this); // Pass up result width if (m_childClkWidth > nodep->width()) m_childClkWidth = nodep->width(); } } virtual void visit(AstSel* nodep) { if (m_inAss) { nodep->iterateChildren(*this); if (m_childClkWidth > nodep->width()) m_childClkWidth = nodep->width(); } } virtual void visit(AstReplicate* nodep) { if (m_inAss) { nodep->iterateChildren(*this); if (nodep->rhsp()->castConst()) { m_childClkWidth = m_childClkWidth * nodep->rhsp()->castConst()->toUInt(); } else { m_childClkWidth = nodep->width(); // can not check in this case. } } } virtual void visit(AstActive* nodep) { m_inClocked = nodep->hasClocked(); nodep->iterateChildren(*this); m_inClocked = false; } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit OrderClkMarkVisitor(AstNode* nodep) { m_hasClk = false; m_inClocked = false; m_inAss = false; m_childClkWidth = 0; m_rightClkWidth = 0; do { m_newClkMarked = false; nodep->accept(*this); } while (m_newClkMarked); } virtual ~OrderClkMarkVisitor() {} }; //###################################################################### // The class used to check if the assignment has clocker inside. class OrderClkAssVisitor : public AstNVisitor { private: bool m_clkAss; // There is signals marked as clocker in the assignment // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual void visit(AstNodeAssign* nodep) { if (AstVarRef* varrefp = nodep->lhsp()->castVarRef() ) if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { m_clkAss = true; UINFO(6, "node was marked as clocker "<rhsp()->iterateChildren(*this); } virtual void visit(AstVarRef* nodep) { if (nodep->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { m_clkAss = true; UINFO(6, "node was marked as clocker "<iterateChildren(*this); } public: // CONSTUCTORS explicit OrderClkAssVisitor(AstNode* nodep) { m_clkAss = false; nodep->accept(*this); } virtual ~OrderClkAssVisitor() {} // METHODS bool isClkAss() {return m_clkAss;} }; //###################################################################### // Order class functions class OrderVisitor : public AstNVisitor { private: // NODE STATE // Forming graph: // Entire Netlist: // AstVarScope::user1p -> OrderUser* for usage var // {statement}Node::user1p-> AstModule* statement is under // USER4 Cleared on each Logic stmt // AstVarScope::user4() -> VarUsage(gen/con/both). Where already encountered signal // Ordering (user3/4/5 cleared between forming and ordering) // AstScope::user1p() -> AstNodeModule*. Module this scope is under // AstNodeModule::user3() -> Number of routines created // Each call to V3Const::constify // AstNode::user4() Used by V3Const::constify, called below AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; //AstUser4InUse m_inuser4; // Used only when building tree, so below // STATE OrderGraph m_graph; // Scoreboard of var usages/dependencies SenTreeFinder m_finder; // Find global sentree's and add them AstSenTree* m_comboDomainp; // Combo activation tree AstSenTree* m_deleteDomainp;// Delete this from tree AstSenTree* m_settleDomainp;// Initial activation tree OrderInputsVertex* m_inputsVxp; // Top level vertex all inputs point from OrderSettleVertex* m_settleVxp; // Top level vertex all settlement vertexes point from OrderLogicVertex* m_logicVxp; // Current statement being tracked, NULL=ignored AstTopScope* m_topScopep; // Current top scope being processed AstScope* m_scopetopp; // Scope under TOPSCOPE AstNodeModule* m_modp; // Current module AstScope* m_scopep; // Current scope being processed AstActive* m_activep; // Current activation block bool m_inSenTree; // Underneath AstSenItem; any varrefs are clocks bool m_inClocked; // Underneath clocked block bool m_inClkAss; // Underneath AstAssign bool m_inPre; // Underneath AstAssignPre bool m_inPost; // Underneath AstAssignPost OrderLogicVertex* m_activeSenVxp; // Sensitivity vertex deque m_orderUserps; // All created OrderUser's for later deletion. // STATE... for inside process AstCFunc* m_pomNewFuncp; // Current function being created int m_pomNewStmts; // Statements in function being created V3Graph m_pomGraph; // Graph of logic elements to move V3List m_pomWaiting; // List of nodes needing inputs to become ready protected: friend class OrderMoveDomScope; V3List m_pomReadyDomScope; // List of ready domain/scope pairs, by loopId vector m_unoptflatVars; // Vector of variables in UNOPTFLAT loop private: // STATS V3Double0 m_statCut[OrderVEdgeType::_ENUM_END]; // Count of each edge type cut // TYPES enum VarUsage { VU_NONE=0, VU_CON=1, VU_GEN=2 }; // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void iterateNewStmt(AstNode* nodep) { if (m_scopep) { UINFO(4," STMT "<sensesp()) nodep->v3fatalSrc("NULL"); // If inside combo logic, ignore the domain, we'll assign one based on interconnect AstSenTree* startDomainp = m_activep->sensesp(); if (startDomainp->hasCombo()) startDomainp=NULL; m_logicVxp = new OrderLogicVertex(&m_graph, m_scopep, startDomainp, nodep); if (m_activeSenVxp) { // If in a clocked activation, add a link from the sensitivity to this block // Add edge logic_sensitive_vertex->logic_vertex new OrderEdge(&m_graph, m_activeSenVxp, m_logicVxp, WEIGHT_NORMAL); } nodep->user1p(m_modp); nodep->iterateChildren(*this); m_logicVxp = NULL; } } OrderVarVertex* newVarUserVertex(AstVarScope* varscp, WhichVertex type, bool* createdp=NULL) { if (!varscp->user1p()) { OrderUser* newup = new OrderUser(); m_orderUserps.push_back(newup); varscp->user1p(newup); } OrderUser* up = (OrderUser*)(varscp->user1p()); OrderVarVertex* varVxp = up->newVarUserVertex(&m_graph, m_scopep, varscp, type, createdp); return varVxp; } void process(); void processCircular(); typedef deque VertexVec; void processInputs(); void processInputsInIterate(OrderEitherVertex* vertexp, VertexVec& todoVec); void processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec& todoVec); void processSensitive(); void processDomains(); void processDomainsIterate(OrderEitherVertex* vertexp); void processEdgeReport(); void processMove(); void processMoveClear(); void processMoveBuildGraph(); void processMoveBuildGraphIterate (OrderMoveVertex* moveVxp, V3GraphVertex* vertexp, int weightmin); void processMovePrepScopes(); void processMovePrepReady(); void processMoveReadyOne(OrderMoveVertex* vertexp); void processMoveDoneOne(OrderMoveVertex* vertexp); void processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* domScopep, int level); static bool domainsExclusive(const AstSenTree* fromp, const AstSenTree* top); string cfuncName(AstNodeModule* modp, AstSenTree* domainp, AstScope* scopep, AstNode* forWhatp) { modp->user3Inc(); int funcnum = modp->user3(); string name = (domainp->hasCombo() ? "_combo" : (domainp->hasInitial() ? "_initial" : (domainp->hasSettle() ? "_settle" : (domainp->isMulti() ? "_multiclk" : "_sequent")))); name = name+"__"+scopep->nameDotless()+"__"+cvtToStr(funcnum); if (v3Global.opt.profileCFuncs()) { name += "__PROF__"+forWhatp->fileline()->profileFuncname(); } return name; } void nodeMarkCircular(OrderVarVertex* vertexp, OrderEdge* edgep) { AstVarScope* nodep = vertexp->varScp(); OrderLogicVertex* fromLVtxp = NULL; OrderLogicVertex* toLVtxp = NULL; if (edgep) { fromLVtxp = dynamic_cast(edgep->fromp()); toLVtxp = dynamic_cast(edgep->top()); } // if ((fromLVtxp && fromLVtxp->nodep()->castInitial()) || (toLVtxp && toLVtxp->nodep()->castInitial())) { // IEEE does not specify ordering between initial blocks, so we can do whatever we want // We especially do not want to evaluate multiple times, so do not mark the edge circular } else { nodep->circular(true); ++m_statCut[vertexp->type()]; if (edgep) ++m_statCut[edgep->type()]; // if (vertexp->isClock()) { // Seems obvious; no warning yet //nodep->v3warn(GENCLK,"Signal unoptimizable: Generated clock: "<prettyName()); } else if (nodep->varp()->isSigPublic()) { nodep->v3warn(UNOPT,"Signal unoptimizable: Feedback to public clock or circular logic: "<prettyName()); if (!nodep->fileline()->warnIsOff(V3ErrorCode::UNOPT)) { nodep->fileline()->modifyWarnOff(V3ErrorCode::UNOPT, true); // Complain just once // Give the user an example. bool tempWeight = (edgep && edgep->weight()==0); if (tempWeight) edgep->weight(1); // Else the below loop detect can't see the loop m_graph.reportLoops(&OrderEdge::followComboConnected, vertexp); // calls OrderGraph::loopsVertexCb if (tempWeight) edgep->weight(0); } } else { // We don't use UNOPT, as there are lots of V2 places where it was needed, that aren't any more // First v3warn not inside warnIsOff so we can see the suppressions with --debug nodep->v3warn(UNOPTFLAT,"Signal unoptimizable: Feedback to clock or circular logic: "<prettyName()); if (!nodep->fileline()->warnIsOff(V3ErrorCode::UNOPTFLAT)) { nodep->fileline()->modifyWarnOff(V3ErrorCode::UNOPTFLAT, true); // Complain just once // Give the user an example. bool tempWeight = (edgep && edgep->weight()==0); if (tempWeight) edgep->weight(1); // Else the below loop detect can't see the loop m_graph.reportLoops(&OrderEdge::followComboConnected, vertexp); // calls OrderGraph::loopsVertexCb if (tempWeight) edgep->weight(0); if (v3Global.opt.reportUnoptflat()) { // Report candidate variables for splitting reportLoopVars(vertexp); // Do a subgraph for the UNOPTFLAT loop OrderGraph loopGraph; m_graph.subtreeLoops(&OrderEdge::followComboConnected, vertexp, &loopGraph); loopGraph.dumpDotFilePrefixedAlways("unoptflat"); } } } } } //! Find all variables in an UNOPTFLAT loop //! //! Ignore vars that are 1-bit wide and don't worry about generated //! variables (PRE and POST vars, __Vdly__, __Vcellin__ and __VCellout). //! What remains are candidates for splitting to break loops. //! //! node->user3 is used to mark if we have done a particular variable. //! vertex->user is used to mark if we have seen this vertex before. //! //! @todo We could be cleverer in the future and consider just //! the width that is generated/consumed. void reportLoopVars(OrderVarVertex* vertexp) { m_graph.userClearVertices(); AstNode::user3ClearTree(); m_unoptflatVars.clear(); reportLoopVarsIterate (vertexp, vertexp->color()); AstNode::user3ClearTree(); m_graph.userClearVertices(); // May be very large vector, so only report the "most important" // elements. Up to 10 of the widest cerr<varScp()->varp(); cerr<fileline()<<" "<prettyName()<width()<<", fanout " <fanout()<varScp()->varp(); cerr<fileline()<<" "<prettyName() <<", width "<width() <<", fanout "<fanout()<user()) return; // Already done vertexp->user(1); if (OrderVarStdVertex* vsvertexp = dynamic_cast(vertexp)) { // Only reporting on standard variable vertices AstVar* varp = vsvertexp->varScp()->varp(); if (!varp->user3()) { string name = varp->prettyName(); if ((varp->width() != 1) && (name.find("__Vdly") == string::npos) && (name.find("__Vcell") == string::npos)) { // Variable to report on and not yet done m_unoptflatVars.push_back(vsvertexp); } varp->user3Inc(); } } // Iterate through all the to and from vertices of the same color for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { if (edgep->top()->color() == color) { reportLoopVarsIterate(edgep->top(), color); } } for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { if (edgep->fromp()->color() == color) { reportLoopVarsIterate(edgep->fromp(), color); } } } // VISITORS virtual void visit(AstNetlist* nodep) { { 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) { // 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) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstScope* nodep) { UINFO(4," SCOPE "<user1p(m_modp); // Iterate nodep->iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstActive* nodep) { // Create required activation blocks and add to module UINFO(4," ACTIVE "<hasClocked(); // Grab the sensitivity list if (nodep->sensesStorep()) nodep->v3fatalSrc("Senses should have been activeTop'ed to be global!"); nodep->sensesp()->accept(*this); // Collect statements under it nodep->iterateChildren(*this); m_activep = NULL; } virtual void visit(AstVarScope* nodep) { // 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) { if (m_scopep) { AstVarScope* varscp = nodep->varScopep(); if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp"); 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?"); 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"); // What new directions is this used // We don't want to add extra edges if the logic block has many usages of same var bool gen = false; bool con = false; if (nodep->lvalue()) { gen = !(varscp->user4() & VU_GEN); } else { con = !(varscp->user4() & VU_CON); if ((varscp->user4() & VU_GEN) && !m_inClocked) { // Dangerous assumption: // If a variable is used in the same activation which defines it first, // consider it something like: // foo = 1 // foo = foo + 1 // and still optimize. This is the rule verilog-mode assumes for /*AS*/ // Note this will break though: // if (sometimes) foo = 1 // foo = foo + 1 con = false; } if (varscp->varp()->attrClockEn() && !m_inPre && !m_inPost && !m_inClocked) { // clock_enable attribute: user's worring about it for us con = false; } if (m_inClkAss && (varscp->varp()->attrClocker()) != AstVarAttrClocker::CLOCKER_YES) { con = false; UINFO(4, "nodep used as clock_enable "<nodep()<user4(varscp->user4() | VU_GEN); if (con) varscp->user4(varscp->user4() | VU_CON); // Add edges if (!m_inClocked || m_inPost ) { // Combo logic { // not settle and (combo or inPost) if (gen) { // Add edge logic_vertex->logic_generated_var OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD); if (m_inPost) { new OrderPostCutEdge(&m_graph, m_logicVxp, varVxp); // Mark the vertex. Used to control marking // internal clocks circular, which must only // happen if they are generated by delayed // assignment. UINFO(5, " Found delayed assignment (post) " << varVxp << endl); varVxp->isDelayed(true); } else { // If the lhs is a clocker, avoid marking that as circular by // putting a hard edge instead of normal cuttable if (varscp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) new OrderEdge(&m_graph, m_logicVxp, varVxp, WEIGHT_NORMAL); else new OrderComboCutEdge(&m_graph, m_logicVxp, varVxp); } // For m_inPost: // Add edge consumed_var_POST->logic_vertex // This prevents a consumer of the "early" value to be scheduled // after we've changed to the next-cycle value // ALWAYS do it: // There maybe a wire a=b; between the two blocks OrderVarVertex* postVxp = newVarUserVertex(varscp, WV_POST); new OrderEdge(&m_graph, postVxp, m_logicVxp, WEIGHT_POST); } if (con) { // Add edge logic_consumed_var->logic_vertex OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD); new OrderEdge(&m_graph, varVxp, m_logicVxp, WEIGHT_MEDIUM); } } } else if (m_inPre) { // AstAssignPre logic if (gen) { // Add edge logic_vertex->generated_var_PREORDER OrderVarVertex* ordVxp = newVarUserVertex(varscp, WV_PORD); new OrderEdge(&m_graph, m_logicVxp, ordVxp, WEIGHT_NORMAL); // Add edge logic_vertex->logic_generated_var (same as if comb) OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD); new OrderEdge(&m_graph, m_logicVxp, varVxp, WEIGHT_NORMAL); } if (con) { // Add edge logic_consumed_var_PREVAR->logic_vertex // This one is cutable (vs the producer) as there's only one of these, but many producers OrderVarVertex* preVxp = newVarUserVertex(varscp, WV_PRE); new OrderPreCutEdge(&m_graph, preVxp, m_logicVxp); } } else { // Seq logic if (gen) { // Add edge logic_generated_var_PREORDER->logic_vertex OrderVarVertex* ordVxp = newVarUserVertex(varscp, WV_PORD); new OrderEdge(&m_graph, ordVxp, m_logicVxp, WEIGHT_NORMAL); // Add edge logic_vertex->logic_generated_var (same as if comb) OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD); new OrderEdge(&m_graph, m_logicVxp, varVxp, WEIGHT_NORMAL); } if (con) { // Add edge logic_vertex->consumed_var_PREVAR // Generation of 'pre' because we want to indicate it should be before AstAssignPre OrderVarVertex* preVxp = newVarUserVertex(varscp, WV_PRE); new OrderEdge(&m_graph, m_logicVxp, preVxp, WEIGHT_NORMAL); // Add edge logic_vertex->consumed_var_POST OrderVarVertex* postVxp = newVarUserVertex(varscp, WV_POST); new OrderEdge(&m_graph, m_logicVxp, postVxp, WEIGHT_POST); } } } } } virtual void visit(AstSenTree* nodep) { // Having a node derived from the sentree isn't required for // correctness, it merely 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) { iterateNewStmt(nodep); } virtual void visit(AstAlwaysPost* nodep) { m_inPost = true; iterateNewStmt(nodep); m_inPost = false; } virtual void visit(AstAlwaysPublic* nodep) { iterateNewStmt(nodep); } virtual void visit(AstAssignAlias* nodep) { iterateNewStmt(nodep); } virtual void visit(AstAssignW* nodep) { OrderClkAssVisitor visitor(nodep); m_inClkAss = visitor.isClkAss(); iterateNewStmt(nodep); m_inClkAss = false; } virtual void visit(AstAssignPre* nodep) { OrderClkAssVisitor visitor(nodep); m_inClkAss = visitor.isClkAss(); m_inPre = true; iterateNewStmt(nodep); m_inPre = false; m_inClkAss = false; } virtual void visit(AstAssignPost* nodep) { OrderClkAssVisitor visitor(nodep); m_inClkAss = visitor.isClkAss(); m_inPost = true; iterateNewStmt(nodep); m_inPost = false; m_inClkAss = false; } virtual void visit(AstCoverToggle* nodep) { iterateNewStmt(nodep); } virtual void visit(AstInitial* nodep) { // We use initials to setup parameters and static consts's which may be referenced // in user initial blocks. So use ordering to sort them all out. iterateNewStmt(nodep); } virtual void visit(AstCFunc*) { // 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) { nodep->iterateChildren(*this); } public: // CONSTUCTORS OrderVisitor() { m_topScopep = NULL; m_scopetopp = NULL; m_modp = NULL; m_scopep = NULL; m_activep = NULL; m_inSenTree = false; m_inClocked = false; m_inClkAss = false; m_inPre = m_inPost = false; m_comboDomainp = NULL; m_deleteDomainp = NULL; m_settleDomainp = NULL; m_settleVxp = NULL; m_inputsVxp = NULL; m_activeSenVxp = NULL; m_logicVxp = NULL; m_pomNewFuncp = NULL; m_pomNewStmts = 0; if (debug()) m_graph.debug(5); // 3 is default if global debug; we want acyc debugging } virtual ~OrderVisitor() { // Stats for (int type=0; type::iterator it=m_orderUserps.begin(); it!=m_orderUserps.end(); ++it) { delete *it; } m_graph.debug(V3Error::debugDefault()); } void main(AstNode* nodep) { nodep->accept(*this); } }; //###################################################################### // Clock propagation void OrderVisitor::processInputs() { m_graph.userClearVertices(); // Vertex::user() // 1 if input recursed, 2 if marked as input, 3 if out-edges recursed // Start at input vertex, process from input-to-output order VertexVec todoVec; // List of newly-input marked vectors we need to process todoVec.push_front(m_inputsVxp); m_inputsVxp->isFromInput(true); // By definition while (!todoVec.empty()) { OrderEitherVertex* vertexp = todoVec.back(); todoVec.pop_back(); processInputsOutIterate(vertexp, todoVec); } } void OrderVisitor::processInputsInIterate(OrderEitherVertex* vertexp, VertexVec& todoVec) { // Propagate PrimaryIn through simple assignments if (vertexp->user()) return; // Already processed if (0 && debug()>=9) { UINFO(9," InIIter "<(vertexp)) { vvertexp->nodep()->dumpTree(cout,"- TT: "); } } vertexp->user(1); // Processing // First handle all inputs to this vertex, in most cases they'll be already processed earlier // Also, determine if this vertex is an input int inonly = 1; // 0=no, 1=maybe, 2=yes until a no for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { OrderEitherVertex* frVertexp = (OrderEitherVertex*)edgep->fromp(); processInputsInIterate(frVertexp, todoVec); if (frVertexp->isFromInput()) { if (inonly==1) inonly = 2; } else if (dynamic_cast(frVertexp)) { // Ignore post assignments, just for ordering } else { //UINFO(9," InItStopDueTo "<user()<2) { // Set it. Note may have already been set earlier, too UINFO(9," Input reassignment: "<isFromInput(true); vertexp->user(2); // 2 means on list // Can't work on out-edges of a node we know is an input immediately, // as it might visit other nodes before their input state is resolved. // So push to list and work on it later when all in-edges known resolved todoVec.push_back(vertexp); } //UINFO(9," InIdone "<user()==3) return; // Already out processed //UINFO(9," InOIter "<isFromInput()) v3fatalSrc("processInputsOutIterate only for input marked vertexes"); vertexp->user(3); // out-edges processed { // Propagate PrimaryIn through simple assignments, followint target of vertex for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { OrderEitherVertex* toVertexp = (OrderEitherVertex*)edgep->top(); if (OrderVarStdVertex* vvertexp = dynamic_cast(toVertexp)) { processInputsInIterate(vvertexp, todoVec); } if (OrderLogicVertex* vvertexp = dynamic_cast(toVertexp)) { if (vvertexp->nodep()->castNodeAssign()) { processInputsInIterate(vvertexp, todoVec); } } } } } //###################################################################### // Circular detection void OrderVisitor::processCircular() { // Take broken edges and add circular flags // The change detect code will use this to force changedets for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (OrderVarStdVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->isClock() && !vvertexp->isFromInput()) { // If a clock is generated internally, we need to do another // loop through the entire evaluation. This fixes races; see // t_clk_dpulse test. // // This all seems to hinge on how the clock is generated. If // it is generated by delayed assignment, we need the loop. If // it is combinatorial, we do not (and indeed it will break // other tests such as t_gated_clk_1. if (!v3Global.opt.orderClockDly()) { UINFO(5,"Circular Clock, no-order-clock-delay "<isDelayed()) { UINFO(5,"Circular Clock, delayed "<outBeginp(); edgep; edgep=edgep->outNextp()) { if (edgep->weight()==0) { // was cut OrderEdge* oedgep = dynamic_cast(edgep); if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type"); UINFO(6," CutCircularO: "<name()<inBeginp(); edgep; edgep = edgep->inNextp()) { if (edgep->weight()==0) { // was cut OrderEdge* oedgep = dynamic_cast(edgep); if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type"); UINFO(6," CutCircularI: "<name()<verticesNextp()) { if (OrderVarStdVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->varScp()->varp()->isInput()) { //UINFO(0," scsen "<outBeginp(); edgep; edgep=edgep->outNextp()) { if (OrderEitherVertex* toVertexp = dynamic_cast(edgep->top())) { if (edgep->weight() && toVertexp->domainp()) { //UINFO(0," "<domainp()<domainp()->hasCombo()) { vvertexp->varScp()->varp()->scSensitive(true); } } } } } } } } void OrderVisitor::processDomains() { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { OrderEitherVertex* vertexp = dynamic_cast(itp); UASSERT(vertexp, "Null or vertex not derived from EitherVertex\n"); processDomainsIterate(vertexp); } } void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) { // The graph routines have already sorted the vertexes and edges into best->worst order // Assign clock domains to each signal. // Sequential logic is forced into the same sequential domain. // Combo logic may be pushed into a seq domain if all its inputs are the same domain, // else, if all inputs are from flops, it's end-of-sequential code // else, it's full combo code if (vertexp->domainp()) return; // Already processed, or sequential logic UINFO(5," pdi: "<(vertexp); AstSenTree* domainp = NULL; UASSERT(m_comboDomainp, "not preset"); if (vvertexp && vvertexp->varScp()->varp()->isInput()) { domainp = m_comboDomainp; } if (vvertexp && vvertexp->varScp()->isCircular()) { domainp = m_comboDomainp; } if (!domainp) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { OrderEitherVertex* fromVertexp = (OrderEitherVertex*)edgep->fromp(); if (edgep->weight() && fromVertexp->domainMatters() ) { UINFO(9," from d="<<(void*)fromVertexp->domainp()<<" "<hasSettle() // or, we can ignore being in the settle domain || domainp->hasInitial()) { domainp = fromVertexp->domainp(); } else if (domainp->hasCombo()) { // Once in combo, keep in combo; already as severe as we can get } else if (fromVertexp->domainp()->hasCombo()) { // Any combo input means this vertex must remain combo domainp = m_comboDomainp; } else if (fromVertexp->domainp()->hasSettle() || fromVertexp->domainp()->hasInitial()) { // Ignore that we have a constant (initial) input } else if (domainp != fromVertexp->domainp()) { // Make a domain that merges the two domains bool ddebug = debug()>=9; if (ddebug) { cout<addSensesp(newtree2p); newtree2p=NULL; // Below edit may replace it V3Const::constifyExpensiveEdit(newtreep); // Remove duplicates newtreep->multi(true); // Comment that it was made from 2 clock domains domainp = m_finder.getSenTree(domainp->fileline(), newtreep); if (ddebug) { UINFO(0," dnew ="<dumpTree(cout); UINFO(0," find ="<dumpTree(cout); cout<deleteTree(); VL_DANGLING(newtreep); } } } // 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); } } } bool OrderVisitor::domainsExclusive(const AstSenTree* fromp, const AstSenTree* top) { // Return 'true' if we can prove that both 'from' and 'to' cannot both // be active on the same eval pass, or false if we can't prove this. // // For now, this only detects the case of 'always @(posedge clk)' // and 'always @(negedge clk)' being exclusive. // // Are there any other cases we need to handle? Maybe not, // because these are not exclusive: // always @(posedge A or posedge B) // always @(negedge A) // // ... unless you know more about A and B, which sounds hard. const AstSenItem* fromSenListp = fromp->sensesp()->castSenItem(); const AstSenItem* toSenListp = top->sensesp()->castSenItem(); // If clk gating is ever reenabled, we may need to update this to handle // AstSenGate also. if (!fromSenListp) fromp->v3fatalSrc("sensitivity list item is not an AstSenItem"); if (!toSenListp) top->v3fatalSrc("sensitivity list item is not an AstSenItem"); if (fromSenListp->nextp()) return false; if (toSenListp->nextp()) return false; const AstNodeVarRef* fromVarrefp = fromSenListp->varrefp(); const AstNodeVarRef* toVarrefp = toSenListp->varrefp(); if (!fromVarrefp || !toVarrefp) return false; // We know nothing about the relationship between different clocks here, // so give up on proving anything. if (fromVarrefp->varScopep() != toVarrefp->varScopep()) return false; return fromSenListp->edgeType().exclusiveEdge(toSenListp->edgeType()); } 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())) { // "Initial" and "settle" domains run at time 0 and never // again. Everything else runs at time >0 and never before. // Ignore deps that cross the time-zero/nonzero boundary. // We'll never run both vertices in the same eval() pass // so there's no need to order them. bool toInitial = (toLVertexp->domainp()->hasInitial() || toLVertexp->domainp()->hasSettle()); bool fromInitial = (moveVxp->logicp()->domainp()->hasInitial() || moveVxp->logicp()->domainp()->hasSettle()); if (toInitial != fromInitial) { continue; } // Sometimes we get deps between 'always @(posedge clk)' and // 'always @(negedge clk)' domains. Discard these. We'll never // evaluate both logic vertices on the same eval() pass so // there's no need to order them. if (domainsExclusive(moveVxp->logicp()->domainp(), toLVertexp->domainp())) { continue; } // Path from vertexp to a logic vertex; new edge // Note we use the last edge's weight, not some function of multiple edges new OrderEdge(&m_pomGraph, moveVxp, toLVertexp->moveVxp(), weight); } else { // Keep hunting forward for a logic node processMoveBuildGraphIterate(moveVxp, edgep->top(), weight); } } } } //###################################################################### // Moving void OrderVisitor::processMove() { // The graph routines have already sorted the vertexes and edges into best->worst order // Make a new waiting graph with only OrderLogicVertex's // (Order is preserved in the recreation so the sorting is preserved) // Move any node with all inputs ready to a "ready" graph mapped by domain and then scope // While waiting graph ! empty (and also known: something in ready graph) // For all scopes in domain of top ready vertex // For all vertexes in domain&scope of top ready vertex // Make ordered activation block for this module // Add that new activation to the list of calls to make. // Move logic to ordered active // Any children that have all inputs now ready move from waiting->ready graph // (This may add nodes the for loop directly above needs to detext) processMovePrepScopes(); processMovePrepReady(); // New domain... another loop UINFO(5," MoveIterate\n"); while (!m_pomReadyDomScope.empty()) { // Start with top node on ready list's domain & scope OrderMoveDomScope* domScopep = m_pomReadyDomScope.begin(); OrderMoveVertex* topVertexp = domScopep->readyVertices().begin(); // lintok-begin-on-ref UASSERT(topVertexp, "domScope on ready list without any nodes ready under it"); // Work on all scopes ready inside this domain while (domScopep) { UINFO(6," MoveDomain l="<domainp()<readyVertices().begin()) { // lintok-begin-on-ref processMoveOne(vertexp, domScopep, 1); } // Done with scope/domain pair, pick new scope under same domain, or NULL if none left OrderMoveDomScope* domScopeNextp = NULL; for (OrderMoveDomScope* huntp = m_pomReadyDomScope.begin(); huntp; huntp = huntp->readyDomScopeNextp()) { if (huntp->domainp() == domScopep->domainp()) { domScopeNextp = huntp; break; } } domScopep = domScopeNextp; } } UASSERT (m_pomWaiting.empty(), "Didn't converge; nodes waiting, none ready, perhaps some input activations lost."); // Cleanup memory processMoveClear(); } void OrderVisitor::processMovePrepScopes() { UINFO(5," MovePrepScopes\n"); // Create a OrderMoveDomScope every domain/scope pairing for (OrderMoveVertex* vertexp = m_pomWaiting.begin(); vertexp; vertexp=vertexp->pomWaitingNextp()) { AstSenTree* domainp = vertexp->logicp()->domainp(); AstScope* scopep = vertexp->logicp()->scopep(); // Create the dom pairing for later lookup OrderMoveDomScope* domScopep = OrderMoveDomScope::findCreate(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(); VL_DANGLING(edgep); 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()->castNodeModule(); UASSERT(modp,"NULL"); // Stashed by visitor func if (nodep->castUntilStable()) { nodep->v3fatalSrc("Not implemented"); } else if (nodep->castSenTree()) { // Just ignore sensitivities, we'll deal with them when we move statements that need them } else { // Normal logic // Make or borrow a CFunc to contain the new statements if (v3Global.opt.profileCFuncs() || (v3Global.opt.outputSplitCFuncs() && v3Global.opt.outputSplitCFuncs() < m_pomNewStmts)) { // Put every statement into a unique function to ease profiling or reduce function size m_pomNewFuncp = NULL; } if (!m_pomNewFuncp && domainp != m_deleteDomainp) { string name = cfuncName(modp, domainp, scopep, nodep); m_pomNewFuncp = new AstCFunc(nodep->fileline(), name, scopep); m_pomNewFuncp->argTypes(EmitCBaseVisitor::symClassVar()); m_pomNewFuncp->symProlog(true); m_pomNewStmts = 0; if (domainp->hasInitial() || domainp->hasSettle()) m_pomNewFuncp->slow(true); scopep->addActivep(m_pomNewFuncp); // Where will we be adding the call? AstActive* callunderp = new AstActive(nodep->fileline(), name, domainp); m_scopetopp->addActivep(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 OrderMoveDomScope::ready(OrderVisitor* ovp) { // Check the domScope is on ready list, add if not if (!m_onReadyList) { m_onReadyList = true; m_readyDomScopeE.pushBack(ovp->m_pomReadyDomScope, this); } } inline void OrderMoveDomScope::movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp) { // Mark one vertex as finished, remove from ready list if done UASSERT(m_onReadyList, "Moving vertex from ready when nothing was on que as ready."); if (m_readyVertices.empty()) { // Else more work to get to later m_onReadyList = false; m_readyDomScopeE.unlink(ovp->m_pomReadyDomScope, this); } } //###################################################################### // Top processing void OrderVisitor::process() { // Dump data m_graph.dumpDotFilePrefixed("orderg_pre"); // Break cycles. Each strongly connected subgraph (including cutable // edges) will have its own color, and corresponds to a loop in the // original graph. However the new graph will be acyclic (the removed // edges are actually still there, just with weight 0). UINFO(2," Acyclic & Order...\n"); m_graph.acyclic(&V3GraphEdge::followAlwaysTrue); m_graph.dumpDotFilePrefixed("orderg_acyc"); // Assign ranks so we know what to follow // Then, sort vertices and edges by that ordering m_graph.order(); m_graph.dumpDotFilePrefixed("orderg_order"); // This finds everything that can be traced from an input (which by // definition are the source clocks). After this any vertex which was // traced has isFromInput() true. UINFO(2," Process Clocks...\n"); processInputs(); // must be before processCircular UINFO(2," Process Circulars...\n"); processCircular(); // must be before processDomains // Assign logic verticesto new domains UINFO(2," Domains...\n"); processDomains(); m_graph.dumpDotFilePrefixed("orderg_domain"); if (debug() && v3Global.opt.dumpTree()) processEdgeReport(); UINFO(2," Construct Move Graph...\n"); processMoveBuildGraph(); if (debug()>=4) m_pomGraph.dumpDotFilePrefixed("ordermv_start"); // Different prefix (ordermv) as it's not the same graph m_pomGraph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); m_pomGraph.dumpDotFilePrefixed("ordermv_simpl"); UINFO(2," Move...\n"); processMove(); // Any SC inputs feeding a combo domain must be marked, so we can make them sc_sensitive UINFO(2," Sensitive...\n"); processSensitive(); // must be after processDomains // Dump data m_graph.dumpDotFilePrefixed("orderg_done"); if (0 && debug()) { string dfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_INT_order"; const vl_unique_ptr logp (V3File::new_ofstream(dfilename)); if (logp->fail()) v3fatalSrc("Can't write "<= 3); } verilator-3.916/src/V3EmitXml.h0000664000177100017500000000221313205574202016246 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit XML code // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EMITXML_H_ #define _V3EMITXML_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3EmitXml { public: static void emitxml(); }; #endif // Guard verilator-3.916/src/V3Life.h0000664000177100017500000000223413205574202015551 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Variable life analysis // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LIFE_H_ #define _V3LIFE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Life { public: static void lifeAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3AssertPre.cpp0000664000177100017500000001051113205574202017132 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Collect and print statistics // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // Pre steps: // Attach clocks to each assertion //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3AssertPre.h" #include "V3Ast.h" //###################################################################### // Assert class functions class AssertPreVisitor : public AstNVisitor { // Removes clocks and other pre-optimizations // Eventually inlines calls to sequences, properties, etc. // We're not parsing the tree, or anything more complicated. private: // NODE STATE/TYPES // STATE // Reset each module: AstNodeSenItem* m_seniDefaultp; // Default sensitivity (from AstDefClock) // Reset each assertion: AstNodeSenItem* m_senip; // Last sensitivity // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } AstSenTree* newSenTree(AstNode* nodep) { // Create sentree based on clocked or default clock // Return NULL for always AstSenTree* newp = NULL; AstNodeSenItem* senip = m_senip ? m_senip : m_seniDefaultp; if (!senip) { nodep->v3error("Unsupported: Unclocked assertion"); newp = new AstSenTree(nodep->fileline(), NULL); } else { newp = new AstSenTree(nodep->fileline(), senip->cloneTree(true)); } return newp; } void clearAssertInfo() { m_senip = NULL; } // VISITORS //========== Statements virtual void visit(AstClocking* nodep) { UINFO(8," CLOCKING"<sensesp(); // Trash it, keeping children if (nodep->bodysp()) { nodep->replaceWith(nodep->bodysp()->unlinkFrBack()); } else { nodep->unlinkFrBack(); } pushDeletep(nodep); VL_DANGLING(nodep); } virtual void visit(AstPslCover* nodep) { if (nodep->sentreep()) return; // Already processed clearAssertInfo(); nodep->iterateChildren(*this); nodep->sentreep(newSenTree(nodep)); clearAssertInfo(); } virtual void visit(AstPslClocked* nodep) { 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); VL_DANGLING(nodep); } virtual void visit(AstNodeModule* nodep) { nodep->iterateChildren(*this); // Reset defaults m_seniDefaultp = NULL; } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit AssertPreVisitor(AstNetlist* nodep) { m_seniDefaultp = NULL; clearAssertInfo(); // Process nodep->accept(*this); } virtual ~AssertPreVisitor() {} }; //###################################################################### // Top Assert class void V3AssertPre::assertPreAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3LanguageWords.h0000664000177100017500000001515313205574202017440 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Language rules // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LANGUAGEWORDS_H_ #define _V3LANGUAGEWORDS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include //============================================================================ class V3LanguageWords { // List of common reserved keywords private: map m_kwdMap; // List of keywords, and what language applies void addKwd(const string& kwd, const string& why) { m_kwdMap.insert(make_pair(kwd,why)); } public: string isKeyword(const string& kwd) { map::iterator it = m_kwdMap.find(kwd); if (it == m_kwdMap.end()) return ""; return it->second; } public: V3LanguageWords() { // C++ keywords // C++ addKwd("NULL", "C++ common word"); addKwd("abort", "C++ common word"); addKwd("alignas", "C++11 keyword"); addKwd("alignof", "C++11 keyword"); addKwd("and", "C++11 keyword"); addKwd("and_eq", "C++11 keyword"); addKwd("asm", "C++ common word"); addKwd("atomic_cancel", "C++ TM TS keyword"); addKwd("atomic_commit", "C++ TM TS keyword"); addKwd("atomic_noexcept", "C++ TM TS keyword"); addKwd("auto", "C++ keyword"); addKwd("bit_vector", "C++ common word"); addKwd("bitand", "C++ keyword"); addKwd("bitor", "C++ keyword"); addKwd("bool", "C++ keyword"); addKwd("break", "C++ keyword"); addKwd("case", "C++ keyword"); addKwd("catch", "C++ keyword"); addKwd("cdecl", "C++ common word"); addKwd("char", "C++ keyword"); addKwd("char16_t", "C++11 keyword"); addKwd("char32_t", "C++11 keyword"); addKwd("class", "C++11 keyword"); addKwd("compl", "C++11 keyword"); addKwd("complex", "C++ common word"); addKwd("concept", "C++20 keyword"); addKwd("const", "C++ keyword"); addKwd("const_cast", "C++ common word"); addKwd("const_iterator", "C++ common word"); addKwd("const_reference ", "C++ common word"); addKwd("constexpr", "C++11 keyword"); addKwd("continue", "C++ keyword"); addKwd("decltype", "C++11 keyword"); addKwd("default", "C++ keyword"); addKwd("delete", "C++ keyword"); addKwd("deque", "C++ common word"); addKwd("do", "C++ keyword"); addKwd("double", "C++ keyword"); addKwd("dynamic_cast", "C++ keyword"); addKwd("else", "C++ keyword"); addKwd("enum", "C++ keyword"); addKwd("explicit", "C++ keyword"); addKwd("export", "C++ keyword"); addKwd("extern", "C++ keyword"); addKwd("false", "C++ keyword"); addKwd("far", "C++ common word"); addKwd("float", "C++ keyword"); addKwd("for", "C++ keyword"); addKwd("friend", "C++ keyword"); addKwd("goto", "C++ keyword"); addKwd("huge", "C++ keyword"); addKwd("if", "C++ keyword"); addKwd("import", "C++ modules TS keyword"); addKwd("inline", "C++ keyword"); addKwd("int", "C++ keyword"); addKwd("interrupt", "C++ common word"); addKwd("iterator", "C++ common word"); addKwd("list", "C++ common word"); addKwd("long", "C++ keyword"); addKwd("map", "C++ common word"); addKwd("module", "C++ modules TS keyword"); addKwd("multimap", "C++ common word"); addKwd("multiset", "C++ common word"); addKwd("mutable", "C++ keyword"); addKwd("namespace", "C++ keyword"); addKwd("near", "C++ common word"); addKwd("new", "C++ keyword"); addKwd("noexcept", "C++11 keyword"); addKwd("not", "C++ keyword"); addKwd("not_eq", "C++ keyword"); addKwd("nullptr", "C++11 keyword"); addKwd("operator", "C++ keyword"); addKwd("or", "C++ keyword"); addKwd("or_eq", "C++ keyword"); addKwd("override", "C++ common word"); addKwd("pascal", "C++ keyword"); addKwd("private", "C++ keyword"); addKwd("protected", "C++ keyword"); addKwd("public", "C++ keyword"); addKwd("queue", "C++ common word"); addKwd("reference", "C++ common word"); addKwd("register", "C++ keyword"); addKwd("reinterpret_cast ", "C++ keyword"); addKwd("requires", "C++20 keyword"); addKwd("restrict", "C++ keyword"); addKwd("return", "C++ keyword"); addKwd("set", "C++ common word"); addKwd("short", "C++ keyword"); addKwd("signed", "C++ keyword"); addKwd("sizeof", "C++ keyword"); addKwd("stack", "C++ common word"); addKwd("static", "C++ keyword"); addKwd("static_assert", "C++11 keyword"); addKwd("static_cast", "C++ keyword"); addKwd("struct", "C++ keyword"); addKwd("switch", "C++ keyword"); addKwd("synchronized", "C++ TM TS keyword"); addKwd("template", "C++ keyword"); addKwd("this", "C++ keyword"); addKwd("thread_local", "C++11 keyword"); addKwd("throw", "C++ keyword"); addKwd("transaction_safe", "C++ common word"); addKwd("transaction_safe_dynamic", "C++ common word"); addKwd("true", "C++ keyword"); addKwd("try", "C++ keyword"); addKwd("type_info", "C++ common word"); addKwd("typedef", "C++ keyword"); addKwd("typeid", "C++ keyword"); addKwd("typename", "C++ keyword"); addKwd("uint16_t", "C++ common word"); addKwd("uint32_t", "C++ common word"); addKwd("uint8_t", "C++ common word"); addKwd("union", "C++ keyword"); addKwd("unsigned", "C++ keyword"); addKwd("using", "C++ keyword"); addKwd("vector", "C++ common word"); addKwd("virtual", "C++ keyword"); addKwd("void", "C++ keyword"); addKwd("volatile", "C++ keyword"); addKwd("wchar_t", "C++ keyword"); addKwd("while", "C++ keyword"); addKwd("xor", "C++ keyword"); addKwd("xor_eq", "C++ keyword"); // This conflicts with header functions, so is ignored //dKwd("final", "C++11 keyword"); // Member function or class head, otherwise not reserved // 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.916/src/V3Graph.cpp0000664000177100017500000002757213205574202016302 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph optimizations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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()!=0.0) 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()!=0.0) *logp<<" f"<fanout(); if (vertexp->color()) *logp<<"\\n c"<color(); *logp<<"\""; *logp<<", color="<dotColor(); if (vertexp->dotStyle()!="") *logp<<", style="<dotStyle(); if (vertexp->dotShape()!="") *logp<<", shape="<dotShape(); *logp<<"];\n"; } if (subgr!="") *logp<<"\t};\n"; // Print edges for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (edgep->weight()) { int fromVnum = numMap[edgep->fromp()]; int toVnum = numMap[edgep->top()]; *logp<<"\tn"<fromp()->dotName()< n"<top()->dotName()<name()!="" ? edgep->name() : "\\E")<<"\"" <<"fontsize=8 label=\""<<(edgep->dotLabel()!="" ? edgep->dotLabel() : "")<<"\"" <<" weight="<weight() <<" color="<dotColor(); if (edgep->dotStyle()!="") *logp<<" style="<dotStyle(); //if (edgep->cutable()) { *logp<<",constraint=false"; } // to rank without following edges *logp<<"];\n"; } } } // Vertex::m_user end, now unused // Trailer *logp << "}\n"; logp->close(); cout << "dot -Tpdf -o ~/a.pdf "< #include #include //###################################################################### // VlcOptions void VlcOptions::addReadFile(const string& filename) { if (m_readFiles.find(filename) == m_readFiles.end()) { m_readFiles.insert(filename); } } string VlcOptions::version() { string ver = DTVERSION; ver += " rev "+cvtToStr(DTVERSION_rev); return ver; } bool VlcOptions::onoff(const char* sw, const char* arg, bool& flag) { // if sw==arg, then return true (found it), and flag=true // if sw=="-no-arg", then return true (found it), and flag=false // if sw=="-noarg", then return true (found it), and flag=false // else return false if (arg[0]!='-') v3fatalSrc("OnOff switches must have leading dash."); if (0==strcmp(sw,arg)) { flag=true; return true; } else if (0==strncmp(sw,"-no",3) && (0==strcmp(sw+3,arg+1))) { flag=false; return true; } else if (0==strncmp(sw,"-no-",4) && (0==strcmp(sw+4,arg+1))) { flag=false; return true; } return false; } void VlcOptions::parseOptsList(int argc, char** argv) { // Parse parameters // Note argc and argv DO NOT INCLUDE the filename in [0]!!! // May be called recursively when there are -f files. #define shift { ++i; } for (int i=0; i= 9) { top.tests().dump(true); top.points().dump(); } V3Error::abortIfWarnings(); if (top.opt.annotateOut() != "") { top.annotate(top.opt.annotateOut()); } if (top.opt.rank()) { top.rank(); top.tests().dump(false); } if (top.opt.writeFile() != "") { top.writeCoverage(top.opt.writeFile()); V3Error::abortIfWarnings(); if (top.opt.unlink()) { const VlStringSet& readFiles = top.opt.readFiles(); for (VlStringSet::iterator it = readFiles.begin(); it != readFiles.end(); ++it) { string filename = *it; unlink(filename.c_str()); } } } // Final writing shouldn't throw warnings, but... V3Error::abortIfWarnings(); UINFO(1,"Done, Exiting...\n"); } // Local Variables: // compile-command: "v4make bin/verilator_coverage --debugi 9 test_regress/t/t_vlcov_data_*.dat" // End: verilator-3.916/src/V3Options.h0000664000177100017500000004076413205574202016337 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Command line options // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3OPTIONS_H_ #define _V3OPTIONS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3LangCode.h" //###################################################################### // V3Options - Command line options class V3OptionsImp; class FileLine; 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 V3StringList m_cFlags; // argument: user CFLAGS V3StringList m_ldLibs; // argument: user LDFLAGS V3StringSet m_futures; // argument: -Wfuture- list V3StringSet m_libraryFiles; // argument: Verilog -v files V3StringSet m_clockers; // argument: Verilog -clk signals V3StringSet m_noClockers; // argument: Verilog -noclk signals V3StringList m_vFiles; // argument: Verilog files to read V3StringList m_forceIncs; // argument: -FI DebugSrcMap m_debugSrcs; // argument: --debugi-= DebugSrcMap m_dumpTrees; // argument: --dump-treei-= map m_parameters; // Parameters bool m_preprocOnly; // main switch: -E bool m_makeDepend; // main switch: -MMD bool m_makePhony; // main switch: -MP bool m_preprocNoLine;// main switch: -P bool m_assert; // main switch: --assert bool m_autoflush; // main switch: --autoflush bool m_bboxSys; // main switch: --bbox-sys bool m_bboxUnsup; // main switch: --bbox-unsup bool m_cdc; // main switch: --cdc bool m_coverageLine; // main switch: --coverage-block bool m_coverageToggle;// main switch: --coverage-toggle bool m_coverageUnderscore;// main switch: --coverage-underscore bool m_coverageUser; // main switch: --coverage-func bool m_debugCheck; // main switch: --debug-check bool m_decoration; // main switch: --decoration bool m_exe; // main switch: --exe bool m_ignc; // main switch: --ignc bool m_inhibitSim; // main switch: --inhibit-sim bool m_lintOnly; // main switch: --lint-only bool m_orderClockDly;// main switch: --order-clock-delay bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified bool m_pinsScUint; // main switch: --pins-sc-uint bool m_pinsScBigUint;// main switch: --pins-sc-biguint bool m_pinsUint8; // main switch: --pins-uint8 bool m_profileCFuncs;// main switch: --profile-cfuncs bool m_public; // main switch: --public bool m_relativeCFuncs; // main switch: --relative-cfuncs bool m_relativeIncludes; // main switch: --relative-includes bool m_reportUnoptflat; // main switch: --report-unoptflat 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_stats; // main switch: --stats bool m_statsVars; // main switch: --stats-vars bool m_trace; // main switch: --trace bool m_traceDups; // main switch: --trace-dups bool m_traceParams; // main switch: --trace-params bool m_traceStructs; // main switch: --trace-structs bool m_traceUnderscore;// main switch: --trace-underscore bool m_underlineZero;// main switch: --underline-zero; undocumented old Verilator 2 bool m_vpi; // main switch: --vpi bool m_xInitialEdge; // main switch: --x-initial-edge bool m_xmlOnly; // main switch: --xml-netlist int m_convergeLimit;// main switch: --converge-limit int m_dumpTree; // main switch: --dump-tree int m_ifDepth; // main switch: --if-depth int m_inlineMult; // main switch: --inline-mult int m_moduleRecursion;// main switch: --module-recursion-depth 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_threads; // main switch: --threads (0 == --no-threads) 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_l2Name; // main switch: --l2name; "" for top-module's 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 string m_xInitial; // main switch: --x-initial // Language is now held in FileLine, on a per-node basis. However we still // have a concept of the default language at a global level. V3LangCode m_defaultLanguage; // main switch: --language // MEMBERS (optimizations) // // main switch: -Op: --public bool m_oAcycSimp; // main switch: -Oy: acyclic pre-optimizations bool m_oCase; // main switch: -Oe: case tree conversion bool m_oCombine; // main switch: -Ob: common icode packing bool m_oConst; // main switch: -Oc: constant folding bool m_oDedupe; // main switch: -Od: logic deduplication bool m_oAssemble; // main switch: -Om: assign assemble bool m_oExpand; // main switch: -Ox: expansion of C macros bool m_oFlopGater; // main switch: -Of: flop gater detection bool m_oGate; // main switch: -Og: gate wire elimination bool m_oLife; // main switch: -Ol: variable lifetime bool m_oLifePost; // main switch: -Ot: delayed assignment elimination bool m_oLocalize; // main switch: -Oz: convert temps to local variables bool m_oInline; // main switch: -Oi: module inlining bool m_oReorder; // main switch: -Or: reorder assignments in blocks bool m_oSplit; // main switch: -Os: always assignment splitting bool m_oSubst; // main switch: -Ou: substitute expression temp values bool m_oSubstConst; // main switch: -Ok: final constant substitution bool m_oTable; // main switch: -Oa: lookup table creation private: // METHODS void addArg(const string& flag); void addDefine(const string& defline, bool allowPlus); void addFuture(const string& flag); void addIncDirUser(const string& incdir); // User requested void addIncDirFallback(const string& incdir); // Low priority if not found otherwise void addParameter(const string& paramline, bool allowPlus); 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 string& 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); // CONSTRUCTORS VL_UNCOPYABLE(V3Options); public: V3Options(); ~V3Options(); void setDebugMode(int level); void setDebugSrcLevel(const string& srcfile, int level); int debugSrcLevel(const string& srcfile, int default_level=V3Error::debugDefault()); void setDumpTreeLevel(const string& srcfile, int level); int dumpTreeLevel(const string& srcfile); // METHODS void addCppFile(const string& filename); void addCFlags(const string& filename); void addLdLibs(const string& filename); void addLibraryFile(const string& filename); void addClocker(const string& signame); void addNoClocker(const string& signame); void addVFile(const string& filename); void addForceInc(const string& filename); // ACCESSORS (options) bool preprocOnly() const { return m_preprocOnly; } bool makeDepend() const { return m_makeDepend; } bool makePhony() const { return m_makePhony; } bool preprocNoLine() const { return m_preprocNoLine; } bool underlineZero() const { return m_underlineZero; } string bin() const { return m_bin; } string flags() const { return m_flags; } bool systemC() const { return m_systemC; } bool usingSystemCLibs() const { return !lintOnly() && systemC(); } bool savable() const { return m_savable; } bool skipIdentical() const { return m_skipIdentical; } bool stats() const { return m_stats; } bool statsVars() const { return m_statsVars; } bool assertOn() const { return m_assert; } // assertOn as __FILE__ may be defined bool autoflush() const { return m_autoflush; } bool bboxSys() const { return m_bboxSys; } bool bboxUnsup() const { return m_bboxUnsup; } bool cdc() const { return m_cdc; } bool coverage() const { return m_coverageLine || m_coverageToggle || m_coverageUser; } bool coverageLine() const { return m_coverageLine; } bool coverageToggle() const { return m_coverageToggle; } bool coverageUnderscore() const { return m_coverageUnderscore; } bool coverageUser() const { return m_coverageUser; } bool debugCheck() const { return m_debugCheck; } bool decoration() const { return m_decoration; } bool exe() const { return m_exe; } bool trace() const { return m_trace; } bool traceDups() const { return m_traceDups; } bool traceParams() const { return m_traceParams; } bool traceStructs() const { return m_traceStructs; } bool traceUnderscore() const { return m_traceUnderscore; } bool orderClockDly() const { return m_orderClockDly; } bool outFormatOk() const { return m_outFormatOk; } bool keepTempFiles() const { return (V3Error::debugDefault()!=0); } bool pinsScUint() const { return m_pinsScUint; } bool pinsScBigUint() const { return m_pinsScBigUint; } bool pinsUint8() const { return m_pinsUint8; } bool profileCFuncs() const { return m_profileCFuncs; } bool allPublic() const { return m_public; } bool lintOnly() const { return m_lintOnly; } bool ignc() const { return m_ignc; } bool inhibitSim() const { return m_inhibitSim; } bool relativeCFuncs() const { return m_relativeCFuncs; } bool reportUnoptflat() const { return m_reportUnoptflat; } bool vpi() const { return m_vpi; } bool xInitialEdge() const { return m_xInitialEdge; } bool xmlOnly() const { return m_xmlOnly; } int convergeLimit() const { return m_convergeLimit; } int dumpTree() const { return m_dumpTree; } int ifDepth() const { return m_ifDepth; } int inlineMult() const { return m_inlineMult; } int moduleRecursionDepth() const { return m_moduleRecursion; } 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 threads() const { return m_threads; } 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 l2Name() const { return m_l2Name; } 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; } string xInitial() const { return m_xInitial; } const V3StringSet& cppFiles() const { return m_cppFiles; } const V3StringList& cFlags() const { return m_cFlags; } const V3StringList& ldLibs() const { return m_ldLibs; } const V3StringSet& libraryFiles() const { return m_libraryFiles; } const V3StringList& vFiles() const { return m_vFiles; } const V3StringList& forceIncs() const { return m_forceIncs; } const V3LangCode& defaultLanguage() const { return m_defaultLanguage; } bool hasParameter(string name); string parameter(string name); void checkParameters(); bool isFuture(const string& flag) const; bool isLibraryFile(const string& filename) const; bool isClocker(const string& signame) const; bool isNoClocker(const string& signame) const; // ACCESSORS (optimization options) bool oAcycSimp() const { return m_oAcycSimp; } bool oCase() const { return m_oCase; } bool oCombine() const { return m_oCombine; } bool oConst() const { return m_oConst; } bool oDedupe() const { return m_oDedupe; } bool oAssemble() const { return m_oAssemble; } bool oExpand() const { return m_oExpand; } bool oFlopGater() const { return m_oFlopGater; } bool oGate() const { return m_oGate; } bool oDup() const { return oLife(); } bool oLife() const { return m_oLife; } bool oLifePost() const { return m_oLifePost; } bool oLocalize() const { return m_oLocalize; } bool oInline() const { return m_oInline; } bool oReorder() const { return m_oReorder; } bool oSplit() const { return m_oSplit; } bool oSubst() const { return m_oSubst; } bool oSubstConst() const { return m_oSubstConst; } bool oTable() const { return m_oTable; } // METHODS (uses above) string traceClassBase() const { return "VerilatedVcd"; } // METHODS (from main) static string version(); static string argString(int argc, char** argv); ///< Return list of arguments as simple string string allArgsString(); ///< Return all passed arguments as simple string void bin(const string& flag) { m_bin = flag; } void parseOpts(FileLine* fl, int argc, char** argv); void parseOptsList (FileLine* fl, const string& optdir, int argc, char** argv); void parseOptsFile (FileLine* fl, const string& filename, bool rel); // METHODS (environment) // Most of these may be built into the executable with --enable-defenv, // see the README. If adding new variables, also see src/Makefile_obj.in // Also add to V3Options::showVersion() static string getenvBuiltins(const string& var); static string getenvPERL(); static string getenvSYSTEMC(); static string getenvSYSTEMC_ARCH(); static string getenvSYSTEMC_INCLUDE(); static string getenvSYSTEMC_LIBDIR(); static string getenvVERILATOR_ROOT(); // METHODS (file utilities using these options) string fileExists (const string& filename); string filePath(FileLine* fl, const string& modname, const string& lastpath, 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.916/src/V3LinkJump.h0000664000177100017500000000226513205574202016427 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3LinkLValue.cpp0000664000177100017500000002050213205574202017231 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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) { // 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) { 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) { 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) { 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) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->filep()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstFFlush* nodep) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->filep()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstFGetC* nodep) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->filep()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstFGetS* nodep) { 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) { 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) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->exprsp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstSysIgnore* nodep) { // 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) { 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) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = false; nodep->searchp()->iterateAndNext(*this); m_setRefLvalue = true; nodep->outp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstSFormat* nodep) { 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) { 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) { 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(AstCellArrayRef* nodep) { bool last_setRefLvalue = m_setRefLvalue; { // selp is not an lvalue m_setRefLvalue = false; nodep->selp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstNodePreSel* nodep) { 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) { m_ftaskp = nodep; nodep->iterateChildren(*this); m_ftaskp = NULL; } virtual void visit(AstNodeFTaskRef* nodep) { 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) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkLValueVisitor(AstNode* nodep, bool start) { m_setRefLvalue = start; m_ftaskp = NULL; nodep->accept(*this); } virtual ~LinkLValueVisitor() {} }; //###################################################################### // Link class functions void V3LinkLValue::linkLValue(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<= 6); } void V3LinkLValue::linkLValueSet(AstNode* nodep) { // Called by later link functions when it is known a node needs // to be converted to a lvalue. UINFO(9,__FUNCTION__<<": "< #include #include #include #include "V3Global.h" #include "V3Inst.h" #include "V3Ast.h" #include "V3Changed.h" #include "V3Const.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) { 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) { UINFO(4," CELL "<iterateChildren(*this); m_cellp = NULL; } virtual void visit(AstPin* nodep) { // 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"); 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() || (nodep->modVarp()->subDTypep()->castUnpackArrayDType() && nodep->modVarp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())) { // 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(); AstVarXRef* xrefp = exprp->castVarXRef(); if (!refp && !xrefp) exprp->v3fatalSrc("Interfaces: Pin is not connected to a VarRef or VarXRef"); AstAssignVarScope* assp = new AstAssignVarScope(exprp->fileline(), lhsp, exprp); m_modp->addStmtp(assp); } else { nodep->v3error("Assigned pin is neither input nor output"); } } // We're done with the pin nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstUdpTable* nodep) { 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*) {} virtual void visit(AstAlways*) {} //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit InstVisitor(AstNetlist* nodep) { m_modp=NULL; m_cellp=NULL; // nodep->accept(*this); } virtual ~InstVisitor() {} }; //###################################################################### class InstDeModVarVisitor : public AstNVisitor { // Expand all module variables, and save names for later reference private: // STATE typedef map VarNameMap; VarNameMap m_modVarNameMap; // Per module, name of cloned variables static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstVar* nodep) { if (nodep->dtypep()->castIfaceRefDType()) { UINFO(8," dm-1-VAR "<iterateChildren(*this); } // Save some time virtual void visit(AstNodeMath*) {} // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // METHODS void insert(AstVar* nodep) { UINFO(8," dmINSERT "<name(), nodep)); } AstVar* find(const string& name) { VarNameMap::iterator it = m_modVarNameMap.find(name); if (it != m_modVarNameMap.end()) { return it->second; } else { return NULL; } } void dump() { for (VarNameMap::iterator it=m_modVarNameMap.begin(); it!=m_modVarNameMap.end(); ++it) { cout<<"-namemap: "<first<<" -> "<second<accept(*this); } virtual ~InstDeModVarVisitor() {} }; //###################################################################### 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_instSelNum; // Current instantiation count 0..N-1 InstDeModVarVisitor m_deModVars; // State of variables for current cell module typedef map VarNameMap; static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstVar* nodep) { if (nodep->dtypep()->castUnpackArrayDType() && nodep->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType()) { UINFO(8," dv-vec-VAR "<dtypep()->castUnpackArrayDType(); AstNode* prevp = NULL; for (int i = arrdtype->lsb(); i <= arrdtype->msb(); ++i) { string varNewName = nodep->name() + "__BRA__" + cvtToStr(i) + "__KET__"; UINFO(8,"VAR name insert "<subDTypep()->castIfaceRefDType()->cloneTree(false); arrdtype->addNextHere(ifaceRefp); ifaceRefp->cellp(NULL); AstVar* varNewp = nodep->cloneTree(false); varNewp->name(varNewName); varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(i) + "__KET__"); varNewp->dtypep(ifaceRefp); m_deModVars.insert(varNewp); if (!prevp) { prevp = varNewp; } else { prevp->addNextHere(varNewp); } } } if (prevp) nodep->addNextHere(prevp); if (prevp && debug()==9) { prevp->dumpTree(cout, "newintf: "); cout << endl; } } nodep->iterateChildren(*this); } virtual void visit(AstCell* nodep) { UINFO(4," CELL "<modp()) nodep->v3fatalSrc("Unlinked"); m_deModVars.main(nodep->modp()); // if (nodep->rangep()) { m_cellRangep = nodep->rangep(); AstVar* ifaceVarp = nodep->nextp()->castVar(); bool isIface = ifaceVarp && ifaceVarp->dtypep()->castUnpackArrayDType() && ifaceVarp->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType(); // Make all of the required clones for (int i = 0; i < m_cellRangep->elementsConst(); i++) { m_instSelNum = m_cellRangep->littleEndian() ? (m_cellRangep->elementsConst() - 1 - i) : i; int instNum = m_cellRangep->lsbConst() + i; 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(instNum)+"__KET__"); newp->origName(newp->origName()+"__BRA__"+cvtToStr(instNum)+"__KET__"); UINFO(8," CELL loop "<dtypep()->castUnpackArrayDType(); AstIfaceRefDType* origIfaceRefp = arrdtype->subDTypep()->castIfaceRefDType(); origIfaceRefp->cellp(NULL); AstVar* varNewp = ifaceVarp->cloneTree(false); AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false); arrdtype->addNextHere(ifaceRefp); ifaceRefp->cellp(newp); ifaceRefp->cellName(newp->name()); varNewp->name(varNewp->name() + "__BRA__" + cvtToStr(instNum) + "__KET__"); varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(instNum) + "__KET__"); varNewp->dtypep(ifaceRefp); newp->addNextHere(varNewp); if (debug()==9) { varNewp->dumpTree(cout, "newintf: "); cout << endl; } } // Fixup pins newp->pinsp()->iterateAndNext(*this); if (debug()==9) { newp->dumpTree(cout,"newcell: "); cout<unlinkFrBack(); pushDeletep(ifaceVarp); VL_DANGLING(ifaceVarp); } nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); } else { m_cellRangep = NULL; nodep->iterateChildren(*this); } } virtual void visit(AstPin* nodep) { // 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(); pair pinDim = nodep->modVarp()->dtypep()->dimensions(false); pair expDim = nodep->exprp()->dtypep()->dimensions(false); UINFO(4," PINVAR "<modVarp()<exprp()<exprp()->unlinkFrBack(); exprp = new AstArraySel (exprp->fileline(), exprp, m_instSelNum); nodep->exprp(exprp); } else 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) if (m_cellRangep->littleEndian()) { nodep->v3warn(LITENDIAN,"Little endian cell range connecting to vector: MSB < LSB of cell range: " <lsbConst()<<":"<msbConst()); } 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_instSelNum, pinwidth); nodep->exprp(exprp); } else { nodep->v3fatalSrc("Width mismatch; V3Width should have errored out."); } } else if (AstArraySel* arrselp = nodep->exprp()->castArraySel()) { if (AstUnpackArrayDType* arrp = arrselp->lhsp()->dtypep()->castUnpackArrayDType()) { if (!arrp->subDTypep()->castIfaceRefDType()) return; V3Const::constifyParamsEdit(arrselp->rhsp()); AstConst* constp = arrselp->rhsp()->castConst(); if (!constp) { nodep->v3error("Unsupported: Non-constant index when passing interface to module"); return; } string index = AstNode::encodeNumber(constp->toSInt()); AstVarRef* varrefp = arrselp->lhsp()->castVarRef(); AstVarXRef* newp = new AstVarXRef(nodep->fileline(), varrefp->name()+"__BRA__"+index+"__KET__", "", true); newp->dtypep(nodep->modVarp()->dtypep()); newp->packagep(varrefp->packagep()); arrselp->addNextHere(newp); arrselp->unlinkFrBack()->deleteTree(); } } else { AstVar* pinVarp = nodep->modVarp(); AstUnpackArrayDType* pinArrp = pinVarp->dtypep()->castUnpackArrayDType(); if (!pinArrp || !pinArrp->subDTypep()->castIfaceRefDType()) return; AstNode* prevp = NULL; AstNode* prevPinp = NULL; // Clone the var referenced by the pin, and clone each var referenced by the varref // Clone pin varp: for (int i = pinArrp->lsb(); i <= pinArrp->msb(); ++i) { string varNewName = pinVarp->name() + "__BRA__" + cvtToStr(i) + "__KET__"; AstVar* varNewp = NULL; // Only clone the var once for all usages of a given child module if (!pinVarp->backp()) { varNewp = m_deModVars.find(varNewName); } else { AstIfaceRefDType* ifaceRefp = pinArrp->subDTypep()->castIfaceRefDType(); ifaceRefp->cellp(NULL); varNewp = pinVarp->cloneTree(false); varNewp->name(varNewName); varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(i) + "__KET__"); varNewp->dtypep(ifaceRefp); m_deModVars.insert(varNewp); if (!prevp) { prevp = varNewp; } else { prevp->addNextHere(varNewp); } } if (!varNewp) { if (debug()>=9) m_deModVars.dump(); nodep->v3fatalSrc("Module dearray failed for "<cloneTree(false); newp->modVarp(varNewp); newp->name(newp->name() + "__BRA__" + cvtToStr(i) + "__KET__"); // And replace exprp with a new varxref AstVarRef* varrefp = newp->exprp()->castVarRef(); string newname = varrefp->name() + "__BRA__" + cvtToStr(i) + "__KET__"; AstVarXRef* newVarXRefp = new AstVarXRef (nodep->fileline(), newname, "", true); newVarXRefp->varp(newp->modVarp()); newVarXRefp->dtypep(newp->modVarp()->dtypep()); newp->exprp()->unlinkFrBack()->deleteTree(); newp->exprp(newVarXRefp); if (!prevPinp) { prevPinp = newp; } else { prevPinp->addNextHere(newp); } } if (prevp) { pinVarp->replaceWith(prevp); pushDeletep(pinVarp); } // else pinVarp already unlinked when another instance did this step nodep->replaceWith(prevPinp); pushDeletep(nodep); } } // Save some time virtual void visit(AstNodeMath*) {} //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit InstDeVisitor(AstNetlist* nodep) { m_cellRangep=NULL; m_instSelNum=0; // nodep->accept(*this); } virtual ~InstDeVisitor() {} }; //###################################################################### // Inst static function class InstStatic { private: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } InstStatic() {} // Static class static AstNode* extendOrSel(FileLine* fl, AstNode* rhsp, AstNode* cmpWidthp) { if (cmpWidthp->width() > rhsp->width()) { rhsp = (rhsp->isSigned() ? static_cast(new AstExtendS(fl, rhsp)) : static_cast(new AstExtend (fl, rhsp))); rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above } else if (cmpWidthp->width() < rhsp->width()) { rhsp = new AstSel (fl, rhsp, 0, cmpWidthp->width()); rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above } // else don't change dtype, as might be e.g. array of something return rhsp; } public: static AstAssignW* pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule*, bool forTristate, bool alwaysCvt) { // If a pin connection is "simple" leave it as-is // Else create a intermediate wire to perform the interconnect // Return the new assignment, if one was made // Note this module calles cloneTree() via new AstVar AstVar* pinVarp = pinp->modVarp(); AstVarRef* connectRefp = pinp->exprp()->castVarRef(); AstVarXRef* connectXRefp = pinp->exprp()->castVarXRef(); AstBasicDType* pinBasicp = pinVarp->dtypep()->castBasicDType(); // Maybe NULL AstBasicDType* connBasicp = NULL; AstAssignW* assignp = NULL; if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->castBasicDType(); // 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 && connectXRefp && connectXRefp->varp() && connectXRefp->varp()->isIfaceRef()) { } 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()) { // Done. One to one interconnect won't need a temporary variable. } else if (!alwaysCvt && !forTristate && pinp->exprp()->castConst()) { // Done. Constant. } else { // Make a new temp wire //if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); } AstNode* pinexprp = pinp->exprp()->unlinkFrBack(); string newvarname = ((string)(pinVarp->isOutput() ? "__Vcellout" : "__Vcellinp") +(forTristate?"t":"") // Prevent name conflict if both tri & non-tri add signals +"__"+cellp->name()+"__"+pinp->name()); AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp); // Important to add statement next to cell, in case there is a generate with same named cell cellp->addNextHere(newvarp); if (pinVarp->isInout()) { pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)"); } else if (pinVarp->isOutput()) { // See also V3Inst AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false); UINFO(5,"pinRecon width "<width()<<" >? "<width()<<" >? "<width()<fileline(), rhsp, pinVarp); pinp->exprp(new AstVarRef (newvarp->fileline(), newvarp, true)); AstNode* rhsSelp = extendOrSel (pinp->fileline(), rhsp, pinexprp); assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsSelp); } else { // V3 width should have range/extended to make the widths correct assignp = new AstAssignW (pinp->fileline(), new AstVarRef(pinp->fileline(), newvarp, true), pinexprp); pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false)); } if (assignp) cellp->addNextHere(assignp); //if (debug()) { pinp->dumpTree(cout,"- out:"); } //if (debug()) { assignp->dumpTree(cout,"- aout:"); } } return assignp; } }; //###################################################################### // Inst class functions AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* modp, bool forTristate, bool alwaysCvt) { return InstStatic::pinReconnectSimple(pinp, cellp, modp, forTristate, alwaysCvt); } //###################################################################### // Inst class visitor void V3Inst::instAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Inst::dearrayAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.916/src/V3Assert.cpp0000664000177100017500000003011313205574202016463 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Collect and print statistics // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Assert.h" #include "V3Ast.h" #include "V3GraphDfa.h" #include "V3Stats.h" //###################################################################### // Assert class functions class AssertVisitor : public AstNVisitor { private: // NODE STATE/TYPES // Cleared on netlist // AstNode::user() -> bool. True if processed AstUser1InUse m_inuser1; // STATE AstNodeModule* m_modp; // Last module AstBegin* m_beginp; // Last begin V3Double0 m_statAsCover; // Statistic tracking V3Double0 m_statAsPsl; // Statistic tracking V3Double0 m_statAsFull; // Statistic tracking V3Double0 m_statAsSV; // Statistic tracking // METHODS string assertDisplayMessage(AstNode* nodep, const string& prefix, const string& message) { return (string("[%0t] "+prefix+": ")+nodep->fileline()->filebasename() +":"+cvtToStr(nodep->fileline()->lineno()) +": Assertion failed in %m" +((message != "")?": ":"")+message +"\n"); } void replaceDisplay(AstDisplay* nodep, const string& prefix) { nodep->displayType(AstDisplayType::DT_WRITE); nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text())); // cppcheck-suppress nullPointer AstNode* timenewp = new AstTime(nodep->fileline()); if (AstNode* timesp = nodep->fmtp()->exprsp()) { timesp->unlinkFrBackWithNext(); timenewp->addNext(timesp); } nodep->fmtp()->addExprsp(timenewp); if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) { nodep->fmtp()->scopeNamep(new AstScopeName(nodep->fileline())); } } AstNode* newIfAssertOn(AstNode* nodep) { // Add a internal if to check assertions are on. // Don't make this a AND term, as it's unlikely to need to test this. AstNode* newp = new AstIf (nodep->fileline(), // If assertions are off, have constant propagation rip them out later // This allows syntax errors and such to be detected normally. (v3Global.opt.assertOn() ? (AstNode*)(new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1)) : (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))), nodep, NULL); newp->user1(true); // Don't assert/cover this if return newp; } AstNode* newFireAssert(AstNode* nodep, const string& message) { AstDisplay* dispp = new AstDisplay (nodep->fileline(), AstDisplayType::DT_ERROR, message, NULL, NULL); AstNode* bodysp = dispp; replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format bodysp->addNext(new AstStop (nodep->fileline())); bodysp = newIfAssertOn(bodysp); return bodysp; } void newPslAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep, AstNode* stmtsp, const string& message) { propp->unlinkFrBack(); sentreep->unlinkFrBack(); if (stmtsp) stmtsp->unlinkFrBack(); // AstNode* bodysp = NULL; bool selfDestruct = false; if (AstPslCover* snodep = nodep->castPslCover()) { if (!v3Global.opt.coverageUser()) { selfDestruct = true; } else { // V3Coverage assigned us a bucket to increment. AstCoverInc* covincp = snodep->coverincp()->castCoverInc(); if (!covincp) snodep->v3fatalSrc("Missing AstCoverInc under assertion"); covincp->unlinkFrBack(); if (message!="") covincp->declp()->comment(message); bodysp = covincp; } } else { nodep->v3fatalSrc("Unknown node type"); } if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp); AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL); bodysp = ifp; if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY); // AstNode* newp = new AstAlways (nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, bodysp); // Install it if (selfDestruct) { // Delete it after making the tree. This way we can tell the user // if it wasn't constructed nicely or has other errors without needing --coverage. newp->deleteTree(); nodep->unlinkFrBack(); } else { nodep->replaceWith(newp); } // Bye pushDeletep(nodep); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } virtual void visit(AstIf* nodep) { if (nodep->user1SetOnce()) return; if (nodep->uniquePragma() || nodep->unique0Pragma()) { AstNodeIf* ifp = nodep; AstNode* propp = NULL; bool hasDefaultElse = false; do { // If this statement ends with 'else if', then nextIf will point to the // nextIf statement. Otherwise it will be null. AstNodeIf* nextifp = dynamic_cast(ifp->elsesp()); ifp->condp()->iterateAndNext(*this); // Recurse into the true case. ifp->ifsp()->iterateAndNext(*this); // If the last else is not an else if, recurse into that too. if (ifp->elsesp() && !nextifp) { ifp->elsesp()->iterateAndNext(*this); } // Build a bitmask of the true predicates AstNode* predp = ifp->condp()->cloneTree(false); if (propp) { propp = new AstConcat(nodep->fileline(), predp, propp); } else { propp = predp; } // Record if this ends with an 'else' that does not have an if if (ifp->elsesp() && !nextifp) { hasDefaultElse = true; } ifp = nextifp; } while (ifp); AstNode *newifp = nodep->cloneTree(false); bool allow_none = nodep->unique0Pragma(); // Empty case means no property if (!propp) propp = new AstConst(nodep->fileline(), AstConst::LogicFalse()); // Note: if this ends with an 'else', then we don't need to validate that one of the // predicates evaluates to true. AstNode* ohot = ((allow_none || hasDefaultElse) ? static_cast(new AstOneHot0(nodep->fileline(), propp)) : static_cast(new AstOneHot (nodep->fileline(), propp))); AstIf* checkifp = new AstIf (nodep->fileline(), new AstLogNot (nodep->fileline(), ohot), newFireAssert(nodep, "'unique if' statement violated"), newifp); checkifp->branchPred(AstBranchPred::BP_UNLIKELY); nodep->replaceWith(checkifp); pushDeletep(nodep); } else { nodep->iterateChildren(*this); } } // VISITORS //========== Case assertions virtual void visit(AstCase* nodep) { 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; if (nodep->casex() || nodep->casez() || nodep->caseInside()) { onep = AstEqWild::newTyped(itemp->fileline(), nodep->exprp()->cloneTree(false), icondp->cloneTree(false)); } else { onep = AstEq::newTyped(icondp->fileline(), nodep->exprp()->cloneTree(false), icondp->cloneTree(false)); } if (propp) propp = new AstConcat(icondp->fileline(), onep, propp); else propp = onep; } } // Empty case means no property if (!propp) propp = new AstConst(nodep->fileline(), AstConst::LogicFalse()); bool allow_none = has_default || nodep->unique0Pragma(); AstNode* ohot = (allow_none ? static_cast(new AstOneHot0(nodep->fileline(), propp)) : static_cast(new AstOneHot (nodep->fileline(), propp))); 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) { 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) { nodep->iterateChildren(*this); if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name()); newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->stmtsp(), nodep->name()); VL_DANGLING(nodep); ++m_statAsCover; } virtual void visit(AstVAssert* nodep) { nodep->iterateChildren(*this); newVAssertion(nodep, nodep->propp()); VL_DANGLING(nodep); ++m_statAsSV; } virtual void visit(AstNodeModule* nodep) { m_modp = nodep; // nodep->iterateChildren(*this); // Reset defaults m_modp = NULL; } virtual void visit(AstBegin* nodep) { // This code is needed rather than a visitor in V3Begin, // because V3Assert is called before V3Begin AstBegin* lastp = m_beginp; { m_beginp = nodep; nodep->iterateChildren(*this); } m_beginp = lastp; } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit AssertVisitor(AstNetlist* nodep) { m_beginp = NULL; m_modp = NULL; // Process nodep->accept(*this); } virtual ~AssertVisitor() { V3Stats::addStat("Assertions, PSL asserts", m_statAsPsl); V3Stats::addStat("Assertions, SystemVerilog asserts", m_statAsSV); V3Stats::addStat("Assertions, cover statements", m_statAsCover); V3Stats::addStat("Assertions, full/parallel case", m_statAsFull); } }; //###################################################################### // Top Assert class void V3Assert::assertAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/.gdbinit0000664000177100017500000000134613205574202015734 0ustar wsnyderwsnyder# DESCRIPTION: Verilator: GDB startup file with useful defines # # Copyright 2012-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. define pn call $arg0->dumpGdb() end document pn Verilator: Print single AstNode NODEP end define pnt call $arg0->dumpTreeGdb() end document pnt Verilator: Print AstNode NODEP's tree end define dtf call AstNode::dumpTreeFileGdb(0) end document dtf Verilator: Dump AstNode tree to file end define watchedit watch AstNode::s_editCntGbl==$arg0 end document watchedit Verilator: Create watch on where a edit number is made end verilator-3.916/src/V3PreProc.h0000664000177100017500000001001613205574202016241 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilog::Preproc: Preprocess verilog code // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2000-2017 by Wilson Snyder. This program is free software; // you can redistribute it and/or modify it under the terms of either the // GNU Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3PREPROC_H_ #define _V3PREPROC_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3FileLine.h" #include #include #include #include // Compatibility with Verilog-Perl's preprocessor #define fatalSrc(msg) v3fatalSrc(msg) class V3InFilter; class V3PreProc { // This defines a preprocessor. Functions are virtual so implementation can be hidden. // After creating, call open(), then getline() in a loop. The class will to the rest... protected: // STATE int m_debug; // Debugging public: // CONSTANTS enum MiscConsts { DEFINE_RECURSION_LEVEL_MAX = 1000, // How many `def substitutions before an error INCLUDE_DEPTH_MAX = 500, // How many `includes deep before an error STREAM_DEPTH_LEVEL_MAX = 2000, // How many streams deep (sometimes `def deep) before an error // // Set more than DEFINE_RECURSION_LEVEL_MAX or INCLUDE_DEPTH_MAX NEWLINES_VS_TICKLINE = 20 // Use `line in place of this many newlines }; // ACCESSORS // Insert given file into this point in input stream virtual void openFile(FileLine* fileline, V3InFilter* filterp, const string& filename)=0; virtual string getline()=0; // Return next line/lines. (Null if done.) virtual bool isEof() const =0; // Return true on EOF. virtual void insertUnreadback(const string& text) = 0; int debug() const { return m_debug; } void debug(int level) { m_debug = level; } FileLine* fileline(); ///< File/Line number for last getline call // CONTROL METHODS // These options control how the parsing proceeds static int keepComments() { return 2; } // Return comments, 0=no, 1=yes, 2=callback static bool keepWhitespace() { return false; } static bool lineDirectives() { // Insert `line directives return !(v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine()); } static bool pedantic() { return false; } // Obey standard; Don't substitute `error // CALLBACK METHODS // This probably will want to be overridden for given child users of this class. virtual void comment(const string& cmt)=0; // Comment detected (if keepComments==2) virtual void include(const string& filename)=0; // Request a include file be processed virtual void undef(const string& name)=0; // Remove a definition virtual void define(FileLine* fileline, const string& name, const string& value, const string& params="", bool cmdline=false)=0; // `define without any parameters virtual void defineCmdLine(FileLine* fileline, const string& name, const string& value) { // `define without any parameters define(fileline, name, value, "", true); } virtual string removeDefines(const string& text)=0; // Remove defines in a text string // UTILITIES void error(const string& msg) { fileline()->v3error(msg); } ///< Report a error void fatal(const 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.916/src/V3Subst.cpp0000664000177100017500000003150013205574202016323 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 explicit 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(); VL_DANGLING(nodep); } 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) { SubstVarEntry* entryp = findEntryp (nodep); if (entryp) { // Don't sweat it. We assign a new temp variable for every new assignment, // so there's no way we'd ever replace a old value. } else { // A simple variable; needs checking. if (m_origStep < nodep->varp()->user2()) { if (m_ok) UINFO(9," RHS variable changed since subst recorded: "<iterateChildren(*this); } public: // CONSTUCTORS SubstUseVisitor(AstNode* nodep, int origStep) { UINFO(9, " SubstUseVisitor "<accept(*this); } virtual ~SubstUseVisitor() {} // METHODS bool ok() const { return m_ok; } }; //###################################################################### // Subst state, as a visitor of each AstNode class SubstVisitor : public SubstBaseVisitor { private: // NODE STATE // Passed to SubstUseVisitor // AstVar::user1p -> SubstVar* for usage var, 0=not set yet // AstVar::user2 -> int step number for last assignment, 0=not set yet AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // STATE vector m_entryps; // Nodes to delete when we are finished int m_ops; // Number of operators on assign rhs int m_assignStep; // Assignment number to determine var lifetime V3Double0 m_statSubsts; // Statistic tracking enum { SUBST_MAX_OPS_SUBST = 30, // Maximum number of ops to substitute in SUBST_MAX_OPS_NA = 9999 }; // Not allowed to substitute // METHODS SubstVarEntry* getEntryp(AstVarRef* nodep) { if (!nodep->varp()->user1p()) { SubstVarEntry* entryp = new SubstVarEntry (nodep->varp()); m_entryps.push_back(entryp); nodep->varp()->user1p(entryp); return entryp; } else { SubstVarEntry* entryp = (SubstVarEntry*)(nodep->varp()->user1p()); return entryp; } } inline bool isSubstVar(AstVar* nodep) { return nodep->isStatementTemp() && !nodep->noSubst(); } // VISITORS virtual void visit(AstNodeAssign* nodep) { m_ops = 0; m_assignStep++; nodep->rhsp()->iterateAndNext(*this); bool hit=false; if (AstVarRef* varrefp = nodep->lhsp()->castVarRef()) { if (isSubstVar(varrefp->varp())) { SubstVarEntry* entryp = getEntryp(varrefp); hit = true; if (m_ops > SUBST_MAX_OPS_SUBST) { UINFO(8," ASSIGNtooDeep "<assignComplex(m_assignStep); } else { UINFO(8," ASSIGNwhole "<assignWhole(m_assignStep, nodep); } } } else if (AstWordSel* wordp = nodep->lhsp()->castWordSel()) { if (AstVarRef* varrefp = wordp->lhsp()->castVarRef()) { if (wordp->rhsp()->castConst() && isSubstVar(varrefp->varp())) { int word = wordp->rhsp()->castConst()->toUInt(); SubstVarEntry* entryp = getEntryp(varrefp); hit = true; if (m_ops > SUBST_MAX_OPS_SUBST) { UINFO(8," ASSIGNtooDeep "<assignWordComplex(m_assignStep, word); } else { UINFO(8," ASSIGNword"<assignWord(m_assignStep, word, nodep); } } } } if (!hit) { nodep->lhsp()->accept(*this); } } void replaceSubstEtc(AstNode* nodep, AstNode* substp) { if (debug()>5) nodep->dumpTree(cout," substw_old: "); AstNode* newp = substp->cloneTree(true); if (!nodep->isQuad() && newp->isQuad()) { newp = new AstCCast (newp->fileline(), newp, nodep); } if (debug()>5) newp->dumpTree(cout," w_new: "); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); ++m_statSubsts; } virtual void visit(AstWordSel* nodep) { nodep->rhsp()->accept(*this); AstVarRef* varrefp = nodep->lhsp()->castVarRef(); AstConst* constp = nodep->rhsp()->castConst(); if (varrefp && isSubstVar(varrefp->varp()) && !varrefp->lvalue() && constp) { // Nicely formed lvalues handled in NodeAssign // Other lvalues handled as unknown mess in AstVarRef int word = constp->toUInt(); UINFO(8," USEword"<substWord (nodep, word)) { // Check that the RHS hasn't changed value since we recorded it. SubstUseVisitor visitor (substp, entryp->getWordStep(word)); if (visitor.ok()) { replaceSubstEtc(nodep, substp); VL_DANGLING(nodep); } else { entryp->consumeWord(word); } } else { entryp->consumeWord(word); } } else { nodep->lhsp()->accept(*this); } } virtual void visit(AstVarRef* nodep) { // Any variable if (nodep->lvalue()) { m_assignStep++; nodep->varp()->user2(m_assignStep); UINFO(9, " ASSIGNstep u2="<varp()->user2()<<" "<varp())) { SubstVarEntry* entryp = getEntryp (nodep); if (nodep->lvalue()) { UINFO(8," ASSIGNcpx "<assignComplex(m_assignStep); } else if (AstNode* substp = entryp->substWhole(nodep)) { // Check that the RHS hasn't changed value since we recorded it. SubstUseVisitor visitor (substp, entryp->getWholeStep()); if (visitor.ok()) { UINFO(8," USEwhole "<consumeWhole(); } } else { // Consumed w/o substitute UINFO(8," USEwtf "<consumeWhole(); } } } virtual void visit(AstVar* nodep) {} virtual void visit(AstConst* nodep) {} virtual void visit(AstNode* nodep) { m_ops++; if (!nodep->isSubstOptimizable()) { m_ops = SUBST_MAX_OPS_NA; } nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit SubstVisitor(AstNode* nodep) { AstNode::user1ClearTree(); // user1p() used on entire tree AstNode::user2ClearTree(); // user2p() used on entire tree m_ops = 0; m_assignStep = 0; nodep->accept(*this); } virtual ~SubstVisitor() { V3Stats::addStat("Optimizations, Substituted temps", m_statSubsts); for (vector::iterator it = m_entryps.begin(); it != m_entryps.end(); ++it) { (*it)->deleteUnusedAssign(); delete (*it); } } }; //###################################################################### // Subst class functions void V3Subst::substituteAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3EmitMk.cpp0000664000177100017500000002115313205574202016414 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit Makefile // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3Os.h" #include "V3EmitMk.h" #include "V3EmitCBase.h" //###################################################################### // Emit statements and math operators class EmitMkVisitor : public EmitCBaseVisitor { public: // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void putMakeClassEntry(V3OutMkFile& of, const string& name) { of.puts("\t"+V3Os::filenameNonDirExt(name)+" \\\n"); } void emitClassMake() { // Generate the makefile V3OutMkFile of (v3Global.opt.makeDir()+"/"+ v3Global.opt.prefix() + "_classes.mk"); of.putsHeader(); of.puts("# DESCR" "IPTION: Verilator output: Make include file with class lists\n"); of.puts("#\n"); of.puts("# This file lists generated Verilated files, for including in higher level makefiles.\n"); of.puts("# See "+v3Global.opt.prefix()+".mk"+" for the caller.\n"); of.puts("\n### Switches...\n"); of.puts("# Coverage output mode? 0/1 (from --coverage)\n"); of.puts("VM_COVERAGE = "); of.puts(v3Global.opt.coverage()?"1":"0"); of.puts("\n"); of.puts("# Threaded output mode? 0/1/N threads (from --threads)\n"); of.puts("VM_THREADS = "); of.puts(cvtToStr(v3Global.opt.threads())); 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.vpi()) { putMakeClassEntry(of, "verilated_vpi.cpp"); } if (v3Global.opt.savable()) { putMakeClassEntry(of, "verilated_save.cpp"); } if (v3Global.opt.coverage()) { putMakeClassEntry(of, "verilated_cov.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!=0) && nodep->support()==(support!=0)) { 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("# 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("# SystemC output mode? 0/1 (from --sc)\n"); of.puts(string("VM_SC = ")+((v3Global.opt.systemC())?"1":"0")+"\n"); of.puts("# Legacy or SystemC output mode? 0/1 (from --sc)\n"); of.puts(string("VM_SP_OR_SC = $(VM_SC)\n")); of.puts("# Deprecated\n"); of.puts(string("VM_PCLI = ")+(v3Global.opt.systemC()?"0":"1")+"\n"); of.puts("# Deprecated: SystemC architecture to find link library path (from $SYSTEMC_ARCH)\n"); of.puts(string("VM_SC_TARGET_ARCH = ")+V3Options::getenvSYSTEMC_ARCH()+"\n"); of.puts("\n### Vars...\n"); of.puts("# Design prefix (from --prefix)\n"); of.puts(string("VM_PREFIX = ")+v3Global.opt.prefix()+"\n"); of.puts("# Module prefix (from --prefix)\n"); of.puts(string("VM_MODPREFIX = ")+v3Global.opt.modPrefix()+"\n"); of.puts("# User CFLAGS (from -CFLAGS on Verilator command line)\n"); of.puts("VM_USER_CFLAGS = \\\n"); const V3StringList& cFlags = v3Global.opt.cFlags(); for (V3StringList::const_iterator it = cFlags.begin(); it != cFlags.end(); ++it) { of.puts("\t"+*it+" \\\n"); } of.puts("\n"); of.puts("# User LDLIBS (from -LDFLAGS on Verilator command line)\n"); of.puts("VM_USER_LDLIBS = \\\n"); const V3StringList& ldLibs = v3Global.opt.ldLibs(); for (V3StringList::const_iterator it = ldLibs.begin(); it != ldLibs.end(); ++it) { of.puts("\t"+*it+" \\\n"); } of.puts("\n"); V3StringSet dirs; of.puts("# User .cpp files (from .cpp's on Verilator command line)\n"); of.puts("VM_USER_CLASSES = \\\n"); const V3StringSet& cppFiles = v3Global.opt.cppFiles(); for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) { string cppfile = *it; of.puts("\t"+V3Os::filenameNonExt(cppfile)+" \\\n"); string dir = V3Os::filenameDir(cppfile); if (dirs.find(dir) == dirs.end()) dirs.insert(dir); } of.puts("\n"); of.puts("# User .cpp directories (from .cpp's on Verilator command line)\n"); of.puts("VM_USER_DIR = \\\n"); for (V3StringSet::iterator it = dirs.begin(); it!=dirs.end(); ++it) { of.puts("\t"+*it+" \\\n"); } of.puts("\n"); of.puts("\n### Default rules...\n"); of.puts("# Include list of all generated classes\n"); of.puts("include "+v3Global.opt.prefix()+"_classes.mk\n"); of.puts("# Include global rules\n"); of.puts("include $(VERILATOR_ROOT)/include/verilated.mk\n"); if (v3Global.opt.exe()) { of.puts("\n### Executable rules... (from --exe)\n"); of.puts("VPATH += $(VM_USER_DIR)\n"); of.puts("\n"); for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) { string cppfile = *it; string basename = V3Os::filenameNonExt(cppfile); of.puts(basename+".o: "+cppfile+"\n"); of.puts("\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<\n"); } of.puts("\n### Link rules... (from --exe)\n"); of.puts(v3Global.opt.exeName()+": $(VK_USER_OBJS) $(VK_GLOBAL_OBJS) $(VM_PREFIX)__ALL.a\n"); of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) $(SC_LIBS) 2>&1 | c++filt\n"); of.puts("\n"); } of.puts("\n"); of.putsHeader(); } //-------------------- virtual void visit(AstNode* nodep) { nodep->v3fatalSrc("No visitors implemented."); } public: explicit 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) // // TODO: This code was written before SLICESEL was a type it might be // simplified to look primarily for SLICESELs. //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3Slice.h" #include "V3Ast.h" //************************************************************************* 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 AstUser1InUse m_inuser1; // STATE AstNode* m_assignp; // Assignment we are under 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; } AstNode* cloneAndSel(AstNode* nodep, int elements, int offset) { // Insert an ArraySel, except for a few special cases AstUnpackArrayDType* arrayp = nodep->dtypep()->skipRefp()->castUnpackArrayDType(); if (!arrayp) { // V3Width should have complained, but... if (!m_assignError) nodep->v3error(nodep->prettyTypeName()<<" is not an unpacked array, but is in an unpacked array context"); m_assignError = true; return nodep->cloneTree(false); // Likely will cause downstream errors } if (arrayp->rangep()->elementsConst() != elements) { if (!m_assignError) nodep->v3error("Slices of arrays in assignments have different unpacked dimensions, " <rangep()->elementsConst()); m_assignError = true; elements = 1; offset = 0; } AstNode* newp; if (AstInitArray* initp = nodep->castInitArray()) { UINFO(9," cloneInitArray("<initsp(); int leOffset = !arrayp->rangep()->littleEndian() ? arrayp->rangep()->elementsConst()-1-offset : offset; for (int pos = 0; itemp && pos < leOffset; ++pos) { itemp = itemp->nextp(); } if (!itemp) { nodep->v3error("Array initialization has too few elements, need element "<initsp(); } newp = itemp->cloneTree(false); } else if (AstNodeCond* snodep = nodep->castNodeCond()) { UINFO(9," cloneCond("<cloneType(snodep->condp()->cloneTree(false), cloneAndSel(snodep->expr1p(), elements, offset), cloneAndSel(snodep->expr2p(), elements, offset)); } else if (AstSliceSel* snodep = nodep->castSliceSel()) { UINFO(9," cloneSliceSel("<declRange().lo() + (!snodep->declRange().littleEndian() ? snodep->declRange().elements()-1-offset : offset)); newp = new AstArraySel(nodep->fileline(), snodep->fromp()->cloneTree(false), leOffset); } else if (nodep->castArraySel() || nodep->castNodeVarRef() || nodep->castNodeSel()) { UINFO(9," cloneSel("<rangep()->littleEndian() ? arrayp->rangep()->elementsConst()-1-offset : offset; newp = new AstArraySel(nodep->fileline(), nodep->cloneTree(false), leOffset); } else { if (!m_assignError) nodep->v3error(nodep->prettyTypeName()<<" unexpected in assignment to unpacked array"); m_assignError = true; newp = nodep->cloneTree(false); // Likely will cause downstream errors } return newp; } virtual void visit(AstNodeAssign* nodep) { // Called recursively on newly created assignments if (!nodep->user1() && !nodep->castAssignAlias()) { nodep->user1(true); m_assignError = false; if (debug()>=9) { cout<dumpTree(cout," Deslice-In: "); } AstNodeDType* dtp = nodep->lhsp()->dtypep()->skipRefp(); if (AstUnpackArrayDType* arrayp = dtp->castUnpackArrayDType()) { // Left and right could have different msb/lsbs/endianness, but #elements is common // and all variables are realigned to start at zero // Assign of a little endian'ed slice to a big endian one must reverse the elements AstNode* newlistp = NULL; int elements = arrayp->rangep()->elementsConst(); for (int offset = 0; offset < elements; ++offset) { AstNode* newp = nodep->cloneType // AstNodeAssign (cloneAndSel(nodep->lhsp(), elements, offset), cloneAndSel(nodep->rhsp(), elements, offset)); if (debug()>=9) { newp->dumpTree(cout,"-new "); } newlistp = AstNode::addNextNull(newlistp, newp); } if (debug()>=9) { cout<dumpTree(cout," Deslice-Dn: "); } nodep->replaceWith(newlistp); nodep->deleteTree(); VL_DANGLING(nodep); // Normal edit iterator will now iterate on all of the expansion assignments // This will potentially call this function again to resolve next level of slicing return; } m_assignp = nodep; nodep->iterateChildren(*this); m_assignp = NULL; } } virtual void visit(AstInitArray* nodep) { if (m_assignp) { nodep->v3fatalSrc("Array initialization should have been removed earlier"); } } void expandBiOp(AstNodeBiop* nodep) { if (!nodep->user1()) { nodep->user1(true); // If it's an unpacked array, blow it up into comparing each element AstNodeDType* fromDtp = nodep->lhsp()->dtypep()->skipRefp(); UINFO(9, " Bi-Eq/Neq expansion "<castUnpackArrayDType()) { AstNodeBiop* logp = NULL; for (int index = 0; index < adtypep->rangep()->elementsConst(); ++index) { // EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1]) AstNodeBiop* clonep = nodep->cloneType (new AstArraySel(nodep->fileline(), nodep->lhsp()->cloneTree(false), index), new AstArraySel(nodep->fileline(), nodep->rhsp()->cloneTree(false), index))->castNodeBiop(); if (!logp) logp = clonep; else { switch (nodep->type()) { case AstType::atEq: // FALLTHRU case AstType::atEqCase: logp = new AstLogAnd(nodep->fileline(), logp, clonep); break; case AstType::atNeq: // FALLTHRU case AstType::atNeqCase: logp = new AstLogOr(nodep->fileline(), logp, clonep); break; default: nodep->v3fatalSrc("Unknown node type processing array slice"); break; } } } if (!logp) nodep->v3fatalSrc("Unpacked array with empty indices range"); nodep->replaceWith(logp); pushDeletep(nodep); VL_DANGLING(nodep); nodep = logp; } nodep->iterateChildren(*this); } } virtual void visit(AstEq* nodep) { expandBiOp(nodep); } virtual void visit(AstNeq* nodep) { expandBiOp(nodep); } virtual void visit(AstEqCase* nodep) { expandBiOp(nodep); } virtual void visit(AstNeqCase* nodep) { expandBiOp(nodep); } virtual void visit(AstNode* nodep) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit SliceVisitor(AstNetlist* rootp) { m_assignp = NULL; m_assignError = false; rootp->accept(*this); } virtual ~SliceVisitor() {} }; //###################################################################### // Link class functions void V3Slice::sliceAll(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3EmitV.cpp0000664000177100017500000005720713205623160016261 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3EmitV.h" #include "V3EmitCBase.h" //###################################################################### // Emit statements and math operators class EmitVBaseVisitor : public EmitCBaseVisitor { // MEMBERS bool m_suppressSemi; AstSenTree* m_sensesp; // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual void puts(const string& str) = 0; virtual void putbs(const string& str) = 0; virtual void putfs(AstNode* nodep, const string& str) = 0; // Fileline and node %% mark virtual void putqs(AstNode* nodep, const string& str) = 0; // Fileline quiet w/o %% mark virtual void putsNoTracking(const string& str) = 0; virtual void putsQuoted(const string& str) { // Quote \ and " for use inside C programs // Don't use to quote a filename for #include - #include doesn't \ escape. // Duplicate in V3File - here so we can print to string putsNoTracking("\""); putsNoTracking(V3Number::quoteNameControls(str)); putsNoTracking("\""); } // VISITORS virtual void visit(AstNetlist* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstNodeModule* nodep) { putfs(nodep, nodep->verilogKwd()+" "+modClassName(nodep)+";\n"); nodep->iterateChildren(*this); putqs(nodep, "end"+nodep->verilogKwd()+"\n"); } virtual void visit(AstNodeFTask* nodep) { 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) { if (nodep->unnamed()) { putbs("begin\n"); } else { putbs("begin : "+nodep->name()+"\n"); } nodep->iterateChildren(*this); puts("end\n"); } virtual void visit(AstGenerate* nodep) { putfs(nodep, "generate\n"); nodep->iterateChildren(*this); putqs(nodep, "end\n"); } virtual void visit(AstFinal* nodep) { putfs(nodep, "final begin\n"); nodep->iterateChildren(*this); putqs(nodep, "end\n"); } virtual void visit(AstInitial* nodep) { putfs(nodep,"initial begin\n"); nodep->iterateChildren(*this); putqs(nodep, "end\n"); } virtual void visit(AstAlways* nodep) { 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) { 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) { nodep->lhsp()->iterateAndNext(*this); putfs(nodep," "+nodep->verilogKwd()+" "); nodep->rhsp()->iterateAndNext(*this); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstAssignDly* nodep) { nodep->lhsp()->iterateAndNext(*this); putfs(nodep," <= "); nodep->rhsp()->iterateAndNext(*this); puts(";\n"); } virtual void visit(AstAssignAlias* nodep) { putbs("alias "); nodep->lhsp()->iterateAndNext(*this); putfs(nodep," = "); nodep->rhsp()->iterateAndNext(*this); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstAssignW* nodep) { putfs(nodep,"assign "); nodep->lhsp()->iterateAndNext(*this); putbs(" = "); nodep->rhsp()->iterateAndNext(*this); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstBreak* nodep) { putbs("break"); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstSenTree* nodep) { // 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) { emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->sensesp(), nodep->rhsp()); } virtual void visit(AstSenItem* nodep) { putfs(nodep,""); puts(nodep->edgeType().verilogKwd()); if (nodep->sensp()) puts(" "); nodep->iterateChildren(*this); } virtual void visit(AstNodeCase* nodep) { 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) { 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) { puts((string)"// "+nodep->name()+"\n"); nodep->iterateChildren(*this); } virtual void visit(AstContinue* nodep) { putbs("continue"); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstCoverDecl*) {} // N/A virtual void visit(AstCoverInc*) {} // N/A virtual void visit(AstCoverToggle*) {} // 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) { putbs("disable "+nodep->name()+";\n"); } virtual void visit(AstDisplay* nodep) { visitNodeDisplay(nodep, nodep->filep(), nodep->fmtp()->text(), nodep->fmtp()->exprsp()); } virtual void visit(AstFScanF* nodep) { visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp()); } virtual void visit(AstSScanF* nodep) { visitNodeDisplay(nodep, nodep->fromp(), nodep->text(), nodep->exprsp()); } virtual void visit(AstSFormat* nodep) { visitNodeDisplay(nodep, nodep->lhsp(), nodep->fmtp()->text(), nodep->fmtp()->exprsp()); } virtual void visit(AstSFormatF* nodep) { visitNodeDisplay(nodep, NULL, nodep->text(), nodep->exprsp()); } virtual void visit(AstFOpen* nodep) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filep()) nodep->filep()->iterateAndNext(*this); putbs(","); if (nodep->filenamep()) nodep->filenamep()->iterateAndNext(*this); putbs(","); if (nodep->modep()) nodep->modep()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstFClose* nodep) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filep()) nodep->filep()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstFFlush* nodep) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filep()) nodep->filep()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstJumpGo* nodep) { putbs("disable "+cvtToStr((void*)(nodep->labelp()))+";\n"); } virtual void visit(AstJumpLabel* nodep) { putbs("begin : "+cvtToStr((void*)(nodep))+"\n"); if (nodep->stmtsp()) nodep->stmtsp()->iterateAndNext(*this); puts("end\n"); } virtual void visit(AstReadMem* nodep) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filenamep()) nodep->filenamep()->iterateAndNext(*this); putbs(","); if (nodep->memp()) nodep->memp()->iterateAndNext(*this); if (nodep->lsbp()) { putbs(","); nodep->lsbp()->iterateAndNext(*this); } if (nodep->msbp()) { putbs(","); nodep->msbp()->iterateAndNext(*this); } puts(");\n"); } virtual void visit(AstSysIgnore* nodep) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); nodep->exprsp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstNodeFor* nodep) { 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) { putfs(nodep,"repeat ("); nodep->countp()->iterateAndNext(*this); puts(") begin\n"); nodep->bodysp()->iterateAndNext(*this); putfs(nodep,"end\n"); } virtual void visit(AstWhile* nodep) { 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) { 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) { putfs(nodep,"return "); nodep->lhsp()->iterateAndNext(*this); puts(";\n"); } virtual void visit(AstStop* nodep) { putfs(nodep,"$stop;\n"); } virtual void visit(AstFinish* nodep) { putfs(nodep,"$finish;\n"); } virtual void visit(AstText* nodep) { putsNoTracking(nodep->text()); } virtual void visit(AstScopeName* nodep) { } virtual void visit(AstCStmt* nodep) { putfs(nodep,"$_CSTMT("); nodep->bodysp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstCMath* nodep) { putfs(nodep,"$_CMATH("); nodep->bodysp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstUCStmt* nodep) { putfs(nodep,"$c("); nodep->bodysp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstUCFunc* nodep) { 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) { emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->lhsp()); } virtual void visit(AstNodeBiop* nodep) { emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->lhsp(), nodep->rhsp()); } virtual void visit(AstNodeTriop* nodep) { emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->lhsp(), nodep->rhsp(), nodep->thsp()); } virtual void visit(AstAttrOf* nodep) { putfs(nodep,"$_ATTROF("); nodep->fromp()->iterateAndNext(*this); if (nodep->dimp()) { putbs(","); nodep->dimp()->iterateAndNext(*this); } puts(")"); } virtual void visit(AstInitArray* nodep) { putfs(nodep,"`{"); int pos = 0; for (AstNode* itemp = nodep->initsp(); itemp; ++pos, itemp=itemp->nextp()) { int index = nodep->posIndex(pos); puts(cvtToStr(index)); puts(":"); itemp->accept(*this); if (itemp->nextp()) putbs(","); } puts("}"); } virtual void visit(AstNodeCond* nodep) { putbs("("); nodep->condp()->iterateAndNext(*this); putfs(nodep," ? "); nodep->expr1p()->iterateAndNext(*this); putbs(" : "); nodep->expr2p()->iterateAndNext(*this); puts(")"); } virtual void visit(AstRange* nodep) { 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) { 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(AstSliceSel* nodep) { nodep->fromp()->iterateAndNext(*this); puts(cvtToStr(nodep->declRange())); } virtual void visit(AstTypedef* nodep) { putfs(nodep,"typedef "); nodep->dtypep()->iterateAndNext(*this); puts(" "); puts(nodep->prettyName()); puts(";\n"); } virtual void visit(AstBasicDType* nodep) { 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) { putfs(nodep,"const "); nodep->subDTypep()->accept(*this); } virtual void visit(AstNodeArrayDType* nodep) { nodep->subDTypep()->accept(*this); nodep->rangep()->iterateAndNext(*this); } virtual void visit(AstNodeClassDType* nodep) { puts(nodep->verilogKwd()+" "); if (nodep->packed()) puts("packed "); puts("\n"); nodep->membersp()->iterateAndNext(*this); puts("}"); } virtual void visit(AstMemberDType* nodep) { nodep->subDTypep()->accept(*this); puts(" "); puts(nodep->name()); puts("}"); } virtual void visit(AstNodeFTaskRef* nodep) { 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) { nodep->exprp()->iterateAndNext(*this); } // Terminals virtual void visit(AstVarRef* nodep) { if (nodep->varScopep()) putfs(nodep,nodep->varScopep()->prettyName()); else { putfs(nodep,nodep->hiername()); puts(nodep->varp()->prettyName()); } } virtual void visit(AstVarXRef* nodep) { putfs(nodep,nodep->dotted()); puts("."); puts(nodep->varp()->prettyName()); } virtual void visit(AstConst* nodep) { putfs(nodep,nodep->num().ascii(true,true)); } // Just iterate virtual void visit(AstTopScope* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstVar* nodep) { putfs(nodep,nodep->verilogKwd()); puts(" "); nodep->dtypep()->iterate(*this); puts(" "); puts(nodep->prettyName()); puts(";\n"); } virtual void visit(AstActive* nodep) { m_sensesp = nodep->sensesp(); nodep->stmtsp()->iterateAndNext(*this); m_sensesp = NULL; } virtual void visit(AstVarScope*) {} virtual void visit(AstNodeText*) {} virtual void visit(AstTraceDecl*) {} virtual void visit(AstTraceInc*) {} // NOPs virtual void visit(AstPragma*) {} virtual void visit(AstCell*) {} // Handled outside the Visit class // Default virtual void visit(AstNode* nodep) { 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: explicit EmitVBaseVisitor(AstSenTree* domainp=NULL) { // Domain for printing one a ALWAYS under a ACTIVE m_suppressSemi = false; m_sensesp = domainp; } virtual ~EmitVBaseVisitor() {} }; //###################################################################### // Emit to an output file class EmitVFileVisitor : public EmitVBaseVisitor { // MEMBERS V3OutFile* m_ofp; // METHODS V3OutFile* ofp() const { return m_ofp; } virtual void puts(const string& str) { ofp()->puts(str); } virtual void putbs(const string& str) { ofp()->putbs(str); } virtual void putfs(AstNode*, const string& str) { putbs(str); } virtual void putqs(AstNode*, const string& str) { putbs(str); } virtual void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); } public: EmitVFileVisitor(AstNode* nodep, V3OutFile* ofp) { m_ofp = ofp; nodep->accept(*this); } virtual ~EmitVFileVisitor() {} }; //###################################################################### // Emit to a stream (perhaps stringstream) class EmitVStreamVisitor : public EmitVBaseVisitor { // MEMBERS ostream& m_os; // METHODS virtual void putsNoTracking(const string& str) { m_os<accept(*this); } virtual ~EmitVStreamVisitor() {} }; //###################################################################### // Emit to a stream (perhaps stringstream) class EmitVPrefixedFormatter : public V3OutFormatter { ostream& m_os; string m_prefix; // What to print at beginning of each line int m_flWidth; // Padding of fileline int m_column; // Rough location; need just zero or non-zero FileLine* m_prefixFl; // METHODS virtual void putcOutput(char chr) { if (chr == '\n') { m_column = 0; m_os<ascii()+":"; m_os<ascii().length()+1)); m_os<<" "; m_os<fileline(); // NETLIST's fileline instead of NULL to avoid NULL checks } virtual ~EmitVPrefixedFormatter() { if (m_column) puts("\n"); } }; class EmitVPrefixedVisitor : public EmitVBaseVisitor { // MEMBERS EmitVPrefixedFormatter m_formatter; // Special verilog formatter (Way down the inheritance is another unused V3OutFormatter) // METHODS virtual void putsNoTracking(const string& str) { m_formatter.putsNoTracking(str); } virtual void puts(const string& str) { m_formatter.puts(str); } // We don't use m_formatter's putbs because the tokens will change filelines // and insert returns at the proper locations virtual void putbs(const string& str) { m_formatter.puts(str); } virtual void putfs(AstNode* nodep, const string& str) { putfsqs(nodep,str,false); } virtual void putqs(AstNode* nodep, const string& str) { putfsqs(nodep,str,true); } void putfsqs(AstNode* nodep, const string& str, bool quiet) { if (m_formatter.prefixFl() != nodep->fileline()) { m_formatter.prefixFl(nodep->fileline()); if (m_formatter.column()) puts("\n"); // This in turn will print the m_prefixFl } if (!quiet && nodep->user3()) puts("%%"); putbs(str); } public: EmitVPrefixedVisitor(AstNode* nodep, ostream& os, const string& prefix, int flWidth, AstSenTree* domainp, bool user3mark) : EmitVBaseVisitor(domainp), m_formatter(os, prefix, flWidth) { if (user3mark) { AstUser3InUse::check(); } nodep->accept(*this); } virtual ~EmitVPrefixedVisitor() {} }; //###################################################################### // EmitV class functions void V3EmitV::emitv() { UINFO(2,__FUNCTION__<<": "<modulesp(); modp; modp=modp->nextp()->castNodeModule()) { V3OutVFile of (v3Global.opt.makeDir() +"/"+EmitCBaseVisitor::modClassName(modp)+"__Vout.v"); of.putsHeader(); EmitVFileVisitor visitor (modp, &of); } } } void V3EmitV::verilogForTree(AstNode* nodep, ostream& os) { EmitVStreamVisitor(nodep, os); } void V3EmitV::verilogPrefixedTree(AstNode* nodep, ostream& os, const string& prefix, int flWidth, AstSenTree* domainp, bool user3mark) { EmitVPrefixedVisitor(nodep, os, prefix, flWidth, domainp, user3mark); } verilator-3.916/src/V3EmitMk.h0000664000177100017500000000223013205574202016054 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit Makefile // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Expand.h0000664000177100017500000000227613205574202016117 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Case.cpp0000664000177100017500000004527313205574202016112 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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) { 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) { // 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) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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"); 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(); VL_DANGLING(tree1p); 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(); VL_DANGLING(nodep); cexprp->deleteTree(); VL_DANGLING(cexprp); 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(); VL_DANGLING(icondp); VL_DANGLING(iconstp); // 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(); VL_DANGLING(icondp); VL_DANGLING(iconstp); 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(); VL_DANGLING(cexprp); 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; VL_DANGLING(ifexprp); if (depth == (CASE_ENCODER_GROUP_DEPTH)) { // End of group - can skip the condition itemexprp->deleteTree(); VL_DANGLING(itemexprp); 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) grouprootp->dumpTree(cout," _new: "); if (grouprootp) nodep->replaceWith(grouprootp); else nodep->unlinkFrBack(); nodep->deleteTree(); VL_DANGLING(nodep); } 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) { 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); VL_DANGLING(nodep); } else { ++m_statCaseSlow; replaceCaseComplicated(nodep); VL_DANGLING(nodep); } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit CaseVisitor(AstNetlist* nodep) { m_caseNoOverlapsAllCovered = false; nodep->accept(*this); } virtual ~CaseVisitor() { V3Stats::addStat("Optimizations, Cases parallelized", m_statCaseFast); V3Stats::addStat("Optimizations, Cases complex", m_statCaseSlow); } }; //###################################################################### // Case class functions void V3Case::caseAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Case::caseLint(AstNodeCase* nodep) { UINFO(4,__FUNCTION__<<": "< #include "V3Global.h" #include "V3Graph.h" class DfaGraph; class DfaVertex; class DfaEdge; //============================================================================= // NFA/DFA Graphs /// The NFA graph consists of: /// DfaVertex(START) The starting point /// DfaVertex() Interior states /// DfaVertex(ACCEPT) The completion point /// /// Transitions include a list of all inputs (arbitrary user pointers), /// or epsilon, represented as a empty list of inputs. /// /// We're only looking for matches, so the only accepting states are /// at the end of the transformations. (If we want the complement, we /// call complement and the algorithm makes a REJECT state, then flips /// accept and reject for you.) /// /// Common transforms: /// /// "*": DfaVertex(START) --> [epsilon] -->DfaVertex(ACCEPT) /// /// "L": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT) /// /// "LR": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT) /// ->[ON_R]-->DfaVtx-->[epsilon]-/ /// /// "L|R": ...->DfaVtx-->[epsilon]-->DfaVtx-->[ON_L]-->DfaVtx()->[epsilon]-->DfaVtx(ACCEPT) /// \->[epsilon]-->DfaVtx-->[ON_R]-->DfaVtx()->[epsilon]-/ /// /// "L*": ...->DfaVtx-->[epsilon]-->DfaVtx-->[ON_L]-->DfaVtx()->[epsilon]-->DfaVtx(ACCEPT) /// | ^\----[epsilon]<-------/ | /// \->[epsilon]-----------------------------------------/ class DfaGraph : public V3Graph { // STATE public: DfaGraph() {} virtual ~DfaGraph() {} // METHODS /// Find start node DfaVertex* findStart(); /// Convert automata: NFA to DFA void nfaToDfa(); /// Simplify a DFA automata void dfaReduce(); /// Complement result (must already be dfa) void dfaComplement(); }; //============================================================================= // Vertex class DfaVertex : public V3GraphVertex { // Each DFA state is captured in this vertex. // Start and accepting are members, rather than the more intuitive // subclasses, as subclassing them would make it harder to inherit from here. bool m_start; // Start state bool m_accepting; // Accepting state? public: // CONSTRUCTORS DfaVertex(DfaGraph* graphp, bool start=false, bool accepting=false) : V3GraphVertex(graphp) , m_start(start), m_accepting(accepting) {} using V3GraphVertex::clone; // We are overriding, not overloading clone(V3Graph*) virtual DfaVertex* clone(DfaGraph* graphp) { return new DfaVertex(graphp, start(), accepting()); } virtual ~DfaVertex() {} // ACCESSORS virtual string dotShape() const { return (accepting()?"doublecircle":""); } virtual string dotColor() const { return start()?"blue":(color()?"red":"black"); } bool start() const { return m_start; } void start(bool flag) { m_start=flag; } bool accepting() const { return m_accepting; } void accepting(bool flag) { m_accepting=flag; } }; //============================================================================ /// Abstract type indicating a specific "input" to the NFA /// DFA assumes each .toInt() is unique typedef VNUser DfaInput; //============================================================================ // Edge types class DfaEdge : public V3GraphEdge { DfaInput m_input; bool m_complement; // Invert value when doing compare public: static DfaInput EPSILON() { return VNUser::fromInt(0); } static DfaInput NA() { return VNUser::fromInt(1); } // as in not-applicable // CONSTRUCTORS DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const 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(input().toInt())) : cvtToStr(input().toInt())); } virtual string dotStyle() const { return (na()||cutable())?"dashed":""; } bool epsilon() const { return input().toInt()==EPSILON().toInt(); } bool na() const { return input().toInt()==NA().toInt(); } bool complement() const { return m_complement; } void complement(bool value) { m_complement=value; } DfaInput input() const { return m_input; } }; //============================================================================ #endif // Guard verilator-3.916/src/V3LinkCells.h0000664000177100017500000000240013205574202016545 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Param.cpp0000664000177100017500000007602313205574202016274 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 CloneMap; struct ModInfo { AstNodeModule* m_modp; // Module with specified name CloneMap m_cloneMap; // Map of old-varp -> new cloned varp explicit 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) AstNodeModule* m_modp; // Current module being processed string m_unlinkedTxt; // Text for AstUnlinkedRef // 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)]++; } } else if (AstParamTypeDType* typep = stmtp->castParamTypeDType()) { char ch = 'T'; typep->user4(usedLetter[static_cast(ch)]*256 + ch); usedLetter[static_cast(ch)]++; } } } string paramSmallName(AstNodeModule* modp, AstNode* 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%25)+'A')); index /= 26; } return st; } string paramValueNumber(AstNode* nodep) { // Given a complicated 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 numeric 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)); // 'z' just to make sure we don't collide with a normal non-hashed number return (string)"z"+cvtToStr(num); } } void collectPins(CloneMap* clonemapp, AstNodeModule* modp) { // Grab all I/O so we can remap our pins later for (AstNode* stmtp=modp->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(); //UINFO(8,"Clone list 0x"< 0x"<<(uint32_t)varp<insert(make_pair(oldvarp, varp)); } } else if (AstParamTypeDType* ptp = stmtp->castParamTypeDType()) { if (ptp->isGParam()) { AstParamTypeDType* oldptp = ptp->clonep(); clonemapp->insert(make_pair(oldptp, ptp)); } } } } void relinkPins(CloneMap* clonemapp, AstPin* startpinp) { for (AstPin* pinp = startpinp; pinp; pinp=pinp->nextp()->castPin()) { if (pinp->modVarp()) { // 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->castVar()); } else if (pinp->modPTypep()) { CloneMap::iterator cloneiter = clonemapp->find(pinp->modPTypep()); UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list"); pinp->modPTypep(cloneiter->second->castParamTypeDType()); } else { pinp->v3fatalSrc("Not linked?"); } } } 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 m_modp = nodep; 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(); m_modp = NULL; } } } // VISITORS virtual void visit(AstNetlist* nodep) { // Modules must be done in top-down-order nodep->iterateChildren(*this); } virtual void visit(AstNodeModule* nodep) { if (nodep->dead()) { UINFO(4," MOD-dead. "<recursiveClone()) { UINFO(4," MOD-recursive-dead. "<dead(true); // So Dead checks won't count references to it } else if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top || nodep->castPackage()) { // Likewise haven't done wrapTopPackages yet // Add request to END of modules left to process m_todoModps.insert(make_pair(nodep->level(), nodep)); visitModules(); } else if (nodep->user5()) { UINFO(4," MOD-done "<user5SetOnce()) { // Process once nodep->iterateChildren(*this); if (nodep->isParam()) { if (!nodep->valuep()) { nodep->v3fatalSrc("Parameter without initial value"); } V3Const::constifyParamsEdit(nodep); // The variable, not just the var->init() if (!nodep->valuep()->castConst()) { // Complex init, like an array // Make a new INITIAL to set the value. // This allows the normal array/struct handling code to properly initialize the parameter nodep->addNext(new AstInitial(nodep->fileline(), new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, true), nodep->valuep()->cloneTree(true)))); } } } } // Make sure varrefs cause vars to constify before things above virtual void visit(AstVarRef* nodep) { if (nodep->varp()) nodep->varp()->iterate(*this); } bool ifaceParamReplace(AstVarXRef* nodep, AstNode* candp) { for (; candp; candp = candp->nextp()) { if (nodep->name() == candp->name()) { if (AstVar* varp = candp->castVar()) { UINFO(9,"Found interface parameter: "<varp(varp); return true; } else if (AstPin* pinp = candp->castPin()) { UINFO(9,"Found interface parameter: "<exprp()) pinp->v3fatalSrc("Interface parameter pin missing expression"); nodep->replaceWith(pinp->exprp()->cloneTree(false)); VL_DANGLING(nodep); return true; } } } return false; } virtual void visit(AstVarXRef* nodep) { // Check to see if the scope is just an interface because interfaces are special string dotted = nodep->dotted(); if (!dotted.empty() && nodep->varp() && nodep->varp()->isParam()) { AstNode* backp = nodep; while ((backp = backp->backp())) { if (backp->castNodeModule()) { UINFO(9,"Hit module boundary, done looking for interface"<castVar() && backp->castVar()->isIfaceRef() && backp->castVar()->childDTypep() && backp->castVar()->childDTypep()->castIfaceRefDType()) { AstIfaceRefDType* ifacerefp = backp->castVar()->childDTypep()->castIfaceRefDType(); // Interfaces passed in on the port map have ifaces if (AstIface* ifacep = ifacerefp->ifacep()) { if (dotted == backp->name()) { UINFO(9,"Iface matching scope: "<stmtsp())) { return; } } } // Interfaces declared in this module have cells else if (AstCell* cellp = ifacerefp->cellp()) { if (dotted == cellp->name()) { UINFO(9,"Iface matching scope: "<paramsp())) { return; } } } } } } nodep->varp(NULL); // Needs relink, as may remove pointed-to var } virtual void visit(AstUnlinkedRef* nodep) { AstVarXRef* varxrefp = nodep->op1p()->castVarXRef(); AstNodeFTaskRef* taskrefp = nodep->op1p()->castNodeFTaskRef(); if (varxrefp) { m_unlinkedTxt = varxrefp->dotted(); } else if (taskrefp) { m_unlinkedTxt = taskrefp->dotted(); } else { nodep->v3fatalSrc("Unexpected AstUnlinkedRef node"); return; } nodep->cellrefp()->iterate(*this); if (varxrefp) { varxrefp->dotted(m_unlinkedTxt); } else { taskrefp->dotted(m_unlinkedTxt); } nodep->replaceWith(nodep->op1p()->unlinkFrBack()); pushDeletep(nodep); VL_DANGLING(nodep); } virtual void visit(AstCellArrayRef* nodep) { V3Const::constifyParamsEdit(nodep->selp()); if (AstConst* constp = nodep->selp()->castConst()) { string index = AstNode::encodeNumber(constp->toSInt()); string replacestr = nodep->name() + "__BRA__??__KET__"; size_t pos = m_unlinkedTxt.find(replacestr); if (pos == string::npos) { nodep->v3error("Could not find array index in unlinked text: '" << m_unlinkedTxt << "' for node: " << nodep); return; } m_unlinkedTxt.replace(pos, replacestr.length(), nodep->name() + "__BRA__"+index+"__KET__"); } else { nodep->v3error("Could not expand constant selection inside dotted reference: "<selp()->prettyName()); return; } } // Generate Statements virtual void visit(AstGenerate* nodep) { 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(); VL_DANGLING(nodep); } virtual void visit(AstGenIf* nodep) { 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(); VL_DANGLING(nodep); // 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) { 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); VL_DANGLING(forp); // 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) { nodep->v3fatalSrc("GENFOR should have been wrapped in BEGIN"); } virtual void visit(AstGenCase* nodep) { 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); VL_DANGLING(ep); // 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(); VL_DANGLING(nodep); } // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit ParamVisitor(AstNetlist* nodep) { m_longId = 0; m_modp = NULL; // 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?"); // We always run this, even if no parameters, as need to look for interfaces, // and remove any recursive references { UINFO(4,"De-parameterize: "<=10) nodep->dumpTree(cout,"-cell:\t"); // Evaluate all module constants V3Const::constifyParamsEdit(nodep); AstNodeModule* srcModp = nodep->modp(); // 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 = srcModp->name(); bool any_overrides = false; if (nodep->recursive()) any_overrides = true; // Must always clone __Vrcm (recursive modules) 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 if (AstVar* modvarp = pinp->modVarp()) { if (!modvarp->isGParam()) { pinp->v3error("Attempted parameter setting of non-parameter: Param "<prettyName()<<" of "<prettyName()); } else if (pinp->exprp()->castInitArray() && modvarp->subDTypep()->castUnpackArrayDType()) { // Array assigned to array AstNode* exprp = pinp->exprp(); longname += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp); any_overrides = true; } else { AstConst* exprp = pinp->exprp()->castConst(); AstConst* origp = modvarp->valuep()->castConst(); if (!exprp) { //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 (origp && exprp->sameTree(origp)) { // 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 if (exprp->num().isDouble() || exprp->num().isString() || exprp->num().isFourState()) { longname += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp); any_overrides = true; } else { longname += "_" + paramSmallName(srcModp, modvarp) + exprp->num().ascii(false); any_overrides = true; } } } else if (AstParamTypeDType* modvarp = pinp->modPTypep()) { AstNodeDType* exprp = pinp->exprp()->castNodeDType(); AstNodeDType* origp = modvarp->subDTypep(); if (!exprp) { pinp->v3error("Parameter type pin value isn't a type: Param "<prettyName()<<" of "<prettyName()); } else if (!origp) { pinp->v3error("Parameter type variable isn't a type: Param "<prettyName()); } else { UINFO(9,"Parameter type assignment expr="<sameTree(origp)) { // 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(srcModp, modvarp) + paramValueNumber(exprp); any_overrides = true; } } } else { pinp->v3error("Parameter not found in sub-module: Param "<prettyName()<<" of "<prettyName()); } } IfaceRefRefs ifaceRefRefs; for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { AstVar* modvarp = pinp->modVarp(); if (modvarp->isIfaceRef()) { AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType(); if (!portIrefp && modvarp->subDTypep()->castUnpackArrayDType()) { portIrefp = modvarp->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType(); } AstIfaceRefDType* pinIrefp = NULL; AstNode* exprp = pinp->exprp(); if (exprp && exprp->castVarRef() && exprp->castVarRef()->varp() && exprp->castVarRef()->varp()->subDTypep() && exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType()) pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType(); else if (exprp && exprp->op1p() && exprp->op1p()->castVarRef() && exprp->op1p()->castVarRef()->varp() && exprp->op1p()->castVarRef()->varp()->subDTypep() && exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType() && exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep() && exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType()) pinIrefp = exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType(); else if (exprp && exprp->castVarRef() && exprp->castVarRef()->varp() && exprp->castVarRef()->varp()->subDTypep() && exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType() && exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep() && exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType()) pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType(); UINFO(9," portIfaceRef "<v3error("Interface port '"<prettyName()<<"' is not an interface " << modvarp); } else if (!pinIrefp) { pinp->v3error("Interface port '"<prettyName()<<"' is not connected to interface/modport pin expression"); } else { UINFO(9," pinIfaceRef "<ifaceViaCellp() != pinIrefp->ifaceViaCellp()) { UINFO(9," IfaceRefDType needs reconnect "<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. // TODO can use new V3Name hash replacement instead of this string newname = longname; if (longname.length()>30) { LongMap::iterator iter = m_longMap.find(longname); if (iter != m_longMap.end()) { newname = iter->second; } else { newname = srcModp->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: "<name()<<"->"<"<second.m_modp; if (!cellmodp) { // 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. cellmodp = srcModp->cloneTree(false); cellmodp->name(newname); cellmodp->user5(false); // We need to re-recurse this module once changed cellmodp->recursive(false); cellmodp->recursiveClone(false); nodep->recursive(false); // Recursion may need level cleanups if (cellmodp->level() <= m_modp->level()) cellmodp->level(m_modp->level()+1); if ((cellmodp->level() - srcModp->level()) >= (v3Global.opt.moduleRecursionDepth() - 2)) { nodep->v3error("Exceeded maximum --module-recursion-depth of "<nextp()->castNodeModule() && insertp->nextp()->castNodeModule()->level() < cellmodp->level()) { insertp = insertp->nextp()->castNodeModule(); } insertp->addNextHere(cellmodp); m_modNameMap.insert(make_pair(cellmodp->name(), ModInfo(cellmodp))); iter = m_modNameMap.find(newname); CloneMap* clonemapp = &(iter->second.m_cloneMap); UINFO(4," De-parameterize to new: "<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(); 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()) { if (pinp->exprp()) { if (AstVar* modvarp = pinp->modVarp()) { AstNode* newp = pinp->exprp(); // Const or InitArray // Remove any existing parameter if (modvarp->valuep()) modvarp->valuep()->unlinkFrBack()->deleteTree(); // Set this parameter to value requested by cell modvarp->valuep(newp->cloneTree(false)); } else if (AstParamTypeDType* modptp = pinp->modPTypep()) { AstNodeDType* dtypep = pinp->exprp()->castNodeDType(); if (!dtypep) pinp->v3fatalSrc("unlinked param dtype"); if (modptp->childDTypep()) pushDeletep(modptp->childDTypep()->unlinkFrBack()); // Set this parameter to value requested by cell modptp->childDTypep(dtypep->cloneTree(false)); // Later V3LinkDot will convert the ParamDType to a Typedef // Not done here as may be localparams, etc, that also need conversion } } } } else { UINFO(4," De-parameterize to old: "<modp(cellmodp); nodep->modName(newname); // We need to relink the pins to the new module CloneMap* clonemapp = &(iter->second.m_cloneMap); relinkPins(clonemapp, nodep->pinsp()); UINFO(8," Done with "<recursive(false); // Delete the parameters from the cell; they're not relevant any longer. if (nodep->paramsp()) nodep->paramsp()->unlinkFrBackWithNext()->deleteTree(); UINFO(8," Done with "<=10) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("param-out.tree")); } // Now remember to process the child module at the end of the module m_todoModps.insert(make_pair(nodep->modp()->level(), nodep->modp())); } //###################################################################### // Param class functions void V3Param::param(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.916/src/V3List.h0000664000177100017500000000751113205574202015610 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: List class with storage in existing classes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LIST_H_ #define _V3LIST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include //============================================================================ template class V3List; template class V3ListEnt; template class V3List { // List container for linked list of elements of type *T (T is a pointer type) private: // STATE T m_headp; // First element T m_tailp; // Last element friend class V3ListEnt; public: V3List() : m_headp(NULL), m_tailp(NULL) {} ~V3List() {} // METHODS T begin() const { return m_headp; } T end() const { return NULL; } bool empty() const { return m_headp==NULL; } void reset() { m_headp=NULL; m_tailp=NULL; } // clear() without walking the list }; //============================================================================ template class V3ListEnt { // List entry for linked list of elements of type *T (T is a pointer type) private: // STATE T m_nextp; // Pointer to next element, NULL=end T m_prevp; // Pointer to previous element, NULL=beginning friend class V3List; static V3ListEnt* baseToListEnt(void* newbasep, size_t offset) { // "this" must be a element inside of *basep // Use that to determine a structure offset, then apply to the new base // to get our new pointer information return (V3ListEnt*) ( ((vluint8_t*)newbasep) + offset); } public: V3ListEnt() : m_nextp(NULL), m_prevp(NULL) {} ~V3ListEnt() { #ifdef VL_DEBUG // Load bogus pointers so we can catch deletion bugs m_nextp = (T)1; m_prevp = (T)1; #endif } T nextp() const { return m_nextp; } // METHODS void pushBack (V3List& listr, T newp) { // "this" must be a element inside of *newp // cppcheck-suppress thisSubtraction size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(newp); m_nextp = NULL; if (!listr.m_headp) listr.m_headp = newp; m_prevp = listr.m_tailp; if (m_prevp) baseToListEnt(m_prevp,offset)->m_nextp = newp; listr.m_tailp = newp; } void pushFront (V3List& listr, T newp) { // "this" must be a element inside of *newp // cppcheck-suppress thisSubtraction size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(newp); m_nextp = listr.m_headp; if (m_nextp) baseToListEnt(m_nextp,offset)->m_prevp = newp; listr.m_headp = newp; m_prevp = NULL; if (!listr.m_tailp) listr.m_tailp = newp; } // Unlink from side void unlink (V3List& listr, T oldp) { // "this" must be a element inside of *oldp // cppcheck-suppress thisSubtraction size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(oldp); if (m_nextp) baseToListEnt(m_nextp,offset)->m_prevp = m_prevp; else listr.m_tailp = m_prevp; if (m_prevp) baseToListEnt(m_prevp,offset)->m_nextp = m_nextp; else listr.m_headp = m_nextp; m_prevp = m_nextp = NULL; } }; //============================================================================ #endif // Guard verilator-3.916/src/V3DepthBlock.cpp0000664000177100017500000001035613205574202017250 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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) { // 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) { visitStmt(nodep); } virtual void visit(AstNodeMath* nodep) {} // Accelerate //-------------------- // Default: Just iterate virtual void visit(AstVar* nodep) {} // Don't hit varrefs under vars virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit DepthBlockVisitor(AstNetlist* nodep) { m_modp=NULL; m_depth=0; // nodep->accept(*this); } virtual ~DepthBlockVisitor() {} }; //###################################################################### // DepthBlock class functions void V3DepthBlock::depthBlockAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3GraphDfa.cpp0000664000177100017500000005121513205574202016704 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph optimizations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3GraphDfa.h" #include "V3GraphAlg.h" //###################################################################### //###################################################################### // Algorithms - find starting node DfaVertex* DfaGraph::findStart() { DfaVertex* startp = NULL; for (V3GraphVertex* vertexp = this->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (DfaVertex* vvertexp = dynamic_cast(vertexp)) { if (vvertexp->start()) { if (startp) v3fatalSrc("Multiple start points in NFA graph"); startp = vvertexp; } } else { v3fatalSrc("Non DfaVertex in DfaGraph"); } } 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().toNodep() == input.toNodep()) { 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* ecNfaStatep = static_cast(nfaEdgep->top()); //UINFO(9," Consider "<top()<<" EP "<epsilon()<epsilon() && unseenNfaThisStep(ecNfaStatep)) { // Not processed? workps.push_back(ecNfaStatep); } } } 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().toInt()) == inputs.end()) { inputs.insert(cNfaEdgep->input().toInt()); UINFO(9," Input to "<input().toInt())<<" via "<::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) { DfaInput input = *inIt; UINFO(9," ==="<<++i<<"=======================\n"); UINFO(9," On input "<<(void*)(input.toNodep())<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); VL_DANGLING(vertexp); } } 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(); VL_DANGLING(edgep); } } } } } 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); VL_DANGLING(vertexp); } } } 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(fromvertexp); fromvertexp->user(1); } } // Transitions to this state removed by the unlink function vertexp->unlinkDelete(m_graphp); VL_DANGLING(vertexp); } } } 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"); // 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(); VL_DANGLING(edgep); } // 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.916/src/config_rev.pl0000775000177100017500000000227413205574202016775 0ustar wsnyderwsnyder#!/usr/bin/perl -w ###################################################################### # # Copyright 2005-2017 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* const 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.916/src/cppcheck_filtered0000775000177100017500000001440313205574202017675 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.881'; our %SuppressMap = ( # New cpp check error Can suppress with old error 'nullPointerRedundantCheck' => 'nullPointer', ); #====================================================================== # main our $Opt_Debug; autoflush STDOUT 1; autoflush STDERR 1; Getopt::Long::config ("no_auto_abbrev","pass_through"); our @Opt_Args = ("cppcheck", @ARGV); if (! GetOptions ( # Local options "help" => \&usage, "version" => sub { print "Version $VERSION\n"; system("cppcheck","--version"); exit(0); }, )) { die "%Error: Bad usage, try 'cppcheck_filtered --help'\n"; } process(); #---------------------------------------------------------------------- sub usage { print "Version $VERSION\n"; pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT, -noperldoc=>1); exit (1); } ####################################################################### sub process { my $cmd = join(' ',@Opt_Args); print "\t$cmd\n" if $Debug; my $fh = IO::File->new("$cmd 2>&1 |"); $fh or die "%Error: '$cmd' failed: $!\n"; my %uniq; my %errs; my $last_error = ""; while (defined(my $line = $fh->getline())) { $line =~ s/^\s+//; $line =~ s/Checking usage of global functions\.+//; # Sometimes tacked at end-of-line # General gunk next if $uniq{$line}++; next if $line =~ m!^<\?xml version!; next if $line =~ m!^!; next if $line =~ m!^!; next if $line =~ m!^!; next if $line =~ m!^error("Cppcheck errors:\n$all"); #die "%Error: cppcheck_filtered found errors\n"; exit(1); } } ###################################################################### sub _suppress { my $filename = shift; my $linenum = shift; my $id = shift; #print "-Suppression search $filename $linenum $id\n" if $Self->{verbose}; return undef if $filename eq "*"; my $fh = IO::File->new("<$filename"); if (!$fh) { warn "%Warning: $! $filename,"; return undef; } my $l = 0; while (defined(my $line = $fh->getline())) { ++$l; if ($l+1 == $linenum) { if ($line =~ /cppcheck-suppress((\s+\S+)+)/) { my $supids = $1; foreach my $supid (split /\s+/, $supids) { if ($supid eq $id || $supid eq ($SuppressMap{$id}||'')) { return 1; } } warn "%Warning: $filename: $l: Found suppress for ids='$supids', not expected id='$id'\n"; } } if ($l == $linenum) { if (0 && # We now use VL_DANGLING instead of this rule $id eq "uselessAssignmentPtrArg" && $line =~ /(delete|Delete|Edit).*p *= *(NULL|nullptr);/) { # delete(nodep); nodep=NULL; # This is ok, it's how we prevent later using nodep return 1; } } } return undef; } 1; ####################################################################### __END__ =pod =head1 NAME cppcheck_filtered - cppcheck wrapper with post-processing =head1 SYNOPSIS cppcheck_filtered ...normal cpp check flags... =head1 DESCRIPTION Cppcheck_Filtered is a wrapper for cppcheck that filters out unnecessary warnings related to Verilator. =head1 ARGUMENTS Most arguments are passed through to cppcheck =over 4 =item --help Displays this message and program version and exits. =item --version Print the version number and exit. =back =head1 DISTRIBUTION This is part of the L free Verilog EDA software tool suite. The latest version is available from CPAN and from L. Copyright 2014-2017 by Wilson Snyder. This package is free software; you can redistribute it and/or modify it under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO C =cut ###################################################################### ### Local Variables: ### compile-command: "./cppcheck_filtered --xml V3Width.cpp" ### End: verilator-3.916/src/VlcSource.h0000664000177100017500000000774613205574202016403 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Source file to annotate with line coverage // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCSOURCE_H_ #define _VLCSOURCE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include //******************************************************************** // VlcColumnCount - count at specific source file, line and column class VlcSourceCount { private: // MEMBERS int m_lineno; ///< Line number int m_column; ///< Column number vluint64_t m_count; ///< Count bool m_ok; ///< Coverage is above threshold public: // CONSTRUCTORS VlcSourceCount(int lineno, int column) { m_lineno = lineno; m_column = column; m_count = 0; m_ok = false; } ~VlcSourceCount() {} // ACCESSORS int lineno() const { return m_lineno; } int column() const { return m_column; } vluint64_t count() const { return m_count; } bool ok() const { return m_ok; } // METHODS void incCount(vluint64_t count, bool ok) { m_count += count; if (ok) m_ok = true; } }; //******************************************************************** // VlcSource - source file to annotate class VlcSource { public: // TYPES typedef map ColumnMap; // Map of {column} typedef map LinenoMap; // Map of {lineno}{column} private: // MEMBERS string m_name; //< Name of the source file bool m_needed; //< Need to annotate; has low coverage LinenoMap m_lines; //< Map of each annotated line public: // CONSTRUCTORS explicit VlcSource(const string& name) { m_name = name; m_needed = false; } ~VlcSource() {} // ACCESSORS const string& name() const { return m_name; } void needed(bool flag) { m_needed = flag; } bool needed() const { return m_needed; } LinenoMap& lines() { return m_lines; } // METHODS void incCount(int lineno, int column, vluint64_t count, bool ok) { LinenoMap::iterator lit = m_lines.find(lineno); if (lit == m_lines.end()) { lit = m_lines.insert(make_pair(lineno,ColumnMap())).first; } ColumnMap& cmap = lit->second; ColumnMap::iterator cit = cmap.find(column); if (cit == cmap.end()) { cit = cmap.insert(make_pair(column,VlcSourceCount(lineno, column))).first; } VlcSourceCount& sc = cit->second; sc.incCount(count,ok); } }; //******************************************************************** // VlcSources - Container of all source files class VlcSources { public: // TYPES typedef map NameMap; private: // MEMBERS NameMap m_sources; //< List of all sources public: // ITERATORS typedef NameMap::iterator iterator; NameMap::iterator begin() { return m_sources.begin(); } NameMap::iterator end() { return m_sources.end(); } public: // CONSTRUCTORS VlcSources() {} ~VlcSources() {} // METHODS VlcSource& findNewSource(const string& name) { NameMap::iterator iter = m_sources.find(name); if (iter != m_sources.end()) { return iter->second; } else { iter = m_sources.insert(make_pair(name, VlcSource(name))).first; return iter->second; } } }; //###################################################################### #endif // Guard verilator-3.916/src/V3Clean.cpp0000664000177100017500000002220313205574202016245 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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()->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) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstNodeUniop* nodep) { nodep->iterateChildren(*this); computeCppWidth(nodep); if (nodep->cleanLhs()) { insureClean(nodep->lhsp()); } setClean (nodep, nodep->cleanOut()); } virtual void visit(AstNodeBiop* nodep) { operandBiop(nodep); setClean (nodep, nodep->cleanOut()); } virtual void visit(AstAnd* nodep) { operandBiop(nodep); setClean (nodep, isClean(nodep->lhsp()) || isClean(nodep->rhsp())); } virtual void visit(AstXor* nodep) { operandBiop(nodep); setClean (nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp())); } virtual void visit(AstOr* nodep) { operandBiop(nodep); setClean (nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp())); } virtual void visit(AstNodeMath* nodep) { nodep->iterateChildren(*this); computeCppWidth(nodep); setClean (nodep, nodep->cleanOut()); } virtual void visit(AstNodeAssign* nodep) { nodep->iterateChildren(*this); computeCppWidth(nodep); if (nodep->cleanRhs()) { insureClean(nodep->rhsp()); } } virtual void visit(AstText* nodep) { setClean (nodep, true); } virtual void visit(AstScopeName* nodep) { setClean (nodep, true); } virtual void visit(AstSel* nodep) { operandTriop(nodep); setClean (nodep, nodep->cleanOut()); } virtual void visit(AstUCFunc* nodep) { 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) { nodep->iterateChildren(*this); insureCleanAndNext (nodep->valuep()); } virtual void visit(AstTypedef* nodep) { // No cleaning, or would loose pointer to enum nodep->iterateChildren(*this); } virtual void visit(AstParamTypeDType* nodep) { // No cleaning, or would loose pointer to enum nodep->iterateChildren(*this); } // Control flow operators virtual void visit(AstNodeCond* nodep) { nodep->iterateChildren(*this); insureClean(nodep->condp()); setClean(nodep, isClean(nodep->expr1p()) && isClean(nodep->expr2p())); } virtual void visit(AstWhile* nodep) { nodep->iterateChildren(*this); insureClean(nodep->condp()); } virtual void visit(AstNodeIf* nodep) { nodep->iterateChildren(*this); insureClean(nodep->condp()); } virtual void visit(AstSFormatF* nodep) { nodep->iterateChildren(*this); insureCleanAndNext (nodep->exprsp()); setClean(nodep, true); // generates a string, so not relevant } virtual void visit(AstUCStmt* nodep) { nodep->iterateChildren(*this); insureCleanAndNext (nodep->bodysp()); } virtual void visit(AstCCall* nodep) { nodep->iterateChildren(*this); insureCleanAndNext (nodep->argsp()); setClean (nodep, true); } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); computeCppWidth(nodep); } public: // CONSTUCTORS explicit CleanVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~CleanVisitor() {} }; //###################################################################### // Clean class functions void V3Clean::cleanAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Localize.h0000664000177100017500000000227313205574202016437 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Convert BLOCKTEMPs to local variables // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LOCALIZE_H_ #define _V3LOCALIZE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Localize { public: static void localizeAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3Table.h0000664000177100017500000000223413205574202015721 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Make lookup tables // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3TABLE_H_ #define _V3TABLE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Table { public: static void tableAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3Changed.h0000664000177100017500000000225213205574202016223 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CHANGED_H_ #define _V3CHANGED_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Changed { public: static void changedAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3Param.h0000664000177100017500000000224513205574202015734 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Param modules/signals together // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3PARAM_H_ #define _V3PARAM_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Param { public: static void param(AstNetlist* rootp); }; #endif // Guard verilator-3.916/src/V3Descope.h0000664000177100017500000000230413205574202016252 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3DESCOPE_H_ #define _V3DESCOPE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Descope { public: static void descopeAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3Const.h0000664000177100017500000000360713205574202015765 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Propagate constants across AST // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CONST_H_ #define _V3CONST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Const { public: static AstNode* constifyParamsEdit(AstNode* nodep); static AstNode* constifyGenerateParamsEdit(AstNode* nodep); // Only do constant pushing, without removing dead logic static void constifyAllLive(AstNetlist* nodep); // Everything that's possible static void constifyAll(AstNetlist* nodep); // Also, warn static void constifyAllLint(AstNetlist* nodep); // C++ datatypes static void constifyCpp(AstNetlist* nodep); // Only the current node and lower // Return new node that may have replaced nodep static AstNode* constifyEdit(AstNode* nodep); // Only the current node and lower, with special SenTree optimization // Return new node that may have replaced nodep static AstNode* constifyExpensiveEdit(AstNode* nodep); }; #endif // Guard verilator-3.916/src/V3StatsReport.cpp0000664000177100017500000001571313205574202017525 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Collect and print statistics // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 VL_INCLUDE_UNORDERED_MAP #include "V3Global.h" #include "V3Stats.h" #include "V3Ast.h" #include "V3File.h" #include "V3Os.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() { // Find all stages size_t maxWidth = 0; 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(); byName.insert(make_pair(repp->name(), repp)); } } // Print organized by stage os<<"Global Statistics:\n"; os<second; if (repp->perf()) continue; os<<" "<name(); repp->dump(os); os<second; if (!repp->perf()) continue; os<<" "<name(); repp->dump(os); os< Stages; Stages stages; vl_unordered_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; VL_DANGLING(ofp); } verilator-3.916/src/V3Global.h0000664000177100017500000001052613205574202016075 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Common headers // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3GLOBAL_H_ #define _V3GLOBAL_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.h" #include "V3FileLine.h" #include "V3Options.h" class AstNetlist; //====================================================================== // Statics //###################################################################### class VWidthMinUsage { public: enum en { LINT_WIDTH, MATCHES_WIDTH, VERILOG_WIDTH }; enum en m_e; inline VWidthMinUsage () : m_e(LINT_WIDTH) {} // cppcheck-suppress noExplicitConstructor inline VWidthMinUsage (en _e) : m_e(_e) {} explicit inline VWidthMinUsage (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (VWidthMinUsage::en lhs, VWidthMinUsage rhs) { return (lhs == rhs.m_e); } //###################################################################### // V3Global - The top level class for the entire program class V3Global { // Globals AstNetlist* m_rootp; // Root of entire netlist VWidthMinUsage m_widthMinUsage; // What AstNode::widthMin() is used for int m_debugFileNumber; // Number to append to debug files created bool m_assertDTypesResolved; // Tree should have dtypep()'s bool m_constRemoveXs; // Const needs to strip any Xs bool m_needHInlines; // Need __Inlines file bool m_needHeavy; // Need verilated_heavy.h include bool m_dpi; // Need __Dpi include files public: // Options V3Options opt; // All options; let user see them directly public: // CONSTRUCTORS V3Global() { m_debugFileNumber = 0; m_widthMinUsage = VWidthMinUsage::LINT_WIDTH; m_assertDTypesResolved = false; m_constRemoveXs = false; m_needHInlines = false; m_needHeavy = false; m_dpi = false; m_rootp = NULL; // created by makeInitNetlist() so static constructors run first } AstNetlist* makeNetlist(); void boot() { UASSERT(!m_rootp,"call once"); m_rootp = makeNetlist(); } void clear(); // ACCESSORS (general) AstNetlist* rootp() const { return m_rootp; } VWidthMinUsage widthMinUsage() const { return m_widthMinUsage; } bool assertDTypesResolved() const { return m_assertDTypesResolved; } // METHODS void readFiles(); void checkTree(); static void dumpCheckGlobalTree(const string& stagename, int newNumber=0, bool doDump=true); void assertDTypesResolved(bool flag) { m_assertDTypesResolved = flag; } void widthMinUsage(const VWidthMinUsage& flag) { m_widthMinUsage = flag; } bool constRemoveXs() const { return m_constRemoveXs; } void constRemoveXs(bool flag) { m_constRemoveXs = flag; } string debugFilename(const string& nameComment, int newNumber=0) { ++m_debugFileNumber; if (newNumber) m_debugFileNumber = newNumber; char digits[100]; sprintf(digits, "%03d", m_debugFileNumber); return opt.makeDir()+"/"+opt.prefix()+"_"+digits+"_"+nameComment; } bool needHInlines() const { return m_needHInlines; } void needHInlines(bool flag) { m_needHInlines=flag; } bool needHeavy() const { return m_needHeavy; } void needHeavy(bool flag) { m_needHeavy=flag; } bool dpi() const { return m_dpi; } void dpi(bool flag) { m_dpi = flag; } }; extern V3Global v3Global; //###################################################################### #endif // guard verilator-3.916/src/V3Width.h0000664000177100017500000000315313205574202015752 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3LinkResolve.h0000664000177100017500000000227413205574202017133 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Assert.h0000664000177100017500000000224113205574202016131 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Assertion expansion // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/astgen0000775000177100017500000004434313205574202015526 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### #require 5.006_001; use Getopt::Long; use IO::File; use Pod::Usage; use strict; use vars qw ($Debug @Types %Classes %Children %ClassRefs %Stages); #====================================================================== # main $Debug = 0; my $opt_classes; my $opt_report; my @Opt_Cpt; my @Opt_I; Getopt::Long::config ("pass_through", "no_auto_abbrev"); if (! GetOptions ( "help" => \&usage, "debug" => sub { $Debug = 1; }, "classes!" => \$opt_classes, "report!" => \$opt_report, "<>" => \¶meter, )) { usage(); } read_types("$Opt_I[0]/V3Ast.h"); read_types("$Opt_I[0]/V3AstNodes.h"); read_stages("$Opt_I[0]/Verilator.cpp"); read_refs(glob("$Opt_I[0]/*.y"), glob("$Opt_I[0]/*.h"), glob("$Opt_I[0]/*.cpp")); if ($opt_report) { write_report(undef); } if ($opt_classes) { write_report("V3Ast__gen_report.txt"); write_classes("V3Ast__gen_classes.h"); write_visitor("V3Ast__gen_visitor.h"); write_intf("V3Ast__gen_interface.h"); write_impl("V3Ast__gen_impl.h"); write_types("V3Ast__gen_types.h"); } foreach my $cpt (@Opt_Cpt) { Cpt::process(in_filename=>"$Opt_I[0]/${cpt}.cpp", out_filename=>"${cpt}__gen.cpp"); } #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } sub parameter { my $param = shift; if ($param =~ /^-+I(\S+)/) { push @Opt_I, $1; } elsif ($param =~ s/\.cpp$//) { push @Opt_Cpt, $param; } else { die "%Error: Unknown parameter: $param,"; } } ####################################################################### sub read_types { my $filename = shift; my $fh = IO::File->new($filename) or die "%Error: $! $filename,"; while (defined (my $line = $fh->getline())) { $line =~ s/\/\/.*$//; next if $line =~ /^\s*$/; if ($line =~ /^\s*(class|struct)\s*(\S+)/) { my $class = $2; my $inh = ""; $inh = $1 if ($line =~ /:\s*public\s+(\S+)/); print "class $class : $inh\n" if $Debug; $inh = "" if $class eq "AstNode"; if ($inh =~ /Ast/ || $class eq "AstNode") { $class =~ s/^Ast//; $inh =~ s/^Ast//; $Classes{$class} = $inh; $Children{$inh}{$class} = 1; } } } } sub read_stages { my $filename = shift; my $fh = IO::File->new($filename) or die "%Error: $! $filename,"; my $n = 0; while (defined (my $line = $fh->getline())) { $line =~ s/\/\/.*$//; next if $line =~ /^\s*$/; if ($line =~ /^\s*([A-Za-z0-9]+)::/) { my $stage = $1.".cpp"; if (!defined ($Stages{$stage})) { $Stages{$stage} = $n++; } } } } sub read_refs { my @filenames = @_; foreach my $filename (@filenames) { (my $basename = $filename) =~ s!.*/!!; my $fh = IO::File->new($filename) or die "%Error: $! $filename,"; while (defined (my $line = $fh->getline())) { $line =~ s/\/\/.*$//; while ($line =~ /\bnew\s*(Ast[A-Za-z0-9_]+)/g) { $ClassRefs{$1}{newed}{$basename} = 1; } while ($line =~ /\b(Ast[A-Za-z0-9_]+)/g) { $ClassRefs{$1}{used}{$basename} = 1; } } } #use Data::Dumper;print Dumper(\%ClassRefs); } #---------------------------------------------------------------------- sub open_file { my $filename = shift; my $fh = IO::File->new($filename,"w") or die "%Error: $! $filename,"; print $fh '// Generated by astgen // -*- mode: C++; c-file-style: "cc-mode" -*-'."\n"; return $fh; } #---------------------------------------------------------------------- sub subclasses_of { my $type = shift; my @cllist; for (my $subclass = $::Classes{$type}; $subclass; ) { push @cllist, $subclass; $subclass = $::Classes{$subclass}; } return (reverse @cllist); } sub children_of { my $type = shift; my @cllist; my @todo; push @todo, $type; while (my $subclass = shift @todo) { foreach my $child (sort keys %{$::Children{$subclass}}) { push @todo, $child; push @cllist, $child; } } return (@cllist); } #---------------------------------------------------------------------- sub write_report { my $filename = shift; my $fh = defined($filename) ? open_file($filename) : \*STDOUT; $fh->print("Processing stages (approximate, based on order in Verilator.cpp):\n"); foreach my $class (sort {$Stages{$a} <=> $Stages{$b}} keys %Stages) { $fh->print("\t$class\n"); } $fh->print("\nProcessing stages (approximate, based on order in Verilator.cpp):\n"); foreach my $type (sort (keys %Classes)) { printf $fh " class %-20s\n", "Ast${type}"; $fh->print("\tparent:\t"); foreach my $subclass (subclasses_of($type)) { next if $subclass eq 'Node'; printf $fh "Ast%-12s ",$subclass; } printf $fh "\n"; $fh->print("\tchilds:\t"); foreach my $subclass (children_of($type)) { next if $subclass eq 'Node'; printf $fh "Ast%-12s ",$subclass; } printf $fh "\n"; if (my $refs = $ClassRefs{"Ast${type}"}) { $fh->print("\tnewed:\t"); foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)} keys %{$refs->{newed}}) { $fh->print($stage." "); } $fh->print("\n"); $fh->print("\tused:\t"); foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)} keys %{$refs->{used}}) { $fh->print($stage." "); } $fh->print("\n"); } $fh->print("\n"); } } sub write_classes { my $fh = open_file(@_); printf $fh "class AstNode;\n"; 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) { visit((Ast${base}*)(nodep)); }\n"; } else { printf $fh " virtual void visit(Ast${type}*) = 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); # For performance, prefer static_cast where we can if (children_of($type)) { printf $fh "inline Ast%-16s AstNode::cast${type}() { return (dynamic_cast(this)); }\n" ,$type."*"; } else { printf $fh "inline Ast%-16s AstNode::cast${type}() { return (this && this->type() == AstType::at${type}) ? static_cast(this) : NULL; }\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",$type,",\n"; } printf $fh "\t_ENUM_END\n"; printf $fh " };\n"; printf $fh " const char* ascii() const {\n"; printf $fh " const char* const names[] = {\n"; foreach my $type (sort (keys %Classes)) { next if $type =~ /^Node/; print $fh "\t\"", uc $type, "\",\n"; } printf $fh "\t\"_ENUM_END\"\n"; printf $fh " };\n"; printf $fh " return names[m_e];\n"; printf $fh " };\n"; $fh->close(); } ####################################################################### package Cpt; sub error { my $self = shift; my $txt = join('', @_); die "%Error: $self->{in_filename}:$self->{in_linenum}: $txt\n"; } sub print { my $self = shift; my $txt = join('', @_); push @{$self->{out_lines}}, $txt; } sub output_func { my $self = shift; my $func = shift; push @{$self->{out_lines}}, $func; } sub _output_line { my $self = shift; $self->print("#line ",$self->{out_linenum}+2," \"$self->{out_filename}\"\n"); } sub process { my $self = { in_filename => undef, out_filename => undef, out_lines => [], out_linenum => 1, @_, }; bless $self, __PACKAGE__; my $ln = 1; my $didln; # Read the file and parse into list of functions that generate output my $fhi = IO::File->new($self->{in_filename}) or die "%Error: $! $self->{in_filename},"; while (defined(my $line = $fhi->getline)) { if (!$didln) { $self->print("#line $. \"$self->{in_filename}\"\n"); $didln = 1; } if ($line =~ /^\s+(TREE.*)$/) { my $func = $1; $self->{in_linenum} = $.; $self->print("//$line"); $self->output_func(sub{my $self=shift; $self->_output_line(); }); $self->tree_line ($func); $didln = 0; } elsif ($line !~ /^\s*\/[\/\*]\s*TREE/ && $line =~ /\s+TREE/) { $self->error("Unknown astgen line: $line"); } else { $self->print($line); } } $fhi->close; # Put out the resultant file, if the list has a reference to a # function, then call that func to generate output my $fho = ::open_file($self->{out_filename}); my @togen = @{$self->{out_lines}}; foreach my $line (@togen) { if (ref $line) { $self->{out_lines} = []; &$line($self); } else { $self->{out_lines} = [$line]; } foreach my $out (@{$self->{out_lines}}) { $self->{out_linenum}++ while ($out =~ /\n/smg); print $fho $out; } } $fho->close; } sub tree_line { my $self = shift; my $func = shift; $func =~ s!\s*//.*$!!; $func =~ s!\s*;\s*$!!; # doflag "S" indicates an op specifying short-circuiting for a type. if ($func =~ /TREEOP(1?)([VCS]?)\s*\(\s* \"([^\"]*)\" \s*,\s* \"([^\"]*)\" \s*\)/sx) { my $order = $1; my $doflag = $2; my $from = $3; my $to = $4; #$self->print("// $from $to\n"); if (!$self->{did_out_tree}) { $self->{did_out_tree} = 1; $self->output_func(sub{ my $self=shift; $self->tree_match(); $self->tree_base(); }); } $from =~ /Ast([a-zA-Z0-9]+)\s*\{(.*)\}\s*$/ or $self->error("Can't parse from function: $func"); my $type = $1; my $subnodes = $2; (::subclasses_of($type)) or $self->error("Unknown AstNode type: $type: in $func"); my $mif; if ($doflag eq '') { $mif = "m_doNConst"; } elsif ($doflag eq 'V') { $mif = "m_doV"; } elsif ($doflag eq 'C') { $mif = ""; } elsif ($doflag eq 'S') { $mif = "m_doNConst"; } # Not just for m_doGenerate else { die; } $subnodes =~ s/,,/__ESCAPEDCOMMA__/g; foreach my $subnode (split /\s*,\s*/, $subnodes) { $subnode =~ s/__ESCAPEDCOMMA__/,/g; next if $subnode =~ /^\$([a-z0-9]+)$/gi; # "$lhs" is just a comment that this op has a lhs $mif .= " && " if $mif; my $subnodeif = $subnode; $subnodeif =~ s/\$([a-zA-Z0-9]+)\.([a-zA-Z0-9]+)$/nodep->$1()->$2()/g; $subnodeif = add_nodep($subnodeif); $mif .= $subnodeif; } my $exec_func = treeop_exec_func($self, $to); $self->{treeop}{$type} ||= []; my $n = $#{$self->{treeop}{$type}} + 1; my $typefunc = { order => $order, comment => $func, match_func => "match_${type}_${n}", match_if => $mif, exec_func => $exec_func, uinfo_level => ($to =~ /^!/ ? 0:7), short_circuit => ($doflag eq 'S'), }; ($typefunc->{uinfo} = $func) =~ s/[ \t\"\{\}]+/ /g; push @{$self->{treeop}{$type}}, $typefunc; } elsif ($func =~ /TREE_SKIP_VISIT\s*\(\s* \"([^\"]*)\" \s*\)/sx) { my $type = $1; $self->{tree_skip_visit}{$type} = 1; $::Classes{$type} or $self->error("Unknown node type: $type"); } else { $self->error("Unknown astgen op: $func"); } } sub add_nodep { my $str = shift; $str =~ s/\$([a-zA-Z0-9]+)/nodep->$1()/g; return $str; } our %_Exec_Syms; our $_Exec_Nsyms; sub _exec_syms_recurse { my $aref = shift; foreach my $sym (@{$aref}) { if (ref $sym) { _exec_syms_recurse($sym); } elsif ($sym =~ /^\$.*/) { if (!defined $_Exec_Syms{$sym}) { $_Exec_Syms{$sym} = "arg".(++$_Exec_Nsyms)."p"; } } } } sub _exec_new_recurse { my $aref = shift; my $out = "new ".$aref->[0]."(nodep->fileline()"; my $first = 1; foreach my $sym (@{$aref}) { if ($first) { $first=0; next; } $out .= ", "; if (ref $sym) { $out.=_exec_new_recurse($sym); } elsif ($sym =~ /^\$.*/) { $out .= $_Exec_Syms{$sym}; } else { $out .= $sym; } } return $out.")"; } sub treeop_exec_func { my $self = shift; my $func = shift; my $out = ""; $func =~ s/^!//; if ($func =~ /^\s*[a-zA-Z0-9]+\s*\(/) { # Function call (my $outl = $func) =~ s/\$([a-zA-Z0-9]+)/nodep->$1()/g; $out .= $outl.";"; } elsif ($func =~ /^\s*Ast([a-zA-Z0-9]+) \s*\{\s* (.*) \s* \}$/x) { my $nargs = 0; my %argnums; # Number for each argument name my $aref = undef; # Recursive array with structure to form my @astack; my $forming = ""; my $argtext = $func . "\000"; # EOF character #print "FF $func\n" if $Debug; while ($argtext =~ s/^(.)//) { my $tok = $1; #print "TOK: $tok $forming\n" if $tok !~ /[a-zA-Z0-9]/; if ($tok eq "\000") { } elsif ($tok =~ /\s+/) { } elsif ($tok eq "{") { my $newref = [$forming]; push @{$aref}, $newref; push @astack, $aref if $aref; $aref = $newref; $forming = ""; } elsif ($tok eq "}") { push @{$aref}, $forming if $forming; $aref = pop @astack; $aref or $self->error("Too many } in execution function: $func\n"); $forming = ""; } elsif ($tok eq ",") { push @{$aref}, $forming if $forming; $forming = ""; } else { $forming .= $tok; } } ($aref && ref $aref->[0] && !$aref->[1]) or $self->error("Badly formed execution function: $func\n"); $aref = $aref->[0]; #use Data::Dumper; print Dumper($aref),"\n"; # Assign numbers to each $ symbol %_Exec_Syms = (); $_Exec_Nsyms = 0; _exec_syms_recurse($aref); foreach my $sym (sort {$_Exec_Syms{$a} cmp $_Exec_Syms{$b}} (keys %_Exec_Syms)) { my $argnp = $_Exec_Syms{$sym}; my $arg = add_nodep($sym); $out .= "AstNode* ${argnp} = ${arg}->unlinkFrBack();\n"; } $out .= "AstNode* newp = " . _exec_new_recurse($aref).";\n"; $out .= "nodep->replaceWith(newp);"; $out .= "nodep->deleteTree(); VL_DANGLING(nodep);"; #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) {\n", " nodep->lhsp()->iterateAndNext(*this);\n", @out_for_type_sc); $self->print(" nodep->rhsp()->iterateAndNext(*this);\n", " AstNodeTriop *tnp = nodep->castNodeTriop();\n", " if (tnp && tnp->thsp()) tnp->thsp()->iterateAndNext(*this);\n", @out_for_type, " }\n") if ($out_for_type[0]); } elsif ($out_for_type[0]) { # Other types with something to print my $skip = $self->{tree_skip_visit}{$type}; my $gen = $skip ? "Gen" : ""; $self->print(" // Generated by astgen\n", " virtual void visit$gen(Ast${type}* nodep) {\n", ($skip?"": " nodep->iterateChildren(*this);\n"), @out_for_type, " }\n"); } } } ####################################################################### package main; __END__ =pod =head1 NAME astgen - Generate V3Ast headers to reduce C++ code duplication =head1 SYNOPSIS astgen =head1 DESCRIPTION Generates several files for Verilator compilations. =head1 ARGUMENTS =over 4 =item --help Displays this message and program version and exits. =item --classes Makes class declaration files. =item --report Makes a report report. =back =head1 DISTRIBUTION Copyright 2002-2017 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.916/src/V3Number_test.cpp0000664000177100017500000001073613205574202017522 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // CHEAT! #define V3NUMBER_ASCII_BINARY #define _V3ERROR_NO_GLOBAL_ 1 #include "V3Error.cpp" #include "V3FileLine.cpp" #include "V3Number.cpp" #include #include "verilatedos.h" #include #include #include #include "V3Number.h" void test(const string& lhss, const string& op, const string& rhss, const string& exps) { char* l1 = strdup(lhss.c_str()); char* r1 = strdup(rhss.c_str()); char* e1 = strdup(exps.c_str()); V3Number lhnum (new FileLine ("ck",__LINE__), l1); V3Number rhnum (new FileLine ("ck",__LINE__), r1); V3Number expnum (new FileLine("ck",__LINE__), e1); V3Number gotnum (new FileLine("ck",__LINE__), expnum.width()); if (op=="redOr") gotnum.opRedOr (lhnum); else if (op=="redAnd") gotnum.opRedAnd (lhnum); else if (op=="redXor") gotnum.opRedXor (lhnum); else if (op=="redXnor") gotnum.opRedXnor (lhnum); else if (op=="concat") gotnum.opConcat (lhnum,rhnum); else if (op=="repl") gotnum.opRepl (lhnum,rhnum); else if (op=="~") gotnum.opNot (lhnum); else if (op=="!") gotnum.opLogNot (lhnum); else if (op=="negate") gotnum.opNegate (lhnum); else if (op=="+") gotnum.opAdd (lhnum,rhnum); else if (op=="-") gotnum.opSub (lhnum,rhnum); else if (op=="*") gotnum.opMul (lhnum,rhnum); else if (op=="/") gotnum.opDiv (lhnum,rhnum); else if (op=="%") gotnum.opModDiv (lhnum,rhnum); else if (op=="&") gotnum.opAnd (lhnum,rhnum); else if (op=="|") gotnum.opOr (lhnum,rhnum); else if (op=="<") gotnum.opLt (lhnum,rhnum); else if (op==">") gotnum.opGt (lhnum,rhnum); else if (op==">>") gotnum.opShiftR (lhnum,rhnum); else if (op=="<<") gotnum.opShiftL (lhnum,rhnum); else if (op=="==") gotnum.opEq (lhnum,rhnum); else if (op=="===") gotnum.opCaseEq (lhnum,rhnum); else if (op=="==?") gotnum.opWildEq (lhnum,rhnum); else if (op=="!=") gotnum.opNeq (lhnum,rhnum); else if (op=="!==") gotnum.opCaseNeq (lhnum,rhnum); else if (op=="!=?") gotnum.opWildNeq (lhnum,rhnum); else if (op=="<=") gotnum.opLte (lhnum,rhnum); else if (op==">=") gotnum.opGte (lhnum,rhnum); else if (op=="&&") gotnum.opLogAnd (lhnum,rhnum); else if (op=="||") gotnum.opLogOr (lhnum,rhnum); else v3fatalSrc("Bad opcode: "<= 6); } static void linkDotParamed(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } static void linkDotArrayed(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } static void linkDotScope(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } }; #endif // Guard verilator-3.916/src/V3Unknown.h0000664000177100017500000000224513205574202016333 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add Unknown assigns // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3UNKNOWN_H_ #define _V3UNKNOWN_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Unknown { public: static void unknownAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3String.h0000664000177100017500000001004513205574202016137 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: String manipulation // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3STRING_H_ #define _V3STRING_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.h" //###################################################################### // 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); static string quotePercent(const string& str); }; //###################################################################### // VHashSha1 - Compute Sha1 hashes class VHashSha1 { // As blocks must be processed in 64 byte chunks, this does not at present // support calling input() on multiple non-64B chunks and getting the correct // hash. To do that first combine the string before calling here. // Or improve to store 0-63 bytes of data between calls to input(). // MEMBERS uint32_t m_inthash[5]; // Intermediate hash, in host order string m_remainder; // Unhashed data bool m_final; // Finalized size_t m_totLength; // Total all-chunk length as needed by output digest public: // CONSTRUCTORS VHashSha1() { init(); } explicit VHashSha1(const string& data) { init(); insert(data); } ~VHashSha1() {} // METHODS string digestBinary(); // Return digest as 20 character binary string digestHex(); // Return digest formatted as a hex string string digestSymbol(); // Return digest formatted as C symbol/base64ish uint64_t digestUInt64(); // Return 64-bits of digest static void selfTest(); // Test this class // Inerting hash data void insert(const void* datap, size_t length); // Process data into the digest void insert(const string& data) { insert(data.data(), data.length()); } // Process data into the digest void insert(uint64_t value) { insert(cvtToStr(value)); } private: void init() { m_inthash[0] = 0x67452301; m_inthash[1] = 0xefcdab89; m_inthash[2] = 0x98badcfe; m_inthash[3] = 0x10325476; m_inthash[4] = 0xc3d2e1f0; m_final = false; m_totLength = 0; } static void selfTestOne(const string& data, const string& data2, const string& exp, const string& exp64); void finalize(); // Process remaining data }; //###################################################################### // VName - string which contains a possibly hashed string // TODO use this wherever there is currently a "string m_name" class VName { string m_name; string m_hashed; static size_t s_maxLength; // Length at which to start hashing static size_t s_minLength; // Length to preserve if over maxLength public: // CONSTRUCTORS explicit VName (const string& name) : m_name(name) {} ~VName() {} // METHODS void name(const string& name) { m_name = name; m_hashed = ""; } string name() const { return m_name; } string hashedName(); // CONFIG STATIC METHORS static void maxLength(size_t flag) { s_maxLength=flag; } // Length at which to start hashing, 0=disable static size_t maxLength() { return s_maxLength; } }; //###################################################################### #endif // guard verilator-3.916/src/V3CCtors.h0000664000177100017500000000233313205574202016067 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit CFunc's for class construction and configuration // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 _V3CCTORS_H_ #define _V3CCTORS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3CCtors { public: static void cctorsAll(); private: static void evalAsserts(); }; #endif // Guard verilator-3.916/src/V3ParseGrammar.cpp0000664000177100017500000000211613205574202017605 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Parse syntax tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Delayed.h0000664000177100017500000000225213205574202016241 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3LinkParse.cpp0000664000177100017500000004111513205574202017116 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LinkParse TRANSFORMATIONS: // Top-down traversal // Move some attributes around //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3LinkParse.h" #include "V3Ast.h" //###################################################################### // Link state, as a visitor of each AstNode class LinkParseVisitor : public AstNVisitor { private: // NODE STATE // Cleared on netlist // AstNode::user1() -> bool. True if processed // AstNode::user2() -> bool. True if fileline recomputed AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // TYPES typedef map ,AstTypedef*> ImplTypedefMap; typedef set FileLineSet; // STATE AstVar* m_varp; // Variable we're under ImplTypedefMap m_implTypedef; // Created typedefs for each FileLineSet m_filelines; // Filelines that have been seen bool m_inAlways; // Inside an always bool m_inGenerate; // Inside a generate bool m_needStart; // Need start marker on lower AstParse AstNodeModule* m_valueModp; // If set, move AstVar->valuep() initial values to this module AstNodeModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Current task AstNodeDType* m_dtypep; // Current data type // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void cleanFileline(AstNode* nodep) { if (!nodep->user2SetOnce()) { // Process once // We make all filelines unique per AstNode. This allows us to // later turn off messages on a fileline when an issue is found // so that messages on replicated blocks occur only once, // without suppressing other token's messages as a side effect. // We could have verilog.l create a new one on every token, // but that's a lot more structures than only doing AST nodes. if (m_filelines.find(nodep->fileline()) != m_filelines.end()) { nodep->fileline(new FileLine(nodep->fileline())); } m_filelines.insert(nodep->fileline()); } } // VISITs virtual void visit(AstNodeFTask* nodep) { if (!nodep->user1SetOnce()) { // Process only once. cleanFileline(nodep); m_ftaskp = nodep; nodep->iterateChildren(*this); m_ftaskp = NULL; } } virtual void visit(AstNodeFTaskRef* nodep) { if (!nodep->user1SetOnce()) { // Process only once. cleanFileline(nodep); UINFO(5," "<iterateChildren(*this); m_valueModp = upperValueModp; } } virtual void visit(AstNodeDType* nodep) { if (!nodep->user1SetOnce()) { // Process only once. cleanFileline(nodep); AstNodeDType* upperDtypep = m_dtypep; m_dtypep = nodep; nodep->iterateChildren(*this); m_dtypep = upperDtypep; } } virtual void visit(AstEnumItem* nodep) { // 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)); AstNode* newp = new AstEnumItem(nodep->fileline(), name, NULL, valuep); if (addp) addp = addp->addNextNull(newp); else addp = newp; } nodep->replaceWith(addp); nodep->deleteTree(); } } virtual void visit(AstVar* nodep) { cleanFileline(nodep); if (nodep->subDTypep()->castParseTypeDType()) { // It's a parameter type. Use a different node type for this. AstNodeDType* dtypep = nodep->valuep()->castNodeDType(); if (!dtypep) { nodep->v3error("Parameter type's initial value isn't a type: "<prettyName()); nodep->unlinkFrBack(); } else { dtypep->unlinkFrBack(); AstNode* newp = new AstParamTypeDType(nodep->fileline(), nodep->varType(), nodep->name(), VFlagChildDType(), dtypep); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } return; } // 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) { cleanFileline(nodep); nodep->iterateChildren(*this); if (nodep->attrType() == AstAttrType::DT_PUBLIC) { AstTypedef* typep = nodep->backp()->castTypedef(); if (!typep) nodep->v3fatalSrc("Attribute not attached to typedef"); typep->attrPublic(true); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } else if (nodep->attrType() == AstAttrType::VAR_CLOCK) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->attrScClocked(true); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } else if (nodep->attrType() == AstAttrType::VAR_SFORMAT) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->attrSFormat(true); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } else if (nodep->attrType() == AstAttrType::VAR_CLOCKER) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->attrClocker(AstVarAttrClocker::CLOCKER_YES); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } else if (nodep->attrType() == AstAttrType::VAR_NO_CLOCKER) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->attrClocker(AstVarAttrClocker::CLOCKER_NO); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } } virtual void visit(AstAlwaysPublic* nodep) { // 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) { 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(); VL_DANGLING(nodep); return; } else { defp = new AstTypedef(nodep->fileline(), nodep->name(), NULL, VFlagChildDType(), dtypep); m_implTypedef.insert(make_pair(make_pair(nodep->containerp(), defp->name()), defp)); backp->addNextHere(defp); } } nodep->replaceWith(new AstRefDType(nodep->fileline(), defp->name())); nodep->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstTypedefFwd* nodep) { // 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(AstForeach* nodep) { // FOREACH(array,loopvars,body) // -> BEGIN(declare vars, loopa=lowest; WHILE(loopa<=highest, ... body)) //nodep->dumpTree(cout, "-foreach-old:"); AstNode* newp = nodep->bodysp()->unlinkFrBackWithNext(); AstNode* arrayp = nodep->arrayp(); int dimension = 1; // Must do innermost (last) variable first AstNode* firstVarsp = nodep->varsp()->unlinkFrBackWithNext(); AstNode* lastVarsp = firstVarsp; while (lastVarsp->nextp()) { lastVarsp = lastVarsp->nextp(); dimension++; } for (AstNode* varsp = lastVarsp; varsp; varsp=varsp->backp()) { UINFO(9,"foreachVar "<fileline(); AstNode* varp = new AstVar(fl, AstVarType::BLOCKTEMP, varsp->name(), nodep->findSigned32DType()); AstNode* leftp = new AstAttrOf(fl, AstAttrType::DIM_LEFT, new AstVarRef(fl, arrayp->name(), false), new AstConst(fl, dimension)); AstNode* rightp = new AstAttrOf(fl, AstAttrType::DIM_RIGHT, new AstVarRef(fl, arrayp->name(), false), new AstConst(fl, dimension)); AstNode* stmtsp = varp; stmtsp->addNext(new AstAssign(fl, new AstVarRef(fl, varp->name(), true), leftp)); AstNode* comparep = new AstCond(fl, new AstLte(fl, leftp->cloneTree(true), rightp->cloneTree(true)), // left increments up to right new AstLte(fl, new AstVarRef(fl, varp->name(), false), rightp->cloneTree(true)), // left decrements down to right new AstGte(fl, new AstVarRef(fl, varp->name(), false), rightp)); AstNode* incp = new AstAssign(fl, new AstVarRef(fl, varp->name(), true), new AstAdd(fl, new AstVarRef(fl, varp->name(), false), new AstNegate(fl, new AstAttrOf(fl, AstAttrType::DIM_INCREMENT, new AstVarRef(fl, arrayp->name(), false), new AstConst(fl, dimension))))); stmtsp->addNext(new AstWhile(fl, comparep, newp, incp)); newp = new AstBegin(nodep->fileline(),"",stmtsp); dimension--; } //newp->dumpTree(cout, "-foreach-new:"); firstVarsp->deleteTree(); VL_DANGLING(firstVarsp); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstNodeModule* nodep) { // 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) { visitIterateNoValueMod(nodep); } virtual void visit(AstFinal* nodep) { visitIterateNoValueMod(nodep); } virtual void visit(AstAlways* nodep) { m_inAlways = true; visitIterateNoValueMod(nodep); m_inAlways = false; } virtual void visit(AstPslCover* nodep) { visitIterateNoValueMod(nodep); } virtual void visit(AstNode* nodep) { // Default: Just iterate cleanFileline(nodep); nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit LinkParseVisitor(AstNetlist* rootp) { m_varp = NULL; m_modp = NULL; m_ftaskp = NULL; m_dtypep = NULL; m_inAlways = false; m_inGenerate = false; m_needStart = false; m_valueModp = NULL; rootp->accept(*this); } virtual ~LinkParseVisitor() {} }; //###################################################################### // Link class functions void V3LinkParse::linkParse(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<= 6); } verilator-3.916/src/V3CoverageJoin.cpp0000664000177100017500000001200113205574202017571 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // COVERAGEJOIN TRANSFORMATIONS: // If two COVERTOGGLEs have same VARSCOPE, combine them //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3CoverageJoin.h" #include "V3Hashed.h" #include "V3Stats.h" //###################################################################### // CoverageJoin state, as a visitor of each AstNode class CoverageJoinVisitor : public AstNVisitor { private: // NODE STATE // V3Hashed // AstCoverToggle->VarRef::user4() // V3Hashed calculation //AstUser4InUse In V3Hashed // TYPES typedef vector ToggleList; // STATE ToggleList m_toggleps; // List of of all AstCoverToggle's V3Double0 m_statToggleJoins; // Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void detectDuplicates() { UINFO(9,"Finding duplicates\n"); // Note uses user4 V3Hashed hashed; // Duplicate code detection // Hash all of the original signals we toggle cover for (ToggleList::iterator it = m_toggleps.begin(); it != m_toggleps.end(); ++it) { AstCoverToggle* nodep = *it; hashed.hashAndInsert(nodep->origp()); } // Find if there are any duplicates for (ToggleList::iterator it = m_toggleps.begin(); it != m_toggleps.end(); ++it) { AstCoverToggle* nodep = *it; if (nodep->backp()) { // nodep->backp() is null if we already detected it's a duplicate and unlinked it // Want to choose a base node, and keep finding duplicates that are identical // This prevents making chains where a->b, then c->d, then b->c, as we'll find a->b, a->c, a->d directly. while (1) { V3Hashed::iterator dupit = hashed.findDuplicate(nodep->origp()); if (dupit == hashed.end()) break; // AstNode* duporigp = hashed.iteratorNodep(dupit); // Note hashed will point to the original variable (what's duplicated), not the covertoggle, // but we need to get back to the covertoggle which is immediately above, so: AstCoverToggle* removep = duporigp->backp()->castCoverToggle(); if (!removep) nodep->v3fatalSrc("CoverageJoin duplicate of wrong type"); UINFO(8," Orig "<> "<incp()->declp()<> "<incp()->declp()<incp()->declp()->dataDeclThisp(); removep->incp()->declp()->dataDeclp (datadeclp); UINFO(8," new "<incp()->declp()<unlinkFrBack(); pushDeletep(removep); VL_DANGLING(removep); // Remove node from comparison so don't hit it again hashed.erase(dupit); ++m_statToggleJoins; } } } } // VISITORS virtual void visit(AstNetlist* nodep) { // Find all Coverage's nodep->iterateChildren(*this); // Simplify detectDuplicates(); } virtual void visit(AstCoverToggle* nodep) { m_toggleps.push_back(nodep); nodep->iterateChildren(*this); } //-------------------- virtual void visit(AstNodeMath* nodep) {} // Accelerate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit CoverageJoinVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~CoverageJoinVisitor() { V3Stats::addStat("Coverage, Toggle points joined", m_statToggleJoins); } }; //###################################################################### // Coverage class functions void V3CoverageJoin::coverageJoin(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3LinkResolve.cpp0000664000177100017500000004243313205574202017467 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LinkResolve TRANSFORMATIONS: // Top-down traversal // Extracts: // Add SUB so that we subtract off the "base 0-start" of the array // SelBit: Convert to ArraySel // Add SUB so that we subtract off the "base 0-start" of the array // File operations // Convert normal var to FILE* type // SenItems: Convert pos/negedge of non-simple signals to temporaries //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3String.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) { // 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) { nodep->iterateChildren(*this); // Initial assignments under function/tasks can just be simple assignments without the initial if (m_ftaskp) { nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()); VL_DANGLING(nodep); } } virtual void visit(AstVAssert* nodep) { 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) { 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) { // VarRef: Resolve its reference if (nodep->varp()) { nodep->varp()->usedParam(true); } nodep->iterateChildren(*this); } virtual void visit(AstNodeFTask* nodep) { // 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) { nodep->iterateChildren(*this); if (nodep->taskp() && (nodep->taskp()->dpiContext() || nodep->taskp()->dpiExport())) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); } } virtual void visit(AstSenItem* nodep) { // 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(); VL_DANGLING(selp); did=1; } // NodeSel doesn't include AstSel.... if (AstSel* selp = nodep->sensp()->castSel()) { AstNode* fromp = selp->fromp()->unlinkFrBack(); selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp); did=1; } if (AstNodePreSel* selp = nodep->sensp()->castNodePreSel()) { AstNode* fromp = selp->lhsp()->unlinkFrBack(); selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp); did=1; } } } if (!nodep->sensp()->castNodeVarRef() && !nodep->sensp()->castEnumItemRef() // V3Const will cleanup && !nodep->isIllegal()) { if (debug()) nodep->dumpTree(cout,"-tree: "); nodep->v3error("Unsupported: Complex statement in sensitivity list"); } } virtual void visit(AstSenGate* nodep) { nodep->v3fatalSrc("SenGates shouldn't be in tree yet"); } virtual void visit(AstNodePreSel* nodep) { 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 (AstUnlinkedRef* uvxrp = basefromp->castUnlinkedRef()) { // Maybe unlinked - so need to clone nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE, uvxrp->cloneTree(false))); } else if (AstMemberSel* fromp = basefromp->castMemberSel()) { nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::MEMBER_BASE, fromp->cloneTree(false))); } else if (AstEnumItemRef* fromp = basefromp->castEnumItemRef()) { nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::ENUM_BASE, fromp->cloneTree(false))); } else { if (basefromp) { UINFO(1," Related node: "<v3fatalSrc("Illegal bit select; no signal/member being extracted from"); } } } virtual void visit(AstCaseItem* nodep) { // 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) { if (nodep->pragType() == AstPragmaType::PUBLIC_MODULE) { if (!m_modp) nodep->v3fatalSrc("PUBLIC_MODULE not under a module"); m_modp->modPublic(true); nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); } else if (nodep->pragType() == AstPragmaType::PUBLIC_TASK) { if (!m_ftaskp) nodep->v3fatalSrc("PUBLIC_TASK not under a task"); m_ftaskp->taskPublic(true); m_modp->modPublic(true); // Need to get to the task... nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } } else { nodep->iterateChildren(*this); } } string expectFormat(AstNode* nodep, const string& format, AstNode* argp, bool isScan) { // Check display arguments, return new format string string newFormat; bool inPct = false; string fmt = ""; for (string::const_iterator it = format.begin(); it != format.end(); ++it) { char ch = *it; if (!inPct && ch=='%') { inPct = true; fmt = ch; } else if (inPct && (isdigit(ch) || ch=='.')) { fmt += ch; } else if (inPct) { inPct = false; fmt += ch; switch (tolower(ch)) { case '%': // %% - just output a % break; case 'm': // %m - auto insert "name" if (isScan) { nodep->v3error("Unsupported: %m in $fscanf"); fmt = ""; } break; case 'l': // %l - auto insert "library" if (isScan) { nodep->v3error("Unsupported: %l in $fscanf"); fmt = ""; } if (m_modp) fmt = VString::quotePercent(m_modp->prettyName()); 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 newFormat += fmt; } else { newFormat += ch; } } if (argp && !isScan) { int skipCount = 0; // number of args consume by any additional format strings while (argp) { if (skipCount) { argp = argp->nextp(); skipCount--; continue; } AstConst *constp = argp->castConst(); bool isFromString = (constp) ? constp->num().isFromString() : false; if (isFromString) { int numchars = argp->dtypep()->width()/8; string str(numchars, ' '); // now scan for % operators bool inpercent = false; for (int i = 0; i < numchars; i++) { int ii = numchars - i - 1; char c = constp->num().dataByte(ii); str[i] = c; if (!inpercent && c == '%') { inpercent = true; } else if (inpercent) { inpercent = 0; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': inpercent = true; break; case '%': break; default: if (V3Number::displayedFmtLegal(c)) { skipCount++; } } } } newFormat.append(str); AstNode *nextp = argp->nextp(); argp->unlinkFrBack(); pushDeletep(argp); VL_DANGLING(argp); argp = nextp; } else { newFormat.append("%h"); argp = argp->nextp(); } } } return newFormat; } 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) { nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } virtual void visit(AstFClose* nodep) { nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } virtual void visit(AstFEof* nodep) { nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } virtual void visit(AstFScanF* nodep) { nodep->iterateChildren(*this); expectFormat(nodep, nodep->text(), nodep->exprsp(), true); } virtual void visit(AstSScanF* nodep) { nodep->iterateChildren(*this); expectFormat(nodep, nodep->text(), nodep->exprsp(), true); } virtual void visit(AstSFormatF* nodep) { nodep->iterateChildren(*this); // Cleanup old-school displays without format arguments if (!nodep->hasFormat()) { if (nodep->text()!="") nodep->v3fatalSrc("Non-format $sformatf should have \"\" format"); if (nodep->exprsp()->castConst() && nodep->exprsp()->castConst()->num().isFromString()) { AstConst* fmtp = nodep->exprsp()->unlinkFrBack()->castConst(); nodep->text(fmtp->num().toString()); pushDeletep(fmtp); VL_DANGLING(fmtp); } nodep->hasFormat(true); } string newFormat = expectFormat(nodep, nodep->text(), nodep->exprsp(), false); nodep->text(newFormat); if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking()) || nodep->formatScopeTracking()) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); } } virtual void visit(AstDisplay* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstUdpTable* nodep) { 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); VL_DANGLING(nodep); } } virtual void visit(AstScCtor* nodep) { // Constructor info means the module must remain public m_modp->modPublic(true); nodep->iterateChildren(*this); } virtual void visit(AstScDtor* nodep) { // Destructor info means the module must remain public m_modp->modPublic(true); nodep->iterateChildren(*this); } virtual void visit(AstScInt* nodep) { // Special class info means the module must remain public m_modp->modPublic(true); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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) { // Iterate modules backwards, in bottom-up order. nodep->iterateChildrenBackwards(*this); } virtual void visit(AstNodeModule* nodep) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCell* nodep) { // Parent module inherits child's publicity if (nodep->modp()->modPublic()) m_modp->modPublic(true); //** No iteration for speed } virtual void visit(AstNodeMath* nodep) { // Speedup } virtual void visit(AstNode* nodep) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit LinkBotupVisitor(AstNetlist* rootp) { m_modp = NULL; // rootp->accept(*this); } virtual ~LinkBotupVisitor() {} }; //###################################################################### // Link class functions void V3LinkResolve::linkResolve(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<= 6); } verilator-3.916/src/Makefile.in0000664000177100017500000000572613205574202016366 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator: Makefile for verilog source # # Code available from: http://www.veripool.org/verilator # #***************************************************************************** # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # # Verilator is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # #****************************************************************************/ #### Start of system configuration section. #### srcdir = @srcdir@ VPATH = @srcdir@ PERL = @PERL@ EXEEXT = @EXEEXT@ #### End of system configuration section. #### default: dbg opt debug: dbg optimize: opt ifneq ($(words $(CURDIR)),1) $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') endif UNDER_GIT = $(wildcard ${srcdir}/../.git/logs/HEAD) #********************************************************************* obj_opt: mkdir $@ obj_dbg: mkdir $@ .SUFFIXES: .PHONY: ../bin/verilator_bin ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg opt: ../bin/verilator_bin ifeq ($(VERILATOR_NO_OPT_BUILD),1) # Faster laptop development... One build ../bin/verilator_bin: ../bin/verilator_bin_dbg -rm -rf $@ $@.exe -cp -p $<$(EXEEXT) $@$(EXEEXT) else ../bin/verilator_bin: obj_opt prefiles cd obj_opt && $(MAKE) -j 1 TGT=../$@ -f ../Makefile_obj serial cd obj_opt && $(MAKE) TGT=../$@ -f ../Makefile_obj endif dbg: ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg ../bin/verilator_bin_dbg: obj_dbg prefiles cd obj_dbg && $(MAKE) -j 1 TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj serial cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj ../bin/verilator_coverage_bin_dbg: obj_dbg prefiles cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj serial_vlcov cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj prefiles:: prefiles:: config_rev.h ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users # This output goes into srcdir if locally configured, as we need to distribute it as part of the kit. config_rev.h: ${srcdir}/config_rev.pl ${srcdir}/../.git/logs/HEAD $(PERL) ${srcdir}/config_rev.pl ${srcdir} >$@ else config_rev.h: ${srcdir}/config_rev.pl $(PERL) ${srcdir}/config_rev.pl ${srcdir} >$@ endif maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_* *.log *.dmp *.vpd core -rm -f *.o *.d perlxsi.c *_gen_* -rm -f *__gen* -rm -f .objcache* distclean maintainer-clean:: -rm -f Makefile Makefile_obj config_build.h maintainer-clean:: -rm -f config_rev.h verilator-3.916/src/V3GraphAcyc.cpp0000664000177100017500000005417013205574202017074 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph acyclic algorithm // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Graph.h" //###################################################################### //###################################################################### // Algorithms - acyclic // Break the minimal number of backward edges to make the graph acyclic class GraphAcycVertex : public V3GraphVertex { // user() is used for various sub-algorithm pieces V3GraphVertex* m_origVertexp; // Pointer to first vertex this represents protected: friend class GraphAcyc; V3ListEnt m_work; // List of vertices with optimization work left uint32_t m_storedRank; // Rank held until commit to edge placement bool m_onWorkList; // True if already on list of work to do bool m_deleted; // True if deleted public: GraphAcycVertex(V3Graph* graphp, V3GraphVertex* origVertexp) : V3GraphVertex(graphp), m_origVertexp(origVertexp) , m_storedRank(0), m_onWorkList(false), m_deleted(false) { } virtual ~GraphAcycVertex() {} V3GraphVertex* origVertexp() const { return m_origVertexp; } void setDelete() { m_deleted = true; } bool isDelete() const { return m_deleted; } virtual string name() const { return m_origVertexp->name(); } virtual string dotColor() const { return m_origVertexp->dotColor(); } }; //-------------------------------------------------------------------- class GraphAcycEdge : public V3GraphEdge { // userp() is always used to point to the head original graph edge private: typedef list OrigEdgeList; // List of orig edges, see also GraphAcyc's decl V3GraphEdge* origEdgep() const { OrigEdgeList* oEListp = ((OrigEdgeList*)userp()); if (!oEListp) v3fatalSrc("No original edge associated with acyc edge "<front()); } public: GraphAcycEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false) : V3GraphEdge(graphp, fromp, top, weight, cutable) { } virtual ~GraphAcycEdge() {} // yellow=we might still cut it, else oldEdge: yellowGreen=made uncutable, red=uncutable virtual string dotColor() const { return (cutable()?"yellow":origEdgep()->dotColor()); } }; //-------------------------------------------------------------------- struct GraphAcycEdgeCmp { inline bool operator () (const V3GraphEdge* lhsp, const V3GraphEdge* rhsp) const { if (lhsp->weight() > rhsp->weight()) return 1; // LHS goes first if (lhsp->weight() < rhsp->weight()) return 0; // RHS goes first return 0; } }; //-------------------------------------------------------------------- // CLASSES class GraphAcyc { private: typedef list OrigEdgeList; // List of orig edges, see also GraphAcycEdge's decl // GRAPH USERS // origGraph // GraphVertex::user() GraphAycVerted* New graph node // m_breakGraph // GraphEdge::user() OrigEdgeList* Old graph edges // GraphVertex::user bool Detection of loops in simplifyDupIterate // MEMBERS V3Graph* m_origGraphp; // Original graph V3Graph m_breakGraph; // Graph with only breakable edges represented V3List m_work; // List of vertices with optimization work left vector m_origEdgeDelp; // List of deletions to do when done V3EdgeFuncP m_origEdgeFuncp; // Function that says we follow this edge (in original graph) uint32_t m_placeStep; // Number that user() must be equal to to indicate processing static int debug() { return V3Graph::debug(); } // METHODS void buildGraph (V3Graph* origGraphp); void buildGraphIterate (V3GraphVertex* overtexp, GraphAcycVertex* avertexp); void simplify (bool allowCut); void simplifyNone (GraphAcycVertex* vertexp); void simplifyOne (GraphAcycVertex* vertexp); void simplifyOut (GraphAcycVertex* vertexp); void simplifyDup (GraphAcycVertex* vertexp); void cutBasic (GraphAcycVertex* vertexp); void cutBackward (GraphAcycVertex* vertexp); void deleteMarked(); void place(); void placeTryEdge(V3GraphEdge* edgep); bool placeIterate(GraphAcycVertex* vertexp, uint32_t currentRank); inline bool origFollowEdge(V3GraphEdge* edgep) { return (edgep->weight() && (m_origEdgeFuncp)(edgep)); } V3GraphEdge* edgeFromEdge (V3GraphEdge* oldedgep, V3GraphVertex* fromp, V3GraphVertex* top) { // Make new breakGraph edge, with old edge as a template GraphAcycEdge* newEdgep = new GraphAcycEdge (&m_breakGraph, fromp, top, oldedgep->weight(), oldedgep->cutable()); newEdgep->userp(oldedgep->userp()); // Keep pointer to OrigEdgeList return newEdgep; } void addOrigEdgep (V3GraphEdge* toEdgep, V3GraphEdge* addEdgep) { // Add addEdge (or it's list) to list of edges that break edge represents // Note addEdge may already have a bunch of similar linked edge representations. Yuk. UASSERT(addEdgep, "Adding NULL"); if (!toEdgep->userp()) { OrigEdgeList* oep = new OrigEdgeList; m_origEdgeDelp.push_back(oep); toEdgep->userp(oep); } OrigEdgeList* oEListp = (OrigEdgeList*)(toEdgep->userp()); if (OrigEdgeList* addListp = (OrigEdgeList*)(addEdgep->userp())) { for (OrigEdgeList::iterator it = addListp->begin(); it != addListp->end(); ++it) { oEListp->push_back(*it); } addListp->clear(); // Done with it } else { oEListp->push_back(addEdgep); } } void cutOrigEdge (V3GraphEdge* breakEdgep, const char* why) { // From the break edge, cut edges in original graph it represents UINFO(8,why<<" CUT "<fromp()<cut(); OrigEdgeList* oEListp = (OrigEdgeList*)(breakEdgep->userp()); if (!oEListp) v3fatalSrc("No original edge associated with cutting edge "<begin(); it != oEListp->end(); ++it) { V3GraphEdge* origEdgep = *it; origEdgep->cut(); UINFO(8," "<fromp()<<" ->"<top()<m_onWorkList) { avertexp->m_onWorkList = true; avertexp->m_work.pushBack(m_work, avertexp); } } GraphAcycVertex* workBeginp() { return m_work.begin(); } void workPop() { GraphAcycVertex* avertexp = workBeginp(); avertexp->m_onWorkList = false; avertexp->m_work.unlink(m_work, avertexp); } public: // CONSTRUCTORS GraphAcyc(V3Graph* origGraphp, V3EdgeFuncP edgeFuncp) { m_origGraphp = origGraphp; m_origEdgeFuncp = edgeFuncp; m_placeStep = 0; } ~GraphAcyc() { for (vector::iterator it = m_origEdgeDelp.begin(); it != m_origEdgeDelp.end(); ++it) { delete (*it); } m_origEdgeDelp.clear(); } void main(); }; //-------------------------------------------------------------------- void GraphAcyc::buildGraph (V3Graph* origGraphp) { // Presumes the graph has been strongly ordered, // and thus there's a unique color if there are loops in this subgraph. // For each old node, make a new graph node for optimization origGraphp->userClearVertices(); origGraphp->userClearEdges(); for (V3GraphVertex* overtexp = origGraphp->verticesBeginp(); overtexp; overtexp=overtexp->verticesNextp()) { if (overtexp->color()) { GraphAcycVertex* avertexp = new GraphAcycVertex(&m_breakGraph, overtexp); overtexp->userp(avertexp); // Stash so can look up later } } // Build edges between logic vertices for (V3GraphVertex* overtexp = origGraphp->verticesBeginp(); overtexp; overtexp=overtexp->verticesNextp()) { if (overtexp->color()) { GraphAcycVertex* avertexp = (GraphAcycVertex*)(overtexp->userp()); buildGraphIterate(overtexp, avertexp); } } } void GraphAcyc::buildGraphIterate (V3GraphVertex* overtexp, GraphAcycVertex* avertexp) { // Make new edges for (V3GraphEdge* edgep = overtexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (origFollowEdge(edgep)) { // not cut V3GraphVertex* toVertexp = edgep->top(); if (toVertexp->color()) { GraphAcycVertex* toAVertexp = (GraphAcycVertex*)(toVertexp->userp()); // Replicate the old edge into the new graph // There may be multiple edges between same pairs of vertices V3GraphEdge* breakEdgep = new GraphAcycEdge (&m_breakGraph, avertexp, toAVertexp, edgep->weight(), edgep->cutable()); addOrigEdgep (breakEdgep, edgep); // So can find original edge } } } } void GraphAcyc::simplify (bool allowCut) { // Add all nodes to list of work to do for (V3GraphVertex* vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { workPush(vertexp); } // Optimize till everything finished while (GraphAcycVertex* vertexp = workBeginp()) { workPop(); simplifyNone(vertexp); simplifyOne(vertexp); simplifyOut(vertexp); simplifyDup(vertexp); if (allowCut) { // The main algorithm works without these, though slower // So if changing the main algorithm, comment these out for a test run if (v3Global.opt.oAcycSimp()) { cutBasic(vertexp); cutBackward(vertexp); } } } deleteMarked(); } void GraphAcyc::deleteMarked () { // Delete nodes marked for removal for (V3GraphVertex* nextp, *vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=nextp) { nextp = vertexp->verticesNextp(); GraphAcycVertex* avertexp = (GraphAcycVertex*)vertexp; if (avertexp->isDelete()) { avertexp->unlinkDelete(&m_breakGraph); VL_DANGLING(avertexp); } } } 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(); VL_DANGLING(edgep); workPush(otherVertexp); } while (V3GraphEdge* edgep = avertexp->inBeginp()) { V3GraphVertex* otherVertexp = edgep->fromp(); //UINFO(9," in "<unlinkDelete(); VL_DANGLING(edgep); 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); // cppcheck-suppress leakReturnValNotUsed edgeFromEdge(templateEdgep, inVertexp, outVertexp); // Remove old edge inEdgep->unlinkDelete(); VL_DANGLING(inEdgep); outEdgep->unlinkDelete(); VL_DANGLING(outEdgep); VL_DANGLING(templateEdgep); 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 // cppcheck-suppress leakReturnValNotUsed edgeFromEdge(inEdgep, inVertexp, outVertexp); // Remove old edge inEdgep->unlinkDelete(); VL_DANGLING(inEdgep); workPush(inVertexp); } outEdgep->unlinkDelete(); VL_DANGLING(outEdgep); 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(); VL_DANGLING(edgep); } else if (!edgep->cutable()) { // !cutable duplicates prev cutable: delete the earlier cutable UINFO(8," DelDupPrev "< "<top()<unlinkDelete(); VL_DANGLING(prevEdgep); outVertexp->userp(edgep); } else { // cutable duplicates prev cutable: combine weights UINFO(8," DelDupComb "< "<top()<weight (prevEdgep->weight() + edgep->weight()); addOrigEdgep (prevEdgep, edgep); edgep->unlinkDelete(); VL_DANGLING(edgep); } 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(); VL_DANGLING(edgep); 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(); VL_DANGLING(edgep); 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(); VL_DANGLING(edgep); // 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.916/src/V3Tristate.cpp0000664000177100017500000014333213205623232017027 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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) { 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) { // 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(AstSliceSel* nodep) { // Doesn't work because we'd set lvalue on the array index's var if (m_lvalue) nodep->v3fatalSrc("SliceSel conversion to output, under tristate node"); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep) { 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(); } 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()->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()->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()->castVar(); // From CASEEQ, foo === 1'bz } AstNode* orp = NULL; AstNode* enp = NULL; AstNode* undrivenp = NULL; // loop through the lhs drivers to build the driver resolution logic for (RefVec::iterator ii=refs->begin(); ii != refs->end(); ++ii) { AstVarRef* refp = (*ii); int w = lhsp->width(); // create the new lhs driver for this var AstVar* newlhsp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP, lhsp->name()+"__out"+cvtToStr(m_unique), VFlagBitPacked(), w); // 2-state ok; sep enable UINFO(9," newout "<addStmtp(newlhsp); refp->varp(newlhsp); // assign the new var to the varref refp->name(newlhsp->name()); // create a new var for this drivers enable signal AstVar* newenp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP, lhsp->name()+"__en"+cvtToStr(m_unique++), VFlagBitPacked(), w); // 2-state ok UINFO(9," newenp "<addStmtp(newenp); AstNode* enassp = new AstAssignW(refp->fileline(), new AstVarRef(refp->fileline(), newenp, true), getEnp(refp)); UINFO(9," newass "<addStmtp(enassp); // now append this driver to the driver logic. AstNode* ref1p = new AstVarRef(refp->fileline(), newlhsp,false); AstNode* ref2p = new AstVarRef(refp->fileline(), newenp, false); AstNode* andp = new AstAnd(refp->fileline(), ref1p, ref2p); // or this to the others orp = (!orp) ? andp : new AstOr(refp->fileline(), orp, andp); if (envarp) { AstNode* ref3p = new AstVarRef(refp->fileline(), newenp, false); enp = (!enp) ? ref3p : new AstOr(ref3p->fileline(), enp, ref3p); } AstNode* tmp = new AstNot(newenp->fileline(), new AstVarRef(newenp->fileline(), newenp, false)); undrivenp = ((!undrivenp) ? tmp : new AstAnd(refp->fileline(), tmp, undrivenp)); } if (!undrivenp) { // No drivers on the bus V3Number ones(invarp->fileline(), lhsp->width()); ones.setAllBits1(); undrivenp = new AstConst(invarp->fileline(), ones); } if (!outvarp) { // This is the final resolution of the tristate, so we apply // the pull direction to any undriven pins. V3Number pull(invarp->fileline(), lhsp->width()); AstPull* pullp = (AstPull*)lhsp->user3p(); if (pullp && pullp->direction() == 1) { pull.setAllBits1(); UINFO(9,"Has pullup "<fileline(), undrivenp, new AstConst(invarp->fileline(), pull)); orp = new AstOr(invarp->fileline(), orp, undrivenp); } else { undrivenp->deleteTree(); VL_DANGLING(undrivenp); } 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) { 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); newconstp->user1p(enp); // propagate up constant with non-Z bits as 1 } } } virtual void visit(AstCond* nodep) { 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) { 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()); 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) { 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(); 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) { // 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()) { 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) { visitAndOr(nodep,true); } virtual void visit(AstOr* nodep) { 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) { visitAssign(nodep); } virtual void visit(AstAssign* nodep) { 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()->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); VL_DANGLING(nodep); } 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) { visitCaseEq(nodep,false); } virtual void visit(AstNeqCase* nodep) { visitCaseEq(nodep,true); } virtual void visit(AstEqWild* nodep) { visitEqNeqWild(nodep); } virtual void visit(AstNeqWild* nodep) { visitEqNeqWild(nodep); } virtual void visit(AstPull* nodep) { 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); VL_DANGLING(nodep); // 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) { 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, // We converted, so use declaration output state nodep->modVarp()->isDeclOutput())); 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(); if (!outModVarp) nodep->v3fatalSrc("Unlinked"); 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) { 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) { 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) { // don't deal with functions } virtual void visit(AstCaseItem* nodep) { // don't deal with casez compare '???? values nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstCell* nodep) { m_cellp = nodep; m_alhs = false; nodep->iterateChildren(*this); m_cellp = NULL; } virtual void visit(AstNetlist* nodep) { nodep->iterateChildrenBackwards(*this); } // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); checkUnhandled(nodep); } public: // CONSTUCTORS explicit TristateVisitor(AstNode* nodep) { m_graphing = false; m_modp = NULL; m_cellp = NULL; m_unique = 0; m_alhs = false; m_logicp = NULL; m_tgraph.clear(); nodep->accept(*this); } virtual ~TristateVisitor() { V3Stats::addStat("Tristate, Tristate resolved nets", m_statTriSigs); } }; //###################################################################### // Tristate class functions void V3Tristate::tristateAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Os.h0000664000177100017500000000506013205574202015253 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Os-specific function wrapper // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3OS_H_ #define _V3OS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include //============================================================================ // V3Os: OS static class class V3Os { public: // METHODS (environment) static string getenvStr(const string& envvar, const string& defaultValue); static void setenvStr(const string& envvar, const string& value, const string& why); // METHODS (generic filename utilities) static string filenameFromDirBase (const string& dir, const string& basename); static string filenameNonDir (const string& filename); ///< Return non-directory part of filename static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename static string filenameDir (const string& filename); ///< Return directory part of filename static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed static string filenameRealPath(const string& fn); ///< Return realpath of filename static bool filenameIsRel (const string& filename); ///< True if relative // METHODS (directory utilities) static void createDir(const string& dirname); static void unlinkRegexp(const string& dir, const string& regexp); // METHODS (performance) static uint64_t timeUsecs(); ///< Return wall time since epoch in microseconds, or 0 if not implemented static uint64_t memUsageBytes(); ///< Return memory usage in bytes, or 0 if not implemented }; #endif // Guard verilator-3.916/src/V3LifePost.cpp0000664000177100017500000001510613205574202016754 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: AssignPost Variable assignment elimination // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LIFE TRANSFORMATIONS: // Build control-flow graph with assignments and var usages // All modules: // Delete these // ASSIGN(Vdly, a) // ... {no reads or writes of a after the first write to Vdly} // ... {no reads of a after the first write to Vdly} // ASSIGNPOST(Vdly,tmp) // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3LifePost.h" #include "V3Stats.h" #include "V3Ast.h" //###################################################################### // LifePost state, as a visitor of each AstNode class LifePostBaseVisitor : public AstNVisitor { protected: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### // LifePost class functions class LifePostElimVisitor : public LifePostBaseVisitor { private: // NODE STATE // INPUT: // AstVarScope::user4p() -> AstVarScope*, If set, replace this varscope with specified new one // STATE // VISITORS virtual void visit(AstVarRef* nodep) { 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(); VL_DANGLING(nodep); } } virtual void visit(AstNodeModule* nodep) { // Only track the top scopes, not lower level functions if (nodep->isTop()) nodep->iterateChildren(*this); } virtual void visit(AstCCall* nodep) { nodep->iterateChildren(*this); // Enter the function and trace it nodep->funcp()->accept(*this); } virtual void visit(AstVar*) {} // Don't want varrefs under it virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit 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) { 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) { // 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) { 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(); VL_DANGLING(nodep); ++m_statAssnDel; } } } } virtual void visit(AstNodeModule* nodep) { // Only track the top scopes, not lower level functions if (nodep->isTop()) nodep->iterateChildren(*this); } virtual void visit(AstCCall* nodep) { nodep->iterateChildren(*this); // Enter the function and trace it nodep->funcp()->accept(*this); } //----- virtual void visit(AstVar*) {} // Don't want varrefs under it virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit LifePostDlyVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~LifePostDlyVisitor() { V3Stats::addStat("Optimizations, Lifetime postassign deletions", m_statAssnDel); } }; //###################################################################### // LifePost class functions void V3LifePost::lifepostAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/VlcTop.h0000664000177100017500000000413713205574202015674 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Top global container // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCTOP_H_ #define _VLCTOP_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "VlcOptions.h" #include "VlcTest.h" #include "VlcPoint.h" #include "VlcSource.h" //###################################################################### // VlcTop - Top level options container class VlcTop { public: // PUBLIC MEMBERS VlcOptions opt; //< Runtime options private: // MEMBERS VlcTests m_tests; //< List of all tests (all coverage files) VlcPoints m_points; //< List of all points VlcSources m_sources; //< List of all source files to annotate // METHODS void createDir(const string& dirname); void annotateCalc(); void annotateCalcNeeded(); void annotateOutputFiles(const string& dirname); public: // CONSTRUCTORS VlcTop() {} ~VlcTop() {} // ACCESSORS VlcTests& tests() { return m_tests; } VlcPoints& points() { return m_points; } VlcSources& sources() { return m_sources; } // METHODS void annotate(const string& dirname); void readCoverage(const string& filename, bool nonfatal=false); void writeCoverage(const string& filename); void rank(); }; //###################################################################### #endif // guard verilator-3.916/src/V3Error.cpp0000664000177100017500000001752713205574202016331 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Error handling // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include #include #include "V3Error.h" #ifndef _V3ERROR_NO_GLOBAL_ # include "V3Ast.h" # include "V3Global.h" # include "V3Stats.h" #endif //====================================================================== // Statics int V3Error::s_errCount = 0; int V3Error::s_warnCount = 0; int V3Error::s_debugDefault = 0; int V3Error::s_errorLimit = V3Error::MAX_ERRORS; bool V3Error::s_warnFatal = true; int V3Error::s_tellManual = 0; ostringstream V3Error::s_errorStr; // Error string being formed V3ErrorCode V3Error::s_errorCode = V3ErrorCode::EC_FATAL; bool V3Error::s_errorSuppressed = false; bool V3Error::s_describedEachWarn[V3ErrorCode::_ENUM_MAX]; bool V3Error::s_describedWarnings = false; bool V3Error::s_pretendError[V3ErrorCode::_ENUM_MAX]; V3Error::MessagesSet V3Error::s_messages; V3Error::ErrorExitCb V3Error::s_errorExitCb = NULL; struct v3errorIniter { v3errorIniter() { V3Error::init(); } }; v3errorIniter v3errorInit; //###################################################################### // ErrorCode class functions V3ErrorCode::V3ErrorCode(const char* msgp) { // Return error encoding for given string, or ERROR, which is a bad code for (int codei=V3ErrorCode::EC_MIN; codei20) numsp = 20; out<<(spaces + numsp); return out.str(); } void V3Error::incErrors() { s_errCount++; if (errorCount() == errorLimit()) { // Not >= as would otherwise recurse v3fatal ("Exiting due to too many errors encountered; --error-limit="<=V3ErrorCode::EC_MIN) { #ifndef _V3ERROR_NO_GLOBAL_ V3Stats::addStatSum(string("Warnings, Suppressed ")+s_errorCode.ascii(), 1); #endif s_errorSuppressed = true; } } string V3Error::warnMore() { return msgPrefix(); } void V3Error::v3errorEnd (ostringstream& sstr) { #if defined(__COVERITY__) || defined(__cppcheck__) if (s_errorCode==V3ErrorCode::EC_FATAL) __coverity_panic__(x); #endif // Skip suppressed messages if (s_errorSuppressed // On debug, show only non default-off warning to prevent pages of warnings && (!debug() || s_errorCode.defaultsOff())) return; string msg = msgPrefix()+sstr.str(); if (msg[msg.length()-1] != '\n') msg += '\n'; // Suppress duplicates if (s_messages.find(msg) != s_messages.end()) return; s_messages.insert(msg); // Output cerr<=V3ErrorCode::EC_FIRST_WARN && !s_describedWarnings) { cerr<dumpTreeFile(v3Global.debugFilename("final.tree",990)); if (s_errorExitCb) s_errorExitCb(); V3Stats::statsFinalAll(v3Global.rootp()); V3Stats::statsReport(); } #endif } vlAbort(); } else if (isError(s_errorCode, s_errorSuppressed)) { // We don't dump tree on any error because a Visitor may be in middle of // a tree cleanup and cause a false broken problem. if (s_errorExitCb) s_errorExitCb(); } } } verilator-3.916/src/V3GenClk.h0000664000177100017500000000224513205574202016037 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Generated Clock Repairs // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/Verilator.cpp0000664000177100017500000004744413205574202016777 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: main() // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 "V3CCtors.h" #include "V3Dead.h" #include "V3Delayed.h" #include "V3Depth.h" #include "V3DepthBlock.h" #include "V3Descope.h" #include "V3EmitC.h" #include "V3EmitMk.h" #include "V3EmitV.h" #include "V3EmitXml.h" #include "V3Expand.h" #include "V3File.h" #include "V3Cdc.h" #include "V3Gate.h" #include "V3GenClk.h" #include "V3Graph.h" #include "V3Inline.h" #include "V3Inst.h" #include "V3Life.h" #include "V3LifePost.h" #include "V3LinkCells.h" #include "V3LinkDot.h" #include "V3LinkJump.h" #include "V3LinkLValue.h" #include "V3LinkLevel.h" #include "V3LinkParse.h" #include "V3LinkResolve.h" #include "V3Localize.h" #include "V3Name.h" #include "V3Order.h" #include "V3Os.h" #include "V3Param.h" #include "V3Parse.h" #include "V3ParseSym.h" #include "V3PreShell.h" #include "V3Premit.h" #include "V3Scope.h" #include "V3Slice.h" #include "V3Split.h" #include "V3SplitAs.h" #include "V3Stats.h" #include "V3String.h" #include "V3Subst.h" #include "V3Table.h" #include "V3Task.h" #include "V3Trace.h" #include "V3TraceDecl.h" #include "V3Tristate.h" #include "V3Undriven.h" #include "V3Unknown.h" #include "V3Unroll.h" #include "V3Width.h" V3Global v3Global; //###################################################################### // V3 Class -- top level AstNetlist* V3Global::makeNetlist() { AstNetlist* newp = new AstNetlist(); newp->addTypeTablep(new AstTypeTable(newp->fileline())); return newp; } void V3Global::checkTree() { rootp()->checkTree(); } void V3Global::clear() { if (m_rootp) { m_rootp->deleteTree(); m_rootp=NULL; } } void V3Global::readFiles() { // NODE STATE // AstNode::user4p() // VSymEnt* Package and typedef symbol names AstUser4InUse inuser4; V3InFilter filter (v3Global.opt.pipeFilter()); V3ParseSym parseSyms (v3Global.rootp()); // Symbol table must be common across all parsing V3Parse parser (v3Global.rootp(), &filter, &parseSyms); // Read top module const V3StringList& vFiles = v3Global.opt.vFiles(); for (V3StringList::const_iterator it = vFiles.begin(); it != vFiles.end(); ++it) { string filename = *it; parser.parseFile(new FileLine("COMMAND_LINE",0), filename, false, "Cannot find file containing module: "); } // Read libraries // To be compatible with other simulators, // this needs to be done after the top file is read const V3StringSet& libraryFiles = v3Global.opt.libraryFiles(); for (V3StringSet::const_iterator it = libraryFiles.begin(); it != libraryFiles.end(); ++it) { string filename = *it; parser.parseFile(new FileLine("COMMAND_LINE",0), filename, true, "Cannot find file containing library module: "); } //v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("parse.tree")); V3Error::abortIfErrors(); if (!v3Global.opt.preprocOnly()) { // Resolve all modules cells refer to V3LinkCells::link(v3Global.rootp(), &filter, &parseSyms); } } void V3Global::dumpCheckGlobalTree(const string& stagename, int newNumber, bool doDump) { v3Global.rootp()->dumpTreeFile(v3Global.debugFilename(stagename+".tree", newNumber), false, doDump); if (v3Global.opt.stats()) V3Stats::statsStage(stagename); } //###################################################################### void process () { // Sort modules by level so later algorithms don't need to care V3LinkLevel::modSortByLevel(); V3Error::abortIfErrors(); // Convert parseref's to varrefs, and other directly post parsing fixups V3LinkParse::linkParse(v3Global.rootp()); // Cross-link signal names // Cross-link dotted hierarchical references V3LinkDot::linkDotPrimary(v3Global.rootp()); v3Global.checkTree(); // Force a check, as link is most likely place for problems // Check if all parameters have been found v3Global.opt.checkParameters(); // Correct state we couldn't know at parse time, repair SEL's V3LinkResolve::linkResolve(v3Global.rootp()); // Set Lvalue's in variable refs V3LinkLValue::linkLValue(v3Global.rootp()); // Convert return/continue/disable to jumps V3LinkJump::linkJump(v3Global.rootp()); V3Error::abortIfErrors(); if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Link"); // Remove parameters by cloning modules to de-parameterized versions // This requires some width calculations and constant propagation V3Param::param(v3Global.rootp()); V3LinkDot::linkDotParamed(v3Global.rootp()); // Cleanup as made new modules V3Error::abortIfErrors(); // Remove any modules that were parameterized and are no longer referenced. V3Dead::deadifyModules(v3Global.rootp()); v3Global.checkTree(); // Calculate and check widths, edit tree to TRUNC/EXTRACT any width mismatches V3Width::width(v3Global.rootp()); V3Error::abortIfErrors(); // Commit to the widths we've chosen; Make widthMin==width V3Width::widthCommit(v3Global.rootp()); v3Global.assertDTypesResolved(true); v3Global.widthMinUsage(VWidthMinUsage::MATCHES_WIDTH); // Coverage insertion // Before we do dead code elimination and inlining, or we'll lose it. if (v3Global.opt.coverage()) { V3Coverage::coverage(v3Global.rootp()); } // Push constants, but only true constants preserving liveness // so V3Undriven sees variables to be eliminated, ie "if (0 && foo) ..." V3Const::constifyAllLive(v3Global.rootp()); // Signal based lint checks, no change to structures // Must be before first constification pass drops dead code V3Undriven::undrivenAll(v3Global.rootp()); // Assertion insertion // After we've added block coverage, but before other nasty transforms V3AssertPre::assertPreAll(v3Global.rootp()); // V3Assert::assertAll(v3Global.rootp()); if (!v3Global.opt.xmlOnly()) { // Add top level wrapper with instance pointing to old top // Move packages to under new top // Must do this after we know parameters and dtypes (as don't clone dtype decls) V3LinkLevel::wrapTop(v3Global.rootp()); } // Propagate constants into expressions V3Const::constifyAllLint(v3Global.rootp()); if (!v3Global.opt.xmlOnly()) { // Remove cell arrays (must be between V3Width and scoping) V3Inst::dearrayAll(v3Global.rootp()); V3LinkDot::linkDotArrayed(v3Global.rootp()); } if (!v3Global.opt.xmlOnly()) { // Expand inouts, stage 2 // Also simplify pin connections to always be AssignWs in prep for V3Unknown V3Tristate::tristateAll(v3Global.rootp()); // Task inlining & pushing BEGINs names to variables/cells // Begin processing must be after Param, before module inlining V3Begin::debeginAll(v3Global.rootp()); // Flatten cell names, before inliner // Move assignments from X into MODULE temps. // (Before flattening, so each new X variable is shared between all scopes of that module.) V3Unknown::unknownAll(v3Global.rootp()); v3Global.constRemoveXs(true); // Module inlining // Cannot remove dead variables after this, as alias information for final // V3Scope's V3LinkDot is in the AstVar. if (v3Global.opt.oInline()) { V3Inline::inlineAll(v3Global.rootp()); V3LinkDot::linkDotArrayed(v3Global.rootp()); // Cleanup as made new modules } } //--PRE-FLAT OPTIMIZATIONS------------------ // Initial const/dead to reduce work for ordering code V3Const::constifyAll(v3Global.rootp()); v3Global.checkTree(); V3Dead::deadifyDTypes(v3Global.rootp()); v3Global.checkTree(); V3Error::abortIfErrors(); //--FLATTENING--------------- if (!v3Global.opt.xmlOnly()) { // We're going to flatten the hierarchy, so as many optimizations that // can be done as possible should be before this.... // Convert instantiations to wassigns and always blocks V3Inst::instAll(v3Global.rootp()); // Inst may have made lots of concats; fix them V3Const::constifyAll(v3Global.rootp()); // Flatten hierarchy, creating a SCOPE for each module's usage as a cell V3Scope::scopeAll(v3Global.rootp()); V3LinkDot::linkDotScope(v3Global.rootp()); } //--SCOPE BASED OPTIMIZATIONS-------------- if (!v3Global.opt.xmlOnly()) { // Cleanup V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyDTypesScoped(v3Global.rootp()); v3Global.checkTree(); // Convert case statements to if() blocks. Must be after V3Unknown // Must be before V3Task so don't need to deal with task in case value compares V3Case::caseAll(v3Global.rootp()); // Inline all tasks V3Task::taskAll(v3Global.rootp()); // Add __PVT's // After V3Task so task internal variables will get renamed V3Name::nameAll(v3Global.rootp()); // Loop unrolling & convert FORs to WHILEs V3Unroll::unrollAll(v3Global.rootp()); // Expand slices of arrays V3Slice::sliceAll(v3Global.rootp()); // Push constants across variables and remove redundant assignments V3Const::constifyAll(v3Global.rootp()); if (v3Global.opt.oLife()) { V3Life::lifeAll(v3Global.rootp()); } // Make large low-fanin logic blocks into lookup tables // This should probably be done much later, once we have common logic elimination. if (!v3Global.opt.lintOnly() && v3Global.opt.oTable()) { V3Table::tableAll(v3Global.rootp()); } // Cleanup V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyDTypesScoped(v3Global.rootp()); v3Global.checkTree(); // Detect clock enables and mode into sensitives, and split always based on clocks // (so this is a good prelude to splitAlways.) if (v3Global.opt.oFlopGater()) { V3ClkGater::clkGaterAll(v3Global.rootp()); } // Move assignments/sensitives into a SBLOCK for each unique sensitivity list // (May convert some ALWAYS to combo blocks, so should be before V3Gate step.) V3Active::activeAll(v3Global.rootp()); // Split single ALWAYS blocks into multiple blocks for better ordering chances if (v3Global.opt.oSplit()) { V3Split::splitAlwaysAll(v3Global.rootp()); } V3SplitAs::splitAsAll(v3Global.rootp()); // Create tracing sample points, before we start eliminating signals if (v3Global.opt.trace()) { V3TraceDecl::traceDeclAll(v3Global.rootp()); } // Gate-based logic elimination; eliminate signals and push constant across cell boundaries // Instant propagation makes lots-o-constant reduction possibilities. if (v3Global.opt.oGate()) { V3Gate::gateAll(v3Global.rootp()); // V3Gate calls constant propagation itself. } else { v3info("Command Line disabled gate optimization with -Og/-O0. This may cause ordering problems."); } // Combine COVERINCs with duplicate terms if (v3Global.opt.coverage()) { V3CoverageJoin::coverageJoin(v3Global.rootp()); } // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyAllScoped(v3Global.rootp()); // Clock domain crossing analysis if (v3Global.opt.cdc()) { V3Cdc::cdcAll(v3Global.rootp()); V3Error::abortIfErrors(); return; } // Reorder assignments in pipelined blocks if (v3Global.opt.oReorder()) { V3Split::splitReorderAll(v3Global.rootp()); } // Create delayed assignments // This creates lots of duplicate ACTIVES so ActiveTop needs to be after this step V3Delayed::delayedAll(v3Global.rootp()); // Make Active's on the top level // Differs from V3Active, because identical clocks may be pushed down to a module and now be identical V3ActiveTop::activeTopAll(v3Global.rootp()); if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "PreOrder"); // Order the code; form SBLOCKs and BLOCKCALLs V3Order::orderAll(v3Global.rootp()); // Change generated clocks to look at delayed signals V3GenClk::genClkAll(v3Global.rootp()); // Convert sense lists into IF statements. V3Clock::clockAll(v3Global.rootp()); // Cleanup any dly vars or other temps that are simple assignments // Life must be done before Subst, as it assumes each CFunc under _eval is called only once. if (v3Global.opt.oLife()) { V3Const::constifyAll(v3Global.rootp()); V3Life::lifeAll(v3Global.rootp()); } if (v3Global.opt.oLifePost()) { V3LifePost::lifepostAll(v3Global.rootp()); } // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyAllScoped(v3Global.rootp()); // Detect change loop V3Changed::changedAll(v3Global.rootp()); // Create tracing logic, since we ripped out some signals the user might want to trace // Note past this point, we presume traced variables won't move between CFuncs // (It's OK if untraced temporaries move around, or vars "effectively" activate the same way.) if (v3Global.opt.trace()) { V3Trace::traceAll(v3Global.rootp()); } if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Scoped"); // Remove scopes; make varrefs/funccalls relative to current module V3Descope::descopeAll(v3Global.rootp()); } //--MODULE OPTIMIZATIONS-------------- if (!v3Global.opt.xmlOnly()) { // Split deep blocks to appease MSVC++. Must be before Localize. if (!v3Global.opt.lintOnly() && v3Global.opt.compLimitBlocks()) { V3DepthBlock::depthBlockAll(v3Global.rootp()); } // Move BLOCKTEMPS from class to local variables if (v3Global.opt.oLocalize()) { V3Localize::localizeAll(v3Global.rootp()); } // Icache packing; combine common code in each module's functions into subroutines if (v3Global.opt.oCombine()) { V3Combine::combineAll(v3Global.rootp()); } } V3Error::abortIfErrors(); //--GENERATION------------------ if (!v3Global.opt.xmlOnly()) { // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyAll(v3Global.rootp()); // Here down, widthMin() is the Verilog width, and width() is the C++ width // Bits between widthMin() and width() are irrelevant, but may be non zero. v3Global.widthMinUsage(VWidthMinUsage::VERILOG_WIDTH); // Make all math operations either 8, 16, 32 or 64 bits V3Clean::cleanAll(v3Global.rootp()); // Move wide constants to BLOCK temps. V3Premit::premitAll(v3Global.rootp()); } // Expand macros and wide operators into C++ primitives if (!v3Global.opt.xmlOnly() && v3Global.opt.oExpand()) { V3Expand::expandAll(v3Global.rootp()); } // Propagate constants across WORDSEL arrayed temporaries if (!v3Global.opt.xmlOnly() && v3Global.opt.oSubst()) { // Constant folding of expanded stuff V3Const::constifyCpp(v3Global.rootp()); V3Subst::substituteAll(v3Global.rootp()); } if (!v3Global.opt.xmlOnly() && v3Global.opt.oSubstConst()) { // Constant folding of substitutions V3Const::constifyCpp(v3Global.rootp()); V3Dead::deadifyAll(v3Global.rootp()); } if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly()) { // Fix very deep expressions // Mark evaluation functions as member functions, if needed. V3Depth::depthAll(v3Global.rootp()); // Branch prediction V3Branch::branchAll(v3Global.rootp()); // Add C casts when longs need to become long-long and vice-versa // Note depth may insert something needing a cast, so this must be last. V3Cast::castAll(v3Global.rootp()); } V3Error::abortIfErrors(); if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly()) { V3CCtors::cctorsAll(); } // Output the text if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly()) { // emitcInlines is first, as it may set needHInlines which other emitters read V3EmitC::emitcInlines(); V3EmitC::emitcSyms(); V3EmitC::emitcTrace(); } if (!v3Global.opt.xmlOnly()) { // Unfortunately we have some lint checks in emitc. V3EmitC::emitc(); } if (v3Global.opt.xmlOnly() // Check XML when debugging to make sure no missing node types || (v3Global.opt.debugCheck() && !v3Global.opt.lintOnly())) { V3EmitXml::emitxml(); } // Statistics if (v3Global.opt.stats()) { V3Stats::statsFinalAll(v3Global.rootp()); V3Stats::statsReport(); } if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly()) { // Makefile must be after all other emitters V3EmitMk::emitmk(v3Global.rootp()); } // Note early return above when opt.cdc() } //###################################################################### int main(int argc, char** argv, char** env) { // General initialization ios::sync_with_stdio(); time_t randseed; time(&randseed); srand( (int) randseed); // Post-constructor initialization of netlists v3Global.boot(); // Preprocessor // Before command parsing so we can handle -Ds on command line. V3PreShell::boot(env); // Command option parsing v3Global.opt.bin(argv[0]); string argString = V3Options::argString(argc-1, argv+1); v3Global.opt.parseOpts(new FileLine("COMMAND_LINE",0), argc-1, argv+1); if (!v3Global.opt.outFormatOk() && !v3Global.opt.preprocOnly() && !v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly() && !v3Global.opt.cdc()) { v3fatal("verilator: Need --cc, --sc, --cdc, --lint-only, --xml_only or --E option"); } // Check environment V3Options::getenvSYSTEMC(); V3Options::getenvSYSTEMC_ARCH(); V3Options::getenvSYSTEMC_INCLUDE(); V3Options::getenvSYSTEMC_LIBDIR(); 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) VHashSha1::selfTest(); AstBasicDTypeKwd::selfTest(); V3Graph::selfTest(); //--FRONTEND------------------ // Cleanup V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.tree"); V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.dot"); V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.txt"); // Read first filename v3Global.readFiles(); // Link, etc, if needed if (!v3Global.opt.preprocOnly()) { process(); } // Final steps V3Global::dumpCheckGlobalTree("final", 990, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); V3Error::abortIfWarnings(); if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc() && v3Global.opt.makeDepend()) { V3File::writeDepend(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__ver.d"); } if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc() && (v3Global.opt.skipIdentical() || v3Global.opt.makeDepend())) { V3File::writeTimes(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__verFiles.dat", argString); } // Final writing shouldn't throw warnings, but... V3Error::abortIfWarnings(); #ifdef VL_LEAK_CHECKS // Cleanup memory for valgrind leak analysis v3Global.clear(); #endif FileLine::deleteAllRemaining(); UINFO(1,"Done, Exiting...\n"); } verilator-3.916/src/verilog.y0000664000177100017500000050413213205574202016155 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Bison grammer file // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // Original code here by Paul Wasson and Duane Galbi //************************************************************************* %{ #include #include #include #include #include "V3Ast.h" #include "V3Global.h" #include "V3Config.h" #include "V3ParseImp.h" // Defines YYTYPE; before including bison header #define YYERROR_VERBOSE 1 #define YYINITDEPTH 10000 // Older bisons ignore YYMAXDEPTH #define YYMAXDEPTH 10000 // Pick up new lexer #define yylex PARSEP->lexToBison #define GATEUNSUP(fl,tok) { if (!v3Global.opt.bboxUnsup()) { (fl)->v3error("Unsupported: Verilog 1995 gate primitive: "<<(tok)); } } extern void yyerror(const char* errmsg); extern void yyerrorf(const char* format, ...); //====================================================================== // Statics (for here only) #define PARSEP V3ParseImp::parsep() #define SYMP PARSEP->symp() #define GRAMMARP V3ParseGrammar::singletonp() class V3ParseGrammar { public: bool m_impliedDecl; // Allow implied wire declarations AstVarType m_varDecl; // Type for next signal declaration (reg/wire/etc) AstVarType m_varIO; // Type for next signal declaration (input/output/etc) AstVar* m_varAttrp; // Current variable for attribute adding AstRange* m_gateRangep; // Current range for gate declarations AstCase* m_caseAttrp; // Current case statement for attribute adding AstNodeDType* m_varDTypep; // Pointer to data type for next signal declaration AstNodeDType* m_memDTypep; // Pointer to data type for next member declaration int m_pinNum; // Pin number currently parsing string m_instModule; // Name of module referenced for instantiations AstPin* m_instParamp; // Parameters for instantiations bool m_tracingParse; // Tracing disable for parser static int s_modTypeImpNum; // Implicit type number, incremented each module // CONSTRUCTORS V3ParseGrammar() { m_impliedDecl = false; m_varDecl = AstVarType::UNKNOWN; m_varIO = AstVarType::UNKNOWN; m_varDTypep = NULL; m_gateRangep = NULL; m_memDTypep = NULL; m_pinNum = -1; m_instModule = ""; m_instParamp = NULL; m_varAttrp = NULL; m_caseAttrp = NULL; m_tracingParse = true; } static V3ParseGrammar* singletonp() { static V3ParseGrammar singleton; return &singleton; } // METHODS void argWrapList(AstNodeFTaskRef* nodep); bool allTracingOn(FileLine* fl) { return v3Global.opt.trace() && m_tracingParse && fl->tracingOn(); } AstNodeDType* createArray(AstNodeDType* basep, AstRange* rangep, bool isPacked); AstVar* createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp); AstNode* createSupplyExpr(FileLine* fileline, string name, int value); AstText* createTextQuoted(FileLine* fileline, string text) { string newtext = deQuote(fileline, text); return new AstText(fileline, newtext); } AstDisplay* createDisplayError(FileLine* fileline) { AstDisplay* nodep = new AstDisplay(fileline,AstDisplayType::DT_ERROR, "", NULL,NULL); nodep->addNext(new AstStop(fileline)); return nodep; } AstNode* createGatePin(AstNode* exprp) { AstRange* rangep = m_gateRangep; if (!rangep) return exprp; else return new AstGatePin(rangep->fileline(), exprp, rangep->cloneTree(true)); } void endLabel(FileLine* fl, AstNode* nodep, string* endnamep) { endLabel(fl, nodep->prettyName(), endnamep); } void endLabel(FileLine* fl, string name, string* endnamep) { if (fl && endnamep && *endnamep != "" && name != *endnamep && name != AstNode::prettyName(*endnamep)) { fl->v3warn(ENDLABEL,"End label '"<<*endnamep<<"' does not match begin label '"<deleteTree(); m_varDTypep=NULL; } // It was cloned, so this is safe. m_varDTypep = dtypep; } AstPackage* unitPackage(FileLine* fl) { // Find one made earlier? VSymEnt* symp = SYMP->symRootp()->findIdFlat(AstPackage::dollarUnitName()); AstPackage* pkgp; if (!symp) { pkgp = PARSEP->rootp()->dollarUnitPkgAddp(); SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global } else { pkgp = symp->nodep()->castPackage(); } 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(); VL_DANGLING(dtypep); dtypep = newp; } dtypep->rangep(finalp); } return createArray(dtypep, rangearraysp, isPacked); } } string deQuote(FileLine* fileline, string text); void checkDpiVer(FileLine* fileline, const string& str) { if (str != "DPI-C" && !v3Global.opt.bboxSys()) { fileline->v3error("Unsupported DPI type '"<copyOrSameFileLine()) // Only use in empty rules, so lines point at beginnings #define VARRESET_LIST(decl) { GRAMMARP->m_pinNum=1; VARRESET(); VARDECL(decl); } // Start of pinlist #define VARRESET_NONLIST(decl) { GRAMMARP->m_pinNum=0; VARRESET(); VARDECL(decl); } // Not in a pinlist #define VARRESET() { VARDECL(UNKNOWN); VARIO(UNKNOWN); VARDTYPE(NULL); } #define VARDECL(type) { GRAMMARP->m_varDecl = AstVarType::type; } #define VARIO(type) { GRAMMARP->m_varIO = AstVarType::type; } #define VARDTYPE(dtypep) { GRAMMARP->setDType(dtypep); } #define VARDONEA(fl,name,array,attrs) GRAMMARP->createVariable((fl),(name),(array),(attrs)) #define VARDONEP(portp,array,attrs) GRAMMARP->createVariable((portp)->fileline(),(portp)->name(),(array),(attrs)) #define PINNUMINC() (GRAMMARP->m_pinNum++) #define GATERANGE(rangep) { GRAMMARP->m_gateRangep = rangep; } #define INSTPREP(modname,paramsp) { GRAMMARP->m_impliedDecl = true; GRAMMARP->m_instModule = modname; GRAMMARP->m_instParamp = paramsp; } #define DEL(nodep) { if (nodep) nodep->deleteTree(); } static void ERRSVKWD(FileLine* fileline, const string& tokname) { static int toldonce = 0; fileline->v3error((string)"Unexpected \""+tokname+"\": \""+tokname+"\" is a SystemVerilog keyword misused as an identifier."); if (!toldonce++) fileline->v3error("Modify the Verilog-2001 code to avoid SV keywords, or use `begin_keywords or --language."); } //====================================================================== class AstSenTree; %} // When writing Bison patterns we use yTOKEN instead of "token", // so Bison will error out on unknown "token"s. // Generic lexer tokens, for example a number // IEEE: real_number %token yaFLOATNUM "FLOATING-POINT NUMBER" // IEEE: identifier, class_identifier, class_variable_identifier, // covergroup_variable_identifier, dynamic_array_variable_identifier, // enum_identifier, interface_identifier, interface_instance_identifier, // package_identifier, type_identifier, variable_identifier, %token yaID__ETC "IDENTIFIER" %token yaID__LEX "IDENTIFIER-in-lex" %token yaID__aPACKAGE "PACKAGE-IDENTIFIER" %token yaID__aTYPE "TYPE-IDENTIFIER" // Can't predecode aFUNCTION, can declare after use // Can't predecode aINTERFACE, can declare after use // Can't predecode aTASK, can declare after use // IEEE: integral_number %token yaINTNUM "INTEGER NUMBER" // IEEE: time_literal + time_unit %token yaTIMENUM "TIME NUMBER" // IEEE: string_literal %token yaSTRING "STRING" %token yaSTRING__IGNORE "STRING-ignored" // Used when expr:string not allowed %token yaTIMINGSPEC "TIMING SPEC ELEMENT" %token yaTABLELINE "TABLE LINE" %token yaSCHDR "`systemc_header BLOCK" %token yaSCINT "`systemc_ctor BLOCK" %token yaSCIMP "`systemc_dtor BLOCK" %token yaSCIMPH "`systemc_interface BLOCK" %token yaSCCTOR "`systemc_implementation BLOCK" %token yaSCDTOR "`systemc_imp_header BLOCK" %token yVLT_COVERAGE_OFF "coverage_off" %token yVLT_COVERAGE_ON "coverage_on" %token yVLT_LINT_OFF "lint_off" %token yVLT_LINT_ON "lint_on" %token yVLT_TRACING_OFF "tracing_off" %token yVLT_TRACING_ON "tracing_on" %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 yDEASSIGN "deassign" %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 yFOREACH "foreach" %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 yTYPE "type" %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_SFORMATF "$sformatf" %token yD_SIGNED "$signed" %token yD_SIZE "$size" %token yD_SQRT "$sqrt" %token yD_SSCANF "$sscanf" %token yD_STIME "$stime" %token yD_STOP "$stop" %token yD_SWRITE "$swrite" %token yD_SYSTEM "$system" %token yD_TESTPLUSARGS "$test$plusargs" %token yD_TIME "$time" %token yD_UNIT "$unit" %token yD_UNPACKED_DIMENSIONS "$unpacked_dimensions" %token yD_UNSIGNED "$unsigned" %token yD_VALUEPLUSARGS "$value$plusargs" %token yD_WARNING "$warning" %token yD_WRITE "$write" %token yVL_CLOCK "/*verilator sc_clock*/" %token yVL_CLOCKER "/*verilator clocker*/" %token yVL_NO_CLOCKER "/*verilator no_clocker*/" %token yVL_CLOCK_ENABLE "/*verilator clock_enable*/" %token yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/" %token yVL_FULL_CASE "/*verilator full_case*/" %token yVL_INLINE_MODULE "/*verilator inline_module*/" %token yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/" %token yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/" %token yVL_NO_INLINE_TASK "/*verilator no_inline_task*/" %token yVL_SC_BV "/*verilator sc_bv*/" %token yVL_SFORMAT "/*verilator sformat*/" %token yVL_PARALLEL_CASE "/*verilator parallel_case*/" %token yVL_PUBLIC "/*verilator public*/" %token yVL_PUBLIC_FLAT "/*verilator public_flat*/" %token yVL_PUBLIC_FLAT_RD "/*verilator public_flat_rd*/" %token yVL_PUBLIC_FLAT_RW "/*verilator public_flat_rw*/" %token yVL_PUBLIC_MODULE "/*verilator public_module*/" %token yP_TICK "'" %token yP_TICKBRA "'{" %token yP_OROR "||" %token yP_ANDAND "&&" %token yP_NOR "~|" %token yP_XNOR "^~" %token yP_NAND "~&" %token yP_EQUAL "==" %token yP_NOTEQUAL "!=" %token yP_CASEEQUAL "===" %token yP_CASENOTEQUAL "!==" %token yP_WILDEQUAL "==?" %token yP_WILDNOTEQUAL "!=?" %token yP_GTE ">=" %token yP_LTE "<=" %token yP_LTE__IGNORE "<=-ignored" // Used when expr:<= means assignment %token yP_SLEFT "<<" %token yP_SRIGHT ">>" %token yP_SSRIGHT ">>>" %token yP_POW "**" %token yP_PLUSCOLON "+:" %token yP_MINUSCOLON "-:" %token yP_MINUSGT "->" %token yP_MINUSGTGT "->>" %token yP_EQGT "=>" %token yP_ASTGT "*>" %token yP_ANDANDAND "&&&" %token yP_POUNDPOUND "##" %token yP_DOTSTAR ".*" %token yP_ATAT "@@" %token yP_COLONCOLON "::" %token yP_COLONEQ ":=" %token yP_COLONDIV ":/" %token yP_ORMINUSGT "|->" %token yP_OREQGT "|=>" %token yP_BRASTAR "[*" %token yP_BRAEQ "[=" %token yP_BRAMINUSGT "[->" %token yP_PLUSPLUS "++" %token yP_MINUSMINUS "--" %token yP_PLUSEQ "+=" %token yP_MINUSEQ "-=" %token yP_TIMESEQ "*=" %token yP_DIVEQ "/=" %token yP_MODEQ "%=" %token yP_ANDEQ "&=" %token yP_OREQ "|=" %token yP_XOREQ "^=" %token yP_SLEFTEQ "<<=" %token yP_SRIGHTEQ ">>=" %token yP_SSRIGHTEQ ">>>=" %token yP_LOGIFF // [* is not a operator, as "[ * ]" is legal // [= and [-> could be repitition operators, but to match [* we don't add them. // '( is not a operator, as "' (" is legal //******************** // PSL op precedence %right yP_MINUSGT yP_LOGIFF %right yP_ORMINUSGT yP_OREQGT // Verilog op precedence %right '?' ':' %left yP_OROR %left yP_ANDAND %left '|' yP_NOR %left '^' yP_XNOR %left '&' yP_NAND %left yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL %left '>' '<' yP_GTE yP_LTE yP_LTE__IGNORE yINSIDE %left yP_SLEFT yP_SRIGHT yP_SSRIGHT %left '+' '-' %left '*' '/' '%' %left yP_POW %left prUNARYARITH yP_MINUSMINUS yP_PLUSPLUS prREDUCTION prNEGATION %left '.' // Not in IEEE, but need to avoid conflicts; TICK should bind tightly just lower than COLONCOLON %left yP_TICK //%left '(' ')' '[' ']' yP_COLONCOLON '.' %nonassoc prLOWER_THAN_ELSE %nonassoc yELSE //BISONPRE_TYPES // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion %start source_text %% //********************************************************************** // Files source_text: // ==IEEE: source_text /* empty */ { } // // timeunits_declaration moved into description:package_item | descriptionList { } ; descriptionList: // IEEE: part of source_text description { } | descriptionList description { } ; description: // ==IEEE: description module_declaration { } // // udp_declaration moved into module_declaration | interface_declaration { } | program_declaration { } | package_declaration { } | package_item { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); } | bind_directive { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); } // unsupported // IEEE: config_declaration // // Verilator only | vltItem { } | error { } ; timeunits_declaration: // ==IEEE: timeunits_declaration yTIMEUNIT yaTIMENUM ';' { $$ = NULL; } | yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';' { $$ = NULL; } | yTIMEPRECISION yaTIMENUM ';' { $$ = NULL; } ; //********************************************************************** // Packages package_declaration: // ==IEEE: package_declaration packageFront package_itemListE yENDPACKAGE endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); SYMP->popScope($1); GRAMMARP->endLabel($4,$1,$4); } ; packageFront: yPACKAGE idAny ';' { $$ = new AstPackage($1,*$2); $$->inLibrary(true); // packages are always libraries; don't want to make them a "top" $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; package_itemListE: // IEEE: [{ package_item }] /* empty */ { $$ = NULL; } | package_itemList { $$ = $1; } ; package_itemList: // IEEE: { package_item } package_item { $$ = $1; } | package_itemList package_item { $$ = $1->addNextNull($2); } ; package_item: // ==IEEE: package_item package_or_generate_item_declaration { $$ = $1; } //UNSUP anonymous_program { $$ = $1; } | package_export_declaration { $$ = $1; } | timeunits_declaration { $$ = $1; } ; package_or_generate_item_declaration: // ==IEEE: package_or_generate_item_declaration net_declaration { $$ = $1; } | data_declaration { $$ = $1; } | task_declaration { $$ = $1; } | function_declaration { $$ = $1; } //UNSUP checker_declaration { $$ = $1; } | dpi_import_export { $$ = $1; } //UNSUP extern_constraint_declaration { $$ = $1; } //UNSUP class_declaration { $$ = $1; } // // class_constructor_declaration is part of function_declaration | local_parameter_declaration ';' { $$ = $1; } | parameter_declaration ';' { $$ = $1; } //UNSUP covergroup_declaration { $$ = $1; } //UNSUP overload_declaration { $$ = $1; } //UNSUP assertion_item_declaration { $$ = $1; } | ';' { $$ = NULL; } ; package_import_declarationList: package_import_declaration { $$ = $1; } | package_import_declarationList package_import_declaration { $$ = $1->addNextNull($2); } ; package_import_declaration: // ==IEEE: package_import_declaration yIMPORT package_import_itemList ';' { $$ = $2; } ; package_import_itemList: package_import_item { $$ = $1; } | package_import_itemList ',' package_import_item { $$ = $1->addNextNull($3); } ; package_import_item: // ==IEEE: package_import_item yaID__aPACKAGE yP_COLONCOLON package_import_itemObj { $$ = new AstPackageImport($1, $1->castPackage(), *$3); SYMP->importItem($1,*$3); } ; package_import_itemObj: // IEEE: part of package_import_item idAny { $$=$1; $$=$1; } | '*' { $$=$1; static string star="*"; $$=☆ } ; package_export_declaration: // IEEE: package_export_declaration yEXPORT '*' yP_COLONCOLON '*' ';' { $$ = new AstPackageExportStarStar($1); SYMP->exportStarStar($1); } | yEXPORT package_export_itemList ';' { $$ = $2; } ; package_export_itemList: package_export_item { $$ = $1; } | package_export_itemList ',' package_export_item { $$ = $1->addNextNull($3); } ; package_export_item: // ==IEEE: package_export_item yaID__aPACKAGE yP_COLONCOLON package_import_itemObj { $$ = new AstPackageExport($1, $1->castPackage(), *$3); SYMP->exportItem($1,*$3); } ; //********************************************************************** // Module headers module_declaration: // ==IEEE: module_declaration // // timeunits_declaration instead in module_item // // IEEE: module_nonansi_header + module_ansi_header modFront importsAndParametersE portsStarE ';' module_itemListE yENDMODULE endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); SYMP->popScope($1); GRAMMARP->endLabel($7,$1,$7); } | udpFront parameter_port_listE portsStarE ';' module_itemListE yENDPRIMITIVE endLabelE { $1->modTrace(false); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); GRAMMARP->m_tracingParse = true; SYMP->popScope($1); GRAMMARP->endLabel($7,$1,$7); } // //UNSUP yEXTERN modFront parameter_port_listE portsStarE ';' //UNSUP { UNSUP } ; modFront: // // General note: all *Front functions must call symPushNew before // // any formal arguments, as the arguments must land in the new scope. yMODULE lifetimeE idAny { $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine()); $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; importsAndParametersE: // IEEE: common part of module_declaration, interface_declaration, program_declaration // // { package_import_declaration } [ parameter_port_list ] parameter_port_listE { $$ = $1; } | package_import_declarationList parameter_port_listE { $$ = $1->addNextNull($2); } ; udpFront: yPRIMITIVE lifetimeE idAny { $$ = new AstPrimitive($1,*$3); $$->inLibrary(true); $$->modTrace(false); $$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE)); GRAMMARP->m_tracingParse = false; PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; parameter_value_assignmentE: // IEEE: [ parameter_value_assignment ] /* empty */ { $$ = NULL; } | '#' '(' cellparamList ')' { $$ = $3; } // // Parentheses are optional around a single parameter | '#' yaINTNUM { $$ = new AstPin($1,1,"",new AstConst($1,*$2)); } | '#' yaFLOATNUM { $$ = new AstPin($1,1,"",new AstConst($1,AstConst::Unsized32(),(int)(($2<0)?($2-0.5):($2+0.5)))); } | '#' idClassSel { $$ = new AstPin($1,1,"",$2); } // // Not needed in Verilator: // // Side effect of combining *_instantiations // // '#' delay_value { UNSUP } ; parameter_port_listE: // IEEE: parameter_port_list + empty == parameter_value_assignment /* empty */ { $$ = NULL; } | '#' '(' ')' { $$ = NULL; } // // IEEE: '#' '(' list_of_param_assignments { ',' parameter_port_declaration } ')' // // IEEE: '#' '(' parameter_port_declaration { ',' parameter_port_declaration } ')' // // Can't just do that as "," conflicts with between vars and between stmts, so // // split into pre-comma and post-comma parts | '#' '(' {VARRESET_LIST(GPARAM);} paramPortDeclOrArgList ')' { $$ = $4; VARRESET_NONLIST(UNKNOWN); } // // Note legal to start with "a=b" with no parameter statement ; paramPortDeclOrArgList: // IEEE: list_of_param_assignments + { parameter_port_declaration } paramPortDeclOrArg { $$ = $1; } | paramPortDeclOrArgList ',' paramPortDeclOrArg { $$ = $1->addNext($3); } ; paramPortDeclOrArg: // IEEE: param_assignment + parameter_port_declaration // // We combine the two as we can't tell which follows a comma parameter_port_declarationFrontE param_assignment { $$ = $2; } ; portsStarE: // IEEE: .* + list_of_ports + list_of_port_declarations + empty /* empty */ { $$ = NULL; } | '(' ')' { $$ = NULL; } // // .* expanded from module_declaration //UNSUP '(' yP_DOTSTAR ')' { UNSUP } | '(' {VARRESET_LIST(PORT);} list_of_ports ')' { $$ = $3; VARRESET_NONLIST(UNKNOWN); } ; list_of_ports: // IEEE: list_of_ports + list_of_port_declarations port { $$ = $1; } | list_of_ports ',' port { $$ = $1->addNextNull($3); } ; port: // ==IEEE: port // // Though not type for interfaces, we factor out the port direction and type // // so we can simply handle it in one place // // // IEEE: interface_port_header port_identifier { unpacked_dimension } // // Expanded interface_port_header // // We use instantCb here because the non-port form looks just like a module instantiation portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE { $$ = $3; VARDECL(AstVarType::IFACEREF); VARIO(UNKNOWN); VARDTYPE(new AstIfaceRefDType($2,"",*$2)); $$->addNextNull(VARDONEP($$,$4,$5)); } | portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE 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 or generic interfaces"); $$=NULL; } | portDirNetE yINTERFACE '.' idAny/*modport*/ portSig rangeListE sigAttrListE { $2->v3error("Unsupported: virtual or generic 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 VARDECL | net_type { } // net_type calls VARDECL ; port_declNetE: // IEEE: part of port_declaration, optional net type /* empty */ { } | net_type { } // net_type calls VARDECL ; portSig: id/*port*/ { $$ = new AstPort($1,PINNUMINC(),*$1); } | idSVKwd { $$ = new AstPort($1,PINNUMINC(),*$1); } ; //********************************************************************** // Interface headers interface_declaration: // IEEE: interface_declaration + interface_nonansi_header + interface_ansi_header: // // timeunits_delcarationE is instead in interface_item intFront parameter_port_listE portsStarE ';' interface_itemListE yENDINTERFACE endLabelE { if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); SYMP->popScope($1); } //UNSUP yEXTERN intFront parameter_port_listE portsStarE ';' { } ; intFront: yINTERFACE lifetimeE idAny/*new_interface*/ { $$ = new AstIface($1,*$3); $$->inLibrary(true); PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; interface_itemListE: /* empty */ { $$ = NULL; } | interface_itemList { $$ = $1; } ; interface_itemList: interface_item { $$ = $1; } | interface_itemList interface_item { $$ = $1->addNextNull($2); } ; interface_item: // IEEE: interface_item + non_port_interface_item port_declaration ';' { $$ = $1; } // // IEEE: non_port_interface_item // // IEEE: generate_region | interface_generate_region { $$ = $1; } | interface_or_generate_item { $$ = $1; } //UNSUP program_declaration { $$ = $1; } //UNSUP interface_declaration { $$ = $1; } | timeunits_declaration { $$ = $1; } // // See note in interface_or_generate item | module_common_item { $$ = $1; } ; interface_generate_region: // ==IEEE: generate_region yGENERATE interface_itemList yENDGENERATE { $$ = new AstGenerate($1, $2); } | yGENERATE yENDGENERATE { $$ = NULL; } ; interface_or_generate_item: // ==IEEE: interface_or_generate_item // // module_common_item in interface_item, as otherwise duplicated // // with module_or_generate_item's module_common_item modport_declaration { $$ = $1; } //UNSUP extern_tf_declaration { $$ = $1; } ; //********************************************************************** // Program headers program_declaration: // IEEE: program_declaration + program_nonansi_header + program_ansi_header: // // timeunits_delcarationE is instead in program_item pgmFront parameter_port_listE portsStarE ';' program_itemListE yENDPROGRAM endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); SYMP->popScope($1); GRAMMARP->endLabel($7,$1,$7); } //UNSUP yEXTERN pgmFront parameter_port_listE portsStarE ';' //UNSUP { PARSEP->symPopScope(VAstType::PROGRAM); } ; pgmFront: yPROGRAM lifetimeE idAny/*new_program*/ { $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine()); $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; program_itemListE: // ==IEEE: [{ program_item }] /* empty */ { $$ = NULL; } | program_itemList { $$ = $1; } ; program_itemList: // ==IEEE: { program_item } program_item { $$ = $1; } | program_itemList program_item { $$ = $1->addNextNull($2); } ; program_item: // ==IEEE: program_item port_declaration ';' { $$ = $1; } | non_port_program_item { $$ = $1; } ; non_port_program_item: // ==IEEE: non_port_program_item continuous_assign { $$ = $1; } | module_or_generate_item_declaration { $$ = $1; } | initial_construct { $$ = $1; } | final_construct { $$ = $1; } | concurrent_assertion_item { $$ = $1; } | timeunits_declaration { $$ = $1; } | program_generate_item { $$ = $1; } ; program_generate_item: // ==IEEE: program_generate_item loop_generate_construct { $$ = $1; } | conditional_generate_construct { $$ = $1; } | generate_region { $$ = $1; } | 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 // // Front must execute first so VARDTYPE is ready before list of vars 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 // // Front must execute first so VARDTYPE is ready before list of vars parameter_declarationFront list_of_param_assignments { $$ = $2; } ; local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment // // Front must execute first so VARDTYPE is ready before list of vars varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); } | varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); } | varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE(new AstParseTypeDType($2)); } ; parameter_declarationFront: // IEEE: parameter_declaration w/o assignment // // Front must execute first so VARDTYPE is ready before list of vars varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } | varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } | varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($2)); } ; parameter_port_declarationFrontE: // IEEE: parameter_port_declaration w/o assignment // // IEEE: parameter_declaration (minus assignment) // // IEEE: local_parameter_declaration (minus assignment) // // Front must execute first so VARDTYPE is ready before list of vars varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } | varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } | varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($2)); } | varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); } | varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); } | varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE(new AstParseTypeDType($2)); } | implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($1); } | data_type { /*VARRESET-in-varGParam*/ VARDTYPE($1); } | yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($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); } // // VAMS - somewhat hackish | yWREAL { VARDECL(WREAL); } ; varGParamReset: yPARAMETER { VARRESET_NONLIST(GPARAM); } ; varLParamReset: yLOCALPARAM { VARRESET_NONLIST(LPARAM); } ; port_direction: // ==IEEE: port_direction + tf_port_direction // // IEEE 19.8 just "input" FIRST forces type to wire - we'll ignore that here yINPUT { VARIO(INPUT); } | yOUTPUT { VARIO(OUTPUT); } | yINOUT { VARIO(INOUT); } //UNSUP yREF { VARIO(REF); } //UNSUP yCONST__REF yREF { VARIO(CONSTREF); } ; port_directionReset: // IEEE: port_direction that starts a port_declaraiton // // Used only for declarations outside the port list yINPUT { VARRESET_NONLIST(UNKNOWN); VARIO(INPUT); } | yOUTPUT { VARRESET_NONLIST(UNKNOWN); VARIO(OUTPUT); } | yINOUT { VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); } //UNSUP yREF { VARRESET_NONLIST(UNKNOWN); VARIO(REF); } //UNSUP yCONST__REF yREF { VARRESET_NONLIST(UNKNOWN); VARIO(CONSTREF); } ; port_declaration: // ==IEEE: port_declaration // // Used inside block; followed by ';' // // SIMILAR to tf_port_declaration // // // IEEE: inout_declaration // // IEEE: input_declaration // // IEEE: output_declaration // // IEEE: ref_declaration port_directionReset port_declNetE data_type { VARDTYPE($3); } list_of_variable_decl_assignments { $$ = $5; } | port_directionReset port_declNetE yVAR data_type { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; } | port_directionReset port_declNetE yVAR implicit_typeE { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; } | port_directionReset port_declNetE signingE rangeList { VARDTYPE(GRAMMARP->addRange(new AstBasicDType($4->fileline(), LOGIC_IMPLICIT, $3),$4,true)); } list_of_variable_decl_assignments { $$ = $6; } | port_directionReset port_declNetE signing { VARDTYPE(new AstBasicDType($3, LOGIC_IMPLICIT, $3)); } list_of_variable_decl_assignments { $$ = $5; } | port_directionReset port_declNetE /*implicit*/ { VARDTYPE(NULL);/*default_nettype*/} list_of_variable_decl_assignments { $$ = $4; } // // IEEE: interface_declaration // // Looks just like variable declaration unless has a period // // See etcInst ; tf_port_declaration: // ==IEEE: tf_port_declaration // // Used inside function; followed by ';' // // SIMILAR to port_declaration // port_directionReset data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } | port_directionReset implicit_typeE { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } | port_directionReset yVAR data_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } | port_directionReset yVAR implicit_typeE { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } ; integer_atom_type: // ==IEEE: integer_atom_type yBYTE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BYTE); } | ySHORTINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::SHORTINT); } | yINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INT); } | yLONGINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LONGINT); } | yINTEGER { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INTEGER); } | yTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::TIME); } ; integer_vector_type: // ==IEEE: integer_atom_type yBIT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BIT); } | yLOGIC { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); } | yREG { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); } // logic==reg ; non_integer_type: // ==IEEE: non_integer_type yREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); } | yREALTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); } //UNSUP ySHORTREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::FLOAT); } ; signingE: // IEEE: signing - plus empty /*empty*/ { $$ = signedst_NOSIGN; } | signing { $$ = $1; } ; signing: // ==IEEE: signing ySIGNED { $$ = $1; $$ = signedst_SIGNED; } | yUNSIGNED { $$ = $1; $$ = signedst_UNSIGNED; } ; //************************************************ // Data Types casting_type: // IEEE: casting_type simple_type { $$ = $1; } // // IEEE: constant_primary // // In expr:cast this is expanded to just "expr" // // // IEEE: signing //See where casting_type used //^^ ySIGNED { $$ = new AstSigned($1,$3); } //^^ yUNSIGNED { $$ = new AstUnsigned($1,$3); } //UNSUP ySTRING { $$ = $1; } //UNSUP yCONST__ETC/*then `*/ { $$ = $1; } ; simple_type: // ==IEEE: simple_type // // IEEE: integer_type integer_atom_type { $$ = $1; } | integer_vector_type { $$ = $1; } | non_integer_type { $$ = $1; } // // IEEE: ps_type_identifier // // IEEE: ps_parameter_identifier (presumably a PARAMETER TYPE) | ps_type { $$ = $1; } // // { generate_block_identifer ... } '.' // // Need to determine if generate_block_identifier can be lex-detected ; data_type: // ==IEEE: data_type // // This expansion also replicated elsewhere, IE data_type__AndID data_typeNoRef { $$ = $1; } // // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension } | ps_type packed_dimensionListE { $$ = GRAMMARP->createArray($1,$2,true); } //UNSUP class_scope_type packed_dimensionListE { UNSUP } // // IEEE: class_type //UNSUP class_typeWithoutId { $$ = $1; } // // IEEE: ps_covergroup_identifier // // we put covergroups under ps_type, so can ignore this ; data_typeBasic: // IEEE: part of data_type integer_vector_type signingE rangeListE { $1->setSignedState($2); $$ = GRAMMARP->addRange($1,$3,true); } | integer_atom_type signingE { $1->setSignedState($2); $$ = $1; } | non_integer_type { $$ = $1; } ; data_typeNoRef: // ==IEEE: data_type, excluding class_type etc references data_typeBasic { $$ = $1; } | struct_unionDecl packed_dimensionListE { $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->s_modTypeImpNum++), SYMP,VFlagChildDType(),$1),$2,true); } | enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->s_modTypeImpNum++), SYMP,VFlagChildDType(),$1); } | ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); } | yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); } //UNSUP yEVENT { UNSUP } //UNSUP yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ { UNSUP } //UNSUP yVIRTUAL__anyID id/*interface*/ { UNSUP } //UNSUP type_reference { UNSUP } // // IEEE: class_scope: see data_type above // // IEEE: class_type: see data_type above // // IEEE: ps_covergroup: see data_type above ; data_type_or_void: // ==IEEE: data_type_or_void data_type { $$ = $1; } //UNSUP yVOID { UNSUP } // No yTAGGED structures ; var_data_type: // ==IEEE: var_data_type data_type { $$ = $1; } | yVAR data_type { $$ = $2; } | yVAR implicit_typeE { $$ = $2; } ; struct_unionDecl: // IEEE: part of data_type // // packedSigningE is NOP for unpacked ySTRUCT packedSigningE '{' { $$ = new AstStructDType($1, $2); SYMP->pushNew($$); } /*cont*/ struct_union_memberList '}' { $$=$4; $$->addMembersp($5); SYMP->popScope($$); } | yUNION taggedE packedSigningE '{' { $$ = new AstUnionDType($1, $3); SYMP->pushNew($$); } /*cont*/ struct_union_memberList '}' { $$=$5; $$->addMembersp($6); SYMP->popScope($$); } ; struct_union_memberList: // IEEE: { struct_union_member } struct_union_member { $$ = $1; } | struct_union_memberList struct_union_member { $$ = $1->addNextNull($2); } ; struct_union_member: // ==IEEE: struct_union_member random_qualifierE data_type_or_void { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member. /*cont*/ list_of_member_decl_assignments ';' { $$ = $4; GRAMMARP->m_memDTypep = NULL; } ; list_of_member_decl_assignments: // Derived from IEEE: list_of_variable_decl_assignments member_decl_assignment { $$ = $1; } | list_of_member_decl_assignments ',' member_decl_assignment { $$ = $1->addNextNull($3); } ; member_decl_assignment: // Derived from IEEE: variable_decl_assignment // // At present we allow only packed structures/unions. So this is different from variable_decl_assignment id variable_dimensionListE { if ($2) $2->v3error("Unsupported: Unpacked array in packed struct/union"); $$ = new AstMemberDType($1, *$1, VFlagChildDType(), GRAMMARP->m_memDTypep->cloneTree(true)); PARSEP->tagNodep($$); } | id variable_dimensionListE '=' variable_declExpr { $4->v3error("Unsupported: Initial values in struct/union members."); } | idSVKwd { $$ = NULL; } // // // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]" // // Matches above with variable_dimensionE = "[]" // // IEEE: "class_variable_identifier [ '=' class_new ]" // // variable_dimensionE must be empty // // Pushed into variable_declExpr:dynamic_array_new // // // IEEE: "[ covergroup_variable_identifier ] '=' class_new // // Pushed into variable_declExpr:class_new //UNSUP '=' class_new { UNSUP } ; list_of_variable_decl_assignments: // ==IEEE: list_of_variable_decl_assignments variable_decl_assignment { $$ = $1; } | list_of_variable_decl_assignments ',' variable_decl_assignment { $$ = $1->addNextNull($3); } ; variable_decl_assignment: // ==IEEE: variable_decl_assignment id variable_dimensionListE sigAttrListE { $$ = VARDONEA($1,*$1,$2,$3); } | id variable_dimensionListE sigAttrListE '=' variable_declExpr { $$ = VARDONEA($1,*$1,$2,$3); $$->valuep($5); } | idSVKwd { $$ = NULL; } // // // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]" // // Matches above with variable_dimensionE = "[]" // // IEEE: "class_variable_identifier [ '=' class_new ]" // // variable_dimensionE must be empty // // Pushed into variable_declExpr:dynamic_array_new // // // IEEE: "[ covergroup_variable_identifier ] '=' class_new // // Pushed into variable_declExpr:class_new //UNSUP '=' class_new { UNSUP } ; list_of_tf_variable_identifiers: // ==IEEE: list_of_tf_variable_identifiers tf_variable_identifier { $$ = $1; } | list_of_tf_variable_identifiers ',' tf_variable_identifier { $$ = $1->addNext($3); } ; tf_variable_identifier: // IEEE: part of list_of_tf_variable_identifiers id variable_dimensionListE sigAttrListE { $$ = VARDONEA($1,*$1, $2, $3); } | id variable_dimensionListE sigAttrListE '=' expr { $$ = VARDONEA($1,*$1, $2, $3); $$->addNext(new AstAssign($4, new AstVarRef($4, *$1, true), $5)); } ; variable_declExpr: // IEEE: part of variable_decl_assignment - rhs of expr expr { $$ = $1; } //UNSUP dynamic_array_new { $$ = $1; } //UNSUP class_new { $$ = $1; } ; variable_dimensionListE: // IEEE: variable_dimension + empty /*empty*/ { $$ = NULL; } | variable_dimensionList { $$ = $1; } ; variable_dimensionList: // IEEE: variable_dimension + empty variable_dimension { $$ = $1; } | variable_dimensionList variable_dimension { $$ = $1->addNext($2)->castRange(); } ; variable_dimension: // ==IEEE: variable_dimension // // IEEE: unsized_dimension //UNSUP '[' ']' { UNSUP } // // IEEE: unpacked_dimension anyrange { $$ = $1; } | '[' constExpr ']' { $$ = new AstRange($1, new AstConst($1, 0), new AstSub($1, $2, new AstConst($1, 1))); } // // IEEE: associative_dimension //UNSUP '[' data_type ']' { UNSUP } //UNSUP yP_BRASTAR ']' { UNSUP } //UNSUP '[' '*' ']' { UNSUP } // // IEEE: queue_dimension // // '[' '$' ']' -- $ is part of expr // // '[' '$' ':' expr ']' -- anyrange:expr:$ ; random_qualifierE: // IEEE: random_qualifier + empty /*empty*/ { } | random_qualifier { } ; random_qualifier: // ==IEEE: random_qualifier yRAND { } // Ignored until we support randomize() | yRANDC { } // Ignored until we support randomize() ; taggedE: /*empty*/ { } //UNSUP yTAGGED { UNSUP } ; packedSigningE: // // AstNumeric::NOSIGN overloaded to indicate not packed /*empty*/ { $$ = signedst_NOSIGN; } | yPACKED signingE { $$ = $2; if ($$ == signedst_NOSIGN) $$ = signedst_UNSIGNED; } ; //************************************************ // enum // IEEE: part of data_type enumDecl: yENUM enum_base_typeE '{' enum_nameList '}' { $$ = new AstEnumDType($1,VFlagChildDType(),$2,$4); } ; enum_base_typeE: // IEEE: enum_base_type /* empty */ { $$ = new AstBasicDType(CRELINE(),AstBasicDTypeKwd::INT); } // // Not in spec, but obviously "enum [1:0]" should work // // implicit_type expanded, without empty // // Note enum base types are always packed data types | signingE rangeList { $$ = GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1),$2,true); } | signing { $$ = new AstBasicDType($1, LOGIC_IMPLICIT, $1); } // | integer_atom_type signingE { $1->setSignedState($2); $$ = $1; } | integer_vector_type signingE rangeListE { $1->setSignedState($2); $$ = GRAMMARP->addRange($1,$3,true); } // // below can be idAny or yaID__aTYPE // // IEEE requires a type, though no shift conflict if idAny | idAny rangeListE { $$ = GRAMMARP->createArray(new AstRefDType($1, *$1), $2, true); } ; enum_nameList: enum_name_declaration { $$ = $1; } | enum_nameList ',' enum_name_declaration { $$ = $1->addNextNull($3); } ; enum_name_declaration: // ==IEEE: enum_name_declaration idAny/*enum_identifier*/ enumNameRangeE enumNameStartE { $$ = new AstEnumItem($1, *$1, $2, $3); } ; enumNameRangeE: // IEEE: second part of enum_name_declaration /* empty */ { $$ = NULL; } | '[' intnumAsConst ']' { $$ = new AstRange($1, new AstConst($1, 0), new AstConst($1, $2->toSInt()-1)); } | '[' intnumAsConst ':' intnumAsConst ']' { $$ = new AstRange($1,$2,$4); } ; enumNameStartE: // IEEE: third part of enum_name_declaration /* empty */ { $$ = NULL; } | '=' constExpr { $$ = $2; } ; intnumAsConst: yaINTNUM { $$ = new AstConst($1,*$1); } ; //************************************************ // Typedef data_declaration: // ==IEEE: data_declaration // // VARRESET can't be called here - conflicts data_declarationVar { $$ = $1; } | type_declaration { $$ = $1; } | package_import_declaration { $$ = $1; } // // IEEE: virtual_interface_declaration // // "yVIRTUAL yID yID" looks just like a data_declaration // // Therefore the virtual_interface_declaration term isn't used ; data_declarationVar: // IEEE: part of data_declaration // // The first declaration has complications between assuming what's the type vs ID declaring data_declarationVarFront list_of_variable_decl_assignments ';' { $$ = $2; } ; data_declarationVarFront: // IEEE: part of data_declaration // // Expanded: "constE yVAR lifetimeE data_type" // // implicit_type expanded into /*empty*/ or "signingE rangeList" /**/ yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE($3); } | /**/ yVAR lifetimeE { VARRESET_NONLIST(VAR); VARDTYPE(new AstBasicDType($1, LOGIC_IMPLICIT)); } | /**/ yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDTYPE(GRAMMARP->addRange(new AstBasicDType($1, LOGIC_IMPLICIT, $3), $4,true)); } // // // implicit_type expanded into /*empty*/ or "signingE rangeList" | yCONST__ETC yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($1, VFlagChildDType(), $4)); } | yCONST__ETC yVAR lifetimeE { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($1, VFlagChildDType(), new AstBasicDType($2, LOGIC_IMPLICIT))); } | yCONST__ETC yVAR lifetimeE signingE rangeList { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($1, VFlagChildDType(), GRAMMARP->addRange(new AstBasicDType($2, LOGIC_IMPLICIT, $4), $5,true))); } // // // Expanded: "constE lifetimeE data_type" | /**/ data_type { VARRESET_NONLIST(VAR); VARDTYPE($1); } | /**/ lifetime data_type { VARRESET_NONLIST(VAR); VARDTYPE($2); } | yCONST__ETC lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($1, VFlagChildDType(), $3)); } // // = class_new is in variable_decl_assignment ; implicit_typeE: // IEEE: part of *data_type_or_implicit // // Also expanded in data_declaration /* empty */ { $$ = NULL; } | signingE rangeList { $$ = GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1),$2,true); } | signing { $$ = new AstBasicDType($1, LOGIC_IMPLICIT, $1); } ; type_declaration: // ==IEEE: type_declaration // // Use idAny, as we can redeclare a typedef on an existing typedef yTYPEDEF data_type idAny variable_dimensionListE dtypeAttrListE ';' /**/ { $$ = new AstTypedef($1, *$3, $5, VFlagChildDType(), GRAMMARP->createArray($2,$4,false)); SYMP->reinsert($$); PARSEP->tagNodep($$); } //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($$); PARSEP->tagNodep($$); } | yTYPEDEF yENUM idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($1, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); } | yTYPEDEF ySTRUCT idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($1, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); } | yTYPEDEF yUNION idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($1, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); } //UNSUP yTYPEDEF yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($1, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); } ; dtypeAttrListE: /* empty */ { $$ = NULL; } | dtypeAttrList { $$ = $1; } ; dtypeAttrList: dtypeAttr { $$ = $1; } | dtypeAttrList dtypeAttr { $$ = $1->addNextNull($2); } ; dtypeAttr: yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::DT_PUBLIC); } ; //************************************************ // Module Items module_itemListE: // IEEE: Part of module_declaration /* empty */ { $$ = NULL; } | module_itemList { $$ = $1; } ; module_itemList: // IEEE: Part of module_declaration module_item { $$ = $1; } | module_itemList module_item { $$ = $1->addNextNull($2); } ; module_item: // ==IEEE: module_item port_declaration ';' { $$ = $1; } | non_port_module_item { $$ = $1; } ; non_port_module_item: // ==IEEE: non_port_module_item generate_region { $$ = $1; } | module_or_generate_item { $$ = $1; } | specify_block { $$ = $1; } | specparam_declaration { $$ = $1; } //UNSUP program_declaration { $$ = $1; } //UNSUP module_declaration { $$ = $1; } //UNSUP interface_declaration { $$ = $1; } | timeunits_declaration { $$ = $1; } // // Verilator specific | yaSCHDR { $$ = new AstScHdr($1,*$1); } | yaSCINT { $$ = new AstScInt($1,*$1); } | yaSCIMP { $$ = new AstScImp($1,*$1); } | yaSCIMPH { $$ = new AstScImpHdr($1,*$1); } | yaSCCTOR { $$ = new AstScCtor($1,*$1); } | yaSCDTOR { $$ = new AstScDtor($1,*$1); } | yVL_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::INLINE_MODULE); } | yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_MODULE); } | yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); v3Global.dpi(true); } ; module_or_generate_item: // ==IEEE: module_or_generate_item // // IEEE: parameter_override yDEFPARAM list_of_defparam_assignments ';' { $$ = $2; } // // IEEE: gate_instantiation + udp_instantiation + module_instantiation // // not here, see etcInst in module_common_item // // We joined udp & module definitions, so this goes here | combinational_body { $$ = $1; } // // This module_common_item shared with interface_or_generate_item:module_common_item | module_common_item { $$ = $1; } ; module_common_item: // ==IEEE: module_common_item module_or_generate_item_declaration { $$ = $1; } // // IEEE: interface_instantiation // // + IEEE: program_instantiation // // + module_instantiation from module_or_generate_item | etcInst { $$ = $1; } | concurrent_assertion_item { $$ = $1; } | bind_directive { $$ = $1; } | continuous_assign { $$ = $1; } // // IEEE: net_alias //UNSUP yALIAS variable_lvalue aliasEqList ';' { UNSUP } | initial_construct { $$ = $1; } | final_construct { $$ = $1; } // // IEEE: always_construct // // Verilator only - event_control attached to always | yALWAYS event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS, $2,$3); } | yALWAYS_FF event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_FF, $2,$3); } | yALWAYS_COMB event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_COMB, $2,$3); } | yALWAYS_LATCH event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_LATCH, $2,$3); } | loop_generate_construct { $$ = $1; } | conditional_generate_construct { $$ = $1; } | elaboration_system_task { $$ = $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(); VL_DANGLING(lowerBegp); } ; genvar_initialization: // ==IEEE: genvar_initalization varRefBase '=' expr { $$ = new AstAssign($2,$1,$3); } | yGENVAR genvar_identifierDecl '=' constExpr { $$ = $2; $2->addNext(new AstAssign($3,new AstVarRef($3,$2,true), $4)); } ; genvar_iteration: // ==IEEE: genvar_iteration varRefBase '=' expr { $$ = new AstAssign($2,$1,$3); } | varRefBase yP_PLUSEQ expr { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),$3)); } | varRefBase yP_MINUSEQ expr { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),$3)); } | varRefBase yP_TIMESEQ expr { $$ = new AstAssign($2,$1,new AstMul ($2,$1->cloneTree(true),$3)); } | varRefBase yP_DIVEQ expr { $$ = new AstAssign($2,$1,new AstDiv ($2,$1->cloneTree(true),$3)); } | varRefBase yP_MODEQ expr { $$ = new AstAssign($2,$1,new AstModDiv ($2,$1->cloneTree(true),$3)); } | varRefBase yP_ANDEQ expr { $$ = new AstAssign($2,$1,new AstAnd ($2,$1->cloneTree(true),$3)); } | varRefBase yP_OREQ expr { $$ = new AstAssign($2,$1,new AstOr ($2,$1->cloneTree(true),$3)); } | varRefBase yP_XOREQ expr { $$ = new AstAssign($2,$1,new AstXor ($2,$1->cloneTree(true),$3)); } | varRefBase yP_SLEFTEQ expr { $$ = new AstAssign($2,$1,new AstShiftL ($2,$1->cloneTree(true),$3)); } | varRefBase yP_SRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftR ($2,$1->cloneTree(true),$3)); } | varRefBase yP_SSRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftRS($2,$1->cloneTree(true),$3)); } // // inc_or_dec_operator // When support ++ as a real AST type, maybe AstWhile::precondsp() becomes generic AstMathStmt? | yP_PLUSPLUS varRefBase { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } | yP_MINUSMINUS varRefBase { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } | varRefBase yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } | varRefBase yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } ; case_generate_itemListE: // IEEE: [{ case_generate_itemList }] /* empty */ { $$ = NULL; } | case_generate_itemList { $$ = $1; } ; case_generate_itemList: // IEEE: { case_generate_itemList } ~c~case_generate_item { $$=$1; } | ~c~case_generate_itemList ~c~case_generate_item { $$=$1; $1->addNext($2); } ; case_generate_item: // ==IEEE: case_generate_item caseCondList ':' generate_block_or_null { $$ = new AstCaseItem($2,$1,$3); } | yDEFAULT ':' generate_block_or_null { $$ = new AstCaseItem($2,NULL,$3); } | yDEFAULT generate_block_or_null { $$ = new AstCaseItem($1,NULL,$2); } ; //************************************************ // Assignments and register declarations assignList: assignOne { $$ = $1; } | assignList ',' assignOne { $$ = $1->addNext($3); } ; assignOne: variable_lvalue '=' expr { $$ = new AstAssignW($2,$1,$3); } ; delayE: /* empty */ { } | delay_control { $1->v3warn(ASSIGNDLY,"Unsupported: Ignoring delay on this assignment/primitive."); } /* ignored */ ; delay_control: //== IEEE: delay_control '#' delay_value { $$ = $1; } /* ignored */ | '#' '(' minTypMax ')' { $$ = $1; } /* ignored */ | '#' '(' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */ | '#' '(' minTypMax ',' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */ ; delay_value: // ==IEEE:delay_value // // IEEE: ps_identifier ps_id_etc { } | yaINTNUM { } | yaFLOATNUM { } | yaTIMENUM { } ; delayExpr: expr { DEL($1); } // // Verilator doesn't support yaTIMENUM, so not in expr | yaTIMENUM { } ; minTypMax: // IEEE: mintypmax_expression and constant_mintypmax_expression delayExpr { } | delayExpr ':' delayExpr ':' delayExpr { } ; netSigList: // IEEE: list_of_port_identifiers netSig { $$ = $1; } | netSigList ',' netSig { $$ = $1; $1->addNext($3); } ; netSig: // IEEE: net_decl_assignment - one element from list_of_port_identifiers netId sigAttrListE { $$ = VARDONEA($1,*$1, NULL, $2); } | netId sigAttrListE '=' expr { $$ = VARDONEA($1,*$1, NULL, $2); $$->addNext(new AstAssignW($3,new AstVarRef($3,$$->name(),true),$4)); } | netId variable_dimensionList sigAttrListE { $$ = VARDONEA($1,*$1, $2, $3); } ; netId: id/*new-net*/ { $$ = $1; $$=$1; } | idSVKwd { $$ = $1; $$=$1; } ; sigAttrListE: /* empty */ { $$ = NULL; } | sigAttrList { $$ = $1; } ; sigAttrList: sigAttr { $$ = $1; } | sigAttrList sigAttr { $$ = $1->addNextNull($2); } ; sigAttr: yVL_CLOCK { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK); } | yVL_CLOCKER { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCKER); } | yVL_NO_CLOCKER { $$ = new AstAttrOf($1,AstAttrType::VAR_NO_CLOCKER); } | yVL_CLOCK_ENABLE { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK_ENABLE); } | yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC); v3Global.dpi(true); } | yVL_PUBLIC_FLAT { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT); v3Global.dpi(true); } | yVL_PUBLIC_FLAT_RD { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RD); v3Global.dpi(true); } | yVL_PUBLIC_FLAT_RW { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); v3Global.dpi(true); } | yVL_PUBLIC_FLAT_RW attr_event_control { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); v3Global.dpi(true); $$ = $$->addNext(new AstAlwaysPublic($1,$2,NULL)); } | yVL_ISOLATE_ASSIGNMENTS { $$ = new AstAttrOf($1,AstAttrType::VAR_ISOLATE_ASSIGNMENTS); } | yVL_SC_BV { $$ = new AstAttrOf($1,AstAttrType::VAR_SC_BV); } | yVL_SFORMAT { $$ = new AstAttrOf($1,AstAttrType::VAR_SFORMAT); } ; rangeListE: // IEEE: [{packed_dimension}] /* empty */ { $$ = NULL; } | rangeList { $$ = $1; } ; rangeList: // IEEE: {packed_dimension} anyrange { $$ = $1; } | rangeList anyrange { $$ = $1; $1->addNext($2); } ; // IEEE: select // Merged into more general idArray anyrange: '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } ; packed_dimensionListE: // IEEE: [{ packed_dimension }] /* empty */ { $$ = NULL; } | packed_dimensionList { $$ = $1; } ; packed_dimensionList: // IEEE: { packed_dimension } packed_dimension { $$ = $1; } | packed_dimensionList packed_dimension { $$ = $1->addNext($2)->castRange(); } ; packed_dimension: // ==IEEE: packed_dimension anyrange { $$ = $1; } //UNSUP '[' ']' { UNSUP } ; //************************************************ // Parameters param_assignment: // ==IEEE: param_assignment // // IEEE: constant_param_expression // // constant_param_expression: '$' is in expr // // note exptOrDataType being a data_type is only for yPARAMETER yTYPE id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' exprOrDataType /**/ { $$ = VARDONEA($1,*$1, $2, $3); $$->valuep($5); } | id/*new-parameter*/ variable_dimensionListE sigAttrListE /**/ { $$ = VARDONEA($1,*$1, $2, $3); } ; list_of_param_assignments: // ==IEEE: list_of_param_assignments param_assignment { $$ = $1; } | list_of_param_assignments ',' param_assignment { $$ = $1; $1->addNext($3); } ; list_of_defparam_assignments: //== IEEE: list_of_defparam_assignments defparam_assignment { $$ = $1; } | list_of_defparam_assignments ',' defparam_assignment { $$ = $1->addNext($3); } ; defparam_assignment: // ==IEEE: defparam_assignment id '.' id '=' expr { $$ = new AstDefParam($4,*$1,*$3,$5); } //UNSUP More general dotted identifiers ; //************************************************ // Instances // We don't know identifier types, so this matches all module,udp,etc instantiation // module_id [#(params)] name (pins) [, name ...] ; // module_instantiation // gate (strong0) [#(delay)] [name] (pins) [, (pins)...] ; // gate_instantiation // program_id [#(params}] name ; // program_instantiation // interface_id [#(params}] name ; // interface_instantiation // checker_id name (pins) ; // checker_instantiation etcInst: // IEEE: module_instantiation + gate_instantiation + udp_instantiation instDecl { $$ = $1; } | gateDecl { $$ = $1; } ; instDecl: id parameter_value_assignmentE {INSTPREP(*$1,$2);} instnameList ';' { $$ = $4; GRAMMARP->m_impliedDecl=false; if (GRAMMARP->m_instParamp) { GRAMMARP->m_instParamp->deleteTree(); GRAMMARP->m_instParamp = NULL; } } // // IEEE: interface_identifier' .' modport_identifier list_of_interface_identifiers | id/*interface*/ '.' id/*modport*/ { VARRESET_NONLIST(AstVarType::IFACEREF); VARDTYPE(new AstIfaceRefDType($1,"",*$1,*$3)); } mpInstnameList ';' { $$ = VARDONEP($5,NULL,NULL); } //UNSUP: strengthSpecE for udp_instantiations ; mpInstnameList: // Similar to instnameList, but for modport instantiations which have no parenthesis mpInstnameParen { $$ = $1; } | mpInstnameList ',' mpInstnameParen { $$ = $1->addNext($3); } ; mpInstnameParen: // Similar to instnameParen, but for modport instantiations which have no parenthesis id instRangeE sigAttrListE { $$ = VARDONEA($1,*$1,$2,$3); } ; instnameList: instnameParen { $$ = $1; } | instnameList ',' instnameParen { $$ = $1->addNext($3); } ; instnameParen: // // Must clone m_instParamp as may be comma'ed list of instances id instRangeE '(' cellpinList ')' { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp->cloneTree(true),$2); $$->trace(GRAMMARP->allTracingOn($1)); } | id instRangeE { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp->cloneTree(true),$2); $$->trace(GRAMMARP->allTracingOn($1)); } //UNSUP instRangeE '(' cellpinList ')' { UNSUP } // UDP // // Adding above and switching to the Verilog-Perl syntax // // causes a shift conflict due to use of idClassSel inside exprScope. // // It also breaks allowing "id foo;" instantiation syntax. ; instRangeE: /* empty */ { $$ = NULL; } | '[' constExpr ']' { $$ = new AstRange($1, new AstConst($1, 0), new AstSub($1, $2, new AstConst($1, 1))); } | '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } ; cellparamList: {VARRESET_LIST(UNKNOWN);} cellparamItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); } ; cellpinList: {VARRESET_LIST(UNKNOWN);} cellpinItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); } ; cellparamItList: // IEEE: list_of_parameter_assignmente cellparamItemE { $$ = $1; } | cellparamItList ',' cellparamItemE { $$ = $1->addNextNull($3)->castPin(); } ; cellpinItList: // IEEE: list_of_port_connections cellpinItemE { $$ = $1; } | cellpinItList ',' cellpinItemE { $$ = $1->addNextNull($3)->castPin(); } ; cellparamItemE: // IEEE: 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 AstParseRef($1,AstParseRefExp::PX_TEXT,*$2,NULL,NULL)); $$->svImplicit(true);} | '.' idAny { $$ = new AstPin($1,PINNUMINC(),*$2,new AstParseRef($1,AstParseRefExp::PX_TEXT,*$2,NULL,NULL)); $$->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 | '.' idAny '(' data_type ')' { $$ = new AstPin($1,PINNUMINC(),*$2,$4); } // // For parameters | data_type { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); } // | expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); } //UNSUP expr ':' expr { } //UNSUP expr ':' expr ':' expr { } ; cellpinItemE: // IEEE: named_port_connection + 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 AstParseRef($1,AstParseRefExp::PX_TEXT,*$2,NULL,NULL)); $$->svImplicit(true);} | '.' idAny { $$ = new AstPin($1,PINNUMINC(),*$2,new AstParseRef($1,AstParseRefExp::PX_TEXT,*$2,NULL,NULL)); $$->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 ')' { } // | 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; } | '(' senitem ')' { $$ = $2; } //UNSUP expr { UNSUP } | '{' event_expression '}' { $$ = $2; } | senitem yP_ANDAND senitem { $$ = new AstSenItem($2, AstSenItem::Illegal()); } //UNSUP expr yIFF expr { UNSUP } // Since expr is unsupported we allow and ignore constants (removed in V3Const) | 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 | yDEASSIGN variable_lvalue ';' { if (!v3Global.opt.bboxUnsup()) $1->v3error("Unsupported: Verilog 1995 deassign"); $$ = NULL; } //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 { AstIf* newp = new AstIf($2,$4,$6,NULL); $$ = newp; if ($1 == uniq_UNIQUE) newp->uniquePragma(true); if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true); if ($1 == uniq_PRIORITY) newp->priorityPragma(true); } | unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock { AstIf* newp = new AstIf($2,$4,$6,$8); $$ = newp; if ($1 == uniq_UNIQUE) newp->uniquePragma(true); if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true); if ($1 == uniq_PRIORITY) newp->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 | yFOREACH '(' idClassForeach '[' loop_variables ']' ')' stmtBlock { $$ = new AstForeach($1,$3,$5,$8); } // // // 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; } ; loop_variables: // IEEE: loop_variables varRefBase { $$ = $1; } | loop_variables ',' varRefBase { $$ = $1;$1->addNext($3); } ; //************************************************ // 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 '(' expr ')' { $$ = 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 '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,NULL,$3); } | yD_WRITE parenE { $$ = NULL; } // NOP | yD_WRITE '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL,$3); } | yD_FDISPLAY '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,$3,NULL); } | yD_FDISPLAY '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,$3,$5); } | yD_FWRITE '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3,$5); } | 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 '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); } | yD_BITS '(' exprOrDataType ',' 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 '(' exprOrDataType ')' { $$ = 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 '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,NULL); } | yD_HIGH '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,$5); } | yD_INCREMENT '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,NULL); } | yD_INCREMENT '(' exprOrDataType ',' 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 '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LEFT,$3,NULL); } | yD_LEFT '(' exprOrDataType ',' 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 '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LOW,$3,NULL); } | yD_LOW '(' exprOrDataType ',' 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 '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_RIGHT,$3,NULL); } | yD_RIGHT '(' exprOrDataType ',' 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); } | yD_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); } | yD_SIZE '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_SIZE,$3,NULL); } | yD_SIZE '(' exprOrDataType ',' 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 '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_UNPK_DIMENSIONS,$3); } | yD_UNSIGNED '(' expr ')' { $$ = new AstUnsigned($1,$3); } | yD_VALUEPLUSARGS '(' expr ',' expr ')' { $$ = new AstValuePlusArgs($1,$3,$5); } ; elaboration_system_task: // IEEE: elaboration_system_task (1800-2009) // // TODO: These currently just make initial statements, should instead give runtime error elaboration_system_task_guts ';' { $$ = new AstInitial($1, $1); } ; elaboration_system_task_guts: // IEEE: part of elaboration_system_task (1800-2009) // // $fatal first argument is exit number, must be constant 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); } ; exprOrDataType: // expr | data_type: combined to prevent conflicts expr { $$ = $1; } // // data_type includes id that overlaps expr, so special flavor | data_type { $$ = $1; } // // not in spec, but needed for $past(sig,1,,@(posedge clk)) //UNSUP event_control { } ; 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 array_methodNoRoot: yOR { $$ = new AstFuncRef($1, "or", NULL); } | yAND { $$ = new AstFuncRef($1, "and", NULL); } | yXOR { $$ = new AstFuncRef($1, "xor", NULL); } ; dpi_import_export: // ==IEEE: dpi_import_export yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE function_prototype ';' { $$ = $5; if (*$4!="") $5->cname(*$4); $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE); $5->dpiImport(true); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); if ($$->prettyName()[0]=='$') SYMP->reinsert($$,NULL,$$->prettyName()); // For $SysTF overriding SYMP->reinsert($$); } | yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE task_prototype ';' { $$ = $5; if (*$4!="") $5->cname(*$4); $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE); $5->dpiImport(true); $5->dpiTask(true); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); if ($$->prettyName()[0]=='$') SYMP->reinsert($$,NULL,$$->prettyName()); // For $SysTF overriding SYMP->reinsert($$); } | yEXPORT yaSTRING dpi_importLabelE yFUNCTION idAny ';' { $$ = new AstDpiExport($1,*$5,*$3); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); } | yEXPORT yaSTRING dpi_importLabelE yTASK idAny ';' { $$ = new AstDpiExport($1,*$5,*$3); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); } ; dpi_importLabelE: // IEEE: part of dpi_import_export /* empty */ { static string s = ""; $$ = &s; } | idAny/*c_identifier*/ '=' { $$ = $1; $$=$1; } ; dpi_tf_import_propertyE: // IEEE: [ dpi_function_import_property + dpi_task_import_property ] /* empty */ { $$ = iprop_NONE; } | yCONTEXT { $$ = iprop_CONTEXT; } | yPURE { $$ = iprop_PURE; } ; //************************************************ // Expressions // // ~l~ means this is the (l)eft hand side of any operator // it will get replaced by "", "f" or "s"equence // ~r~ means this is a (r)ight hand later expansion in the same statement, // not under parenthesis for <= disambiguation // it will get replaced by "", or "f" // ~p~ means this is a (p)arenthetized expression // it will get replaced by "", or "s"equence constExpr: expr { $$ = $1; } ; expr: // IEEE: part of expression/constant_expression/primary // *SEE BELOW* // IEEE: primary/constant_primary // // // IEEE: unary_operator primary '+' ~r~expr %prec prUNARYARITH { $$ = $2; } | '-' ~r~expr %prec prUNARYARITH { $$ = new AstNegate ($1,$2); } | '!' ~r~expr %prec prNEGATION { $$ = new AstLogNot ($1,$2); } | '&' ~r~expr %prec prREDUCTION { $$ = new AstRedAnd ($1,$2); } | '~' ~r~expr %prec prNEGATION { $$ = new AstNot ($1,$2); } | '|' ~r~expr %prec prREDUCTION { $$ = new AstRedOr ($1,$2); } | '^' ~r~expr %prec prREDUCTION { $$ = new AstRedXor ($1,$2); } | yP_NAND ~r~expr %prec prREDUCTION { $$ = new AstLogNot($1,new AstRedAnd($1,$2)); } | yP_NOR ~r~expr %prec prREDUCTION { $$ = new AstLogNot($1,new AstRedOr ($1,$2)); } | yP_XNOR ~r~expr %prec prREDUCTION { $$ = new AstRedXnor ($1,$2); } // // // IEEE: inc_or_dec_expression //UNSUP ~l~inc_or_dec_expression { UNSUP } // // // IEEE: '(' operator_assignment ')' // // Need exprScope of variable_lvalue to prevent conflict //UNSUP '(' ~p~exprScope '=' expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_PLUSEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_MINUSEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_TIMESEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_DIVEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_MODEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_ANDEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_OREQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_XOREQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_SLEFTEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_SRIGHTEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_SSRIGHTEQ expr ')' { UNSUP } // // // IEEE: expression binary_operator expression | ~l~expr '+' ~r~expr { $$ = new AstAdd ($2,$1,$3); } | ~l~expr '-' ~r~expr { $$ = new AstSub ($2,$1,$3); } | ~l~expr '*' ~r~expr { $$ = new AstMul ($2,$1,$3); } | ~l~expr '/' ~r~expr { $$ = new AstDiv ($2,$1,$3); } | ~l~expr '%' ~r~expr { $$ = new AstModDiv ($2,$1,$3); } | ~l~expr yP_EQUAL ~r~expr { $$ = new AstEq ($2,$1,$3); } | ~l~expr yP_NOTEQUAL ~r~expr { $$ = new AstNeq ($2,$1,$3); } | ~l~expr yP_CASEEQUAL ~r~expr { $$ = new AstEqCase ($2,$1,$3); } | ~l~expr yP_CASENOTEQUAL ~r~expr { $$ = new AstNeqCase ($2,$1,$3); } | ~l~expr yP_WILDEQUAL ~r~expr { $$ = new AstEqWild ($2,$1,$3); } | ~l~expr yP_WILDNOTEQUAL ~r~expr { $$ = new AstNeqWild ($2,$1,$3); } | ~l~expr yP_ANDAND ~r~expr { $$ = new AstLogAnd ($2,$1,$3); } | ~l~expr yP_OROR ~r~expr { $$ = new AstLogOr ($2,$1,$3); } | ~l~expr yP_POW ~r~expr { $$ = new AstPow ($2,$1,$3); } | ~l~expr '<' ~r~expr { $$ = new AstLt ($2,$1,$3); } | ~l~expr '>' ~r~expr { $$ = new AstGt ($2,$1,$3); } | ~l~expr yP_GTE ~r~expr { $$ = new AstGte ($2,$1,$3); } | ~l~expr '&' ~r~expr { $$ = new AstAnd ($2,$1,$3); } | ~l~expr '|' ~r~expr { $$ = new AstOr ($2,$1,$3); } | ~l~expr '^' ~r~expr { $$ = new AstXor ($2,$1,$3); } | ~l~expr yP_XNOR ~r~expr { $$ = new AstXnor ($2,$1,$3); } | ~l~expr yP_NOR ~r~expr { $$ = new AstNot($2,new AstOr ($2,$1,$3)); } | ~l~expr yP_NAND ~r~expr { $$ = new AstNot($2,new AstAnd ($2,$1,$3)); } | ~l~expr yP_SLEFT ~r~expr { $$ = new AstShiftL ($2,$1,$3); } | ~l~expr yP_SRIGHT ~r~expr { $$ = new AstShiftR ($2,$1,$3); } | ~l~expr yP_SSRIGHT ~r~expr { $$ = new AstShiftRS ($2,$1,$3); } // // <= is special, as we need to disambiguate it with <= assignment // // We copy all of expr to fexpr and rename this token to a fake one. | ~l~expr yP_LTE~f__IGNORE~ ~r~expr { $$ = new AstLte ($2,$1,$3); } // // // IEEE: conditional_expression | ~l~expr '?' ~r~expr ':' ~r~expr { $$ = new AstCond($2,$1,$3,$5); } // // // IEEE: inside_expression | ~l~expr yINSIDE '{' open_range_list '}' { $$ = new AstInside($2,$1,$4); } // // // IEEE: tagged_union_expression //UNSUP yTAGGED id/*member*/ %prec prTAGGED { UNSUP } //UNSUP yTAGGED id/*member*/ %prec prTAGGED expr { UNSUP } // //======================// PSL expressions // | ~l~expr yP_MINUSGT ~r~expr { $$ = new AstLogIf ($2,$1,$3); } | ~l~expr yP_LOGIFF ~r~expr { $$ = new AstLogIff ($2,$1,$3); } // //======================// IEEE: primary/constant_primary // // // IEEE: primary_literal (minus string, which is handled specially) | yaINTNUM { $$ = new AstConst($1,*$1); } | yaFLOATNUM { $$ = new AstConst($1,AstConst::RealDouble(),$1); } //UNSUP yaTIMENUM { UNSUP } | strAsInt~noStr__IGNORE~ { $$ = $1; } // // // IEEE: "... hierarchical_identifier select" see below // // // IEEE: empty_queue //UNSUP '{' '}' // // // IEEE: concatenation/constant_concatenation // // Part of exprOkLvalue below // // // IEEE: multiple_concatenation/constant_multiple_concatenation | '{' constExpr '{' cateList '}' '}' { $$ = new AstReplicate($1,$4,$2); } // | function_subroutine_callNoMethod { $$ = $1; } // // method_call | ~l~expr '.' function_subroutine_callNoMethod { $$ = new AstDot($2,$1,$3); } // // method_call:array_method requires a '.' | ~l~expr '.' array_methodNoRoot { $$ = new AstDot($2,$1,$3); } // // // IEEE: let_expression // // see funcRef // // // IEEE: '(' mintypmax_expression ')' | ~noPar__IGNORE~'(' expr ')' { $$ = $2; } //UNSUP ~noPar__IGNORE~'(' expr ':' expr ':' expr ')' { $$ = $4; } // // PSL rule | '_' '(' expr ')' { $$ = $3; } // Arbitrary Verilog inside PSL // // // IEEE: cast/constant_cast | casting_type yP_TICK '(' expr ')' { $$ = new AstCast($2,$4,$1); } // // expanded from casting_type | ySIGNED yP_TICK '(' expr ')' { $$ = new AstSigned($1,$4); } | yUNSIGNED yP_TICK '(' expr ')' { $$ = new AstUnsigned($1,$4); } // // Spec only allows primary with addition of a type reference // // We'll be more general, and later assert LHS was a type. | ~l~expr yP_TICK '(' expr ')' { $$ = new AstCastParse($2,$4,$1); } // // // IEEE: assignment_pattern_expression // // IEEE: streaming_concatenation // // See exprOkLvalue // // // IEEE: sequence_method_call // // Indistinguishable from function_subroutine_call:method_call // //UNSUP '$' { UNSUP } //UNSUP yNULL { UNSUP } // // IEEE: yTHIS // // See exprScope // //---------------------- // // // Part of expr that may also be used as lvalue | ~l~exprOkLvalue { $$ = $1; } // //---------------------- // // // IEEE: cond_predicate - here to avoid reduce problems // // Note expr includes cond_pattern //UNSUP ~l~expr yP_ANDANDAND ~r~expr { UNSUP } // // // IEEE: cond_pattern - here to avoid reduce problems // // "expr yMATCHES pattern" // // IEEE: pattern - expanded here to avoid conflicts //UNSUP ~l~expr yMATCHES patternNoExpr { UNSUP } //UNSUP ~l~expr yMATCHES ~r~expr { UNSUP } // // // IEEE: expression_or_dist - here to avoid reduce problems // // "expr yDIST '{' dist_list '}'" //UNSUP ~l~expr yDIST '{' dist_list '}' { UNSUP } ; fexpr: // For use as first part of statement (disambiguates <=) BISONPRE_COPY(expr,{s/~l~/f/g; s/~r~/f/g; s/~f__IGNORE~/__IGNORE/g;}) // {copied} ; exprNoStr: // expression with string removed BISONPRE_COPY(expr,{s/~noStr__IGNORE~/Ignore/g;}) // {copied} ; exprOkLvalue: // expression that's also OK to use as a variable_lvalue ~l~exprScope { $$ = $1; } // // IEEE: concatenation/constant_concatenation // // Replicate(1) required as otherwise "{a}" would not be self-determined | '{' cateList '}' { $$ = new AstReplicate($1,$2,1); } // // IEEE: assignment_pattern_expression // // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type] // // We allow more here than the spec requires //UNSUP ~l~exprScope assignment_pattern { UNSUP } | data_type assignment_pattern { $$ = $2; $2->childDTypep($1); } | assignment_pattern { $$ = $1; } // | streaming_concatenation { $$ = $1; } ; fexprOkLvalue: // exprOkLValue, For use as first part of statement (disambiguates <=) BISONPRE_COPY(exprOkLvalue,{s/~l~/f/g}) // {copied} ; fexprLvalue: // For use as first part of statement (disambiguates <=) fexprOkLvalue { $$=$1; $$ = $1; } ; exprScope: // scope and variable for use to inside an expression // // Here we've split method_call_root | implicit_class_handle | class_scope | package_scope // // from the object being called and let expr's "." deal with resolving it. // // (note method_call_root was simplified to require a primary in 1800-2009) // // // IEEE: [ implicit_class_handle . | class_scope | package_scope ] hierarchical_identifier select // // Or method_call_body without parenthesis // // See also varRefClassBit, which is the non-expr version of most of this //UNSUP yTHIS { UNSUP } idArrayed { $$ = $1; } | package_scopeIdFollows idArrayed { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); } //UNSUP class_scopeIdFollows idArrayed { UNSUP } | ~l~expr '.' idArrayed { $$ = new AstDot($2,$1,$3); } // // expr below must be a "yTHIS" //UNSUP ~l~expr '.' ySUPER { UNSUP } // // Part of implicit_class_handle //UNSUP ySUPER { UNSUP } ; fexprScope: // exprScope, For use as first part of statement (disambiguates <=) BISONPRE_COPY(exprScope,{s/~l~/f/g}) // {copied} ; // PLI calls exclude "" as integers, they're strings // For $c("foo","bar") we want "bar" as a string, not a Verilog integer. exprStrText: exprNoStr { $$ = $1; } | strAsText { $$ = $1; } ; cStrList: exprStrText { $$ = $1; } | exprStrText ',' cStrList { $$ = $1;$1->addNext($3); } ; cateList: // // Not just 'expr' to prevent conflict via stream_concOrExprOrType stream_expression { $$ = $1; } | cateList ',' stream_expression { $$ = new AstConcat($2,$1,$3); } ; exprListE: /* empty */ { $$ = NULL; } | exprList { $$ = $1; } ; exprList: expr { $$ = $1; } | exprList ',' expr { $$ = $1;$1->addNext($3); } ; commaEListE: /* empty */ { $$ = NULL; } | ',' exprList { $$ = $2; } ; vrdList: idClassSel { $$ = $1; } | vrdList ',' idClassSel { $$ = $1;$1->addNext($3); } ; commaVRDListE: /* empty */ { $$ = NULL; } | ',' vrdList { $$ = $2; } ; argsExprList: // IEEE: part of list_of_arguments (used where ,, isn't legal) expr { $$ = $1; } | argsExprList ',' expr { $$ = $1->addNext($3); } ; argsExprListE: // IEEE: part of list_of_arguments argsExprOneE { $$ = $1; } | argsExprListE ',' argsExprOneE { $$ = $1->addNext($3); } ; argsExprOneE: // IEEE: part of list_of_arguments /*empty*/ { $$ = new AstArg(CRELINE(),"",NULL); } | expr { $$ = new AstArg(CRELINE(),"",$1); } ; argsDottedList: // IEEE: part of list_of_arguments argsDotted { $$ = $1; } | argsDottedList ',' argsDotted { $$ = $1->addNextNull($3); } ; argsDotted: // IEEE: part of list_of_arguments '.' idAny '(' ')' { $$ = new AstArg($1,*$2,NULL); } | '.' idAny '(' expr ')' { $$ = new AstArg($1,*$2,$4); } ; streaming_concatenation: // ==IEEE: streaming_concatenation // // Need to disambiguate {<< expr-{ ... expr-} stream_concat } // // From {<< stream-{ ... stream-} } // // Likewise simple_type's idScoped from constExpr's idScope // // Thus we allow always any two operations. Sorry // // IEEE: "'{' yP_SL/R stream_concatenation '}'" // // IEEE: "'{' yP_SL/R simple_type stream_concatenation '}'" // // IEEE: "'{' yP_SL/R constExpr stream_concatenation '}'" '{' yP_SLEFT stream_concOrExprOrType '}' { $$ = new AstStreamL($1, $3, new AstConst($1,1)); } | '{' yP_SRIGHT stream_concOrExprOrType '}' { $$ = new AstStreamR($1, $3, new AstConst($1,1)); } | '{' yP_SLEFT stream_concOrExprOrType stream_concatenation '}' { $$ = new AstStreamL($1, $4, $3); } | '{' yP_SRIGHT stream_concOrExprOrType stream_concatenation '}' { $$ = new AstStreamR($1, $4, $3); } ; stream_concOrExprOrType: // IEEE: stream_concatenation | slice_size:simple_type | slice_size:constExpr cateList { $$ = $1; } | simple_type { $$ = $1; } // // stream_concatenation found via cateList:stream_expr:'{-normal-concat' // // simple_typeRef found via cateList:stream_expr:expr:id // // constant_expression found via cateList:stream_expr:expr ; stream_concatenation: // ==IEEE: stream_concatenation '{' cateList '}' { $$ = $2; } ; stream_expression: // ==IEEE: stream_expression // // IEEE: array_range_expression expanded below expr { $$ = $1; } //UNSUP expr yWITH__BRA '[' expr ']' { UNSUP } //UNSUP expr yWITH__BRA '[' expr ':' expr ']' { UNSUP } //UNSUP expr yWITH__BRA '[' expr yP_PLUSCOLON expr ']' { UNSUP } //UNSUP expr yWITH__BRA '[' expr yP_MINUSCOLON expr ']' { UNSUP } ; //************************************************ // Gate declarations gateDecl: yBUF delayE gateBufList ';' { $$ = $3; } | yBUFIF0 delayE gateBufif0List ';' { $$ = $3; } | yBUFIF1 delayE gateBufif1List ';' { $$ = $3; } | yNOT delayE gateNotList ';' { $$ = $3; } | yNOTIF0 delayE gateNotif0List ';' { $$ = $3; } | yNOTIF1 delayE gateNotif1List ';' { $$ = $3; } | yAND delayE gateAndList ';' { $$ = $3; } | yNAND delayE gateNandList ';' { $$ = $3; } | yOR delayE gateOrList ';' { $$ = $3; } | yNOR delayE gateNorList ';' { $$ = $3; } | yXOR delayE gateXorList ';' { $$ = $3; } | yXNOR delayE gateXnorList ';' { $$ = $3; } | yPULLUP delayE gatePullupList ';' { $$ = $3; } | yPULLDOWN delayE gatePulldownList ';' { $$ = $3; } | yNMOS delayE gateBufif1List ';' { $$ = $3; } // ~=bufif1, as don't have strengths yet | yPMOS delayE gateBufif0List ';' { $$ = $3; } // ~=bufif0, as don't have strengths yet // | yTRAN delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tran"); } // Unsupported | yRCMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rcmos"); } // Unsupported | yCMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"cmos"); } // Unsupported | yRNMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rmos"); } // Unsupported | yRPMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"pmos"); } // Unsupported | yRTRAN delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtran"); } // Unsupported | yRTRANIF0 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtranif0"); } // Unsupported | yRTRANIF1 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtranif1"); } // Unsupported | yTRANIF0 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tranif0"); } // Unsupported | yTRANIF1 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tranif1"); } // Unsupported ; gateBufList: gateBuf { $$ = $1; } | gateBufList ',' gateBuf { $$ = $1->addNext($3); } ; gateBufif0List: gateBufif0 { $$ = $1; } | gateBufif0List ',' gateBufif0 { $$ = $1->addNext($3); } ; gateBufif1List: gateBufif1 { $$ = $1; } | gateBufif1List ',' gateBufif1 { $$ = $1->addNext($3); } ; gateNotList: gateNot { $$ = $1; } | gateNotList ',' gateNot { $$ = $1->addNext($3); } ; gateNotif0List: gateNotif0 { $$ = $1; } | gateNotif0List ',' gateNotif0 { $$ = $1->addNext($3); } ; gateNotif1List: gateNotif1 { $$ = $1; } | gateNotif1List ',' gateNotif1 { $$ = $1->addNext($3); } ; gateAndList: gateAnd { $$ = $1; } | gateAndList ',' gateAnd { $$ = $1->addNext($3); } ; gateNandList: gateNand { $$ = $1; } | gateNandList ',' gateNand { $$ = $1->addNext($3); } ; gateOrList: gateOr { $$ = $1; } | gateOrList ',' gateOr { $$ = $1->addNext($3); } ; gateNorList: gateNor { $$ = $1; } | gateNorList ',' gateNor { $$ = $1->addNext($3); } ; gateXorList: gateXor { $$ = $1; } | gateXorList ',' gateXor { $$ = $1->addNext($3); } ; gateXnorList: gateXnor { $$ = $1; } | gateXnorList ',' gateXnor { $$ = $1->addNext($3); } ; gatePullupList: gatePullup { $$ = $1; } | gatePullupList ',' gatePullup { $$ = $1->addNext($3); } ; gatePulldownList: gatePulldown { $$ = $1; } | gatePulldownList ',' gatePulldown { $$ = $1->addNext($3); } ; gateUnsupList: gateUnsup { $$ = $1; } | gateUnsupList ',' gateUnsup { $$ = $1->addNext($3); } ; gateRangeE: instRangeE { $$ = $1; GATERANGE($1); } ; gateBuf: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateBufif0: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8),$6)); DEL($2); } ; gateBufif1: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8,$6)); DEL($2); } ; gateNot: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateNotif0: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8), new AstNot($3, $6))); DEL($2); } ; gateNotif1: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8, new AstNot($3,$6))); DEL($2); } ; gateAnd: gateIdE gateRangeE '(' variable_lvalue ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateNand: gateIdE gateRangeE '(' variable_lvalue ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateOr: gateIdE gateRangeE '(' variable_lvalue ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateNor: gateIdE gateRangeE '(' variable_lvalue ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateXor: gateIdE gateRangeE '(' variable_lvalue ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateXnor: gateIdE gateRangeE '(' variable_lvalue ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gatePullup: gateIdE gateRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, true); DEL($2); } ; gatePulldown: gateIdE gateRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, false); DEL($2); } ; gateUnsup: gateIdE gateRangeE '(' gateUnsupPinList ')' { $$ = new AstImplicit ($3,$4); DEL($2); } ; gateIdE: /*empty*/ {} | id {} ; gateAndPinList: gatePinExpr { $$ = $1; } | gateAndPinList ',' gatePinExpr { $$ = new AstAnd($2,$1,$3); } ; gateOrPinList: gatePinExpr { $$ = $1; } | gateOrPinList ',' gatePinExpr { $$ = new AstOr($2,$1,$3); } ; gateXorPinList: gatePinExpr { $$ = $1; } | gateXorPinList ',' gatePinExpr { $$ = new AstXor($2,$1,$3); } ; gateUnsupPinList: gatePinExpr { $$ = $1; } | gateUnsupPinList ',' gatePinExpr { $$ = $1->addNext($3); } ; gatePinExpr: expr { $$ = GRAMMARP ->createGatePin($1); } ; strengthSpecE: // IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty /* empty */ { } //UNSUP strengthSpec { } ; //************************************************ // Tables combinational_body: // IEEE: combinational_body + sequential_body yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable($1,$2); } ; tableEntryList: // IEEE: { combinational_entry | sequential_entry } tableEntry { $$ = $1; } | tableEntryList tableEntry { $$ = $1->addNext($2); } ; tableEntry: // IEEE: combinational_entry + sequential_entry yaTABLELINE { $$ = new AstUdpTableLine($1,*$1); } | error { $$ = NULL; } ; //************************************************ // Specify specify_block: // ==IEEE: specify_block ySPECIFY specifyJunkList yENDSPECIFY { $$ = NULL; } | ySPECIFY yENDSPECIFY { $$ = NULL; } ; specifyJunkList: specifyJunk { } /* ignored */ | specifyJunkList specifyJunk { } /* ignored */ ; specifyJunk: BISONPRE_NOT(ySPECIFY,yENDSPECIFY) { } | ySPECIFY specifyJunk yENDSPECIFY { } | error {} ; specparam_declaration: // ==IEEE: specparam_declaration ySPECPARAM junkToSemiList ';' { $$ = NULL; } ; junkToSemiList: junkToSemi { } /* ignored */ | junkToSemiList junkToSemi { } /* ignored */ ; junkToSemi: BISONPRE_NOT(';',yENDSPECIFY,yENDMODULE) { } | error {} ; //************************************************ // IDs id: yaID__ETC { $$ = $1; $$=$1; } ; idAny: // Any kind of identifier //UNSUP yaID__aCLASS { $$ = $1; $$=$1; } //UNSUP yaID__aCOVERGROUP { $$ = $1; $$=$1; } yaID__aPACKAGE { $$ = $1; $$=$1; } | yaID__aTYPE { $$ = $1; $$=$1; } | yaID__ETC { $$ = $1; $$=$1; } ; idSVKwd: // Warn about non-forward compatible Verilog 2001 code // // yBIT, yBYTE won't work here as causes conflicts yDO { static string s = "do" ; $$ = &s; ERRSVKWD($1,*$$); $$=$1; } | yFINAL { static string s = "final"; $$ = &s; ERRSVKWD($1,*$$); $$=$1; } ; variable_lvalue: // IEEE: variable_lvalue or net_lvalue // // Note many variable_lvalue's must use exprOkLvalue when arbitrary expressions may also exist idClassSel { $$ = $1; } | '{' variable_lvalueConcList '}' { $$ = $2; } // // IEEE: [ assignment_pattern_expression_type ] assignment_pattern_variable_lvalue // // We allow more assignment_pattern_expression_types then strictly required //UNSUP data_type yP_TICKBRA variable_lvalueList '}' { UNSUP } //UNSUP idClassSel yP_TICKBRA variable_lvalueList '}' { UNSUP } //UNSUP /**/ yP_TICKBRA variable_lvalueList '}' { UNSUP } //UNSUP streaming_concatenation { UNSUP } | streaming_concatenation { $$ = $1; } ; variable_lvalueConcList: // IEEE: part of variable_lvalue: '{' variable_lvalue { ',' variable_lvalue } '}' variable_lvalue { $$ = $1; } | variable_lvalueConcList ',' variable_lvalue { $$ = new AstConcat($2,$1,$3); } ; // VarRef to dotted, and/or arrayed, and/or bit-ranged variable idClassSel: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable idDotted { $$ = $1; } // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select //UNSUP yTHIS '.' idDotted { UNSUP } //UNSUP ySUPER '.' idDotted { UNSUP } //UNSUP yTHIS '.' ySUPER '.' idDotted { UNSUP } // // Expanded: package_scope idDotted //UNSUP class_scopeIdFollows idDotted { UNSUP } //UNSUP package_scopeIdFollows idDotted { UNSUP } ; idDotted: //UNSUP yD_ROOT '.' idDottedMore { UNSUP } idDottedMore { $$ = $1; } ; idDottedMore: idArrayed { $$ = $1; } | idDottedMore '.' idArrayed { $$ = new AstDot($2,$1,$3); } ; // Single component of dotted path, maybe [#]. // Due to lookahead constraints, we can't know if [:] or [+:] are valid (last dotted part), // we'll assume so and cleanup later. // id below includes: // enum_identifier idArrayed: // IEEE: id + select id { $$ = new AstParseRef($1,AstParseRefExp::PX_TEXT,*$1,NULL,NULL); } // // IEEE: id + part_select_range/constant_part_select_range | idArrayed '[' expr ']' { $$ = new AstSelBit($2,$1,$3); } // Or AstArraySel, don't know yet. | idArrayed '[' constExpr ':' constExpr ']' { $$ = new AstSelExtract($2,$1,$3,$5); } // // IEEE: id + indexed_range/constant_indexed_range | idArrayed '[' expr yP_PLUSCOLON constExpr ']' { $$ = new AstSelPlus($2,$1,$3,$5); } | idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2,$1,$3,$5); } ; idClassForeach: idForeach { $$ = $1; } | package_scopeIdFollows idForeach { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); } ; idForeach: varRefBase { $$ = $1; } | idForeach '.' varRefBase { $$ = new AstDot($2,$1,$3); } ; // VarRef without any dots or vectorizaion varRefBase: id { $$ = new AstVarRef($1,*$1,false);} ; // yaSTRING shouldn't be used directly, instead via an abstraction below str: // yaSTRING but with \{escapes} need decoded yaSTRING { $$ = PARSEP->newString(GRAMMARP->deQuote($1,*$1)); } ; strAsInt: yaSTRING { $$ = new AstConst($1,V3Number(V3Number::VerilogStringLiteral(),$1,GRAMMARP->deQuote($1,*$1)));} ; strAsIntIgnore: // strAsInt, but never matches for when expr shouldn't parse strings yaSTRING__IGNORE { $$ = NULL; yyerror("Impossible token"); } ; strAsText: yaSTRING { $$ = GRAMMARP->createTextQuoted($1,*$1);} ; endLabelE: /* empty */ { $$ = NULL; $$=NULL; } | ':' idAny { $$ = $2; $$=$2; } //UNSUP ':' yNEW__ETC { $$ = $2; $$=$2; } ; //************************************************ // Clocking clocking_declaration: // IEEE: clocking_declaration (INCOMPLETE) yDEFAULT yCLOCKING '@' '(' senitemEdge ')' ';' yENDCLOCKING { $$ = new AstClocking($1, $5, NULL); } //UNSUP: Vastly simplified grammar ; //************************************************ // Asserts labeledStmt: immediate_assert_statement { $$ = $1; } ; concurrent_assertion_item: // IEEE: concurrent_assertion_item concurrent_assertion_statement { $$ = $1; } | id/*block_identifier*/ ':' concurrent_assertion_statement { $$ = new AstBegin($2,*$1,$3); } // // IEEE: checker_instantiation // // identical to module_instantiation; see etcInst ; concurrent_assertion_statement: // ==IEEE: concurrent_assertion_statement //UNSUP: assert/assume // // IEEE: cover_property_statement yCOVER yPROPERTY '(' property_spec ')' stmtBlock { $$ = new AstPslCover($1,$4,$6); } ; property_spec: // IEEE: property_spec //UNSUP: This rule has been super-specialized to what is supported now '@' '(' senitemEdge ')' yDISABLE yIFF '(' expr ')' expr { $$ = new AstPslClocked($1,$3,$8,$10); } | '@' '(' senitemEdge ')' expr { $$ = new AstPslClocked($1,$3,NULL,$5); } | yDISABLE yIFF '(' expr ')' expr { $$ = new AstPslClocked($4->fileline(),NULL,$4,$6); } | expr { $$ = new AstPslClocked($1->fileline(),NULL,NULL,$1); } ; immediate_assert_statement: // ==IEEE: immediate_assert_statement // // action_block expanded here, for compatibility with AstVAssert yASSERT '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstVAssert($1,$3,$5, GRAMMARP->createDisplayError($1)); } | yASSERT '(' expr ')' yELSE stmtBlock { $$ = new AstVAssert($1,$3,NULL,$6); } | yASSERT '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstVAssert($1,$3,$5,$7); } ; //************************************************ // Covergroup //********************************************************************** // Randsequence //********************************************************************** // Class //========= // Package scoping - to traverse the symbol table properly, the final identifer // must be included in the rules below. // Each of these must end with {symsPackageDone | symsClassDone} ps_id_etc: // package_scope + general id package_scopeIdFollowsE id { } ; ps_type: // IEEE: ps_parameter_identifier | ps_type_identifier // Even though we looked up the type and have a AstNode* to it, // we can't fully resolve it because it may have been just a forward definition. package_scopeIdFollowsE yaID__aTYPE { $$ = new AstRefDType($2, *$2); $$->castRefDType()->packagep($1); } // // Simplify typing - from ps_covergroup_identifier //UNSUP package_scopeIdFollowsE yaID__aCOVERGROUP { $$=$1; $$=$1+$2; } ; //=== Below rules assume special scoping per above package_scopeIdFollowsE: // IEEE: [package_scope] // // IMPORTANT: The lexer will parse the following ID to be in the found package // // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ] /* empty */ { $$ = NULL; } | package_scopeIdFollows { $$ = $1; } ; package_scopeIdFollows: // IEEE: package_scope // // IMPORTANT: The lexer will parse the following ID to be in the found package // //vv mid rule action needed otherwise we might not have NextId in time to parse the id token yD_UNIT { SYMP->nextId(PARSEP->rootp()); } /*cont*/ yP_COLONCOLON { $$ = GRAMMARP->unitPackage($1); } | yaID__aPACKAGE { SYMP->nextId($1); } /*cont*/ yP_COLONCOLON { $$ = $1->castPackage(); } //UNSUP yLOCAL__COLONCOLON { PARSEP->symTableNextId($1); } //UNSUP /*cont*/ yP_COLONCOLON { UNSUP } ; //********************************************************************** // VLT Files vltItem: vltOffFront { V3Config::addIgnore($1,false,"*",0,0); } | vltOffFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,false,*$3,0,0); } | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,false,*$3,$5->toUInt(),$5->toUInt()+1); } | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,false,*$3,$5->toUInt(),$7->toUInt()+1); } | vltOnFront { V3Config::addIgnore($1,true,"*",0,0); } | vltOnFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,true,*$3,0,0); } | vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,true,*$3,$5->toUInt(),$5->toUInt()+1); } | vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,true,*$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<: yVLT_COVERAGE_ON { $$ = V3ErrorCode::I_COVERAGE; } | yVLT_TRACING_ON { $$ = V3ErrorCode::I_TRACING; } | yVLT_LINT_ON { $$ = V3ErrorCode::I_LINT; } | yVLT_LINT_ON 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 static const char** nameTablep = NULL; if (!nameTablep) { int size; for (size=0; yytname[size]; ++size) ; nameTablep = new const char* [size]; // Workaround bug in bison's which have '!' in yytname but not token values int iout = 0; for (int i=0; yytname[i]; ++i) { if (yytname[i][0] == '\'') continue; nameTablep[iout++] = yytname[i]; } } if (token >= 255) { return nameTablep[token-255]; } else { static char ch[2]; ch[0]=token; ch[1]='\0'; return ch; } #else return ""; #endif } void V3ParseImp::parserClear() { // Clear up any dynamic memory V3Parser required VARDTYPE(NULL); } void V3ParseGrammar::argWrapList(AstNodeFTaskRef* nodep) { // Convert list of expressions to list of arguments AstNode* outp = NULL; while (nodep->pinsp()) { AstNode* exprp = nodep->pinsp()->unlinkFrBack(); // addNext can handle nulls: outp = AstNode::addNext(outp, 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 (GRAMMARP->m_varDecl == AstVarType::WREAL) { // dtypep might not be null, might be implicit LOGIC before we knew better dtypep = new AstBasicDType(fileline,AstBasicDTypeKwd::DOUBLE); } 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)); } if (dtypep->castParseTypeDType()) { // Parser needs to know what is a type AstNode* newp = new AstTypedefFwd(fileline, name); nodep->addNext(newp); SYMP->reinsert(newp); } // Don't set dtypep in the ranging; // We need to autosize parameters and integers separately // // Propagate from current module tracing state if (nodep->isGenVar()) nodep->trace(false); else if (nodep->isParam() && !v3Global.opt.traceParams()) nodep->trace(false); else nodep->trace(allTracingOn(nodep->fileline())); // Remember the last variable created, so we can attach attributes to it in later parsing GRAMMARP->m_varAttrp = nodep; PARSEP->tagNodep(GRAMMARP->m_varAttrp); return nodep; } string V3ParseGrammar::deQuote(FileLine* fileline, string text) { // Fix up the quoted strings the user put in, for example "\"" becomes " // Reverse is V3Number::quoteNameControls(...) bool quoted = false; string newtext; unsigned char octal_val = 0; int octal_digits = 0; for (string::const_iterator cp=text.begin(); cp!=text.end(); ++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.916/src/V3Task.cpp0000664000177100017500000014370013205574202016133 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 "V3Const.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: explicit 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: explicit 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()->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->user4u().toGraphVertex()); } // VISITORS virtual void visit(AstScope* nodep) { // 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) { m_assignwp = nodep; nodep->iterateChildren(*this); VL_DANGLING(nodep); // May delete nodep. m_assignwp = NULL; } virtual void visit(AstNodeFTaskRef* nodep) { 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) { UINFO(9," TASK "<dpiImport()) m_curVxp->noInline(true); nodep->iterateChildren(*this); m_curVxp = lastVxp; } virtual void visit(AstPragma* nodep) { 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) { nodep->iterateChildren(*this); nodep->user4p(m_curVxp); // Remember what task it's under } virtual void visit(AstVarRef* nodep) { nodep->iterateChildren(*this); if (nodep->varp()->user4u().toGraphVertex() != m_curVxp) { if (m_curVxp->pure() && !nodep->varp()->isXTemp()) { m_curVxp->impure(nodep); } } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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) { // Similar code in V3Inline if (nodep->varp()->user2p()) { // It's being converted to a alias. UINFO(9, " relinkVar "<<(void*)nodep->varp()->user2p()<<" "<varp()->user2p()->castVarScope(); if (!newvscp) nodep->v3fatalSrc("not linked"); nodep->varScopep(newvscp); nodep->varp(nodep->varScopep()->varp()); nodep->name(nodep->varp()->name()); } nodep->iterateChildren(*this); } //-------------------- virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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, const 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(); VL_DANGLING(tempp); } // if (debug()>=9) { beginp->dumpTreeAndNext(cout,"-iotask: "); } return beginp; } AstNode* createNonInlinedFTask(AstNodeFTaskRef* refp, const string& namePrefix, AstVarScope* outvscp) { // outvscp is the variable for functions only, if NULL, it's a task if (!refp->taskp()) refp->v3fatalSrc("Unlinked?"); AstCFunc* cfuncp = m_statep->ftaskCFuncp(refp->taskp()); if (!cfuncp) refp->v3fatalSrc("No non-inline task associated with this task call?"); // AstNode* beginp = new AstComment(refp->fileline(), (string)("Function: ")+refp->name()); AstCCall* ccallp = new AstCCall(refp->fileline(), cfuncp, NULL); beginp->addNext(ccallp); // Convert complicated outputs to temp signals V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp()); for (V3TaskConnects::iterator it=tconnects.begin(); it!=tconnects.end(); ++it) { AstVar* portp = it->first; AstNode* pinp = it->second->exprp(); if (!pinp) { // Too few arguments in function call } else { UINFO(9, " Port "<isInout()||portp->isOutput()) && pinp->castConst()) { pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName()); } else if (portp->isInout()) { if (pinp->castVarRef()) { // Connect to this exact variable } else { pinp->v3warn(E_TASKNSVAR,"Unsupported: Function/task input argument is not simple variable"); } } else if (portp->isOutput()) { // Make output variables // Correct lvalue; we didn't know when we linked // This is slightly scary; are we sure no decisions were made // before here based on this not being a lvalue? // Doesn't seem so; V3Unknown uses it earlier, but works ok. V3LinkLValue::linkLValueSet(pinp); // Even if it's referencing a varref, we still make a temporary // Else task(x,x,x) might produce incorrect results AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName()); portp->user2p(outvscp); pinp->replaceWith(new AstVarRef(outvscp->fileline(), outvscp, true)); AstAssign* assp = new AstAssign (pinp->fileline(), pinp, new AstVarRef(outvscp->fileline(), outvscp, false)); assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block // Put assignment BEHIND of all other statements beginp->addNext(assp); } } } // First argument is symbol table, then output if a function bool needSyms = !refp->taskp()->dpiImport(); if (needSyms) ccallp->argTypes("vlSymsp"); if (refp->taskp()->dpiContext()) { // __Vscopep AstNode* snp = refp->scopeNamep()->unlinkFrBack(); if (!snp) refp->v3fatalSrc("Missing scoping context"); ccallp->addArgsp(snp); // __Vfilenamep ccallp->addArgsp(new AstCMath(refp->fileline(), "\""+refp->fileline()->filename()+"\"", 64, true)); // __Vlineno ccallp->addArgsp(new AstConst(refp->fileline(), refp->fileline()->lineno())); } // Create connections AstNode* nextpinp; for (AstNode* pinp = refp->pinsp(); pinp; pinp=nextpinp) { nextpinp = pinp->nextp(); // Move pin to the CCall, removing all Arg's AstNode* exprp = pinp->castArg()->exprp(); exprp->unlinkFrBack(); ccallp->addArgsp(exprp); } if (outvscp) { ccallp->addArgsp(new AstVarRef(refp->fileline(), outvscp, true)); } if (debug()>=9) { beginp->dumpTreeAndNext(cout,"-nitask: "); } return beginp; } string dpiprotoName(AstNodeFTask* nodep, AstVar* rtnvarp) const { // Return fancy export-ish name for DPI function // Variable names are NOT included so differences in only IO names won't matter string dpiproto; if (nodep->pure()) dpiproto += "pure "; if (nodep->dpiContext()) dpiproto += "context "; dpiproto += rtnvarp ? rtnvarp->dpiArgType(true,true):"void"; dpiproto += " "+nodep->cname()+" ("; string args; for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && !portp->isFuncReturn() && portp!=rtnvarp) { if (args != "") { args+= ", "; dpiproto+= ", "; } args += portp->name(); // Leftover so ,'s look nice if (nodep->dpiImport()) dpiproto += portp->dpiArgType(false,false); } } } dpiproto += ")"; return dpiproto; } AstNode* createDpiTemp(AstVar* portp, const string& suffix) { bool bitvec = (portp->basicp()->isBitLogic() && portp->width() > 32); string stmt; if (bitvec) { stmt += "svBitVecVal "+portp->name()+suffix; stmt += " ["+cvtToStr(portp->widthWords())+"]"; } else { stmt += portp->dpiArgType(true,true); stmt += " "+portp->name()+suffix; } stmt += ";\n"; return new AstCStmt(portp->fileline(), stmt); } AstNode* createAssignInternalToDpi(AstVar* portp, bool isRtn, bool isPtr, const string& frSuffix, const string& toSuffix) { // Create assignment from internal format into DPI temporary bool bitvec = (portp->basicp()->isBitLogic() && portp->width() > 32); if (isRtn && bitvec) { portp->v3error("DPI functions cannot return > 32 bits; use a two-state type or task instead: "<prettyName()); // Code below works, but won't compile right, and IEEE illegal } string stmt; string ket; // Someday we'll have better type support, and this can make variables and casts. // But for now, we'll just text-bash it. if (bitvec) { if (portp->isWide()) { stmt += ("VL_SET_SVBV_W("+cvtToStr(portp->width()) +", "+portp->name()+toSuffix+", "+portp->name()+frSuffix+")"); } else { stmt += "VL_SET_WQ("+portp->name()+toSuffix+", "+portp->name()+frSuffix+")"; } } else { if (isPtr) stmt += "*"; // DPI outputs are pointers stmt += portp->name()+toSuffix+" = "; if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::CHANDLE) { stmt += "VL_CVT_Q_VP("; ket += ")"; } stmt += portp->name()+frSuffix; if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::STRING) { stmt += ".c_str()"; } } stmt += ket + ";\n"; return new AstCStmt(portp->fileline(), stmt); } AstNode* createAssignDpiToInternal(AstVarScope* portvscp, const string& frName, bool cvt) { // Create assignment from DPI temporary into internal format AstVar* portp = portvscp->varp(); string stmt; string ket; if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::CHANDLE) { stmt += "VL_CVT_VP_Q("; ket += ")"; } else if (portp->basicp() && portp->basicp()->isBitLogic() && portp->width() != 1 && portp->isQuad()) { // SV is vector, Verilator isn't stmt += "VL_SET_QW("; ket += ")"; } if (!cvt && portp->basicp() && portp->basicp()->isBitLogic() && portp->width() != 1 && !portp->isWide() && !portp->isQuad()) stmt += "*"; // it's a svBitVecVal, which other code won't think is arrayed (as WData aren't), but really is stmt += frName; stmt += ket; // Use a AstCMath, as we want V3Clean to mask off bits that don't make sense. int cwidth = VL_WORDSIZE; if (portp->basicp()) cwidth = portp->basicp()->keyword().width(); if (portp->basicp() && portp->basicp()->isBitLogic()) cwidth = VL_WORDSIZE*portp->widthWords(); AstNode* newp = new AstAssign(portp->fileline(), new AstVarRef(portp->fileline(), portvscp, true), new AstSel(portp->fileline(), new AstCMath(portp->fileline(), stmt, cwidth, false), 0, portp->width())); return newp; } AstCFunc* makeDpiExportWrapper(AstNodeFTask* nodep, AstVar* rtnvarp) { AstCFunc* dpip = new AstCFunc(nodep->fileline(), nodep->cname(), m_scopep, (rtnvarp ? rtnvarp->dpiArgType(true,true) : "")); dpip->dontCombine(true); dpip->entryPoint(true); dpip->isStatic(true); dpip->dpiExportWrapper(true); dpip->cname(nodep->cname()); // Add DPI reference to top, since it's a global function m_topScopep->scopep()->addActivep(dpip); {// Create dispatch wrapper // Note this function may dispatch to myfunc on a different class. // Thus we need to be careful not to assume a particular function layout. // // Func numbers must be the same for each function, even when there are // completely different models with the same function name. // Thus we can't just use a constant computed at Verilation time. // We could use 64-bits of a MD5/SHA hash rather than a string here, // but the compare is only done on first call then memoized, so it's not worth optimizing. string stmt; stmt += "static int __Vfuncnum = -1;\n"; // Static doesn't need save-restore as if below will re-fill proper value // First time init (faster than what the compiler does if we did a singleton stmt += "if (VL_UNLIKELY(__Vfuncnum==-1)) { __Vfuncnum = Verilated::exportFuncNum(\""+nodep->cname()+"\"); }\n"; // If the find fails, it will throw an error stmt += "const VerilatedScope* __Vscopep = Verilated::dpiScope();\n"; // If dpiScope is fails and is null; the exportFind function throws and error string cbtype = v3Global.opt.prefix()+"__Vcb_"+nodep->cname()+"_t"; stmt += cbtype+" __Vcb = ("+cbtype+")(VerilatedScope::exportFind(__Vscopep, __Vfuncnum));\n"; // Can't use static_cast // 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); VL_DANGLING(argnodesp); 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,false,true,"__Vcvt","")); } } } if (rtnvarp) { dpip->addStmtsp(createDpiTemp(rtnvarp,"")); dpip->addStmtsp(createAssignInternalToDpi(rtnvarp,true,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()->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,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()->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"); // We don't warn on logic either, although the 4-stateness is lost. // That's what other simulators do. } } } 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(); VL_DANGLING(tempp); } // Delete rest of cloned task and return new func pushDeletep(nodep); VL_DANGLING(nodep); 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) { m_modp = nodep; m_insStmtp = NULL; m_modNCalls = 0; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstTopScope* nodep) { m_topScopep = nodep; nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep) { m_scopep = nodep; m_insStmtp = NULL; nodep->iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstNodeFTaskRef* nodep) { 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(); VL_DANGLING(nodep); UINFO(4," FTask REF Done.\n"); } virtual void visit(AstNodeFTask* nodep) { 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()); VL_DANGLING(vscp); } } 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()); VL_DANGLING(vscp); } } // Just push for deletion, as other references to func may // remain until visitor exits nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); } m_insMode = prevInsMode; m_insStmtp = prevInsStmtp; } virtual void visit(AstWhile* nodep) { // 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) { nodep->v3fatalSrc("For statements should have been converted to while statements in V3Begin.cpp"); } virtual void visit(AstNodeStmt* nodep) { 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) { 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(); VL_DANGLING(pinp); } 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(); VL_DANGLING(pinp); } } 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()) { // The default value for this port might be a constant // expression that hasn't been folded yet. Try folding it // now; we don't have much to lose if it fails. newvaluep = V3Const::constifyParamsEdit(portp->valuep()); if (!newvaluep->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 = newvaluep->cloneTree(true); } } else { newvaluep = portp->valuep()->cloneTree(true); } // To avoid problems with callee needing to know to deleteTree or not, we make this into a pin UINFO(9,"Default pin for "<fileline(), portp->name(), newvaluep); if (tconnects[i].second) { // Have a "NULL" pin already defined for it tconnects[i].second->unlinkFrBack()->deleteTree(); tconnects[i].second=NULL; } tconnects[i].second = newp; reorganize = true; } if (tconnects[i].second) { UINFO(9,"Connect "< "< NONE"<pinsp()) nodep->pinsp()->unlinkFrBack(); // Must unlink each pin, not all pins linked together as one list for (int i=0; iv3fatalSrc("Lost argument in func conversion"); nodep->addPinsp(argp); } } if (debug()>=9) { nodep->dumpTree(cout,"-ftref-out: "); for (int i=0; i= 3); } verilator-3.916/src/V3Dead.cpp0000664000177100017500000003531413205574202016067 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Dead code elimination // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // DEAD TRANSFORMATIONS: // Remove any unreferenced modules // Remove any unreferenced variables // // TODO: A graph would make the process of circular and interlinked // dependencies easier to resolve. // NOTE: If redo this, consider using maybePointedTo()/broken() ish scheme // instead of needing as many visitors. // // The following nodes have package pointers and are cleaned up here: // AstRefDType, AstEnumItemRef, AstNodeVarRef, AstNodeFTask // These have packagep but will not exist at this stage // AstPackageImport, AstDot, AstPackageRef // // Note on packagep: After the V3Scope/V3LinkDotScoped stage, package links // are no longer used, but their presence prevents us from removing empty // packages. As the links as no longer used after V3Scope, we remove them // here after scoping to allow more dead node // removal. // ************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Dead.h" #include "V3Ast.h" //###################################################################### class DeadModVisitor : public AstNVisitor { // In a module that is dead, cleanup the in-use counts of the modules private: // NODE STATE // ** Shared with DeadVisitor ** // VISITORS virtual void visit(AstCell* nodep) { nodep->iterateChildren(*this); nodep->modp()->user1Inc(-1); } //----- virtual void visit(AstNodeMath* nodep) {} // Accelerate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit DeadModVisitor(AstNodeModule* nodep) { nodep->accept(*this); } virtual ~DeadModVisitor() {} }; //###################################################################### // Dead state, as a visitor of each AstNode class DeadVisitor : public AstNVisitor { private: // NODE STATE // Entire Netlist: // AstNodeModule::user1() -> int. Count of number of cells referencing this module. // AstVar::user1() -> int. Count of number of references // AstVarScope::user1() -> int. Count of number of references // AstNodeDType::user1() -> int. Count of number of references AstUser1InUse m_inuser1; // TYPES typedef multimap AssignMap; // STATE AstNodeModule* m_modp; // Current module vector m_varsp; // List of all encountered to avoid another loop through tree vector m_dtypesp; // List of all encountered to avoid another loop through tree vector m_vscsp; // List of all encountered to avoid another loop through tree vector m_scopesp; // List of all encountered to avoid another loop through tree vector m_cellsp; // 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_elimScopes; // Allow removal of Scopes bool m_elimCells; // Allow removal of Cells 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_dtypesp.push_back(nodep); } if (AstNode* subnodep = nodep->virtRefDTypep()) { subnodep->user1Inc(); } } // VISITORS virtual void visit(AstNodeModule* nodep) { m_modp = nodep; if (!nodep->dead()) { nodep->iterateChildren(*this); checkAll(nodep); } m_modp = NULL; } virtual void visit(AstCFunc* nodep) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->scopep()) nodep->scopep()->user1Inc(); } virtual void visit(AstScope* nodep) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->aboveScopep()) nodep->aboveScopep()->user1Inc(); if (!nodep->isTop() && !nodep->varsp() && !nodep->blocksp() && !nodep->finalClksp()) { m_scopesp.push_back(nodep); } } virtual void visit(AstCell* nodep) { nodep->iterateChildren(*this); checkAll(nodep); m_cellsp.push_back(nodep); nodep->modp()->user1Inc(); } virtual void visit(AstNodeVarRef* nodep) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->varScopep()) { nodep->varScopep()->user1Inc(); nodep->varScopep()->varp()->user1Inc(); } if (nodep->varp()) { nodep->varp()->user1Inc(); } if (nodep->packagep()) { if (m_elimCells) nodep->packagep(NULL); else nodep->packagep()->user1Inc(); } } virtual void visit(AstNodeFTaskRef* nodep) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->packagep()) { if (m_elimCells) nodep->packagep(NULL); else nodep->packagep()->user1Inc(); } } virtual void visit(AstRefDType* nodep) { nodep->iterateChildren(*this); checkDType(nodep); checkAll(nodep); if (nodep->packagep()) { if (m_elimCells) nodep->packagep(NULL); else nodep->packagep()->user1Inc(); } } virtual void visit(AstNodeDType* nodep) { nodep->iterateChildren(*this); checkDType(nodep); checkAll(nodep); } virtual void visit(AstEnumItemRef* nodep) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->packagep()) { if (m_elimCells) nodep->packagep(NULL); else nodep->packagep()->user1Inc(); } checkAll(nodep); } virtual void visit(AstModport* nodep) { nodep->iterateChildren(*this); if (m_elimCells) { if (!nodep->varsp()) { pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep); return; } } checkAll(nodep); } virtual void visit(AstTypedef* nodep) { nodep->iterateChildren(*this); if (m_elimCells && !nodep->attrPublic()) { pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep); return; } checkAll(nodep); // Don't let packages with only public variables disappear // Normal modules may disappear, e.g. if they are parameterized then removed if (nodep->attrPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc(); } virtual void visit(AstVarScope* nodep) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->scopep()) nodep->scopep()->user1Inc(); if (mightElimVar(nodep->varp())) { m_vscsp.push_back(nodep); } } virtual void visit(AstVar* nodep) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->isSigPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc(); if (mightElimVar(nodep)) { m_varsp.push_back(nodep); } } virtual void visit(AstNodeAssign* nodep) { // 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) { 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->dead() || (modp->level()>2 && modp->user1()==0 && !modp->internal())) { // > 2 because L1 is the wrapper, L2 is the top user module UINFO(4," Dead module "<dead()) { // If was dead didn't increment user1's DeadModVisitor visitor(modp); } modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp); retry = true; } } } } bool mightElimVar(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 deadCheckScope() { for (bool retry=true; retry; ) { retry = false; for (vector::iterator it = m_scopesp.begin(); it != m_scopesp.end();++it) { AstScope* scp = *it; if (!scp) continue; if (scp->user1() == 0) { UINFO(4, " Dead AstScope " << scp << endl); scp->aboveScopep()->user1Inc(-1); if (scp->dtypep()) { scp->dtypep()->user1Inc(-1); } scp->unlinkFrBack()->deleteTree(); VL_DANGLING(scp); *it = NULL; retry = true; } } } } void deadCheckCells() { for (vector::iterator it = m_cellsp.begin(); it!=m_cellsp.end(); ++it) { AstCell* cellp = *it; if (cellp->user1() == 0 && !cellp->modp()->stmtsp()) { cellp->modp()->user1Inc(-1); cellp->unlinkFrBack()->deleteTree(); VL_DANGLING(cellp); } } } 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 itr = eqrange.first; itr != eqrange.second; ++itr) { AstNodeAssign* assp = itr->second; UINFO(4," Dead assign "<dtypep()->user1Inc(-1); assp->unlinkFrBack()->deleteTree(); VL_DANGLING(assp); } if (vscp->scopep()) vscp->scopep()->user1Inc(-1); vscp->dtypep()->user1Inc(-1); vscp->unlinkFrBack()->deleteTree(); VL_DANGLING(vscp); } } for (bool retry=true; retry; ) { retry = false; for (vector::iterator it = m_varsp.begin(); it != m_varsp.end();++it) { AstVar* varp = *it; if (!varp) continue; if (varp->user1() == 0) { UINFO(4, " Dead " << varp << endl); if (varp->dtypep()) { varp->dtypep()->user1Inc(-1); } varp->unlinkFrBack()->deleteTree(); VL_DANGLING(varp); *it = NULL; retry = true; } } } for (vector::iterator it = m_dtypesp.begin(); it != m_dtypesp.end();++it) { if ((*it)->user1() == 0) { AstNodeClassDType *classp; // It's possible that there if a reference to each individual member, but // not to the dtype itself. Check and don't remove the parent dtype if // members are still alive. if ((classp = (*it)->castNodeClassDType())) { bool cont = true; for (AstMemberDType *memberp = classp->membersp(); memberp; memberp = memberp->nextp()->castMemberDType()) { if (memberp->user1() != 0) { cont = false; break; } } if (!cont) continue; } (*it)->unlinkFrBack()->deleteTree(); VL_DANGLING(*it); } } } public: // CONSTRUCTORS DeadVisitor(AstNetlist* nodep, bool elimUserVars, bool elimDTypes, bool elimScopes, bool elimCells) { m_modp = NULL; m_elimCells = elimCells; m_elimUserVars = elimUserVars; m_elimDTypes = elimDTypes; m_elimScopes = elimScopes; m_sideEffect = false; // Prepare to remove some datatypes nodep->typeTablep()->clearCache(); // Operate on whole netlist nodep->accept(*this); deadCheckVar(); // We only elimate scopes when in a flattened structure // Otherwise we have no easy way to know if a scope is used if (elimScopes) deadCheckScope(); if (elimCells) deadCheckCells(); // Modules after vars, because might be vars we delete inside a mod we delete deadCheckMod(); // We may have removed some datatypes, cleanup nodep->typeTablep()->repairCache(); } virtual ~DeadVisitor() {} }; //###################################################################### // Dead class functions void V3Dead::deadifyModules(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } void V3Dead::deadifyDTypes(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Dead::deadifyDTypesScoped(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Dead::deadifyAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Dead::deadifyAllScoped(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3EmitV.h0000664000177100017500000000255613205574202015725 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit Verilog code for module tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EMITV_H_ #define _V3EMITV_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3EmitV { public: static void emitv(); static void verilogForTree(AstNode* nodep, ostream& os=cout); static void verilogPrefixedTree(AstNode* nodep, ostream& os, const string& prefix, int flWidth, AstSenTree* domainp, bool user3percent); }; #endif // Guard verilator-3.916/src/V3LifePost.h0000664000177100017500000000226013205574202016416 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Lifepost variable analysis // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LIFEPOST_H_ #define _V3LIFEPOST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3LifePost { public: static void lifepostAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3Coverage.h0000664000177100017500000000231013205574202016420 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Coverage modules/signals together // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3COVERAGE_H_ #define _V3COVERAGE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Coverage { public: // CONSTRUCTORS static void coverage(AstNetlist* rootp); }; #endif // Guard verilator-3.916/src/VlcBucket.h0000664000177100017500000000764313205574202016354 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Bucket container // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCBUCKET_H_ #define _VLCBUCKET_H_ 1 #include "config_build.h" #include "verilatedos.h" //******************************************************************** // VlcBuckets - Container of all coverage point hits for a given test // This is a bitmap array - we store a single bit to indicate a test // has hit that point with sufficient coverage. class VlcBuckets { private: // MEMBERS vluint64_t* m_datap; ///< Pointer to first bucket (dynamically allocated) vluint64_t m_dataSize; ///< Current entries in m_datap vluint64_t m_bucketsCovered; ///< Num buckets with sufficient coverage private: static inline vluint64_t covBit(vluint64_t point) { return 1ULL<<(point & 63); } inline vluint64_t allocSize() const { return sizeof(vluint64_t) * m_dataSize / 64; } void allocate(vluint64_t point) { vluint64_t oldsize = m_dataSize; if (m_dataSize= sufficient()) { //UINFO(9," addData "< #include #include #include #include #include #include #include "V3Global.h" #include "V3GraphAlg.h" //###################################################################### //###################################################################### // Algorithms - delete void V3Graph::deleteCutableOnlyEdges() { // Any vertices with only cutable edges will get deleted // Vertex::m_user begin: indicates can be deleted // Pass 1, mark those. Don't delete now, as we don't want to rip out whole trees for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertexp->user(true); for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { if (!edgep->cutable()) { vertexp->user(false); // Can't delete it break; } } for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (!edgep->cutable()) { vertexp->user(false); // Can't delete it break; } } } // Pass 2, delete those marked // Rather than doing a delete() we set the weight to 0 which disconnects the edge. for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (vertexp->user()) { //UINFO(7,"Disconnect "<name()<outBeginp(); edgep; edgep=edgep->outNextp()) { edgep->cut(); } } } // Vertex::m_user end, now unused } //###################################################################### //###################################################################### // Algorithms - weakly connected components class GraphRemoveRedundant : GraphAlg { bool m_sumWeights; ///< Sum, rather then maximize weights private: void main() { for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertexIterate(vertexp); } } void vertexIterate(V3GraphVertex* vertexp) { // Clear marks for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { edgep->top()->userp(NULL); } // Mark edges and detect duplications for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); if (followEdge(edgep)) { V3GraphVertex* outVertexp = edgep->top(); V3GraphEdge* prevEdgep = (V3GraphEdge*)outVertexp->userp(); if (!prevEdgep) { // No previous assignment outVertexp->userp(edgep); } else { // Duplicate bool saveOld = true; if (prevEdgep->cutable() && !edgep->cutable()) { saveOld = false; // new !cutable more important than old } else if (!prevEdgep->cutable() && edgep->cutable()) { saveOld = true; // old !cutable more important than new } else { saveOld = true; if (!m_sumWeights && (prevEdgep->weight() < edgep->weight())) { // Keep max weight prevEdgep->weight(edgep->weight()); } } if (saveOld) { if (m_sumWeights) prevEdgep->weight(prevEdgep->weight() + edgep->weight()); edgep->unlinkDelete(); VL_DANGLING(edgep); } else { if (m_sumWeights) edgep->weight(prevEdgep->weight() + edgep->weight()); prevEdgep->unlinkDelete(); VL_DANGLING(prevEdgep); 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 + vertexp->rankAdder()); } } 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"); 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.916/src/V3LangCode.h0000664000177100017500000000447013205574202016352 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Language code class // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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* const 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) {} // cppcheck-suppress noExplicitConstructor inline V3LangCode (en _e) : m_e(_e) {} explicit V3LangCode (const char* textp); explicit inline V3LangCode (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; //###################################################################### #endif // guard verilator-3.916/src/V3Order.h0000664000177100017500000000223513205574202015746 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Block code ordering // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Undriven.h0000664000177100017500000000226713205574202016472 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/VlcPoint.h0000664000177100017500000001131213205574202016214 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Coverage points // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCPOINT_H_ #define _VLCPOINT_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "verilated_cov_key.h" #include #include #include VL_INCLUDE_UNORDERED_MAP //******************************************************************** // VlcPoint - A coverage point (across all tests) class VlcPoint { private: // MEMBERS string m_name; //< Name of the point vluint64_t m_pointNum; //< Point number vluint64_t m_testsCovering;//< Number tests with non-zero coverage of this point vluint64_t m_count; //< Count of hits across all tests public: // CONSTRUCTORS VlcPoint(const string& name, int pointNum) { m_name = name; m_pointNum = pointNum; m_testsCovering = 0; m_count = 0; } ~VlcPoint() {} // ACCESSORS const string& name() const { return m_name; } vluint64_t pointNum() const { return m_pointNum; } vluint64_t testsCovering() const { return m_testsCovering; } void countInc(vluint64_t inc) { m_count += inc; } vluint64_t count() const { return m_count; } void testsCoveringInc() { m_testsCovering++; } // KEY ACCESSORS string filename() const { return keyExtract(VL_CIK_FILENAME); } string comment() const { return keyExtract(VL_CIK_COMMENT); } string type() const { return keyExtract(VL_CIK_TYPE); } string thresh() const { return keyExtract(VL_CIK_THRESH); } // string as maybe "" int lineno() const { return atoi(keyExtract(VL_CIK_LINENO).c_str()); } int column() const { return atoi(keyExtract(VL_CIK_COLUMN).c_str()); } // METHODS string keyExtract(const char* shortKey) const { // Hot function size_t shortLen = strlen(shortKey); const string namestr = name(); for (const char* cp = namestr.c_str(); *cp; ++cp) { if (*cp == '\001') { if (0==strncmp(cp+1, shortKey, shortLen) && cp[shortLen+1] == '\002') { cp += shortLen+2; // Skip \001+short+\002 const char* ep = cp; while (*ep && *ep != '\001') ++ep; return string(cp, ep-cp); } } } return ""; } static void dumpHeader() { cout<<"Points:\n"; cout<<" Num, TestsCover, Count, Name"< NameMap; NameMap m_nameMap; //< Name to point-number vector m_points; //< List of all points vluint64_t m_numPoints; //< Total unique points public: // ITERATORS typedef NameMap ByName; typedef ByName::iterator iterator; ByName::iterator begin() { return m_nameMap.begin(); } ByName::iterator end() { return m_nameMap.end(); } public: // CONSTRUCTORS VlcPoints() { m_numPoints = 0; } ~VlcPoints() {} // METHODS void dump() { UINFO(2,"dumpPoints...\n"); VlcPoint::dumpHeader(); for (VlcPoints::ByName::iterator it=begin(); it!=end(); ++it) { const VlcPoint& point = pointNumber(it->second); point.dump(); } } VlcPoint& pointNumber(vluint64_t num) { return m_points[num]; } vluint64_t findAddPoint(const string& name, vluint64_t count) { vluint64_t pointnum; NameMap::iterator iter = m_nameMap.find(name); if (iter != m_nameMap.end()) { pointnum = iter->second; m_points[pointnum].countInc(count); } else { pointnum = m_numPoints++; VlcPoint point (name, pointnum); point.countInc(count); m_points.push_back(point); m_nameMap.insert(make_pair(point.name(), point.pointNum())); } return pointnum; } }; //###################################################################### #endif // guard verilator-3.916/src/V3OrderGraph.h0000664000177100017500000004620013205574202016730 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Block code ordering // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 // OrderVarVertex // OrderVarStdVertex // OrderVarPreVertex // OrderVarPostVertex // OrderVarPordVertex // OrderVarSettleVertex // // V3GraphEdge // OrderEdge // OrderComboCutEdge // OrderPostCutEdge // OrderPreCutEdge //************************************************************************* #ifndef _V3ORDERGRAPH_H_ #define _V3ORDERGRAPH_H_ #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 struct OrderVEdgeType { enum en { VERTEX_UNKNOWN = 0, VERTEX_INPUTS, VERTEX_SETTLE, VERTEX_LOGIC, VERTEX_VARSTD, VERTEX_VARPRE, VERTEX_VARPOST, VERTEX_VARPORD, VERTEX_VARSETTLE, VERTEX_MOVE, EDGE_STD, EDGE_CHANGEDET, EDGE_COMBOCUT, EDGE_PRECUT, EDGE_POSTCUT, _ENUM_END }; const char* ascii() const { static const char* const names[] = { "%E-vedge", "VERTEX_INPUTS", "VERTEX_SETTLE", "VERTEX_LOGIC", "VERTEX_VARSTD", "VERTEX_VARPRE", "VERTEX_VARPOST", "VERTEX_VARPORD", "VERTEX_VARSETTLE", "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) {} // cppcheck-suppress noExplicitConstructor 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) bool m_isFromInput; // From input, or derived therefrom (conservatively false) protected: OrderEitherVertex(V3Graph* graphp, const OrderEitherVertex& old) : V3GraphVertex(graphp, old), m_scopep(old.m_scopep), m_domainp(old.m_domainp) , m_isFromInput(old.m_isFromInput) {} public: OrderEitherVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp) : V3GraphVertex(graphp), m_scopep(scopep), m_domainp(domainp) , 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; } void isFromInput(bool flag) { m_isFromInput=flag; } bool isFromInput() const { return m_isFromInput; } }; class OrderInputsVertex : public OrderEitherVertex { OrderInputsVertex(V3Graph* graphp, const OrderInputsVertex& old) : OrderEitherVertex(graphp, old) {} public: OrderInputsVertex(V3Graph* graphp, AstSenTree* domainp) : OrderEitherVertex(graphp, NULL, domainp) { isFromInput(true); // By definition } virtual ~OrderInputsVertex() {} virtual OrderInputsVertex* clone(V3Graph* graphp) const { return new OrderInputsVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_INPUTS; } virtual string name() const { return "*INPUTS*"; } virtual string dotColor() const { return "green"; } virtual string dotName() const { return ""; } virtual bool domainMatters() { return false; } }; class OrderSettleVertex : public OrderEitherVertex { OrderSettleVertex(V3Graph* graphp, const OrderSettleVertex& old) : OrderEitherVertex(graphp, old) {} public: OrderSettleVertex(V3Graph* graphp, AstSenTree* domainp) : OrderEitherVertex(graphp, NULL, domainp) {} virtual ~OrderSettleVertex() {} virtual OrderSettleVertex* clone(V3Graph* graphp) const { return new OrderSettleVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_SETTLE; } virtual string name() const { return "*SETTLE*"; } virtual string dotColor() const { return "green"; } virtual string dotName() const { return ""; } virtual bool domainMatters() { return true; } }; class OrderLogicVertex : public OrderEitherVertex { AstNode* m_nodep; OrderMoveVertex* m_moveVxp; protected: OrderLogicVertex(V3Graph* graphp, const OrderLogicVertex& old) : OrderEitherVertex(graphp, old), m_nodep(old.m_nodep), m_moveVxp(old.m_moveVxp) {} public: OrderLogicVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp, AstNode* nodep) : OrderEitherVertex(graphp, scopep, domainp), m_nodep(nodep), m_moveVxp(NULL) {} virtual ~OrderLogicVertex() {} virtual OrderLogicVertex* clone(V3Graph* graphp) const { return new OrderLogicVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOGIC; } virtual bool domainMatters() { return true; } // Accessors virtual string name() const { return (cvtToStr((void*)m_nodep)+"\\n "+cvtToStr(nodep()->typeName())); } AstNode* nodep() const { return m_nodep; } virtual string dotColor() const { return "yellow"; } OrderMoveVertex* moveVxp() const { return m_moveVxp; } void moveVxp(OrderMoveVertex* moveVxp) { m_moveVxp = moveVxp; } }; class OrderVarVertex : public OrderEitherVertex { AstVarScope* m_varScp; OrderVarVertex* m_pilNewVertexp; // for processInsLoopNewVar bool m_isClock; // Used as clock bool m_isDelayed; // Set in a delayed assignment protected: OrderVarVertex(V3Graph* graphp, const OrderVarVertex& old) : OrderEitherVertex(graphp, old) , m_varScp(old.m_varScp), m_pilNewVertexp(old.m_pilNewVertexp), m_isClock(old.m_isClock) , m_isDelayed(old.m_isDelayed) {} public: OrderVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp) , m_pilNewVertexp(NULL), m_isClock(false), m_isDelayed(false) {} virtual ~OrderVarVertex() {} virtual OrderVarVertex* clone (V3Graph* graphp) const = 0; virtual OrderVEdgeType type() const = 0; // Accessors AstVarScope* varScp() const { return m_varScp; } void isClock(bool flag) { m_isClock=flag; } bool isClock() const { return m_isClock; } void isDelayed(bool flag) { m_isDelayed=flag; } bool isDelayed() const { return m_isDelayed; } OrderVarVertex* pilNewVertexp() const { return m_pilNewVertexp; } void pilNewVertexp (OrderVarVertex* vertexp) { m_pilNewVertexp = vertexp; } }; class OrderVarStdVertex : public OrderVarVertex { OrderVarStdVertex(V3Graph* graphp, const OrderVarStdVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarStdVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep, varScp) {} virtual ~OrderVarStdVertex() {} virtual OrderVarStdVertex* clone(V3Graph* graphp) const { return new OrderVarStdVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSTD; } virtual string name() const { return (cvtToStr((void*)varScp())+"\\n "+varScp()->name());} virtual string dotColor() const { return "skyblue"; } virtual bool domainMatters() { return true; } }; class OrderVarPreVertex : public OrderVarVertex { OrderVarPreVertex(V3Graph* graphp, const OrderVarPreVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarPreVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual ~OrderVarPreVertex() {} virtual OrderVarPreVertex* clone(V3Graph* graphp) const { return new OrderVarPreVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPRE; } virtual string name() const { return (cvtToStr((void*)varScp())+" PRE\\n "+varScp()->name());} virtual string dotColor() const { return "lightblue"; } virtual bool domainMatters() { return false; } }; class OrderVarPostVertex : public OrderVarVertex { OrderVarPostVertex(V3Graph* graphp, const OrderVarPostVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarPostVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual OrderVarPostVertex* clone(V3Graph* graphp) const { return new OrderVarPostVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPOST; } virtual ~OrderVarPostVertex() {} virtual string name() const { return (cvtToStr((void*)varScp())+" POST\\n "+varScp()->name());} virtual string dotColor() const { return "CadetBlue"; } virtual bool domainMatters() { return false; } }; class OrderVarPordVertex : public OrderVarVertex { OrderVarPordVertex(V3Graph* graphp, const OrderVarPordVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarPordVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual ~OrderVarPordVertex() {} virtual OrderVarPordVertex* clone(V3Graph* graphp) const { return new OrderVarPordVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPORD; } virtual string name() const { return (cvtToStr((void*)varScp())+" PORD\\n "+varScp()->name());} virtual string dotColor() const { return "NavyBlue"; } virtual bool domainMatters() { return false; } }; class OrderVarSettleVertex : public OrderVarVertex { OrderVarSettleVertex(V3Graph* graphp, const OrderVarSettleVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarSettleVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual ~OrderVarSettleVertex() {} virtual OrderVarSettleVertex* clone(V3Graph* graphp) const { return new OrderVarSettleVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSETTLE; } virtual string name() const { return (cvtToStr((void*)varScp())+" STL\\n "+varScp()->name());} virtual string dotColor() const { return "PowderBlue"; } virtual bool domainMatters() { return false; } }; //###################################################################### //--- 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 { if (logicp()) { return logicp()->dotColor(); } else { return ""; } } virtual string name() const { string nm; if (logicp()) { nm = logicp()->name(); nm += (string("\\nMV:") +" d="+cvtToStr((void*)logicp()->domainp()) +" s="+cvtToStr((void*)logicp()->scopep())); } else { nm = "nul"; } 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 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; } }; #endif // _V3ORDERGRAPH_H_ verilator-3.916/src/V3File.h0000664000177100017500000002007213205574202015551 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 { public: // TYPES typedef list StrList; private: V3InFilterImp* m_impp; // CONSTRUCTORS VL_UNCOPYABLE(V3InFilter); public: explicit V3InFilter(const string& command); ~V3InFilter(); // METHODS // Read file contents and return it. Return true on success. bool readWholefile(const string& filename, StrList& outl); }; //============================================================================ // V3OutFormatter: A class for automatic indentation of C++ or Verilog code. class V3OutFormatter { // TYPES enum MiscConsts { 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_blockIndent; // Characters per block indent int m_commaWidth; // Width after which to break at ,'s 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 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; } int blockIndent() const { return m_blockIndent; } void blockIndent(int flag) { m_blockIndent=flag; } // 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 string& strg); void putsQuoted(const string& strg); void putBreak(); // Print linebreak if line is too wide void putBreakExpr(); // Print linebreak in expression if line is too wide void putbs(const char* strg) { putBreakExpr(); puts(strg); } void putbs(const string& strg) { putBreakExpr(); puts(strg); } bool exceededWidth() const { return m_column > m_commaWidth; } bool tokenStart(const char* cp, const char* cmp); bool tokenEnd(const char* cp); void indentInc() { m_indentLevel += m_blockIndent; } void indentDec() { m_indentLevel -= m_blockIndent; UASSERT(m_indentLevel>=0, ": "<printf("%-19s\t%s;\n", classStar.c_str(), cellname.c_str()); } virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); } virtual void putsIntTopInclude() { putsForceIncs(); } // 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: explicit V3OutScFile(const string& filename) : V3OutCFile(filename) {} virtual ~V3OutScFile() {} virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); } virtual void putsIntTopInclude() { putsForceIncs(); puts("#include \"systemc.h\"\n"); puts("#include \"verilated_sc.h\"\n"); } }; class V3OutVFile : public V3OutFile { public: explicit V3OutVFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_VERILOG) {} virtual ~V3OutVFile() {} virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); } }; class V3OutXmlFile : public V3OutFile { public: explicit V3OutXmlFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_XML) { blockIndent(2); } virtual ~V3OutXmlFile() {} virtual void putsHeader() { puts("\n"); } }; class V3OutMkFile : public V3OutFile { public: explicit 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.916/src/V3Graph.h0000664000177100017500000002671013205574202015740 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph optimizations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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() const { 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) const; void dumpDotFilePrefixed(const string& nameComment, bool colorAsSubgraph=false) const; void dumpDotFilePrefixedAlways(const string& nameComment, bool colorAsSubgraph=false) const; void userClearVertices(); void userClearEdges(); static void selfTest(); // 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: explicit 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 uint32_t rankAdder() const { return 1; } 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.916/src/V3CCtors.cpp0000664000177100017500000001371013205574202016423 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Generate C language constructors and AstCReset nodes. // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3CCtors's Transformations: // Iterates over all modules and // for all AstVar, create a creates a AstCReset node in an _ctor_var_reset AstCFunc. // for all AstCoverDecl, move the declaration into a _configure_coverage AstCFunc. // For each variable that needs reset, add a AstCReset node. // // For primary inputs, add _eval_debug_assertions. // // This transformation honors outputSplitCFuncs. //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3EmitCBase.h" #include "V3CCtors.h" class V3CCtorsVisitor { private: string m_basename; string m_argsp; string m_callargsp; AstNodeModule* m_modp; // Current module AstCFunc* m_tlFuncp; // Top level function being built AstCFunc* m_funcp; // Current function int m_numStmts; // Number of statements output int m_funcNum; // Function number being built public: void add(AstNode* nodep) { if (v3Global.opt.outputSplitCFuncs() && v3Global.opt.outputSplitCFuncs() < m_numStmts) { m_funcp = NULL; } if (!m_funcp) { m_funcp = new AstCFunc(m_modp->fileline(), m_basename + "_" + cvtToStr(++m_funcNum), NULL, "void"); m_funcp->isStatic(false); m_funcp->declPrivate(true); m_funcp->slow(true); m_funcp->argTypes(m_argsp); m_modp->addStmtp(m_funcp); // Add a top call to it AstCCall* callp = new AstCCall(m_modp->fileline(), m_funcp); callp->argTypes(m_callargsp); m_tlFuncp->addStmtsp(callp); m_numStmts = 0; } m_funcp->addStmtsp(nodep); m_numStmts += 1; } V3CCtorsVisitor(AstNodeModule* nodep, string basename, string argsp="", string callargsp="", const string& stmt="") { m_basename = basename; m_argsp = argsp; m_callargsp = callargsp; m_modp = nodep; m_numStmts = 0; m_funcNum = 0; m_tlFuncp = new AstCFunc(nodep->fileline(), basename, NULL, "void"); m_tlFuncp->declPrivate(true); m_tlFuncp->isStatic(false); m_tlFuncp->slow(true); m_tlFuncp->argTypes(m_argsp); if (stmt != "") { m_tlFuncp->addStmtsp(new AstCStmt(nodep->fileline(), stmt)); } m_funcp = m_tlFuncp; m_modp->addStmtp(m_tlFuncp); } ~V3CCtorsVisitor() {} private: VL_UNCOPYABLE(V3CCtorsVisitor); }; //###################################################################### void V3CCtors::evalAsserts() { AstNodeModule* modp = v3Global.rootp()->modulesp(); // Top module AstCFunc* funcp = new AstCFunc(modp->fileline(), "_eval_debug_assertions", NULL, "void"); funcp->declPrivate(true); funcp->isStatic(false); funcp->slow(false); funcp->ifdef("VL_DEBUG"); modp->addStmtp(funcp); for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) { if (AstVar* varp = np->castVar()) { if (varp->isPrimaryIn() && !varp->isSc()) { if (AstBasicDType* basicp = varp->dtypeSkipRefp()->castBasicDType()) { int storedWidth = basicp->widthAlignBytes() * 8; int lastWordWidth = varp->width() % storedWidth; if (lastWordWidth != 0) { // if (signal & CONST(upper_non_clean_mask)) { fail; } AstNode* newp = new AstVarRef(varp->fileline(), varp, false); if (varp->isWide()) { newp = new AstWordSel(varp->fileline(), newp, new AstConst(varp->fileline(), varp->widthWords()-1)); } uint64_t value = VL_MASK_Q(storedWidth) & ~VL_MASK_Q(lastWordWidth); V3Number num (varp->fileline(), storedWidth, value); newp = new AstAnd(varp->fileline(), newp, new AstConst(varp->fileline(), num)); AstNodeIf* ifp = new AstIf(varp->fileline(), newp, new AstCStmt(varp->fileline(), "Verilated::overWidthError(\""+varp->prettyName()+"\");")); ifp->branchPred(AstBranchPred::BP_UNLIKELY); newp = ifp; funcp->addStmtsp(newp); } } } } } } void V3CCtors::cctorsAll() { UINFO(2,__FUNCTION__<<": "<modulesp(); modp; modp=modp->nextp()->castNodeModule()) { // Process each module in turn { V3CCtorsVisitor var_reset (modp, "_ctor_var_reset"); for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) { if (AstVar* varp = np->castVar()) { var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true))); } } } if (v3Global.opt.coverage()) { V3CCtorsVisitor configure_coverage (modp, "_configure_coverage", EmitCBaseVisitor::symClassVar()+ ", bool first", "vlSymsp, first", "if (0 && vlSymsp && first) {} // Prevent unused\n"); for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) { if (AstCoverDecl* coverp = np->castCoverDecl()) { AstNode* backp = coverp->backp(); coverp->unlinkFrBack(); configure_coverage.add(coverp); np = backp; } } } } } verilator-3.916/src/V3Number.cpp0000664000177100017500000016344513205624356016477 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Number.h" #define MAX_SPRINTF_DOUBLE_SIZE 100 // Maximum characters with a sprintf %e/%f/%g (probably < 30) //###################################################################### // Read class functions // CREATION V3Number::V3Number(VerilogStringLiteral, FileLine* fileline, const string& str) { // Create a number using a verilog string as the value, thus 8 bits per character. // cppcheck bug - doesn't see init() resets these // cppcheck: Member variable 'm_sized/m_width' is not initialized in the constructor init(fileline, str.length()*8); m_fromString = true; for (unsigned pos=0; posopAdd(product,addend); if (product.bitsValue(width(), 4)) { // Overflowed m_fileline->v3error("Too many digits for "<v3error("As that number was unsized ('d...) it is limited to 32 bits (IEEE 2012 5.7.1)"); } } while (*(cp+1)) cp++; // Skip ahead so don't get multiple warnings } } olen++; got_01 = 1; break; } case 'z': case '?': { if (!m_sized) m_fileline->v3error("Unsized X/Z/? not legal in decimal constant: "<<*cp); setAllBitsZ(); got_z = 1; break; } case 'x': { if (!m_sized) m_fileline->v3error("Unsized X/Z/? not legal in decimal constant: "<<*cp); got_x = 1; setAllBitsX(); break; } case '_': break; default: { m_fileline->v3error("Illegal character in decimal constant: "<<*cp); break; } } } obit = width(); if ((got_01+got_x+got_z)>1) m_fileline->v3error("Mixing X/Z/? with digits not legal in decimal constant: "<=value_startp && obit<=width()); cp--) { if (*cp!='_' && *cp!='0' && obit>=width()) { m_fileline->v3error("Too many digits for "<v3error("Illegal character in binary constant: "<<*cp); } break; } case 'o': case 'c': { switch(tolower(*cp)) { case '0': setBit(obit++, 0); setBit(obit++, 0); setBit(obit++, 0); break; case '1': setBit(obit++, 1); setBit(obit++, 0); setBit(obit++, 0); break; case '2': setBit(obit++, 0); setBit(obit++, 1); setBit(obit++, 0); break; case '3': setBit(obit++, 1); setBit(obit++, 1); setBit(obit++, 0); break; case '4': setBit(obit++, 0); setBit(obit++, 0); setBit(obit++, 1); break; case '5': setBit(obit++, 1); setBit(obit++, 0); setBit(obit++, 1); break; case '6': setBit(obit++, 0); setBit(obit++, 1); setBit(obit++, 1); break; case '7': setBit(obit++, 1); setBit(obit++, 1); setBit(obit++, 1); break; case 'z': case '?': setBit(obit++, 'z'); setBit(obit++, 'z'); setBit(obit++, 'z'); break; case 'x': setBit(obit++, 'x'); setBit(obit++, 'x'); setBit(obit++, 'x'); break; case '_': break; default: m_fileline->v3error("Illegal character in octal constant"); } break; } case 'h': { switch(tolower(*cp)) { case '0': setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); break; case '1': setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); break; case '2': setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); break; case '3': setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); break; case '4': setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); break; case '5': setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); break; case '6': setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); break; case '7': setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); break; case '8': setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); break; case '9': setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); break; case 'a': setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); break; case 'b': setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); break; case 'c': setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); break; case 'd': setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); break; case 'e': setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); break; case 'f': setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); break; case 'z': case '?': setBit(obit++,'z'); setBit(obit++,'z'); setBit(obit++,'z'); setBit(obit++,'z'); break; case 'x': setBit(obit++,'x'); setBit(obit++,'x'); setBit(obit++,'x'); setBit(obit++,'x'); break; case '_': break; default: m_fileline->v3error("Illegal character in hex constant: "<<*cp); } break; } default: m_fileline->v3error("Illegal base character: "<0; bit--) if (num & (VL_ULL(1)<>VL_ULL(32)) & VL_ULL(0xffffffff); opCleanThis(); return *this; } V3Number& V3Number::setLong(uint32_t value) { for (int i=0; iv3fatalSrc("Real operation on wrong sized number"); } m_double = true; union { double d; uint32_t u[2]; } u; u.d = value; for (int i=2; i>6)&3, (pos[0]>>3)&7, pos[0]&7); out += octal; } } return out; } bool V3Number::displayedFmtLegal(char format) { // Is this a valid format letter? switch (tolower(format)) { case 'b': return true; case 'c': return true; case 'd': return true; // Unsigned decimal case 'e': return true; case 'f': return true; case 'g': return true; case 'h': return true; case 'o': return true; case 'p': return true; // Pattern case 's': return true; case 't': return true; case 'u': return true; // Packed 2-state case 'v': return true; // Strength case 'x': return true; case 'z': return true; // Packed 4-state case '@': return true; // Packed string case '~': return true; // Signed decimal default: return false; } } string V3Number::displayed(FileLine*fl, const string& vformat) const { string::const_iterator pos = vformat.begin(); UASSERT(pos != vformat.end() && pos[0]=='%', "$display-like function with non format argument "<<*this); ++pos; string fmtsize; for (; pos != vformat.end() && (isdigit(pos[0]) || pos[0]=='.'); ++pos) { fmtsize += pos[0]; } string str; char code = tolower(pos[0]); switch (code) { case 'b': { int bit = width()-1; if (fmtsize == "0") while (bit && bitIs0(bit)) bit--; for (; bit>=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) fl->v3warn(WIDTH,"$display-like format of %c format of > 8 bit value"); unsigned int v = bitsValue(0, 8); char strc[2]; strc[0] = v&0xff; strc[1] = '\0'; str = strc; 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) { fl->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; } // 'l' // Library - converted to text by V3LinkResolve // 'p' // Packed - converted to another code by V3Width case 'u': { // Packed 2-state for (int i=0; i> 0) & 0xff); str += (char)((m_value[i] >> 8) & 0xff); str += (char)((m_value[i] >> 16) & 0xff); str += (char)((m_value[i] >> 24) & 0xff); } return str; } case 'z': { // Packed 4-state for (int i=0; i> 0) & 0xff); str += (char)((m_value[i] >> 8) & 0xff); str += (char)((m_value[i] >> 16) & 0xff); str += (char)((m_value[i] >> 24) & 0xff); str += (char)((m_valueX[i] >> 0) & 0xff); str += (char)((m_valueX[i] >> 8) & 0xff); str += (char)((m_valueX[i] >> 16) & 0xff); str += (char)((m_valueX[i] >> 24) & 0xff); } return str; } case 'v': { // Strength int bit = width()-1; for (; bit>=0; bit--) { if (bitIs0(bit)) str+="St0 "; // Yes, always a space even for bit 0 else if (bitIs1(bit)) str+="St1 "; else if (bitIsZ(bit)) str+="StZ "; else str+="StX"; } return str; } case '@': { // Packed string return toString(); } default: fl->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); // We allow wide numbers that represent values <= 64 bits for (int i=2; iwidth()-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->v3warn(WIDTHCONCAT,"More than a 8k bit replication is probably wrong: "<v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in streams."); } // Slice size should never exceed the lhs width int ssize=min(rhs.toUInt(), (unsigned)lhs.width()); for (int istart=0; istartwidth() != rhs.width()) return false; for (int bit=0; bitwidth(),rhs.width()); bit++) { if (this->bitIs(bit) != rhs.bitIs(bit)) { return false; } } return true; } V3Number& V3Number::opCaseEq (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.isCaseEq(rhs) ? 1:0); } V3Number& V3Number::opCaseNeq (const V3Number& lhs, const V3Number& rhs) { // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend. char outc = 0; for (int bit=0; bit - else if (lhs.bitIs1Extend(mbit) && rhs.bitIs0(mbit)) { outc=0; } // - !> + else { // both positive or negative, normal > for (int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIs((bit + rhsval) % this->width())); } return *this; } V3Number& V3Number::opRotL (const V3Number& lhs, const V3Number& rhs) { // L(lhs) bit return if (rhs.isFourState()) return setAllBitsX(); setZero(); uint32_t rhsval = rhs.toUInt(); for (int bit=0; bitwidth(); bit++) { if (bit >= (int)rhsval) { setBit(bit,lhs.bitIs((bit - rhsval) % this->width())); } } return *this; } V3Number& V3Number::opShiftR (const V3Number& lhs, const V3Number& rhs) { // L(lhs) bit return if (rhs.isFourState()) return setAllBitsX(); setZero(); for (int bit=32; bitwidth(); bit++) { setBit(bit,lhs.bitIs(bit + rhsval)); } } return *this; } V3Number& V3Number::opShiftRS (const V3Number& lhs, const V3Number& rhs, uint32_t lbits) { // L(lhs) bit return // The spec says a unsigned >>> still acts as a normal >>. // We presume it is signed; as that's V3Width's job to convert to opShiftR if (rhs.isFourState()) return setAllBitsX(); setZero(); for (int bit=32; bitwidth(); bit++) { setBit(bit,lhs.bitIs(lbits-1)); // 0/1/X/Z } if (rhs.bitIs1(lbits-1)) setAllBits1(); // -1 else 0 return *this; // shift of over 2^32 must be -1/0 } uint32_t rhsval = rhs.toUInt(); if (rhsval < (uint32_t)lhs.width()) { for (int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIsExtend(bit + rhsval, lbits)); } } else { for (int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIs(lbits-1)); // 0/1/X/Z } } return *this; } V3Number& V3Number::opShiftL (const V3Number& lhs, const V3Number& rhs) { // L(lhs) bit return if (rhs.isFourState()) return setAllBitsX(); setZero(); for (int bit=32; 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; iwidth(); 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"); } opAssign(lhs); m_double = false; return *this; } 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"); } opAssign(lhs); m_double = true; return *this; } V3Number& V3Number::opNegateD (const V3Number& lhs) { return setDouble(- lhs.toDouble()); } V3Number& V3Number::opAddD (const V3Number& lhs, const V3Number& rhs) { return setDouble(lhs.toDouble() + rhs.toDouble()); } V3Number& V3Number::opSubD (const V3Number& lhs, const V3Number& rhs) { return setDouble(lhs.toDouble() - rhs.toDouble()); } V3Number& V3Number::opMulD (const V3Number& lhs, const V3Number& rhs) { return setDouble(lhs.toDouble() * rhs.toDouble()); } V3Number& V3Number::opDivD (const V3Number& lhs, const V3Number& rhs) { // On exceptions, we just generate 'inf' through floating point // IEEE says it's implementation defined what happens return setDouble(lhs.toDouble() / rhs.toDouble()); } V3Number& V3Number::opPowD (const V3Number& lhs, const V3Number& rhs) { // On exceptions, we just generate 'inf' through floating point // IEEE says it's implementation defined what happens return setDouble(pow(lhs.toDouble(), rhs.toDouble())); } V3Number& V3Number::opEqD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() == rhs.toDouble()); } V3Number& V3Number::opNeqD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() != rhs.toDouble()); } V3Number& V3Number::opGtD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() > rhs.toDouble()); } V3Number& V3Number::opGteD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() >= rhs.toDouble()); } V3Number& V3Number::opLtD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() < rhs.toDouble()); } V3Number& V3Number::opLteD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() <= rhs.toDouble()); } //====================================================================== // Ops - String V3Number& V3Number::opConcatN (const V3Number& lhs, const V3Number& rhs) { return setString(lhs.toString() + rhs.toString()); } V3Number& V3Number::opReplN (const V3Number& lhs, const V3Number& rhs) { return opReplN(lhs, rhs.toUInt()); } V3Number& V3Number::opReplN (const V3Number& lhs, uint32_t rhsval) { string out; out.reserve(lhs.toString().length() * rhsval); for (unsigned times=0; times rhs.toString()); } V3Number& V3Number::opGteN (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toString() >= rhs.toString()); } V3Number& V3Number::opLtN (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toString() < rhs.toString()); } V3Number& V3Number::opLteN (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toString() <= rhs.toString()); } verilator-3.916/src/V3SymTable.h0000664000177100017500000002717613205574202016426 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Symbol table // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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; typedef set VSymConstMap; 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, VSymConstMap& doneSymsr, const string& indent, int numLevels, const string& searchName) const { os<= 1) { it->second->dumpIterate(os, doneSymsr, indent+"| ", numLevels-1, it->first); } } } } void dump(ostream& os, const string& indent="", int numLevels=1) const { VSymConstMap 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 { return m_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: void 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); } } void exportOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) { if (srcp->exported()) { if (VSymEnt* symp = findIdFlat(name)) { // Should already exist in current table if (!symp->exported()) symp->exported(true); } } } public: void importFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) { // Import tokens from source symbol table into this symbol table if (id_or_star != "*") { IdNameMap::const_iterator it = srcp->m_idNameMap.find(id_or_star); if (it != srcp->m_idNameMap.end()) { importOneSymbol(graphp, it->first, it->second); } } else { for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) { importOneSymbol(graphp, it->first, it->second); } } } void exportFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) { // Export tokens from source symbol table into this symbol table if (id_or_star != "*") { IdNameMap::const_iterator it = srcp->m_idNameMap.find(id_or_star); if (it != srcp->m_idNameMap.end()) { exportOneSymbol(graphp, it->first, it->second); } } else { for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) { exportOneSymbol(graphp, it->first, it->second); } } } void exportStarStar(VSymGraph* graphp) { // Export *:*: Export all tokens from imported packages for (IdNameMap::const_iterator it=m_idNameMap.begin(); it!=m_idNameMap.end(); ++it) { VSymEnt* symp = it->second; if (!symp->exported()) symp->exported(true); } } void importFromIface(VSymGraph* graphp, const VSymEnt* srcp, bool onlyUnmodportable = false) { // Import interface tokens from source symbol table into this symbol table, recursively UINFO(9, " importIf se"<<(void*)this<<" from se"<<(void*)srcp<m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) { const string& name = it->first; VSymEnt* subSrcp = it->second; AstVar* varp = subSrcp->nodep()->castVar(); if (!onlyUnmodportable || (varp && varp->varType() == AstVarType::GPARAM)) { VSymEnt* subSymp = new VSymEnt(graphp, subSrcp); reinsert(name, subSymp); // And recurse to create children subSymp->importFromIface(graphp, subSrcp); } } } void cellErrorScopes(AstNode* lookp, string prettyName="") { if (prettyName=="") prettyName = lookp->prettyName(); string scopes; for (IdNameMap::iterator it = m_idNameMap.begin(); it!=m_idNameMap.end(); ++it) { AstNode* nodep = it->second->nodep(); if (nodep->castCell() || (nodep->castModule() && nodep->castModule()->isTop())) { if (scopes != "") scopes += ", "; scopes += AstNode::prettyName(it->first); } } if (scopes=="") scopes=""; cerr< SymStack; // MEMBERS VSymEnt* m_symRootp; // Root symbol table SymStack m_symsp; // All symbol tables, to cleanup // CONSTRUCTORS VL_UNCOPYABLE(VSymGraph); public: explicit VSymGraph(AstNetlist* nodep) { m_symRootp = new VSymEnt(this, nodep); } ~VSymGraph() { for (SymStack::iterator it = m_symsp.begin(); it != m_symsp.end(); ++it) { delete (*it); } } public: // METHODS VSymEnt* rootp() const { return m_symRootp; } // Debug void dump(ostream& os, const string& indent="") { VSymConstMap 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->m_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.916/src/config_build.h.in0000664000177100017500000000467313205574202017523 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Configure source; system configuration // // This file is part of Verilator. // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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_VERILATOR_ROOT # define DEFENV_VERILATOR_ROOT "" #endif //********************************************************************** //**** Compile options #include #include #include #include #include using namespace std; //********************************************************************** //**** Configure-discovered library options // Define if struct stat has st_mtim.tv_nsec (from configure) #undef HAVE_STAT_NSEC //********************************************************************** //**** OS and compiler specifics #include "verilatedos.h" verilator-3.916/src/V3ParseLex.cpp0000664000177100017500000000510413205574202016747 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Error.h" #include "V3Global.h" #include "V3File.h" #include "V3ParseImp.h" //====================================================================== // Build in LEX script #define yyFlexLexer V3LexerBase #include "V3Lexer.yy.cpp" #undef yyFlexLexer //###################################################################### // Lex-derived class /// Override the base lexer class so we can add some access functions class V3Lexer : public V3LexerBase { public: // CONSTRUCTORS V3Lexer() : V3LexerBase(NULL) {} ~V3Lexer() {} // METHODS void statePop() { yy_pop_state(); } void unputString(const char* textp, size_t length) { // Add characters to input stream in back-to-front order const char* cp = textp; for (cp += length - 1; length--; cp--) { unput(*cp); } } }; void V3ParseImp::statePop() { parsep()->m_lexerp->statePop(); } void V3ParseImp::unputString(const char* textp, size_t length) { parsep()->m_lexerp->unputString(textp, length); } int V3ParseImp::yylexReadTok() { // Call yylex() remembering last non-whitespace token int token = parsep()->m_lexerp->yylex(); m_prevLexToken = token; // Save so can find '#' to parse following number return token; } //###################################################################### // Read class functions void V3ParseImp::lexNew(int debug) { if (m_lexerp) delete m_lexerp; // Restart from clean slate. m_lexerp = new V3Lexer(); if (debugFlex()>=9) { m_lexerp->set_debug(~0); } } void V3ParseImp::lexDestroy() { if (m_lexerp) { delete m_lexerp; m_lexerp = NULL; } } verilator-3.916/src/V3ClkGater.cpp0000664000177100017500000010232713206350461016725 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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: explicit 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: explicit 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: explicit 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) { okIterate(nodep); } virtual void visit(AstAnd* nodep) { okIterate(nodep); } virtual void visit(AstNot* nodep) { okIterate(nodep); } virtual void visit(AstLogOr* nodep) { okIterate(nodep); } virtual void visit(AstLogAnd* nodep) { okIterate(nodep); } virtual void visit(AstLogNot* nodep) { okIterate(nodep); } virtual void visit(AstVarRef* nodep) { 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) { m_isSimple = false; //nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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) { if (nodep->lvalue()) { AstVarScope* vscp = nodep->varScopep(); if (vscp->user2p() == 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(); VL_DANGLING(nodep); // Pass upwards we did delete m_state |= STATE_DELETE; } else { // Pass upwards we must keep m_state |= STATE_KEEP; } } virtual void visit(AstNode* nodep) { 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); VL_DANGLING(vVxp); VL_DANGLING(edgep); } 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(); VL_DANGLING(edgep); 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(); VL_DANGLING(edgep); } 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); VL_DANGLING(toVxp); VL_DANGLING(edgep); } } } } } 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); VL_DANGLING(toVxp); VL_DANGLING(edgep); } } } } 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"); } 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) cVxp->nodep()->v3fatalSrc("null condition"); if (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(nodep->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) { 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) { 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) { // iterateChildrenAlw will detect this is a statement for us iterateChildrenAlw(nodep, false); } virtual void visit(AstNodeAssign* nodep) { // 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) { if (!nodep->isClocked()) { nonOptimizable(nodep, "Non-clocked sensitivity"); } iterateChildrenAlw(nodep, false); } //-------------------- virtual void visit(AstNode* nodep) { 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 explicit GaterVisitor(AstNetlist* nodep) { // AstAlways visitor does the real work, so most zeroing needs to be in clear() clear(); nodep->accept(*this); } void clear() { m_nonopt = ""; m_directlyUnderAlw = false; m_ifDepth = 0; m_numIfs = 0; AstNode::user1ClearTree(); AstNode::user2ClearTree(); // Prepare graph m_graph.clear(); GaterVertex::clearRank(); m_pliVertexp = NULL; m_headVertexp = new GaterHeadVertex(&m_graph); m_aboveVertexp = m_headVertexp; m_aboveTrue = false; m_stmtVscp = NULL; m_stmtInPli = false; } virtual ~GaterVisitor() { V3Stats::addStat("Optimizations, Gaters inserted", m_statGaters); V3Stats::addStat("Optimizations, Gaters impacted bits", m_statBits); } }; //###################################################################### // Active class functions void V3ClkGater::clkGaterAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Width.cpp0000664000177100017500000050316713206351133016314 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Expression width calculations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Width's Transformations: // Top down traversal: // Determine width of sub-expressions // width() = # bits upper expression wants, 0 for anything-goes // widthUnsized() = # bits for unsized constant, or 0 if it's sized // widthMin() = Alternative acceptable width for linting, or width() if sized // Determine this subop's width, can be either: // Fixed width X // Unsized, min width X ('d5 is unsized, min 3 bits.) // Pass up: // width() = # bits this expression generates // widthSized() = true if all constants sized, else false // Compute size of this expression // Lint warn about mismatches // If expr size != subop fixed, bad // If expr size < subop unsized minimum, bad // If expr size != subop, edit netlist // For == and similar ops, if multibit underneath, add a REDOR // If subop larger, add a EXTRACT // If subop smaller, add a EXTEND // Pass size to sub-expressions if required (+/-* etc) // FINAL = true. // Subexpressions lint and extend as needed // //************************************************************************* // Signedness depends on: // Decimal numbers are signed // Based numbers are unsigned unless 's' prefix // Comparison results are unsigned // Bit&Part selects are unsigned, even if whole // Concatenates are unsigned // Ignore signedness of self-determined: // shift rhs, ** rhs, x?: lhs, concat and replicate members // Else, if any operand unsigned, output unsigned // // Real number rules: // Real numbers are real (duh) // Reals convert to integers by rounding // Reals init to 0.0 // Logicals convert compared to zero // If any operand is real, result is real //************************************************************************* // V3Width is the only visitor that uses vup. We could switch to using userp, // though note some iterators operate on next() and so would need to pass the // same value on each nextp(). //************************************************************************* // See notes in internal.txt about misuse of iterateAndNext and use of // iterateSubtreeReturnEdits. //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3Width.h" #include "V3Number.h" #include "V3Const.h" #include "V3String.h" #include "V3Task.h" // More code; this file was getting too large; see actions there #define _V3WIDTH_CPP_ #include "V3WidthCommit.h" //###################################################################### enum Stage { PRELIM=1,FINAL=2,BOTH=3 }; // Numbers are a bitmask <0>=prelim, <1>=final ostream& operator<<(ostream& str, const Stage& rhs) { return str<<("-PFB"[(int)rhs]); } enum Determ { SELF, // Self-determined CONTEXT, // Context-determined ASSIGN // Assignment-like where sign comes from RHS only }; ostream& operator<<(ostream& str, const Determ& rhs) { static const char* const s_det[] = {"SELF","CNTX","ASSN"}; return str<width(); } int widthMin() const { if (!m_dtypep) v3fatalSrc("Width request on self-determined or preliminary VUP"); return m_dtypep->widthMin(); } bool prelim() const { return m_stage & PRELIM; } bool final() const { return m_stage & FINAL; } void dump(ostream& str) const { if (!m_dtypep) { str<<" VUP(s="<dump(str); return str; } //###################################################################### class WidthClearVisitor { // Rather than a AstNVisitor, can just quickly touch every node void clearWidthRecurse(AstNode* nodep) { for (; nodep; nodep = nodep->nextp()) { nodep->didWidth(false); if (nodep->op1p()) clearWidthRecurse(nodep->op1p()); if (nodep->op2p()) clearWidthRecurse(nodep->op2p()); if (nodep->op3p()) clearWidthRecurse(nodep->op3p()); if (nodep->op4p()) clearWidthRecurse(nodep->op4p()); } } public: // CONSTUCTORS explicit WidthClearVisitor(AstNetlist* nodep) { clearWidthRecurse(nodep); } virtual ~WidthClearVisitor() {} }; //###################################################################### #define accept in_WidthVisitor_use_AstNode_iterate_instead_of_AstNode_accept //###################################################################### class WidthVisitor : public AstNVisitor { private: // TYPES typedef map, AstVar*> TableMap; typedef map PatVecMap; // STATE WidthVP* m_vup; // Current node state bool m_paramsOnly; // Computing parameter value; limit operation AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations AstFunc* m_funcp; // Current function AstInitial* m_initialp; // Current initial block AstAttrOf* m_attrp; // Current attribute bool m_doGenerate; // Do errors later inside generate statement int m_dtTables; // Number of created data type tables TableMap m_tableMap; // Created tables so can remove duplicates // ENUMS enum ExtendRule { EXTEND_EXP, // Extend if expect sign and node signed, e.g. node=y in ADD(x,y), "x + y" EXTEND_ZERO, // Extend with zeros. e.g. node=y in EQ(x,y), "x == y" EXTEND_LHS, // Extend with sign if node signed. e.g. node=y in ASSIGN(y,x), "x = y" EXTEND_OFF // No extension }; // METHODS static int debug() { return V3Width::debug(); } // VISITORS // Naming: width_O{outputtype}_L{lhstype}_R{rhstype}_W{widthing}_S{signing} // Where type: // _O1=boolean (width 1 unsigned) // _Ou=unsigned // _Os=signed // _Ous=unsigned or signed // _Or=real // _Ox=anything // Widths: 1 bit out, lhs 1 bit; Real: converts via compare with 0 virtual void visit(AstLogNot* nodep) { visit_log_not(nodep); } // Widths: 1 bit out, lhs 1 bit, rhs 1 bit; Real: converts via compare with 0 virtual void visit(AstLogAnd* nodep) { visit_log_and_or(nodep); } virtual void visit(AstLogOr* nodep) { visit_log_and_or(nodep); } virtual void visit(AstLogIf* nodep) { visit_log_and_or(nodep); } // Conversion from real not in IEEE, but a fallout virtual void visit(AstLogIff* nodep) { visit_log_and_or(nodep); } // Conversion from real not in IEEE, but a fallout // Widths: 1 bit out, Any width lhs virtual void visit(AstRedAnd* nodep) { visit_red_and_or(nodep); } virtual void visit(AstRedOr* nodep) { visit_red_and_or(nodep); } virtual void visit(AstRedXnor* nodep){ visit_red_and_or(nodep); } virtual void visit(AstRedXor* nodep) { visit_red_and_or(nodep); } virtual void visit(AstOneHot* nodep) { visit_red_and_or(nodep); } virtual void visit(AstOneHot0* nodep) { visit_red_and_or(nodep); } virtual void visit(AstIsUnknown* nodep) { visit_red_unknown(nodep); } // Allow real // These have different node types, as they operate differently // Must add to case statement below, // Widths: 1 bit out, lhs width == rhs width. real if lhs|rhs real virtual void visit(AstEq* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstNeq* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstGt* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstGte* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstLt* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstLte* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstGtS* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstGteS* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstLtS* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstLteS* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstEqCase* nodep) { visit_cmp_eq_gt(nodep, true); } virtual void visit(AstNeqCase* nodep) { visit_cmp_eq_gt(nodep, true); } // ... These comparisons don't allow reals virtual void visit(AstEqWild* nodep) { visit_cmp_eq_gt(nodep, false); } virtual void visit(AstNeqWild* nodep) { visit_cmp_eq_gt(nodep, false); } // ... Real compares virtual void visit(AstEqD* nodep) { visit_cmp_real(nodep); } virtual void visit(AstNeqD* nodep) { visit_cmp_real(nodep); } virtual void visit(AstLtD* nodep) { visit_cmp_real(nodep); } virtual void visit(AstLteD* nodep) { visit_cmp_real(nodep); } virtual void visit(AstGtD* nodep) { visit_cmp_real(nodep); } virtual void visit(AstGteD* nodep) { visit_cmp_real(nodep); } // ... String compares virtual void visit(AstEqN* nodep) { visit_cmp_string(nodep); } virtual void visit(AstNeqN* nodep) { visit_cmp_string(nodep); } virtual void visit(AstLtN* nodep) { visit_cmp_string(nodep); } virtual void visit(AstLteN* nodep) { visit_cmp_string(nodep); } virtual void visit(AstGtN* nodep) { visit_cmp_string(nodep); } virtual void visit(AstGteN* nodep) { visit_cmp_string(nodep); } // Widths: out width = lhs width = rhs width // Signed: Output signed iff LHS & RHS signed. // Real: Not allowed virtual void visit(AstAnd* nodep) { visit_boolmath_and_or(nodep); } virtual void visit(AstOr* nodep) { visit_boolmath_and_or(nodep); } virtual void visit(AstXnor* nodep) { visit_boolmath_and_or(nodep); } virtual void visit(AstXor* nodep) { visit_boolmath_and_or(nodep); } virtual void visit(AstBufIf1* nodep) { visit_boolmath_and_or(nodep); } // 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) { visit_add_sub_replace(nodep, true); } virtual void visit(AstSub* nodep) { visit_add_sub_replace(nodep, true); } virtual void visit(AstDiv* nodep) { visit_add_sub_replace(nodep, true); } virtual void visit(AstMul* nodep) { visit_add_sub_replace(nodep, true); } // These can't promote to real virtual void visit(AstModDiv* nodep) { visit_add_sub_replace(nodep, false); } virtual void visit(AstModDivS* nodep) { visit_add_sub_replace(nodep, false); } virtual void visit(AstMulS* nodep) { visit_add_sub_replace(nodep, false); } virtual void visit(AstDivS* nodep) { visit_add_sub_replace(nodep, 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) { visit_negate_not(nodep, true); } // Unary never real virtual void visit(AstNot* nodep) { visit_negate_not(nodep, false); } // Real: inputs and output real virtual void visit(AstAddD* nodep) { visit_real_add_sub(nodep); } virtual void visit(AstSubD* nodep) { visit_real_add_sub(nodep); } virtual void visit(AstDivD* nodep) { visit_real_add_sub(nodep); } virtual void visit(AstMulD* nodep) { visit_real_add_sub(nodep); } virtual void visit(AstPowD* nodep) { visit_real_add_sub(nodep); } // Real: Output real virtual void visit(AstNegateD* nodep) { visit_real_neg_ceil(nodep); } virtual void visit(AstCeilD* nodep) { visit_real_neg_ceil(nodep); } virtual void visit(AstExpD* nodep) { visit_real_neg_ceil(nodep); } virtual void visit(AstFloorD* nodep) { visit_real_neg_ceil(nodep); } virtual void visit(AstLogD* nodep) { visit_real_neg_ceil(nodep); } virtual void visit(AstLog10D* nodep) { visit_real_neg_ceil(nodep); } virtual void visit(AstSqrtD* nodep) { visit_real_neg_ceil(nodep); } // Widths: out signed/unsigned width = lhs width, input un|signed virtual void visit(AstSigned* nodep) { visit_signed_unsigned(nodep, AstNumeric::SIGNED); } virtual void visit(AstUnsigned* nodep) { visit_signed_unsigned(nodep, AstNumeric::UNSIGNED); } // Widths: Output width from lhs, rhs<33 bits // Signed: If lhs signed virtual void visit(AstShiftL* nodep) { visit_shift(nodep); } virtual void visit(AstShiftR* nodep) { visit_shift(nodep); } // ShiftRS converts to ShiftR, but not vice-versa virtual void visit(AstShiftRS* nodep) { visit_shift(nodep); } //======== // Widths: Output real, input integer signed virtual void visit(AstBitsToRealD* nodep) { visit_Or_Lu64(nodep); } virtual void visit(AstIToRD* nodep) { visit_Or_Ls32(nodep); } // Widths: Output integer signed, input real virtual void visit(AstRToIS* nodep) { visit_Os32_Lr(nodep); } virtual void visit(AstRToIRoundS* nodep) { visit_Os32_Lr(nodep); } // Widths: Output integer unsigned, input real virtual void visit(AstRealToBits* nodep) { visit_Ou64_Lr(nodep); } // Widths: Constant, terminal virtual void visit(AstTime* nodep) { nodep->dtypeSetUInt64(); } virtual void visit(AstTimeD* nodep) { nodep->dtypeSetDouble(); } virtual void visit(AstTestPlusArgs* nodep) { nodep->dtypeSetSigned32(); } virtual void visit(AstScopeName* nodep) { nodep->dtypeSetUInt64(); } // A pointer, but not that it matters // Special cases. So many.... virtual void visit(AstNodeCond* nodep) { // op=cond?expr1:expr2 // Signed: Output signed iff RHS & THS signed (presumed, not in IEEE) // See IEEE-2012 11.4.11 and Table 11-21. // LHS is self-determined // Width: max(RHS,THS) // Real: Output real if either expression is real, non-real argument gets converted if (m_vup->prelim()) { // First stage evaluation // Just once, do the conditional, expect one bit out. iterateCheckBool(nodep,"Conditional Test",nodep->condp(),BOTH); // Determine sub expression widths only relying on what's in the subops // CONTEXT determined, but need data type for pattern assignments userIterateAndNext(nodep->expr1p(), WidthVP(m_vup->dtypeNullp(),PRELIM).p()); userIterateAndNext(nodep->expr2p(), WidthVP(m_vup->dtypeNullp(),PRELIM).p()); // Calculate width of this expression. // First call (prelim()) m_vup->width() is probably zero, so we'll return // the size of this subexpression only. // Second call (final()) m_vup->width() is probably the expression size, so // the expression includes the size of the output too. if (nodep->expr1p()->isDouble() || nodep->expr2p()->isDouble()) { nodep->dtypeSetDouble(); } else { int width = max(nodep->expr1p()->width(), nodep->expr2p()->width()); int mwidth = max(nodep->expr1p()->widthMin(), nodep->expr2p()->widthMin()); bool issigned = nodep->expr1p()->isSigned() && nodep->expr2p()->isSigned(); nodep->dtypeSetLogicSized(width,mwidth,AstNumeric::fromBool(issigned)); } } if (m_vup->final()) { AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // Error report and change sizes for suboperands of this node. iterateCheck(nodep,"Conditional True", nodep->expr1p(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); iterateCheck(nodep,"Conditional False",nodep->expr2p(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); } } virtual void visit(AstConcat* nodep) { // Real: Not allowed (assumed) // Signed: unsigned output, input either (assumed) // IEEE-2012 Table 11-21, and 11.8.1: // LHS, RHS is self-determined // signed: Unsigned (11.8.1) // width: LHS + RHS if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); nodep->dtypeSetLogicSized(nodep->lhsp()->width() + nodep->rhsp()->width(), nodep->lhsp()->widthMin() + nodep->rhsp()->widthMin(), AstNumeric::UNSIGNED); // Cleanup zero width Verilog2001 {x,{0{foo}}} now, // otherwise having width(0) will cause later assertions to fire if (AstReplicate* repp=nodep->lhsp()->castReplicate()) { if (repp->width()==0) { // Keep rhs nodep->replaceWith(nodep->rhsp()->unlinkFrBack()); pushDeletep(nodep); VL_DANGLING(nodep); return; } } if (AstReplicate* repp=nodep->rhsp()->castReplicate()) { if (repp->width()==0) { // Keep lhs nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); pushDeletep(nodep); VL_DANGLING(nodep); return; } } if (nodep->lhsp()->isString() || nodep->rhsp()->isString()) { AstNode* newp = new AstConcatN (nodep->fileline(),nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); return; } } if (m_vup->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations."); } } } virtual void visit(AstConcatN* nodep) { // String concatenate. // Already did AstConcat simplifications if (m_vup->prelim()) { iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckString(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetString(); } if (m_vup->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) { // IEEE-2012 Table 11-21: // LHS, RHS is self-determined // width: value(LHS) * width(RHS) if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change AstConst* constp = nodep->rhsp()->castConst(); if (!constp) { nodep->v3error("Replication value isn't a constant."); return; } uint32_t times = constp->toUInt(); if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up. nodep->v3error("Replication value of 0 is only legal under a concatenation (IEEE 2012 11.4.12.1)"); times=1; } if (nodep->lhsp()->isString()) { AstNode* newp = new AstReplicateN(nodep->fileline(),nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); return; } else { nodep->dtypeSetLogicSized((nodep->lhsp()->width() * times), (nodep->lhsp()->widthMin() * times), AstNumeric::UNSIGNED); } } if (m_vup->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications."); } } } virtual void visit(AstReplicateN* nodep) { // Replicate with string if (m_vup->prelim()) { iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change AstConst* constp = nodep->rhsp()->castConst(); if (!constp) { nodep->v3error("Replication value isn't a constant."); return; } uint32_t times = constp->toUInt(); if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up. nodep->v3error("Replication value of 0 is only legal under a concatenation (IEEE 2012 11.4.12.1)"); } nodep->dtypeSetString(); } if (m_vup->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications."); } } } virtual void visit(AstNodeStream* nodep) { if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change AstConst* constp = nodep->rhsp()->castConst(); AstBasicDType* basicp = nodep->rhsp()->castBasicDType(); if (!constp && !basicp) { nodep->v3error("Slice size isn't a constant or basic data type."); return; } if (basicp) { // Convert data type to a constant size AstConst* newp = new AstConst(basicp->fileline(), basicp->width()); nodep->rhsp()->replaceWith(newp); pushDeletep(basicp); } else { uint32_t sliceSize = constp->toUInt(); if (!sliceSize) { nodep->v3error("Slice size cannot be zero."); return; } } nodep->dtypeSetLogicSized((nodep->lhsp()->width()), (nodep->lhsp()->widthMin()), AstNumeric::UNSIGNED); } if (m_vup->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in streams."); } } } virtual void visit(AstRange* nodep) { // 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 (m_vup->prelim()) { // Don't need to iterate because V3Const already constified int width = nodep->elementsConst(); if (width > (1<<28)) nodep->v3error("Width of bit range is huge; vector of over 1billion bits: 0x"<littleEndian() && !nodep->backp()->castUnpackArrayDType() && !nodep->backp()->castCell()) { // For cells we warn in V3Inst nodep->v3warn(LITENDIAN,"Little bit endian vector: MSB < LSB of bit range: "<lsbConst()<<":"<msbConst()); } } } virtual void visit(AstSel* nodep) { // Signed: always unsigned; Real: Not allowed // LSB is self-determined (IEEE 2012 11.5.1) // We also use SELs to shorten a signed constant etc, in this case they are signed. if (nodep->didWidth()) return; if (m_vup->prelim()) { if (debug()>=9) nodep->dumpTree(cout,"-selWidth: "); userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); userIterateAndNext(nodep->lsbp(), WidthVP(SELF,PRELIM).p()); checkCvtUS(nodep->fromp()); iterateCheckSizedSelf(nodep,"Select Width",nodep->widthp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"Select LHS",nodep->lhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->widthp()); // widthp may change AstConst* widthConstp = nodep->widthp()->castConst(); if (!widthConstp) { nodep->v3error("Width of bit extract isn't a constant"); nodep->dtypeSetLogicBool(); return; } int width = nodep->widthConst(); if (!nodep->dtypep()) nodep->v3fatalSrc("dtype wasn't set") // by V3WidthSel if (nodep->lsbp()->castConst() && nodep->msbConst() < nodep->lsbConst()) { nodep->v3error("Unsupported: MSB < LSB of bit extract: " <msbConst()<<"<"<lsbConst()); width = (nodep->lsbConst() - nodep->msbConst() + 1); nodep->dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); nodep->widthp()->replaceWith(new AstConst(nodep->widthp()->fileline(), width)); nodep->lsbp()->replaceWith(new AstConst(nodep->lsbp()->fileline(), 0)); } // We're extracting, so just make sure the expression is at least wide enough. if (nodep->fromp()->width() < width) { nodep->v3error("Extracting "<fromp()->width()<<" bit number"); // Extend it. AstNodeDType* subDTypep = nodep->findLogicDType(width,width,nodep->fromp()->dtypep()->numeric()); widthCheckSized(nodep,"errorless...",nodep->fromp(),subDTypep,EXTEND_EXP, false/*noerror*/); } // Check bit indexes. // What is the MSB? We want the true MSB, not one starting at 0, // because a 4 bit index is required to look at a one-bit variable[15:15] and 5 bits for [15:-2] int frommsb = nodep->fromp()->width() - 1; int fromlsb = 0; int elw = nodep->declElWidth(); // Must adjust to tell user bit ranges if (nodep->declRange().ranged()) { frommsb = nodep->declRange().hiMaxSelect()*elw + (elw-1); // Corrected for negative lsb fromlsb = nodep->declRange().lo()*elw; } else { //nodep->v3fatalSrc("Should have been declRanged in V3WidthSel"); } int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit AstNodeDType* selwidthDTypep = nodep->findLogicDType(selwidth,selwidth,nodep->lsbp()->dtypep()->numeric()); userIterateAndNext(nodep->fromp(), WidthVP(SELF,FINAL).p()); userIterateAndNext(nodep->lsbp(), WidthVP(SELF,FINAL).p()); if (widthBad(nodep->lsbp(),selwidthDTypep) && nodep->lsbp()->width()!=32) { if (!nodep->fileline()->warnIsOff(V3ErrorCode::WIDTH)) { nodep->v3warn(WIDTH,"Bit extraction of var["<<(frommsb/elw)<<":"<<(fromlsb/elw)<<"] requires " <<(selwidth/elw)<<" bit index, not " <<(nodep->lsbp()->width()/elw) <<(nodep->lsbp()->width()!=nodep->lsbp()->widthMin() ?" or "+cvtToStr(nodep->lsbp()->widthMin()/elw):"") <<" bits."); UINFO(1," Related node: "<lsbp()->castConst() && nodep->msbConst() > frommsb) { // See also warning in V3Const // We need to check here, because the widthCheckSized may silently // add another SEL which will lose the out-of-range check // // We don't want to trigger an error here if we are just // evaluating type sizes for a generate block condition. We // should only trigger the error if the out-of-range access is // actually generated. if (m_doGenerate) { UINFO(5, "Selection index out of range inside generate."<v3warn(SELRANGE,"Selection index out of range: " <msbConst()<<":"<lsbConst() <<" outside "<lsbp(),selwidthDTypep,EXTEND_EXP, false/*NOWARN*/); } } } virtual void visit(AstArraySel* nodep) { // Signed/Real: Output signed iff LHS signed/real; binary operator // Note by contrast, bit extract selects are unsigned // LSB is self-determined (IEEE 2012 11.5.1) if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"Bit select",nodep->bitp(),SELF,BOTH); userIterateAndNext(nodep->fromp(), WidthVP(SELF,BOTH).p()); // int frommsb; int fromlsb; AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp(); if (AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType()) { frommsb = adtypep->msb(); fromlsb = adtypep->lsb(); if (fromlsb>frommsb) {int t=frommsb; frommsb=fromlsb; fromlsb=t; } // However, if the lsb<0 we may go negative, so need more bits! if (fromlsb < 0) frommsb += -fromlsb; nodep->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference } else { // Note PackArrayDType doesn't use an ArraySel but a normal Sel. UINFO(1," Related dtype: "<v3fatalSrc("Array reference exceeds dimension of array"); frommsb = fromlsb = 0; } int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit AstNodeDType* selwidthDTypep = nodep->findLogicDType(selwidth,selwidth,nodep->bitp()->dtypep()->numeric()); if (widthBad(nodep->bitp(),selwidthDTypep) && nodep->bitp()->width()!=32) { nodep->v3warn(WIDTH,"Bit extraction of array["<bitp()->width() <<(nodep->bitp()->width()!=nodep->bitp()->widthMin() ?" or "+cvtToStr(nodep->bitp()->widthMin()):"") <<" bits."); if (!nodep->fileline()->warnIsOff(V3ErrorCode::WIDTH)) { UINFO(1," Related node: "<dtypep()<bitp()->castConst() && (nodep->bitp()->castConst()->toSInt() > (frommsb-fromlsb) || nodep->bitp()->castConst()->toSInt() < 0)) { nodep->v3warn(SELRANGE,"Selection index out of range: " <<(nodep->bitp()->castConst()->toSInt()+fromlsb) <<" outside "<bitp(),selwidthDTypep,EXTEND_EXP, false/*NOWARN*/); } } } virtual void visit(AstSliceSel* nodep) { // Always creates as output an unpacked array if (m_vup->prelim()) { userIterateAndNext(nodep->fromp(), WidthVP(SELF,BOTH).p()); // // Array indices are always constant AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp(); AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType(); if (!adtypep) { UINFO(1," Related dtype: "<v3fatalSrc("Packed array reference exceeds dimension of array"); } // Build new array Dtype based on the original's base type, but with new bounds AstNodeDType* newDtp = new AstUnpackArrayDType(nodep->fileline(), adtypep->subDTypep(), new AstRange(nodep->fileline(), nodep->declRange())); v3Global.rootp()->typeTablep()->addTypesp(newDtp); nodep->dtypeFrom(newDtp); if (!m_doGenerate) { // Must check bounds before adding a select that truncates the bound // Note we've already subtracted off LSB if ((nodep->declRange().hi() > adtypep->declRange().hi()) || nodep->declRange().lo() < adtypep->declRange().lo()) { // Other simulators warn too nodep->v3error("Slice selection index '"<< nodep->declRange() << "'" <<" outside data type's '"<< adtypep->declRange() << "'"); } else if ((nodep->declRange().littleEndian() != adtypep->declRange().littleEndian())) { nodep->v3error("Slice selection '"<< nodep->declRange() << "'" <<" has backward indexing versus data type's '"<< adtypep->declRange() << "'"); } } } } virtual void visit(AstSelBit* nodep) { // Just a quick check as after V3Param these nodes instead are AstSel's userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->attrp(), WidthVP(SELF,BOTH).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; userIterate(selp, m_vup); return; } nodep->v3fatalSrc("AstSelBit should disappear after widthSel"); } virtual void visit(AstSelExtract* nodep) { // Just a quick check as after V3Param these nodes instead are AstSel's userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->attrp(), WidthVP(SELF,BOTH).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; userIterate(selp, m_vup); return; } nodep->v3fatalSrc("AstSelExtract should disappear after widthSel"); } virtual void visit(AstSelPlus* nodep) { userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->attrp(), WidthVP(SELF,BOTH).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; userIterate(selp, m_vup); return; } nodep->v3fatalSrc("AstSelPlus should disappear after widthSel"); } virtual void visit(AstSelMinus* nodep) { userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel userIterateAndNext(nodep->attrp(), WidthVP(SELF,BOTH).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; userIterate(selp, m_vup); return; } nodep->v3fatalSrc("AstSelMinus should disappear after widthSel"); } virtual void visit(AstExtend* nodep) { // Only created by this process, so we know width from here down is correct. } virtual void visit(AstExtendS* nodep) { // Only created by this process, so we know width from here down is correct. } virtual void visit(AstConst* nodep) { // 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 (m_vup && m_vup->prelim()) { if (nodep->num().isString()) { nodep->dtypeSetString(); } else if (nodep->num().sized()) { nodep->dtypeChgWidth(nodep->num().width(), nodep->num().width()); } else { nodep->dtypeChgWidth(nodep->num().width(), nodep->num().widthMin()); } } // We don't size the constant until we commit the widths, as need parameters // to remain unsized, and numbers to remain unsized to avoid backp() warnings } virtual void visit(AstRand* nodep) { if (m_vup->prelim()) { nodep->dtypeSetSigned32(); // Says the spec } } virtual void visit(AstUCFunc* nodep) { // Give it the size the user wants. if (m_vup && m_vup->prelim()) { nodep->dtypeSetLogicSized(32,1,AstNumeric::UNSIGNED); // We don't care // All arguments seek their natural sizes userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); } if (m_vup->final()) { AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); nodep->dtypeFrom(expDTypep); // Assume user knows the rules; go with the flow if (nodep->width()>64) nodep->v3error("Unsupported: $c can't generate wider than 64 bits"); } } virtual void visit(AstCLog2* nodep) { if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); nodep->dtypeSetSigned32(); } } virtual void visit(AstPow* nodep) { // Pow is special, output sign only depends on LHS sign, but function result depends on both signs // RHS is self-determined (IEEE) // Real if either side is real (as with AstAdd) if (m_vup->prelim()) { userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); spliceCvtD(nodep->rhsp()); replaceWithDVersion(nodep); VL_DANGLING(nodep); return; } checkCvtUS(nodep->lhsp()); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); nodep->dtypeFrom(nodep->lhsp()); } if (m_vup->final()) { AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); nodep->dtypeFrom(expDTypep); // rhs already finalized in iterate_shift_prelim iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,nodep->dtypep(),EXTEND_EXP); AstNode* newp = NULL; // No change if (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()) { newp = new AstPowSS (nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); } else if (nodep->lhsp()->isSigned() && !nodep->rhsp()->isSigned()) { newp = new AstPowSU (nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); } else if (!nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()) { newp = new AstPowUS (nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); } if (newp) { newp->dtypeFrom(nodep); UINFO(9,"powOld "<replaceWith(newp); VL_DANGLING(nodep); } } } virtual void visit(AstPowSU* nodep) { // POWSU/SS/US only created here, dtype already determined, so nothing to do in this function userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->rhsp(), WidthVP(SELF,BOTH).p()); } virtual void visit(AstPowSS* nodep) { // POWSU/SS/US only created here, dtype already determined, so nothing to do in this function userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->rhsp(), WidthVP(SELF,BOTH).p()); } virtual void visit(AstPowUS* nodep) { // POWSU/SS/US only created here, dtype already determined, so nothing to do in this function userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->rhsp(), WidthVP(SELF,BOTH).p()); } virtual void visit(AstCountOnes* nodep) { if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); // If it's a 32 bit number, we need a 6 bit number as we need to return '32'. int selwidth = V3Number::log2b(nodep->lhsp()->width())+1; nodep->dtypeSetLogicSized(selwidth,selwidth,AstNumeric::UNSIGNED); // Spec doesn't indicate if an integer } } virtual void visit(AstCvtPackString* nodep) { // Opaque returns, so arbitrary userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); // Type set in constructor } virtual void visit(AstAttrOf* nodep) { AstAttrOf* oldAttr = m_attrp; m_attrp = nodep; userIterateAndNext(nodep->fromp(), WidthVP(SELF,BOTH).p()); // Don't iterate children, don't want to lose VarRef. switch (nodep->attrType()) { case AstAttrType::VAR_BASE: case AstAttrType::MEMBER_BASE: case AstAttrType::ENUM_BASE: // Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf break; case AstAttrType::DIM_DIMENSIONS: case AstAttrType::DIM_UNPK_DIMENSIONS: { if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); pair dim = nodep->fromp()->dtypep()->dimensions(true); int val = (nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS ? dim.second : (dim.first+dim.second)); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32(), val)); nodep->deleteTree(); VL_DANGLING(nodep); break; } case AstAttrType::DIM_BITS: case AstAttrType::DIM_HIGH: case AstAttrType::DIM_INCREMENT: case AstAttrType::DIM_LEFT: case AstAttrType::DIM_LOW: case AstAttrType::DIM_RIGHT: case AstAttrType::DIM_SIZE: { if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); pair dim = nodep->fromp()->dtypep()->skipRefp()->dimensions(true); uint32_t msbdim = dim.first+dim.second; if (!nodep->dimp() || nodep->dimp()->castConst() || msbdim<1) { int dim = !nodep->dimp() ? 1 : nodep->dimp()->castConst()->toSInt(); AstConst* newp = dimensionValue(nodep->fromp()->dtypep(), nodep->attrType(), dim); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } else { // Need a runtime lookup table. Yuk. if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); AstVar* varp = dimensionVarp(nodep->fromp()->dtypep(), nodep->attrType(), msbdim); AstNode* dimp = nodep->dimp()->unlinkFrBack(); AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false); varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp()); AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, dimp); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } break; } default: { // Everything else resolved earlier nodep->dtypeSetLogicSized(32,1,AstNumeric::UNSIGNED); // Approximation, unsized 32 UINFO(1,"Missing ATTR type case node: "<v3fatalSrc("Missing ATTR type case"); break; } } m_attrp = oldAttr; } virtual void visit(AstText* nodep) { // Only used in CStmts which don't care.... } // DTYPES virtual void visit(AstNodeArrayDType* nodep) { 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 userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p()); nodep->dtypep(nodep); // The array itself, not subDtype if (nodep->castUnpackArrayDType()) { // Historically array elements have width of the ref type not the full array nodep->widthFromSub(nodep->subDTypep()); } else { int width = nodep->subDTypep()->width() * nodep->rangep()->elementsConst(); nodep->widthForce(width,width); } UINFO(4,"dtWidthed "<didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->generic()) return; // Already perfect if (nodep->rangep()) { userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p()); // Because this DType has a unique child range, we know it's not pointed at by // other nodes unless they are referencing this type. Furthermore the width() // calculation would return identical values. Therefore we can directly replace the width nodep->widthForce(nodep->rangep()->elementsConst(), nodep->rangep()->elementsConst()); } else if (nodep->isRanged()) { nodep->widthForce(nodep->nrange().elements(), nodep->nrange().elements()); } 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())); userIterateChildren(nodep, NULL); 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 userIterateChildren(nodep, NULL); 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)); userIterateChildren(nodep, NULL); nodep->dtypep(iterateEditDTypep(nodep, nodep->subDTypep())); } virtual void visit(AstParamTypeDType* nodep) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); userIterateChildren(nodep, NULL); nodep->dtypep(iterateEditDTypep(nodep, nodep->subDTypep())); nodep->widthFromSub(nodep->subDTypep()); } virtual void visit(AstCastParse* nodep) { // nodep->dtp could be data type, or a primary_constant // Don't iterate lhsp, will deal with that once convert the type V3Const::constifyParamsEdit(nodep->dtp()); // itemp may change if (AstConst* constp = nodep->dtp()->castConst()) { constp->unlinkFrBack(); AstNode* newp = new AstCastSize(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), constp); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); userIterate(newp, m_vup); } else { nodep->v3error("Unsupported: Cast to "<dtp()->prettyTypeName()); nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); } } virtual void visit(AstCast* nodep) { if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep())); //if (debug()) nodep->dumpTree(cout," CastPre: "); userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); // When more general casts are supported, the cast elimination will be done later. // For now, replace it ASAP, so widthing can propagate easily // The cast may change signing, but we don't know the sign yet. Make it so. // Note we don't sign lhsp() that would make the algorithm O(n^2) if lots of casting. AstBasicDType* basicp = nodep->dtypep()->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Casting non-simple data type"); // When implement more complicated types need to convert childDTypep to dtypep() not as a child if (!basicp->isDouble() && !nodep->lhsp()->isDouble()) { // Note widthCheckSized might modify nodep->lhsp() AstNodeDType* subDTypep = nodep->findLogicDType(nodep->width(),nodep->width(), nodep->lhsp()->dtypep()->numeric()); widthCheckSized(nodep,"Cast",nodep->lhsp(),subDTypep,EXTEND_EXP, false); } AstNode* newp = nodep->lhsp()->unlinkFrBack(); if (basicp->isDouble() && !newp->isDouble()) { newp = new AstIToRD(nodep->fileline(), newp); } else if (!basicp->isDouble() && newp->isDouble()) { if (basicp->isSigned()) { newp = new AstRToIRoundS(nodep->fileline(), newp); } else { newp = new AstUnsigned(nodep->fileline(), new AstRToIS(nodep->fileline(), newp)); } } else if (basicp->isSigned() && !newp->isSigned()) { newp = new AstSigned(nodep->fileline(), newp); } else if (!basicp->isSigned() && newp->isSigned()) { newp = new AstUnsigned(nodep->fileline(), newp); } else { //newp = newp; // Can just remove cast } nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); //if (debug()) newp->dumpTree(cout," CastOut: "); } virtual void visit(AstCastSize* nodep) { // IEEE: Signedness of result is same as self-determined signedness // However, the result is same as BITSEL, so we do not sign extend the LHS if (!nodep->rhsp()->castConst()) nodep->v3fatalSrc("Unsupported: Non-const cast of size"); //if (debug()) nodep->dumpTree(cout," CastSizePre: "); if (m_vup->prelim()) { int width = nodep->rhsp()->castConst()->toSInt(); if (width < 1) { nodep->v3error("Size-changing cast to zero or negative size"); width=1; } userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); AstBasicDType* underDtp = nodep->lhsp()->dtypep()->castBasicDType(); if (!underDtp) { underDtp = nodep->lhsp()->dtypep()->basicp(); } if (!underDtp) { nodep->v3error("Unsupported: Size-changing cast on non-basic data type"); underDtp = nodep->findLogicBoolDType()->castBasicDType(); } // A cast propagates its size to the lower expression and is included in the maximum // width, so 23'(1'b1 + 1'b1) uses 23-bit math, but 1'(2'h2 * 2'h1) uses two-bit math. // However the output width is exactly that requested. // So two steps, first do the calculation's width (max of the two widths) { int calcWidth = max(width, underDtp->width()); AstNodeDType* calcDtp = (underDtp->keyword().isFourstate() ? nodep->findLogicDType(calcWidth, calcWidth, underDtp->numeric()) : nodep->findBitDType(calcWidth, calcWidth, underDtp->numeric())); nodep->dtypep(calcDtp); // We ignore warnings as that is sort of the point of a cast iterateCheck(nodep,"Cast expr",nodep->lhsp(),CONTEXT,FINAL,calcDtp,EXTEND_EXP, false); } if (debug()) nodep->dumpTree(cout," CastSizeClc: "); // Next step, make the proper output width { AstNodeDType* outDtp = (underDtp->keyword().isFourstate() ? nodep->findLogicDType(width, width, underDtp->numeric()) : nodep->findBitDType(width, width, underDtp->numeric())); nodep->dtypep(outDtp); // We ignore warnings as that is sort of the point of a cast widthCheckSized(nodep,"Cast expr",nodep->lhsp(),outDtp,EXTEND_EXP, false); } } if (m_vup->final()) { // CastSize not needed once sizes determined AstNode* underp = nodep->lhsp()->unlinkFrBack(); nodep->replaceWith(underp); pushDeletep(nodep); VL_DANGLING(nodep); } //if (debug()) nodep->dumpTree(cout," CastSizeOut: "); } virtual void visit(AstVar* nodep) { //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()) { userIterateAndNext(nodep->valuep(), WidthVP(nodep->dtypep(),PRELIM).p()); UINFO(9,"implicitParamPRELIMIV "<valuep()<valuep()->isDouble()) { nodep->dtypeSetDouble(); VL_DANGLING(bdtypep); } else { int width=0; AstBasicDType* valueBdtypep = nodep->valuep()->dtypep()->basicp(); bool issigned = false; if (bdtypep->isNosign()) { if (valueBdtypep && valueBdtypep->isSigned()) issigned=true; } else issigned = bdtypep->isSigned(); if (nodep->valuep()->dtypep()->widthSized()) { width = nodep->valuep()->width(); } else { if (nodep->valuep()->width()>32) nodep->valuep()->v3warn(WIDTH,"Assigning >32 bit to unranged parameter (defaults to 32 bits)"); width = 32; } // Can't just inherit valuep()->dtypep() as mwidth might not equal width if (width==1) { // one bit parameter is same as "parameter [0] foo", not "parameter logic foo" // as you can extract "foo[0]" from a parameter but not a wire nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(), AstNumeric::fromBool(issigned)); nodep->dtypep(nodep->findLogicRangeDType (VNumRange(0,0,false), nodep->valuep()->widthMin(), AstNumeric::fromBool(issigned))); } else { nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(), AstNumeric::fromBool(issigned)); } didchk = true; } iterateCheckAssign(nodep,"Initial value",nodep->valuep(),FINAL,nodep->dtypep()); UINFO(9,"implicitParamFromIV "<valuep()<dtypeSetSigned32(); VL_DANGLING(bdtypep); } } else if (bdtypep && bdtypep->implicit()) { // Implicits get converted to size 1 nodep->dtypeSetLogicSized(1,1,bdtypep->numeric()); VL_DANGLING(bdtypep); } if (nodep->valuep() && !didchk) { //if (debug()) nodep->dumpTree(cout," final: "); // AstPattern requires assignments to pass datatype on PRELIM userIterateAndNext(nodep->valuep(), WidthVP(nodep->dtypep(),PRELIM).p()); iterateCheckAssign(nodep,"Initial value",nodep->valuep(),FINAL,nodep->dtypep()); } UINFO(4,"varWidthed "<dumpTree(cout," InitOut: "); nodep->didWidth(true); nodep->doingWidth(false); } virtual void visit(AstNodeVarRef* nodep) { if (nodep->didWidth()) return; if (!nodep->varp()) { if (m_paramsOnly && nodep->castVarXRef()) { checkConstantOrReplace(nodep, "Parameter-resolved constants must not use dotted references: "+nodep->prettyName()); VL_DANGLING(nodep); return; } else { nodep->v3fatalSrc("Unlinked varref"); } } if (!nodep->varp()->didWidth()) { // Var hasn't been widthed, so make it so. userIterate(nodep->varp(), NULL); } //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()) nodep->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) { 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 userIterateAndNext(nodep->itemsp(), 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 illegally wrapped around (IEEE 2012 6.19)"); 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) { UINFO(5," ENUMITEM "<dtypep(); if (!vdtypep) nodep->v3fatalSrc("ENUMITEM not under ENUM"); nodep->dtypep(vdtypep); if (nodep->valuep()) { // else the value will be assigned sequentially // Default type is int, but common to assign narrower values, so minwidth from value userIterateAndNext(nodep->valuep(), WidthVP(CONTEXT,PRELIM).p()); int mwidth = nodep->valuep()->widthMin(); // Value determines minwidth nodep->dtypeChgWidth(nodep->width(), mwidth); iterateCheck(nodep,"Enum value",nodep->valuep(),CONTEXT,FINAL,nodep->dtypep(),EXTEND_EXP); } } virtual void visit(AstEnumItemRef* nodep) { 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"); userIterate(enump, m_vup); VL_DANGLING(enump); // parent's connection to enump may be relinked } nodep->dtypeFrom(nodep->itemp()); } virtual void visit(AstInitArray* nodep) { // InitArray has type of the array; children are array values if (m_vup->prelim()) { // First stage evaluation AstNodeDType* vdtypep = m_vup->dtypep(); if (!vdtypep) nodep->v3fatalSrc("InitArray type not assigned by AstPattern/Var visitor"); nodep->dtypep(vdtypep); if (AstNodeArrayDType* arrayp = vdtypep->skipRefp()->castNodeArrayDType()) { userIterateChildren(nodep, WidthVP(arrayp->subDTypep(),BOTH).p()); } else { nodep->v3fatalSrc("InitArray on non-array"); } } } virtual void visit(AstInside* nodep) { userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT,PRELIM).p()); for (AstNode* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp(); // Prelim may cause the node to get replaced userIterate(itemp, WidthVP(CONTEXT,PRELIM).p()); VL_DANGLING(itemp); } // Take width as maximum across all items int width = nodep->exprp()->width(); int mwidth = nodep->exprp()->widthMin(); for (AstNode* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()) { width = max(width,itemp->width()); mwidth = max(mwidth,itemp->widthMin()); } // Apply width AstNodeDType* subDTypep = nodep->findLogicDType(width,mwidth,nodep->exprp()->dtypep()->numeric()); iterateCheck(nodep,"Inside expression",nodep->exprp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); for (AstNode* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()) { iterateCheck(nodep,"Inside Item",itemp,CONTEXT,FINAL,subDTypep,EXTEND_EXP); } nodep->dtypeSetLogicBool(); if (debug()>=9) nodep->dumpTree(cout,"-inside-in: "); // Now rip out the inside and replace with simple math AstNode* newp = NULL; for (AstNode* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp(); // Will be unlinking AstNode* inewp; if (AstInsideRange* irangep = itemp->castInsideRange()) { // Similar logic in V3Case inewp = new AstAnd(itemp->fileline(), new AstGte(itemp->fileline(), nodep->exprp()->cloneTree(true), irangep->lhsp()->unlinkFrBack()), new AstLte(itemp->fileline(), nodep->exprp()->cloneTree(true), irangep->rhsp()->unlinkFrBack())); } else { inewp = new AstEqWild(itemp->fileline(), nodep->exprp()->cloneTree(true), itemp->unlinkFrBack()); } if (newp) newp = new AstOr(nodep->fileline(), newp, inewp); else newp = inewp; } if (!newp) newp = new AstConst(nodep->fileline(), AstConst::LogicFalse()); if (debug()>=9) newp->dumpTree(cout,"-inside-out: "); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); } virtual void visit(AstInsideRange* nodep) { // Just do each side; AstInside will rip these nodes out later userIterateAndNext(nodep->lhsp(), m_vup); userIterateAndNext(nodep->rhsp(), m_vup); nodep->dtypeFrom(nodep->lhsp()); } virtual void visit(AstIfaceRefDType* nodep) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed UINFO(5," IFACEREF "<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"); } userIterateChildren(nodep, NULL); // 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) { 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) { UINFO(5," MEMBERSEL "<=9) nodep->dumpTree("-mbs-in: "); userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); if (debug()>=9) nodep->dumpTree("-mbs-ic: "); // Find the fromp dtype - should be a class AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump(); UINFO(9," from dt "<castNodeClassDType()) { // No need to width-resolve the class, as it was done when we did the child memberp = adtypep->findMember(nodep->name()); if (!memberp) { nodep->v3error("Member '"<prettyName()<<"' not found in structure"); } } else if (fromDtp->castEnumDType()) { // Method call on enum without following parenthesis, e.g. "ENUM.next" // Convert this into a method call, and let that visitor figure out what to do next AstNode* newp = new AstMethodSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), NULL); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); userIterate(newp, m_vup); return; } else { nodep->v3error("Member selection of non-struct/union object '" <fromp()->prettyTypeName()<<"' which is a '"<fromp()->dtypep()->prettyTypeName()<<"'"); } if (memberp) { if (m_attrp) { // Looking for the base of the attribute nodep->dtypep(memberp); UINFO(9," MEMBERSEL(attr) -> "< "<dtypep()<fileline(), nodep->fromp()->unlinkFrBack(), memberp->lsb(), memberp->width()); newp->dtypep(memberp->subDTypep()->skipRefToEnump()); // Must skip over the member to find the union; as the member may disappear later newp->didWidth(true); // Don't replace dtype with basic type UINFO(9," MEMBERSEL -> "< "<dtypep()<replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); // 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); VL_DANGLING(nodep); } } virtual void visit(AstMethodSel* nodep) { UINFO(5," METHODSEL "<=9) nodep->dumpTree("-mts-in: "); // Should check types the method requires, but at present we don't do much userIterate(nodep->fromp(), WidthVP(SELF,BOTH).p()); for (AstArg* argp = nodep->pinsp()->castArg(); argp; argp = argp->nextp()->castArg()) { if (argp->exprp()) userIterate(argp->exprp(), WidthVP(SELF,BOTH).p()); } // Find the fromp dtype - should be a class if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump(); UINFO(9," from dt "<castEnumDType()) { // Method call on enum without following parenthesis, e.g. "ENUM.next" // Convert this into a method call, and let that visitor figure out what to do next if (adtypep) {} if (nodep->name() == "num" || nodep->name() == "first" || nodep->name() == "last") { // Constant value AstConst* newp = NULL; if (nodep->pinsp()) nodep->v3error("Arguments passed to enum.num method, but it does not take arguments"); if (nodep->name() == "num") { int items = 0; for (AstNode* itemp = adtypep->itemsp(); itemp; itemp = itemp->nextp()) ++items; newp = new AstConst(nodep->fileline(), AstConst::Signed32(), items); } else if (nodep->name() == "first") { AstEnumItem* itemp = adtypep->itemsp(); if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const } else if (nodep->name() == "last") { AstEnumItem* itemp = adtypep->itemsp(); while (itemp && itemp->nextp()) itemp = itemp->nextp()->castEnumItem(); if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const } if (!newp) nodep->v3fatalSrc("Enum method (perhaps enum item) not const"); newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer; may have warning disables nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); } else if (nodep->name() == "name" || nodep->name() == "next" || nodep->name() == "prev") { AstAttrType attrType; if (nodep->name() == "name") attrType = AstAttrType::ENUM_NAME; else if (nodep->name() == "next") attrType = AstAttrType::ENUM_NEXT; else if (nodep->name() == "prev") attrType = AstAttrType::ENUM_PREV; else nodep->v3fatalSrc("Bad case"); if (nodep->pinsp() && nodep->name() == "name") { nodep->v3error("Arguments passed to enum.name method, but it does not take arguments"); } else if (nodep->pinsp() && !(nodep->pinsp()->castArg()->exprp()->castConst() && nodep->pinsp()->castArg()->exprp()->castConst()->toUInt()==1 && !nodep->pinsp()->nextp())) { nodep->v3error("Unsupported: Arguments passed to enum.next method"); } // Need a runtime lookup table. Yuk. // Most enums unless overridden are 32 bits, so we size array based on max enum value used. // Ideally we would have a fast algorithm when a number is // of small width and complete and so can use an array, and // a map for when the value is many bits and sparse. uint64_t msbdim = 0; { for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp = itemp->nextp()->castEnumItem()) { AstConst* vconstp = itemp->valuep()->castConst(); if (!vconstp) nodep->v3fatalSrc("Enum item without constified value"); if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad(); } if (adtypep->itemsp()->width() > 64 || msbdim >= (1<<16)) { nodep->v3error("Unsupported; enum next/prev method on enum with > 10 bits"); return; } } int selwidth = V3Number::log2b(msbdim)+1; // Width to address a bit AstVar* varp = enumVarp(adtypep, attrType, (VL_ULL(1)<fileline(), varp, false); varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp()); AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, // Select in case widths are off due to msblen!=width new AstSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), 0, selwidth)); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } else { nodep->v3error("Unknown built-in enum method '"<fromp()->prettyTypeName()<<"'"); } } else if (AstUnpackArrayDType* arrayType = fromDtp->castUnpackArrayDType()) { enum { UNKNOWN = 0, ARRAY_OR, ARRAY_AND, ARRAY_XOR } methodId; methodId = UNKNOWN; if (nodep->name() == "or") methodId = ARRAY_OR; else if (nodep->name() == "and") methodId = ARRAY_AND; else if (nodep->name() == "xor") methodId = ARRAY_XOR; if (methodId) { if (nodep->pinsp()) nodep->v3error("Arguments passed to array method, but it does not take arguments"); FileLine* fl = nodep->fileline(); AstNode* newp = NULL; for (int i = 0; i < arrayType->elementsConst(); ++i) { AstNode* arrayRef = nodep->fromp()->cloneTree(false); AstNode* selector = new AstArraySel(fl, arrayRef, i); if (!newp) newp = selector; else { switch (methodId) { case ARRAY_OR: newp = new AstOr(fl, newp, selector); break; case ARRAY_AND: newp = new AstAnd(fl, newp, selector); break; case ARRAY_XOR: newp = new AstXor(fl, newp, selector); break; default: nodep->v3fatalSrc("bad case"); } } } nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } else { nodep->v3error("Unknown built-in array method '"<fromp()->prettyTypeName()<<"'"); } } else { nodep->v3error("Unsupported: Member call on non-enum object '" <fromp()->prettyTypeName()<<"' which is a '"<fromp()->dtypep()->prettyTypeName()<<"'"); } } virtual void visit(AstPattern* nodep) { if (nodep->didWidthAndSet()) return; UINFO(9,"PATTERN "<childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); // data_type '{ pattern } if (!nodep->dtypep() && m_vup->dtypeNullp()) { // Get it from parent assignment/pin/etc nodep->dtypep(m_vup->dtypep()); } AstNodeDType* vdtypep = nodep->dtypep(); if (!vdtypep) nodep->v3error("Unsupported/Illegal: Assignment pattern member not underneath a supported construct: "<backp()->prettyTypeName()); { vdtypep = vdtypep->skipRefp(); nodep->dtypep(vdtypep); UINFO(9," adtypep "<dtypep(vdtypep); // Determine replication count, and replicate initial value as widths need to be individually determined for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) { int times = visitPatMemberRep(patp); for (int i=1; icloneTree(false); patp->addNextHere(newp); // This loop will see the new elements as part of nextp() } } // Convert any PatMember with multiple items to multiple PatMembers for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) { if (patp->lhssp()->nextp()) { // Can't just addNext, as would add to end of all members. So detach, add next and reattach AstNRelinker relinkHandle; patp->unlinkFrBack(&relinkHandle); while (AstNode* movep = patp->lhssp()->nextp()) { movep->unlinkFrBack(); // Not unlinkFrBackWithNext, just one AstPatMember* newp = new AstPatMember(patp->fileline(), movep, patp->keyp()->cloneTree(true), NULL); patp->addNext(newp); } relinkHandle.relink(patp); } } AstPatMember* defaultp = NULL; for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) { if (patp->isDefault()) { if (defaultp) nodep->v3error("Multiple '{ default: } clauses"); defaultp = patp; patp->unlinkFrBack(); } } while (AstConstDType* classp = vdtypep->castConstDType()) { vdtypep = classp->subDTypep()->skipRefp(); } if (AstNodeClassDType* classp = vdtypep->castNodeClassDType()) { // Due to "default" and tagged patterns, we need to determine // which member each AstPatMember corresponds to before we can // determine the dtypep for that PatMember's value, and then // width the initial value appropriately. typedef map PatMap; PatMap patmap; { AstMemberDType* memp = classp->membersp(); AstPatMember* patp = nodep->itemsp()->castPatMember(); for (; memp || patp; ) { if (patp) { if (patp->keyp()) { if (AstText* textp = patp->keyp()->castText()) { memp = classp->findMember(textp->text()); if (!memp) { patp->keyp()->v3error("Assignment pattern key '"<text()<<"' not found as member"); continue; } } else { patp->keyp()->v3error("Assignment pattern key not supported/understood: "<keyp()->prettyTypeName()); } } } if (memp && !patp) { // Missing init elements, warn below memp=NULL; patp=NULL; break; } else if (!memp && patp) { patp->v3error("Assignment pattern contains too many elements"); memp=NULL; patp=NULL; break; } else { pair ret = patmap.insert(make_pair(memp, patp)); if (!ret.second) { patp->v3error("Assignment pattern contains duplicate entry: " << patp->keyp()->castText()->text()); } } // Next if (memp) memp = memp->nextp()->castMemberDType(); if (patp) patp = patp->nextp()->castPatMember(); } } AstNode* newp = NULL; for (AstMemberDType* memp = classp->membersp(); memp; memp=memp->nextp()->castMemberDType()) { PatMap::iterator it = patmap.find(memp); AstPatMember* newpatp = NULL; AstPatMember* patp = NULL; if (it == patmap.end()) { if (defaultp) { newpatp = defaultp->cloneTree(false); patp = newpatp; } else { if (!classp->castUnionDType()) { patp->v3error("Assignment pattern missed initializing elements: "<prettyTypeName()); } } } else { patp = it->second; } if (patp) { // Determine initial values vdtypep = memp; if (vdtypep) {} patp->dtypep(memp); userIterate(patp, WidthVP(memp,BOTH).p()); // See visit(AstPatMember* // Convert to concat for now AstNode* valuep = patp->lhssp()->unlinkFrBack(); if (valuep->castConst()) { // Forming a AstConcat will cause problems with unsized (uncommitted sized) constants if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) { pushDeletep(valuep); VL_DANGLING(valuep); valuep = newp; } } if (!newp) newp = valuep; else { AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep); newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), concatp->lhsp()->width()+concatp->rhsp()->width(), nodep->dtypep()->numeric()); } } if (newpatp) { pushDeletep(newpatp); VL_DANGLING(newpatp); } } if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present } else if (vdtypep->castNodeArrayDType()) { AstNodeArrayDType* arrayp = vdtypep->castNodeArrayDType(); VNumRange range = arrayp->declRange(); PatVecMap patmap = patVectorMap(nodep, range); UINFO(9,"ent "<=range.lo(); --ent) { AstPatMember* newpatp = NULL; AstPatMember* patp = NULL; PatVecMap::iterator it=patmap.find(ent); if (it == patmap.end()) { if (defaultp) { newpatp = defaultp->cloneTree(false); patp = newpatp; } else { nodep->v3error("Assignment pattern missed initializing elements: "<second; patmap.erase(it); } if (patp) { // Determine initial values vdtypep = arrayp->subDTypep(); // Don't want the RHS an array patp->dtypep(vdtypep); // Determine values - might be another InitArray userIterate(patp, WidthVP(patp->dtypep(),BOTH).p()); // See visit(AstPatMember* // Convert to InitArray or constify immediately AstNode* valuep = patp->lhssp()->unlinkFrBack(); if (valuep->castConst()) { // Forming a AstConcat will cause problems with unsized (uncommitted sized) constants if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) { pushDeletep(valuep); VL_DANGLING(valuep); valuep = newp; } } if (arrayp->castUnpackArrayDType()) { if (!newp) { AstInitArray* newap = new AstInitArray(nodep->fileline(), arrayp, NULL); newap->addValuep(valuep); newp = newap; } else { // We iterate hi()..lo() as that is what packed needs, // but INITARRAY needs lo() first newp->castInitArray()->addFrontValuep(valuep); } } else { // Packed. Convert to concat for now. if (!newp) newp = valuep; else { AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep); newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), concatp->lhsp()->width()+concatp->rhsp()->width(), nodep->dtypep()->numeric()); } } } if (newpatp) { pushDeletep(newpatp); VL_DANGLING(newpatp); } } if (!patmap.empty()) nodep->v3error("Assignment pattern with too many elements"); if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); //if (debug()>=9) newp->dumpTree("-apat-out: "); pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present } else if (vdtypep->castBasicDType() && vdtypep->castBasicDType()->isRanged()) { AstBasicDType* bdtypep = vdtypep->castBasicDType(); VNumRange range = bdtypep->declRange(); PatVecMap patmap = patVectorMap(nodep, range); UINFO(9,"ent "<=range.lo(); --ent) { AstPatMember* newpatp = NULL; AstPatMember* patp = NULL; PatVecMap::iterator it=patmap.find(ent); if (it == patmap.end()) { if (defaultp) { newpatp = defaultp->cloneTree(false); patp = newpatp; } else { nodep->v3error("Assignment pattern missed initializing elements: "<second; patmap.erase(it); } if (patp) { // Determine initial values vdtypep = nodep->findLogicBoolDType(); // Don't want the RHS an array patp->dtypep(vdtypep); // Determine values - might be another InitArray userIterate(patp, WidthVP(patp->dtypep(),BOTH).p()); // Convert to InitArray or constify immediately AstNode* valuep = patp->lhssp()->unlinkFrBack(); if (valuep->castConst()) { // Forming a AstConcat will cause problems with unsized (uncommitted sized) constants if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) { pushDeletep(valuep); VL_DANGLING(valuep); valuep = newp; } } { // Packed. Convert to concat for now. if (!newp) newp = valuep; else { AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep); newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), concatp->lhsp()->width()+concatp->rhsp()->width(), nodep->dtypep()->numeric()); } } } if (newpatp) { pushDeletep(newpatp); VL_DANGLING(newpatp); } } if (!patmap.empty()) nodep->v3error("Assignment pattern with too many elements"); if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); //if (debug()>=9) newp->dumpTree("-apat-out: "); pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present } else { nodep->v3error("Unsupported: Assignment pattern applies against non struct/union: "<prettyTypeName()); } } } virtual void visit(AstPatMember* nodep) { AstNodeDType* vdtypep = m_vup->dtypeNullp(); if (!vdtypep) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor"); nodep->dtypep(vdtypep); UINFO(9," PATMEMBER "<lhssp()->nextp()) nodep->v3fatalSrc("PatMember value should be singular w/replicates removed"); // Need to propagate assignment type downwards, even on prelim userIterateChildren(nodep, WidthVP(nodep->dtypep(),PRELIM).p()); iterateCheck(nodep,"Pattern value",nodep->lhssp(),ASSIGN,FINAL,vdtypep,EXTEND_LHS); } int visitPatMemberRep(AstPatMember* nodep) { uint32_t times = 1; if (nodep->repp()) { // else repp()==NULL shorthand for rep count 1 iterateCheckSizedSelf(nodep,"LHS",nodep->repp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->repp()); // repp may change AstConst* constp = nodep->repp()->castConst(); if (!constp) { nodep->v3error("Replication value isn't a constant."); times=0; } else times = constp->toUInt(); if (times==0) { nodep->v3error("Pattern replication value of 0 is not legal."); times=1; } nodep->repp()->unlinkFrBackWithNext()->deleteTree(); // Done with replicate before cloning } return times; } virtual void visit(AstPslClocked* nodep) { if (m_vup->prelim()) { // First stage evaluation iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); userIterateAndNext(nodep->sensesp(), NULL); if (nodep->disablep()) { iterateCheckBool(nodep,"Disable",nodep->disablep(),BOTH); // it's like an if() condition. } nodep->dtypeSetLogicBool(); } } //-------------------- // Top levels virtual void visit(AstNodeCase* nodep) { // IEEE-2012 12.5: // Width: MAX(expr, all items) // Signed: Only if expr, and all items signed assertAtStatement(nodep); userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT,PRELIM).p()); for (AstCaseItem* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp()->castCaseItem(); // Prelim may cause the node to get replaced if (!nodep->castGenCase()) userIterateAndNext(itemp->bodysp(), NULL); for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) { nextcp = condp->nextp(); // Prelim may cause the node to get replaced userIterate(condp, WidthVP(CONTEXT,PRELIM).p()); VL_DANGLING(condp); } } // Take width as maximum across all items, if any is real whole thing is real AstNodeDType* subDTypep = nodep->exprp()->dtypep(); for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* condp = itemp->condsp(); condp; condp=condp->nextp()) { if (condp->dtypep() != subDTypep) { if (condp->dtypep()->isDouble()) { subDTypep = nodep->findDoubleDType(); } else { int width = max(subDTypep->width(),condp->width()); int mwidth = max(subDTypep->widthMin(),condp->widthMin()); bool issigned = subDTypep->isSigned() && condp->isSigned(); subDTypep = nodep->findLogicDType(width,mwidth,AstNumeric::fromBool(issigned)); } } } } // Apply width iterateCheck(nodep,"Case expression",nodep->exprp(),CONTEXT,FINAL,subDTypep,EXTEND_LHS); for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) { nextcp = condp->nextp(); // Final may cause the node to get replaced iterateCheck(nodep,"Case Item",condp,CONTEXT,FINAL,subDTypep,EXTEND_LHS); } } } virtual void visit(AstNodeFor* nodep) { assertAtStatement(nodep); userIterateAndNext(nodep->initsp(), NULL); iterateCheckBool(nodep,"For Test Condition",nodep->condp(),BOTH); // it's like an if() condition. if (!nodep->castGenFor()) userIterateAndNext(nodep->bodysp(), NULL); userIterateAndNext(nodep->incsp(), NULL); } virtual void visit(AstRepeat* nodep) { assertAtStatement(nodep); userIterateAndNext(nodep->countp(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->bodysp(), NULL); } virtual void visit(AstWhile* nodep) { assertAtStatement(nodep); userIterateAndNext(nodep->precondsp(), NULL); iterateCheckBool(nodep,"For Test Condition",nodep->condp(),BOTH); // it's like an if() condition. userIterateAndNext(nodep->bodysp(), NULL); userIterateAndNext(nodep->incsp(), NULL); } virtual void visit(AstNodeIf* nodep) { assertAtStatement(nodep); //if (debug()) nodep->dumpTree(cout," IfPre: "); if (!nodep->castGenIf()) { // for m_paramsOnly userIterateAndNext(nodep->ifsp(), NULL); userIterateAndNext(nodep->elsesp(), NULL); } iterateCheckBool(nodep,"If",nodep->condp(),BOTH); // it's like an if() condition. //if (debug()) nodep->dumpTree(cout," IfOut: "); } virtual void visit(AstNodeAssign* nodep) { // IEEE-2012 10.7, 11.8.2, 11.8.3, 11.5: (Careful of 11.8.1 which is // only one step; final dtype depends on assign LHS.) // Determine RHS type width and signing // Propagate type down to *non-self-determined* operators // Real propagates only across one operator if one side is real - handled in each visitor. // Then LHS sign-extends only if *RHS* is signed assertAtStatement(nodep); //if (debug()) nodep->dumpTree(cout," AssignPre: "); { //if (debug()) nodep->dumpTree(cout,"- assin: "); userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); if (!nodep->lhsp()->dtypep()) nodep->v3fatalSrc("How can LHS be untyped?"); if (!nodep->lhsp()->dtypep()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?"); nodep->dtypeFrom(nodep->lhsp()); // // AstPattern needs to know the proposed data type of the lhs, so pass on the prelim userIterateAndNext(nodep->rhsp(), WidthVP(nodep->dtypep(),PRELIM).p()); // //if (debug()) nodep->dumpTree(cout,"- assign: "); AstNodeDType* lhsDTypep = nodep->lhsp()->dtypep(); // Note we use rhsp for context determined iterateCheckAssign(nodep,"Assign RHS",nodep->rhsp(),FINAL,lhsDTypep); //if (debug()) nodep->dumpTree(cout," AssignOut: "); } } virtual void visit(AstSFormatF* nodep) { // Excludes NodeDisplay, see below if (m_vup && !m_vup->prelim()) return; // Can be called as statement or function // Just let all arguments seek their natural sizes userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); // UINFO(9," Display in "<text()<exprsp(); string txt = nodep->text(); string fmt; for (string::const_iterator it = txt.begin(); it!=txt.end(); ++it) { char ch = *it; if (!inPct && ch=='%') { inPct = true; fmt = ch; } else if (inPct && (isdigit(ch) || ch=='.')) { fmt += ch; } else if (tolower(inPct)) { inPct = false; bool added = false; switch (tolower(ch)) { case '%': break; // %% - just output a % case 'm': break; // %m - auto insert "name" case 'l': break; // %m - auto insert "library" case 'd': { // Convert decimal to either 'd' or '#' if (argp && argp->isSigned()) { // Convert it ch = '~'; } if (argp) argp=argp->nextp(); break; } case 'p': { // Packed // Very hacky and non-compliant; print strings as strings, otherwise as hex if (argp && argp->dtypep()->basicp()->isString()) { // Convert it added = true; newFormat += "\"%@\""; } else { added = true; newFormat += "'h%0h"; } if (argp) argp=argp->nextp(); break; } case 's': { // Convert string to pack string if (argp && argp->dtypep()->basicp()->isString()) { // Convert it ch = '@'; } if (argp) argp=argp->nextp(); break; } default: { // Most operators, just move to next argument if (argp) argp=argp->nextp(); break; } } // switch if (!added) { fmt += ch; newFormat += fmt; } } else { newFormat += ch; } } nodep->text(newFormat); UINFO(9," Display out "<text()<filep()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); } // Just let all arguments seek their natural sizes userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); } virtual void visit(AstFOpen* nodep) { // Although a system function in IEEE, here a statement which sets the file pointer (MCD) assertAtStatement(nodep); iterateCheckFileDesc(nodep,nodep->filep(),BOTH); userIterateAndNext(nodep->filenamep(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->modep(), WidthVP(SELF,BOTH).p()); } virtual void visit(AstFClose* nodep) { assertAtStatement(nodep); iterateCheckFileDesc(nodep,nodep->filep(),BOTH); } virtual void visit(AstFEof* nodep) { if (m_vup->prelim()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); nodep->dtypeSetLogicSized(32,1,AstNumeric::SIGNED); // Spec says integer return } } virtual void visit(AstFFlush* nodep) { assertAtStatement(nodep); if (nodep->filep()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); } } virtual void visit(AstFGetC* nodep) { if (m_vup->prelim()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); nodep->dtypeSetLogicSized(32,8,AstNumeric::SIGNED); // Spec says integer return } } virtual void visit(AstFGetS* nodep) { if (m_vup->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return iterateCheckFileDesc(nodep,nodep->filep(),BOTH); userIterateAndNext(nodep->strgp(), WidthVP(SELF,BOTH).p()); } } virtual void visit(AstFScanF* nodep) { if (m_vup->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return iterateCheckFileDesc(nodep,nodep->filep(),BOTH); userIterateAndNext(nodep->exprsp(), WidthVP(SELF,BOTH).p()); } } virtual void visit(AstSScanF* nodep) { if (m_vup->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return userIterateAndNext(nodep->fromp(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->exprsp(), WidthVP(SELF,BOTH).p()); } } virtual void visit(AstSysIgnore* nodep) { userIterateAndNext(nodep->exprsp(), WidthVP(SELF,BOTH).p()); } virtual void visit(AstSystemF* nodep) { if (m_vup->prelim()) { userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); nodep->dtypeSetSigned32(); // Spec says integer return } } virtual void visit(AstSystemT* nodep) { assertAtStatement(nodep); userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); } virtual void visit(AstReadMem* nodep) { assertAtStatement(nodep); userIterateAndNext(nodep->filenamep(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->memp(), WidthVP(SELF,BOTH).p()); if (!nodep->memp()->dtypep()->skipRefp()->castUnpackArrayDType()) { nodep->memp()->v3error("Unsupported: $readmem into other than unpacked array"); } userIterateAndNext(nodep->lsbp(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->msbp(), WidthVP(SELF,BOTH).p()); } virtual void visit(AstValuePlusArgs* nodep) { if (m_vup->prelim()) { userIterateAndNext(nodep->searchp(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->outp(), WidthVP(SELF,BOTH).p()); nodep->dtypeChgWidthSigned(32,1,AstNumeric::SIGNED); // Spec says integer return } } virtual void visit(AstUCStmt* nodep) { // Just let all arguments seek their natural sizes assertAtStatement(nodep); userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); } virtual void visit(AstPslCover* nodep) { assertAtStatement(nodep); iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); // it's like an if() condition. userIterateAndNext(nodep->stmtsp(), NULL); } virtual void visit(AstVAssert* nodep) { assertAtStatement(nodep); iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); // it's like an if() condition. userIterateAndNext(nodep->passsp(), NULL); userIterateAndNext(nodep->failsp(), NULL); } virtual void visit(AstPin* nodep) { //if (debug()) nodep->dumpTree(cout,"- PinPre: "); // TOP LEVEL NODE if (nodep->modVarp() && nodep->modVarp()->isGParam()) { // Widthing handled as special init() case userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); } else if (!m_paramsOnly) { if (!nodep->modVarp()->didWidth()) { // Var hasn't been widthed, so make it so. userIterate(nodep->modVarp(), NULL); } 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. userIterateAndNext(nodep->exprp(), WidthVP(nodep->modVarp()->dtypep(),PRELIM).p()); AstNodeDType* pinDTypep = nodep->modVarp()->dtypep(); AstNodeDType* conDTypep = nodep->exprp()->dtypep(); AstNodeDType* subDTypep = pinDTypep; int pinwidth = pinDTypep->width(); int conwidth = conDTypep->width(); if (conDTypep == pinDTypep // If match, we're golden || similarDTypeRecurse(conDTypep, pinDTypep)) { userIterateAndNext(nodep->exprp(), WidthVP(subDTypep,FINAL).p()); } else if (m_cellRangep) { int numInsts = m_cellRangep->elementsConst(); if (conwidth == pinwidth) { // Arrayed instants: widths match so connect to each instance subDTypep = conDTypep; // = same expr dtype } else if (conwidth == numInsts*pinwidth) { // Arrayed instants: one bit for each of the instants (each assign is 1 pinwidth wide) subDTypep = conDTypep; // = same expr dtype (but numInst*pin_dtype) } else { // Must be a error according to spec // (Because we need to know if to connect to one or all instants) nodep->v3error(ucfirst(nodep->prettyOperatorName())<<" as part of a module instance array" <<" requires "<exprp()->prettyTypeName() <<" generates "<exprp(), WidthVP(subDTypep,FINAL).p()); } else { if (nodep->modVarp()->isTristate()) { if (pinwidth != conwidth) { nodep->v3error("Unsupported: "<prettyOperatorName()) <<" to inout signal requires "<exprp()->prettyTypeName() <<" generates "<modVarp()->dtypep(); AstNodeDType* exprDTypep = nodep->exprp()->dtypep(); if ((modDTypep->castIfaceRefDType() && !exprDTypep->castIfaceRefDType()) || (exprDTypep->castIfaceRefDType() && !modDTypep->castIfaceRefDType())) { nodep->v3error("Illegal "<prettyOperatorName()<<"," <<" mismatch between port which is"<<(modDTypep->castIfaceRefDType()?"":" not")<<" an interface," <<" and expression which is"<<(exprDTypep->castIfaceRefDType()?"":" not")<<" an interface."); } // TODO Simple dtype checking, should be a more general check AstNodeArrayDType* exprArrayp = exprDTypep->skipRefp()->castUnpackArrayDType(); AstNodeArrayDType* modArrayp = modDTypep->skipRefp()->castUnpackArrayDType(); if (exprArrayp && modArrayp && exprArrayp->subDTypep()->skipRefp()->castIfaceRefDType() && exprArrayp->declRange().elements() != modArrayp->declRange().elements()) { int exprSize = exprArrayp->declRange().elements(); int modSize = modArrayp->declRange().elements(); nodep->v3error("Illegal "<prettyOperatorName()<<"," <<" mismatch between port which is an interface array of size "<skipRefp()<skipRefp()<v3error("Illegal "<prettyOperatorName()<<"," <<" mismatch between port which is"<<(modArrayp?"":" not")<<" an array," <<" and expression which is"<<(exprArrayp?"":" not")<<" an array."); UINFO(1," Related lo: "<skipRefp()<skipRefp()<exprp(),FINAL,subDTypep); } } //if (debug()) nodep->dumpTree(cout,"- PinOut: "); } virtual void visit(AstCell* nodep) { 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(); userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p()); } userIterateAndNext(nodep->pinsp(), NULL); } userIterateAndNext(nodep->paramsp(), NULL); m_cellRangep = NULL; } virtual void visit(AstGatePin* nodep) { if (m_vup->prelim()) { userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p()); userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT,PRELIM).p()); nodep->dtypeFrom(nodep->rangep()); // Very much like like an pin AstNodeDType* conDTypep = nodep->exprp()->dtypep(); int numInsts = nodep->rangep()->elementsConst(); int pinwidth = numInsts; int conwidth = conDTypep->width(); if (conwidth == 1 && pinwidth > 1) { // Multiple connections AstNodeDType* subDTypep = nodep->findLogicDType(1,1, conDTypep->numeric()); userIterateAndNext(nodep->exprp(), WidthVP(subDTypep,FINAL).p()); AstNode* newp = new AstReplicate(nodep->fileline(), nodep->exprp()->unlinkFrBack(), numInsts); nodep->replaceWith(newp); } else { // Eliminating so pass down all of vup userIterateAndNext(nodep->exprp(), m_vup); nodep->replaceWith(nodep->exprp()->unlinkFrBack()); } pushDeletep(nodep); VL_DANGLING(nodep); } } virtual void visit(AstNodeFTask* nodep) { // 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 userIterateChildren(nodep, NULL); 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) { // IEEE: Assignment-like context assertAtStatement(nodep); if (!m_funcp) { if (nodep->lhsp()) { // Return w/o value ok other places nodep->v3error("Return with return value isn't underneath a function"); } } else { if (nodep->lhsp()) { // Function hasn't been widthed, so make it so. nodep->dtypeFrom(m_funcp->fvarp()); // AstPattern requires assignments to pass datatype on PRELIM userIterateAndNext(nodep->lhsp(), WidthVP(nodep->dtypep(),PRELIM).p()); iterateCheckAssign(nodep,"Return value",nodep->lhsp(),FINAL,nodep->dtypep()); } } } virtual void visit(AstFuncRef* nodep) { visit(nodep->castNodeFTaskRef()); nodep->dtypeFrom(nodep->taskp()); //if (debug()) nodep->dumpTree(cout," FuncOut: "); } virtual void visit(AstNodeFTaskRef* nodep) { // For arguments, is assignment-like context; see IEEE rules in AstNodeAssign // Function hasn't been widthed, so make it so. UINFO(5, " FTASKREF "<taskp()) nodep->v3fatalSrc("Unlinked"); if (nodep->didWidth()) return; userIterate(nodep->taskp(), NULL); // // 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 = AstNode::addNext(argsp, 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); VL_DANGLING(argp); AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, false, argsp); if (!newp->scopeNamep() && newp->formatScopeTracking()) { newp->scopeNamep(new AstScopeName(newp->fileline())); } handle.relink(new AstArg(newp->fileline(), "", newp)); // Connection list is now incorrect (has extra args in it). goto reloop; // so exit early; next loop will correct it } else if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::STRING && !pinp->castCvtPackString() && !pinp->castSFormatF() // Already generates a string && !(pinp->castVarRef() && pinp->castVarRef()->varp()->basicp()->keyword()==AstBasicDTypeKwd::STRING)) { UINFO(4," Add CvtPackString: "<unlinkFrBack(&handle); // No next, that's the next pin AstNode* newp = new AstCvtPackString(pinp->fileline(), pinp); handle.relink(newp); pinp = newp; } // AstPattern requires assignments to pass datatype on PRELIM userIterate(pinp, WidthVP(portp->dtypep(),PRELIM).p()); VL_DANGLING(pinp); } else if (accept_mode==1) { // Change data types based on above accept completion if (portp->isDouble()) { spliceCvtD(pinp); VL_DANGLING(pinp); } } else if (accept_mode==2) { // Do PRELIM again, because above accept may have exited early due to node replacement userIterate(pinp, WidthVP(portp->dtypep(),PRELIM).p()); if ((portp->isOutput() || portp->isInout()) && pinp->width() != portp->width()) { pinp->v3error("Unsupported: Function output argument '"<prettyName()<<"'" <<" requires "<width() <<" bits, but connection's "<prettyTypeName() <<" generates "<width()<<" bits."); // otherwise would need some mess to force both sides to proper size // (get an ASSIGN with EXTEND on the lhs instead of rhs) } if (!portp->basicp() || portp->basicp()->isOpaque()) { userIterate(pinp, WidthVP(portp->dtypep(),FINAL).p()); } else { iterateCheckAssign(nodep,"Function Argument",pinp,FINAL,portp->dtypep()); } } } } } nodep->didWidth(true); } virtual void visit(AstInitial* nodep) { assertAtStatement(nodep); m_initialp = nodep; userIterateChildren(nodep, NULL); m_initialp = NULL; } virtual void visit(AstNetlist* nodep) { // Iterate modules backwards, in bottom-up order. That's faster userIterateChildrenBackwards(nodep, NULL); } //-------------------- // Default virtual void visit(AstNodeMath* nodep) { nodep->v3fatalSrc("Visit function missing? Widthed function missing for math node: "<v3fatalSrc("Visit function missing? Widthed expectation for this node: "<prelim()) { // First stage evaluation nodep->dtypeSetDouble(); AstNodeDType* subDTypep = nodep->findLogicDType(64,64, AstNumeric::UNSIGNED); // Self-determined operand userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,subDTypep,EXTEND_EXP); } } void visit_Or_Ls32(AstNodeUniop* nodep) { // CALLER: AstIToRD // Real: Output real // LHS presumed self-determined, then coerced to real if (m_vup->prelim()) { // First stage evaluation nodep->dtypeSetDouble(); AstNodeDType* subDTypep = nodep->findLogicDType(32,32, AstNumeric::SIGNED); // Self-determined operand userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,subDTypep,EXTEND_EXP); } } void visit_Os32_Lr(AstNodeUniop* nodep) { // CALLER: RToI // Real: LHS real // LHS presumed self-determined, then coerced to real if (m_vup->prelim()) { // First stage evaluation iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetSigned32(); } } void visit_Ou64_Lr(AstNodeUniop* nodep) { // CALLER: RealToBits // Real: LHS real // LHS presumed self-determined, then coerced to real if (m_vup->prelim()) { // First stage evaluation iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetUInt64(); } } void visit_log_not(AstNode* nodep) { // CALLER: LogNot // Width-check: lhs 1 bit // Real: Allowed; implicitly compares with zero // We calculate the width of the UNDER expression. // We then check its width to see if it's legal, and edit if not // We finally set the width of our output // IEEE-2012: Table 11-21 and 11.8.1 (same as RedAnd): // LHS is self-determined // Width: 1 bit out // Sign: unsigned out (11.8.1) if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); if (m_vup->prelim()) { iterateCheckBool(nodep,"LHS",nodep->op1p(),BOTH); nodep->dtypeSetLogicBool(); } } void visit_log_and_or(AstNodeBiop* nodep) { // CALLER: LogAnd, LogOr, LogIf, LogIff // Widths: 1 bit out, lhs 1 bit, rhs 1 bit // IEEE-2012 Table 11-21: // LHS is self-determined // RHS is self-determined if (m_vup->prelim()) { iterateCheckBool(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckBool(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetLogicBool(); } } void visit_red_and_or(AstNodeUniop* nodep) { // CALLER: RedAnd, RedOr, ... // Signed: Output unsigned, Lhs/Rhs/etc non-real (presumed, not in IEEE) // IEEE-2012: Table 11-21 and 11.8.1: // LHS is self-determined // Width: 1 bit out // Sign: unsigned out (11.8.1) if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); nodep->dtypeSetLogicBool(); } } void visit_red_unknown(AstNodeUniop* nodep) { // CALLER: IsUnknown // Signed: Output unsigned, Lhs/Rhs/etc non-real (presumed, not in IEEE) // IEEE-2012: Table 11-21 and 11.8.1: // LHS is self-determined // Width: 1 bit out // Sign: unsigned out (11.8.1) if (m_vup->prelim()) { userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); nodep->dtypeSetLogicBool(); } } void visit_cmp_eq_gt(AstNodeBiop* nodep, bool realok) { // CALLER: AstEq, AstGt, ..., AstLtS // Real allowed if and only if real_lhs set // See IEEE-2012 11.4.4, and 11.8.1: // Widths: 1 bit out, width is max of LHS or RHS // Sign: signed compare (not output) if both signed, compare is signed, width mismatches sign extend // else, compare is unsigned, **zero-extends** // Real: If either real, other side becomes real and real compare // TODO: chandle/class handle/iface handle: WildEq/WildNeq same as Eq/Neq // TODO: chandle/class handle/iface handle only allowed to self-compare or against null // TODO: chandle/class handle/iface handle no relational compares if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); if (m_vup->prelim()) { userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { if (!realok) nodep->v3error("Real not allowed as operand to in ?== operator"); if (AstNodeBiop* newp=replaceWithDVersion(nodep)) { VL_DANGLING(nodep); nodep = newp; // Process new node instead iterateCheckReal(nodep,"LHS",nodep->lhsp(),FINAL); iterateCheckReal(nodep,"RHS",nodep->rhsp(),FINAL); } } else if (nodep->lhsp()->isString() || nodep->rhsp()->isString()) { if (AstNodeBiop* newp=replaceWithNVersion(nodep)) { VL_DANGLING(nodep); nodep = newp; // Process new node instead iterateCheckString(nodep,"LHS",nodep->lhsp(),FINAL); iterateCheckString(nodep,"RHS",nodep->rhsp(),FINAL); } } else { bool signedFl = nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned(); if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, signedFl)) { VL_DANGLING(nodep); nodep = newp; // Process new node instead } int width = max(nodep->lhsp()->width(), nodep->rhsp()->width()); int ewidth = max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin()); AstNodeDType* subDTypep = nodep->findLogicDType(width, ewidth, AstNumeric::fromBool(signedFl)); iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,signedFl?EXTEND_LHS:EXTEND_ZERO); iterateCheck(nodep,"RHS",nodep->rhsp(),CONTEXT,FINAL,subDTypep,signedFl?EXTEND_LHS:EXTEND_ZERO); } nodep->dtypeSetLogicBool(); } } void visit_cmp_real(AstNodeBiop* nodep) { // CALLER: EqD, LtD // Widths: 1 bit out, lhs width == rhs width // Signed compare (not output) if both sides signed // Real if and only if real_allow set // IEEE, 11.4.4: relational compares (<,>,<=,>=,==,===,!=,!==) use "zero padding" on unsigned if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); if (m_vup->prelim()) { // See similar handling in visit_cmp_eq_gt where created iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckReal(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetLogicBool(); } } void visit_cmp_string(AstNodeBiop* nodep) { // CALLER: EqN, LtN // Widths: 1 bit out, lhs width == rhs width // String compare (not output) // Real if and only if real_allow set if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); if (m_vup->prelim()) { // See similar handling in visit_cmp_eq_gt where created iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckString(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetLogicBool(); } } void visit_negate_not(AstNodeUniop* nodep, bool real_ok) { // CALLER: (real_ok=false) Not // CALLER: (real_ok=true) Negate // Signed: From lhs // IEEE-2012 Table 11-21: // Widths: out width = lhs width if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); if (m_vup->prelim()) { userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); if (!real_ok) checkCvtUS(nodep->lhsp()); } if (real_ok && nodep->lhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); if (AstNodeUniop* newp=replaceWithDVersion(nodep)) { VL_DANGLING(nodep); nodep = newp; // Process new node instead iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetDouble(); return; } } else { // Note there aren't yet uniops that need version changes // So no need to call replaceWithUOrSVersion(nodep, nodep->isSigned()) } if (m_vup->prelim()) { nodep->dtypeFrom(nodep->lhsp()); } if (m_vup->final()) { AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); nodep->dtypep(expDTypep); // Propagate expression type to negation AstNodeDType* subDTypep = expDTypep; iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); } } void visit_signed_unsigned(AstNodeUniop* nodep, AstNumeric rs_out) { // CALLER: Signed, Unsigned // Width: lhs is self determined width // See IEEE-2012 6.24.1: // Width: Returns packed array, of size $bits(expression). // Sign: Output sign is as specified by operation // TODO: Type: Two-state if input is two-state, else four-state if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); if (m_vup->prelim()) { userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); checkCvtUS(nodep->lhsp()); int width = nodep->lhsp()->width(); AstNodeDType* expDTypep = nodep->findLogicDType(width,width,rs_out); nodep->dtypep(expDTypep); AstNodeDType* subDTypep = expDTypep; // The child's width is self determined iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,subDTypep,EXTEND_EXP); } } void visit_shift(AstNodeBiop* nodep) { // CALLER: ShiftL, ShiftR, ShiftRS // Widths: Output width from lhs, rhs<33 bits // Signed: Output signed iff LHS signed; unary operator // See IEEE 2012 11.4.10: // RHS is self-determined. RHS is always treated as unsigned, has no effect on result. iterate_shift_prelim(nodep); nodep->dtypeChgSigned(nodep->lhsp()->isSigned()); AstNodeBiop* newp = iterate_shift_final(nodep); VL_DANGLING(nodep); if (newp) {} // Ununused } void iterate_shift_prelim(AstNodeBiop* nodep) { // Shifts // See IEEE-2012 11.4.10 and Table 11-21. // RHS is self-determined. RHS is always treated as unsigned, has no effect on result. if (m_vup->prelim()) { userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); checkCvtUS(nodep->lhsp()); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); nodep->dtypeFrom(nodep->lhsp()); } } AstNodeBiop* iterate_shift_final(AstNodeBiop* nodep) { // Nodep maybe edited if (m_vup->final()) { AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // ShiftRS converts to ShiftR, but not vice-versa if (nodep->castShiftRS()) { if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, nodep->isSigned())) { VL_DANGLING(nodep); nodep = newp; // Process new node instead } } bool warnOn = true; // No warning if "X = 1'b1<lhsp()->isOne() && nodep->backp()->castNodeAssign()) warnOn = false; iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP,warnOn); if (nodep->rhsp()->width()>32) { AstConst* shiftp = nodep->rhsp()->castConst(); if (shiftp && shiftp->num().mostSetBitP1() <= 32) { // If (number)<<96'h1, then make it into (number)<<32'h1 V3Number num (shiftp->fileline(), 32, 0); num.opAssign(shiftp->num()); AstNode* shiftp = nodep->rhsp(); nodep->rhsp()->replaceWith(new AstConst(shiftp->fileline(), num)); shiftp->deleteTree(); VL_DANGLING(shiftp); } } } return nodep; // May edit } void visit_boolmath_and_or(AstNodeBiop* nodep) { // CALLER: And, Or, Xor, ... // Lint widths: out width = lhs width = rhs width // Signed: if lhs & rhs signed // IEEE-2012 Table 11-21: // Width: max(LHS, RHS) if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); // If errors are off, we need to follow the spec; thus we really need to do the max() // because the rhs could be larger, and we need to have proper editing to get the widths // to be the same for our operations. if (m_vup->prelim()) { // First stage evaluation // Determine expression widths only relying on what's in the subops userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); int width = max(nodep->lhsp()->width(), nodep->rhsp()->width()); int mwidth = max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin()); bool expSigned = (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); nodep->dtypeChgWidthSigned(width,mwidth,AstNumeric::fromBool(expSigned)); } if (m_vup->final()) { AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // Error report and change sizes for suboperands of this node. iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); iterateCheck(nodep,"RHS",nodep->rhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); } } void visit_add_sub_replace(AstNodeBiop* nodep, bool real_ok) { // CALLER: (real_ok=false) AddS, SubS, ... // CALLER: (real_ok=true) Add, Sub, ... // Widths: out width = lhs width = rhs width // Signed: Replace operator with signed operator, or signed to unsigned // Real: Replace operator with real operator // IEEE-2012 Table 11-21: // Width: max(LHS, RHS) // If errors are off, we need to follow the spec; thus we really need to do the max() // because the rhs could be larger, and we need to have proper editing to get the widths // to be the same for our operations. // //if (debug()>=9) { UINFO(0,"-rus "<dumpTree(cout,"-rusin-"); } if (m_vup->prelim()) { // First stage evaluation // Determine expression widths only relying on what's in the subops userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); if (!real_ok) { checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); } if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); spliceCvtD(nodep->rhsp()); if (AstNodeBiop* newp=replaceWithDVersion(nodep)) { VL_DANGLING(nodep); nodep = newp; // Process new node instead } nodep->dtypeSetDouble(); iterateCheckReal(nodep,"LHS",nodep->lhsp(),FINAL); iterateCheckReal(nodep,"RHS",nodep->rhsp(),FINAL); return; } else { int width = max(nodep->lhsp()->width(), nodep->rhsp()->width()); int mwidth = max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin()); bool expSigned = (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); nodep->dtypeChgWidthSigned(width,mwidth,AstNumeric::fromBool(expSigned)); } } if (m_vup->final()) { // Parent's data type was computed using the max(upper, nodep->dtype) AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // We don't use LHS && RHS -- unspecified language corner, see t_math_signed5 test //bool expSigned = (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, expDTypep->isSigned())) { VL_DANGLING(nodep); nodep = newp; // Process new node instead } // Some warning suppressions bool lhsWarn=true; bool rhsWarn = true; if (nodep->castAdd() || nodep->castSub()) { if (subDTypep->widthMin() == (nodep->lhsp()->widthMin()+1)) lhsWarn=false; // Warn if user wants extra bit from carry if (subDTypep->widthMin() == (nodep->rhsp()->widthMin()+1)) rhsWarn=false; // Warn if user wants extra bit from carry } else if (nodep->castMul() || nodep->castMulS()) { if (subDTypep->widthMin() >= (nodep->lhsp()->widthMin())) lhsWarn=false; if (subDTypep->widthMin() >= (nodep->rhsp()->widthMin())) rhsWarn=false; } // Final call, so make sure children check their sizes // Error report and change sizes for suboperands of this node. iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP,lhsWarn); iterateCheck(nodep,"RHS",nodep->rhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP,rhsWarn); } //if (debug()>=9) nodep->dumpTree(cout,"-rusou-"); } void visit_real_add_sub(AstNodeBiop* nodep) { // CALLER: AddD, MulD, ... if (m_vup->prelim()) { // First stage evaluation // Note similar steps in visit_add_sub_replace promotion to double iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckReal(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetDouble(); } } void visit_real_neg_ceil(AstNodeUniop* nodep) { // CALLER: Negate, Ceil, Log, ... if (m_vup->prelim()) { // First stage evaluation // See alsl visit_negate_not conversion iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetDouble(); } } //---------------------------------------------------------------------- // LOWER LEVEL WIDTH METHODS (none iterate) bool widthBad (AstNode* nodep, AstNodeDType* expDTypep) { int expWidth = expDTypep->width(); int expWidthMin = expDTypep->widthMin(); if (!nodep->dtypep()) nodep->v3fatalSrc("Under node "<prettyTypeName()<<" has no dtype?? Missing Visitor func?"); if (nodep->width()==0) nodep->v3fatalSrc("Under node "<prettyTypeName()<<" has no expected width?? Missing Visitor func?"); if (expWidth==0) nodep->v3fatalSrc("Node "<prettyTypeName()<<" has no expected width?? Missing Visitor func?"); if (expWidthMin==0) expWidthMin = expWidth; if (nodep->dtypep()->width() == expWidth) return false; if (nodep->dtypep()->widthSized() && nodep->width() != expWidthMin) return true; if (!nodep->dtypep()->widthSized() && nodep->widthMin() > expWidthMin) return true; return false; } void fixWidthExtend (AstNode* nodep, AstNodeDType* expDTypep, ExtendRule extendRule) { // Fix the width mismatch by extending or truncating bits // *ONLY* call this from checkWidth() // Truncation is rarer, but can occur: parameter [3:0] FOO = 64'h12312; // A(CONSTwide)+B becomes A(CONSTwidened)+B // A(somewide)+B becomes A(TRUNC(somewide,width))+B // or A(EXTRACT(somewide,width,0))+B // Sign extension depends on the type of the *present* // node, while the output dtype is the *expected* sign. // It is reasonable to have sign extension with unsigned output, // for example $unsigned(a)+$signed(b), the SIGNED(B) will be unsigned dtype out UINFO(4," widthExtend_(r="<castConst(); int expWidth = expDTypep->width(); if (constp && !constp->num().isNegative()) { // Save later constant propagation work, just right-size it. V3Number num (nodep->fileline(), expWidth); num.opAssign(constp->num()); num.isSigned(false); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); pushDeletep(constp); VL_DANGLING(constp); VL_DANGLING(nodep); nodep=newp; } else if (expWidthwidth()) { // Trunc - Extract AstNRelinker linker; nodep->unlinkFrBack(&linker); AstNode* newp = new AstSel(nodep->fileline(), nodep, 0, expWidth); newp->didWidth(true); // Don't replace dtype with unsigned linker.relink(newp); nodep=newp; } else { // Extend AstNRelinker linker; nodep->unlinkFrBack(&linker); bool doSigned = false; switch (extendRule) { case EXTEND_ZERO: doSigned = false; break; case EXTEND_EXP: doSigned = nodep->isSigned() && expDTypep->isSigned(); break; case EXTEND_LHS: doSigned = nodep->isSigned(); break; default: nodep->v3fatalSrc("bad case"); } AstNode* newp = (doSigned ? static_cast(new AstExtendS(nodep->fileline(), nodep)) : static_cast(new AstExtend (nodep->fileline(), nodep))); linker.relink(newp); nodep=newp; } if (expDTypep->isDouble() && !nodep->isDouble()) { // For AstVar init() among others // TODO do all to-real and to-integer conversions in this function rather than in callers AstNode* newp = spliceCvtD(nodep); nodep = newp; } nodep->dtypeFrom(expDTypep); UINFO(4," _new: "<castConst(); if (constp) { V3Number num (nodep->fileline(), expWidth); num.opRedOr(constp->num()); num.isSigned(expSigned); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); constp->deleteTree(); VL_DANGLING(constp); VL_DANGLING(nodep); nodep=newp; } else { AstNRelinker linker; nodep->unlinkFrBack(&linker); AstNode* newp = new AstRedOr(nodep->fileline(), nodep); linker.relink(newp); nodep=newp; } nodep->dtypeChgWidthSigned(expWidth,expWidth,AstNumeric::fromBool(expSigned)); UINFO(4," _new: "<castConst()) { if (constp->num().autoExtend() && !constp->num().sized() && constp->width()==1) { // Make it the proper size. Careful of proper extension of 0's/1's V3Number num (constp->fileline(), expWidth); num.opRepl(constp->num(), expWidth); // {width{'1}} AstNode* newp = new AstConst(constp->fileline(), num); // Spec says always unsigned with proper width if (debug()>4) constp->dumpTree(cout," fixAutoExtend_old: "); if (debug()>4) newp->dumpTree(cout," _new: "); constp->replaceWith(newp); constp->deleteTree(); VL_DANGLING(constp); // Tell caller the new constp, and that we changed it. nodepr = newp; return true; } } return false; // No change } bool similarDTypeRecurse(AstNodeDType* node1p, AstNodeDType* node2p) { return node1p->skipRefp()->similarDType(node2p->skipRefp()); } void iterateCheckFileDesc (AstNode* nodep, AstNode* underp, Stage stage) { if (stage != BOTH) nodep->v3fatalSrc("Bad call"); // underp may change as a result of replacement underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p()); AstNodeDType* expDTypep = underp->findUInt32DType(); underp = iterateCheck(nodep,"file_descriptor",underp,SELF,FINAL,expDTypep,EXTEND_EXP); if (underp) {} // cppcheck } void iterateCheckReal (AstNode* nodep, const char* side, AstNode* underp, Stage stage) { // Coerce child to real if not already. Child is self-determined // e.g. nodep=ADDD, underp=ADD in ADDD(ADD(a,b), real-CONST) // Don't need separate PRELIM and FINAL(double) calls; // as if resolves to double, the BOTH correctly resolved double, // otherwise self-determined was correct // underp may change as a result of replacement if (stage & PRELIM) { underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p()); } if (stage & FINAL) { AstNodeDType* expDTypep = nodep->findDoubleDType(); underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP); } if (underp) {} // cppcheck } void iterateCheckString (AstNode* nodep, const char* side, AstNode* underp, Stage stage) { if (stage & PRELIM) { underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p()); } if (stage & FINAL) { AstNodeDType* expDTypep = nodep->findStringDType(); underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP); } if (underp) {} // cppcheck } void iterateCheckSizedSelf (AstNode* nodep, const char* side, AstNode* underp, Determ determ, Stage stage) { // Coerce child to any sized-number data type; child is self-determined i.e. isolated from expected type. // e.g. nodep=CONCAT, underp=lhs in CONCAT(lhs,rhs) if (determ != SELF) nodep->v3fatalSrc("Bad call"); if (stage != FINAL && stage != BOTH) nodep->v3fatalSrc("Bad call"); // underp may change as a result of replacement if (stage & PRELIM) underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p()); underp = checkCvtUS(underp); AstNodeDType* expDTypep = underp->dtypep(); underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP); if (underp) {} // cppcheck } void iterateCheckAssign(AstNode* nodep, const char* side, AstNode* rhsp, Stage stage, AstNodeDType* lhsDTypep) { // Check using assignment-like context rules //if (debug()) nodep->dumpTree(cout,"-checkass: "); if (stage != FINAL) nodep->v3fatalSrc("Bad width call"); // We iterate and size the RHS based on the result of RHS evaluation bool lhsStream = (nodep->castNodeAssign() && nodep->castNodeAssign()->lhsp()->castNodeStream()); rhsp = iterateCheck(nodep,side,rhsp,ASSIGN,FINAL,lhsDTypep,lhsStream?EXTEND_OFF:EXTEND_LHS); //if (debug()) nodep->dumpTree(cout,"-checkout: "); if (rhsp) {} // cppcheck } void iterateCheckBool (AstNode* nodep, const char* side, AstNode* underp, Stage stage) { if (stage != BOTH) nodep->v3fatalSrc("Bad call"); // Booleans always self-determined so do BOTH at once // Underp is used in a self-determined but boolean context, reduce a multibit number to one bit // stage is always BOTH so not passed as argument // underp may change as a result of replacement if (!underp) nodep->v3fatalSrc("Node has no type"); underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,BOTH).p()); if (!underp || !underp->dtypep()) nodep->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it? // // For DOUBLE under a logical op, add implied test against zero, never a warning if (underp && underp->isDouble()) { UINFO(6," spliceCvtCmpD0: "<unlinkFrBack(&linker); AstNode* newp = new AstNeqD(nodep->fileline(), underp, new AstConst(nodep->fileline(), AstConst::RealDouble(), 0.0)); linker.relink(newp); } else if (!underp->dtypep()->basicp()) { nodep->v3error("Logical Operator "<prettyTypeName() <<" expects a non-complex data type on the "<replaceWith(new AstConst(nodep->fileline(), AstConst::LogicFalse())); pushDeletep(underp); VL_DANGLING(underp); } else { bool bad = widthBad(underp,nodep->findLogicBoolDType()); if (bad) { bool warnOn = true; // Not used if (warnOn) { if (debug()>4) nodep->backp()->dumpTree(cout," back: "); nodep->v3warn(WIDTH,"Logical Operator "<prettyTypeName() <<" expects 1 bit on the "<prettyTypeName()<<" generates "<width() <<(underp->width()!=underp->widthMin() ?" or "+cvtToStr(underp->widthMin()):"") <<" bits."); } fixWidthReduce(underp); VL_DANGLING(underp);//Changed } } } AstNode* iterateCheck (AstNode* nodep, const char* side, AstNode* underp, Determ determ, Stage stage, AstNodeDType* expDTypep, ExtendRule extendRule, bool warnOn=true) { // Perform data type check on underp, which is underneath nodep used for error reporting // Returns the new underp // Conversion to/from doubles and integers are before iterating. if (stage != FINAL) nodep->v3fatalSrc("Bad state to iterateCheck"); if (!underp || !underp->dtypep()) nodep->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it? if (expDTypep == underp->dtypep()) { // Perfect underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (expDTypep->isDouble() && underp->isDouble()) { // Also good underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (expDTypep->isDouble() && !underp->isDouble()) { underp = spliceCvtD(underp); underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (!expDTypep->isDouble() && underp->isDouble()) { underp = spliceCvtS(underp, true); // Round RHS underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (expDTypep->isString() && !underp->dtypep()->isString()) { underp = spliceCvtString(underp); underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else { AstBasicDType* expBasicp = expDTypep->basicp(); AstBasicDType* underBasicp = underp->dtypep()->basicp(); if (expBasicp && underBasicp) { AstNodeDType* subDTypep = expDTypep; // We then iterate FINAL before width fixes, as if the under-operation // is e.g. an ADD, the ADD will auto-adjust to the proper data type // or if another operation e.g. ATOI will not. if (determ == SELF) { underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (determ == ASSIGN) { // IEEE: Signedness is solely determined by the RHS (underp), not by the LHS (expDTypep) if (underp->isSigned() != subDTypep->isSigned() || underp->width() != subDTypep->width()) { subDTypep = nodep->findLogicDType(max(subDTypep->width(), underp->width()), max(subDTypep->widthMin(), underp->widthMin()), AstNumeric::fromBool(underp->isSigned())); UINFO(9,"Assignment of opposite-signed RHS to LHS: "<basicp(); AstBasicDType* underBasicp = underp->dtypep()->basicp(); if (expDTypep == underp->dtypep()) { return; // Same type must match } else if (!expBasicp || expBasicp->isDouble() || !underBasicp || underBasicp->isDouble()) { // This is perhaps a v3fatalSrc as we should have checked the types before calling widthCheck, // but we may have missed a non-sized check in earlier code, so might as well assume it is the users' fault. nodep->v3error(ucfirst(nodep->prettyOperatorName())<<" expected non-complex non-double "<v3fatalSrc("widthCheckSized should not be called on doubles/complex types"); #endif return; } else { int expWidth = expDTypep->width(); int expWidthMin = expDTypep->widthMin(); if (expWidthMin==0) expWidthMin = expWidth; bool bad = widthBad(underp,expDTypep); if ((bad || underp->width() != expWidth) && fixAutoExtend(underp/*ref*/,expWidth)) { underp=NULL; // Changes underp return; } if (underp->castConst() && underp->castConst()->num().isFromString() && expWidth > underp->width() && (((expWidth - underp->width()) % 8) == 0)) { // At least it's character sized // reg [31:0] == "foo" we'll consider probably fine. // Maybe this should be a special warning? Not for now. warnOn = false; } if ((nodep->castAdd() && underp->width()==1 && underp->isOne()) || (nodep->castSub() && underp->width()==1 && underp->isOne() && 0==strcmp(side,"RHS"))) { // "foo + 1'b1", or "foo - 1'b1" are very common, people assume they extend correctly warnOn = false; } if (bad && warnOn) { if (debug()>4) nodep->backp()->dumpTree(cout," back: "); nodep->v3warn(WIDTH,ucfirst(nodep->prettyOperatorName()) <<" expects "<prettyTypeName()<<" generates "<width() <<(underp->width()!=underp->widthMin() ?" or "+cvtToStr(underp->widthMin()):"") <<" bits."); } if (bad || underp->width()!=expWidth) { // If we're in an NodeAssign, don't truncate the RHS if the LHS is // a NodeStream. The streaming operator changes the rules regarding // which bits to truncate. AstNodeAssign* assignp = nodep->castNodeAssign(); AstPin* pinp = nodep->castPin(); if (assignp && assignp->lhsp()->castNodeStream()) { } else if (pinp && !pinp->modVarp()->isInput()) { // V3Inst::pinReconnectSimple must deal UINFO(5,"pinInSizeMismatch: "<isDouble()) { nodep->v3error("Expected integral (non-real) input to "<backp()->prettyTypeName()); nodep = spliceCvtS(nodep, true); } return nodep; } AstNode* spliceCvtD(AstNode* nodep) { // For integer used in REAL context, convert to real // We don't warn here, "2.0 * 2" is common and reasonable if (nodep && !nodep->isDouble()) { UINFO(6," spliceCvtD: "<unlinkFrBack(&linker); AstNode* newp = new AstIToRD(nodep->fileline(), nodep); linker.relink(newp); return newp; } else { return nodep; } } AstNode* spliceCvtS(AstNode* nodep, bool warnOn) { // IEEE-2012 11.8.1: Signed: Type coercion creates signed // 11.8.2: Argument to convert is self-determined if (nodep && nodep->isDouble()) { UINFO(6," spliceCvtS: "<unlinkFrBack(&linker); if (warnOn) nodep->v3warn(REALCVT,"Implicit conversion of real to integer"); AstNode* newp = new AstRToIRoundS(nodep->fileline(), nodep); linker.relink(newp); return newp; } else { return nodep; } } AstNode* spliceCvtString(AstNode* nodep) { // IEEE-2012 11.8.1: Signed: Type coercion creates signed // 11.8.2: Argument to convert is self-determined if (nodep && !nodep->dtypep()->basicp()->isString()) { UINFO(6," spliceCvtString: "<unlinkFrBack(&linker); AstNode* newp = new AstCvtPackString(nodep->fileline(), nodep); linker.relink(newp); return newp; } else { return nodep; } } AstNodeBiop* replaceWithUOrSVersion(AstNodeBiop* nodep, bool signedFlavorNeeded) { // Given a signed/unsigned node type, create the opposite type // Return new node or NULL if nothing if (signedFlavorNeeded == nodep->signedFlavor()) { return NULL; } if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp()); // To simplify callers, some node types don't need to change switch (nodep->type()) { case AstType::atEq: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atNeq: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atEqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atNeqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atAdd: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atSub: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atShiftL: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; default: break; } FileLine* fl = nodep->fileline(); AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeBiop* newp = NULL; switch (nodep->type()) { case AstType::atGt: newp = new AstGtS (fl,lhsp,rhsp); break; case AstType::atGtS: newp = new AstGt (fl,lhsp,rhsp); break; case AstType::atGte: newp = new AstGteS (fl,lhsp,rhsp); break; case AstType::atGteS: newp = new AstGte (fl,lhsp,rhsp); break; case AstType::atLt: newp = new AstLtS (fl,lhsp,rhsp); break; case AstType::atLtS: newp = new AstLt (fl,lhsp,rhsp); break; case AstType::atLte: newp = new AstLteS (fl,lhsp,rhsp); break; case AstType::atLteS: newp = new AstLte (fl,lhsp,rhsp); break; case AstType::atDiv: newp = new AstDivS (fl,lhsp,rhsp); break; case AstType::atDivS: newp = new AstDiv (fl,lhsp,rhsp); break; case AstType::atModDiv: newp = new AstModDivS (fl,lhsp,rhsp); break; case AstType::atModDivS: newp = new AstModDiv (fl,lhsp,rhsp); break; case AstType::atMul: newp = new AstMulS (fl,lhsp,rhsp); break; case AstType::atMulS: newp = new AstMul (fl,lhsp,rhsp); break; case AstType::atShiftR: newp = new AstShiftRS (fl,lhsp,rhsp); break; case AstType::atShiftRS: newp = new AstShiftR (fl,lhsp,rhsp); break; default: nodep->v3fatalSrc("Node needs sign change, but bad case: "<replaceWith(newp); newp->dtypeFrom(nodep); pushDeletep(nodep); VL_DANGLING(nodep); return newp; } AstNodeBiop* replaceWithDVersion(AstNodeBiop* nodep) { // Given a signed/unsigned node type, create the opposite type // Return new node or NULL if nothing if (nodep->doubleFlavor()) { return NULL; } FileLine* fl = nodep->fileline(); AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeBiop* newp = NULL; // No width change on output;... // All below have bool or double outputs switch (nodep->type()) { case AstType::atAdd: newp = new AstAddD (fl,lhsp,rhsp); break; case AstType::atSub: newp = new AstSubD (fl,lhsp,rhsp); break; case AstType::atPow: newp = new AstPowD (fl,lhsp,rhsp); break; case AstType::atEq: case AstType::atEqCase: newp = new AstEqD (fl,lhsp,rhsp); break; case AstType::atNeq: case AstType::atNeqCase: newp = new AstNeqD (fl,lhsp,rhsp); break; case AstType::atGt: case AstType::atGtS: newp = new AstGtD (fl,lhsp,rhsp); break; case AstType::atGte: case AstType::atGteS: newp = new AstGteD (fl,lhsp,rhsp); break; case AstType::atLt: case AstType::atLtS: newp = new AstLtD (fl,lhsp,rhsp); break; case AstType::atLte: case AstType::atLteS: newp = new AstLteD (fl,lhsp,rhsp); break; case AstType::atDiv: case AstType::atDivS: newp = new AstDivD (fl,lhsp,rhsp); break; case AstType::atMul: case AstType::atMulS: newp = new AstMulD (fl,lhsp,rhsp); break; default: nodep->v3fatalSrc("Node needs conversion to double, but bad case: "<replaceWith(newp); // No width change; the default created type (bool or double) is correct pushDeletep(nodep); VL_DANGLING(nodep); return newp; } AstNodeBiop* replaceWithNVersion(AstNodeBiop* nodep) { // Given a signed/unsigned node type, replace with string version // Return new node or NULL if nothing if (nodep->stringFlavor()) { return NULL; } FileLine* fl = nodep->fileline(); AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeBiop* newp = NULL; // No width change on output;... // All below have bool or double outputs switch (nodep->type()) { case AstType::atEq: case AstType::atEqCase: newp = new AstEqN (fl,lhsp,rhsp); break; case AstType::atNeq: case AstType::atNeqCase: newp = new AstNeqN (fl,lhsp,rhsp); break; case AstType::atGt: case AstType::atGtS: newp = new AstGtN (fl,lhsp,rhsp); break; case AstType::atGte: case AstType::atGteS: newp = new AstGteN (fl,lhsp,rhsp); break; case AstType::atLt: case AstType::atLtS: newp = new AstLtN (fl,lhsp,rhsp); break; case AstType::atLte: case AstType::atLteS: newp = new AstLteN (fl,lhsp,rhsp); break; default: nodep->v3fatalSrc("Node needs conversion to string, but bad case: "<replaceWith(newp); // No width change; the default created type (bool or string) is correct pushDeletep(nodep); VL_DANGLING(nodep); 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); VL_DANGLING(nodep); 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"); userIterate(nodep, NULL); return nodep; } AstConst* dimensionValue(AstNodeDType* nodep, AstAttrType attrType, int dim) { // Return the dimension value for the specified attribute and constant dimension AstNodeDType* dtypep = nodep->skipRefp(); VNumRange declRange; // ranged() set false for (int i = 1; i <= dim; ++i) { //UINFO(9, " dim at "<castNodeArrayDType()) { declRange = adtypep->declRange(); if (isubDTypep()->skipRefp(); continue; } else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) { declRange = adtypep->declRange(); if (adtypep) {} // UNUSED break; // Sub elements don't look like arrays and can't iterate into } else if (AstBasicDType* adtypep = dtypep->castBasicDType()) { if (adtypep->isRanged()) declRange = adtypep->declRange(); break; } break; } AstConst* valp = NULL; // If NULL, construct from val int val = 0; switch (attrType) { case AstAttrType::DIM_BITS: { int bits = 1; while (dtypep) { //UINFO(9, " bits at "<castNodeArrayDType()) { bits *= adtypep->declRange().elements(); dtypep = adtypep->subDTypep()->skipRefp(); continue; } else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) { bits *= adtypep->width(); break; } else if (AstBasicDType* adtypep = dtypep->castBasicDType()) { bits *= adtypep->width(); break; } break; } if (dim == 0) { val = 0; } else if (dim == 1 && !declRange.ranged() && bits==1) { // $bits should be sane for non-arrays val = nodep->width(); } else { val = bits; } break; } case AstAttrType::DIM_HIGH: val = !declRange.ranged() ? 0 : declRange.hi(); break; case AstAttrType::DIM_LEFT: val = !declRange.ranged() ? 0 : declRange.left(); break; case AstAttrType::DIM_LOW: val = !declRange.ranged() ? 0 : declRange.lo(); break; case AstAttrType::DIM_RIGHT: val = !declRange.ranged() ? 0 : declRange.right(); break; case AstAttrType::DIM_INCREMENT: val = (declRange.ranged() && declRange.littleEndian()) ? -1 : 1; break; case AstAttrType::DIM_SIZE: val = !declRange.ranged() ? 0 : declRange.elements(); break; default: nodep->v3fatalSrc("Missing DIM ATTR type case"); break; } if (!valp) valp = new AstConst(nodep->fileline(), AstConst::Signed32(), val); UINFO(9," $dimension "<second; } AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(), nodep->findSigned32DType(), new AstRange(nodep->fileline(), msbdim, 0)); AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL); v3Global.rootp()->typeTablep()->addTypesp(vardtypep); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, "__Vdimtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++), vardtypep); varp->isConst(true); varp->isStatic(true); varp->valuep(initp); // Add to root, as don't know module we are in, and aids later structure sharing v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); // Element 0 is a non-index and has speced values initp->addValuep(dimensionValue(nodep, attrType, 0)); for (unsigned i=1; iaddValuep(dimensionValue(nodep, attrType, i)); } userIterate(varp, NULL); // May have already done $unit so must do this var m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp)); return varp; } AstVar* enumVarp(AstEnumDType* nodep, AstAttrType attrType, uint32_t msbdim) { // Return a variable table which has specified dimension properties for this variable TableMap::iterator pos = m_tableMap.find(make_pair(nodep, attrType)); if (pos != m_tableMap.end()) { return pos->second; } UINFO(9, "Construct Venumtab attr="<findStringDType(); } else { basep = nodep->dtypep(); } AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(), basep, new AstRange(nodep->fileline(), msbdim, 0)); AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL); v3Global.rootp()->typeTablep()->addTypesp(vardtypep); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, "__Venumtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++), vardtypep); varp->isConst(true); varp->isStatic(true); varp->valuep(initp); // Add to root, as don't know module we are in, and aids later structure sharing v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); // Default for all unspecified values if (attrType == AstAttrType::ENUM_NAME) { initp->defaultp(new AstConst(nodep->fileline(), AstConst::String(), "")); } else if (attrType == AstAttrType::ENUM_NEXT || attrType == AstAttrType::ENUM_PREV) { initp->defaultp(new AstConst(nodep->fileline(), V3Number(nodep->fileline(), nodep->width(), 0))); } else { nodep->v3fatalSrc("Bad case"); } // Find valid values and populate if (!nodep->itemsp()) nodep->v3fatalSrc("enum without items"); vector values; values.reserve(msbdim+1); for (unsigned i=0; i<(msbdim+1); ++i) { values[i] = NULL; } { AstEnumItem* firstp = nodep->itemsp(); AstEnumItem* prevp = firstp; // Prev must start with last item while (prevp->nextp()) prevp = prevp->nextp()->castEnumItem(); for (AstEnumItem* itemp = firstp; itemp;) { AstEnumItem* nextp = itemp->nextp()->castEnumItem(); AstConst* vconstp = itemp->valuep()->castConst(); if (!vconstp) nodep->v3fatalSrc("Enum item without constified value"); uint32_t i = vconstp->toUInt(); if (attrType == AstAttrType::ENUM_NAME) { values[i] = new AstConst(nodep->fileline(), AstConst::String(), itemp->name()); } else if (attrType == AstAttrType::ENUM_NEXT) { values[i] = (nextp ? nextp : firstp)->valuep()->cloneTree(false); // A const } else if (attrType == AstAttrType::ENUM_PREV) { values[i] = prevp->valuep()->cloneTree(false); // A const } else { nodep->v3fatalSrc("Bad case"); } prevp = itemp; itemp = nextp; } } // Add all specified values to table for (unsigned i=0; i<(msbdim+1); ++i) { AstNode* valp = values[i]; if (valp) initp->addIndexValuep(i, valp); } userIterate(varp, NULL); // May have already done $unit so must do this var m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp)); return varp; } PatVecMap patVectorMap(AstPattern* nodep, const VNumRange& range) { PatVecMap patmap; int element = range.left(); for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) { if (patp->keyp()) { if (AstConst* constp = patp->keyp()->castConst()) { element = constp->toSInt(); } else { patp->keyp()->v3error("Assignment pattern key not supported/understood: "<keyp()->prettyTypeName()); } } if (patmap.find(element) != patmap.end()) { patp->v3error("Assignment pattern key used multiple times: "<selfDtm())) { UINFO(1,"-: "<v3fatalSrc("No dtype expected at statement "<prettyTypeName()); } } void checkConstantOrReplace(AstNode* nodep, const string& message) { // See also V3WidthSel::checkConstantOrReplace // Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us! if (!nodep->castConst()) { nodep->v3error(message); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1)); pushDeletep(nodep); VL_DANGLING(nodep); } } //---------------------------------------------------------------------- // METHODS - special iterators // These functions save/restore the AstNUser information so it can pass to child nodes. AstNode* userIterateSubtreeReturnEdits(AstNode* nodep, WidthVP* vup) { if (!nodep) return NULL; WidthVP* saveVup = m_vup; AstNode* ret; { m_vup = vup; ret = nodep->iterateSubtreeReturnEdits(*this); } m_vup = saveVup; return ret; } void userIterate(AstNode* nodep, WidthVP* vup) { if (!nodep) return; WidthVP* saveVup = m_vup; { m_vup = vup; nodep->iterate(*this); } m_vup = saveVup; } void userIterateAndNext(AstNode* nodep, WidthVP* vup) { if (!nodep) return; WidthVP* saveVup = m_vup; { m_vup = vup; nodep->iterateAndNext(*this); } m_vup = saveVup; } void userIterateChildren(AstNode* nodep, WidthVP* vup) { if (!nodep) return; WidthVP* saveVup = m_vup; { m_vup = vup; nodep->iterateChildren(*this); } m_vup = saveVup; } void userIterateChildrenBackwards(AstNode* nodep, WidthVP* vup) { if (!nodep) return; WidthVP* saveVup = m_vup; { m_vup = vup; nodep->iterateChildrenBackwards(*this); } m_vup = saveVup; } 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; m_vup = NULL; } AstNode* mainAcceptEdit(AstNode* nodep) { return userIterateSubtreeReturnEdits(nodep, WidthVP(SELF,BOTH).p()); } virtual ~WidthVisitor() {} }; //###################################################################### // Width class functions int V3Width::debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void V3Width::width(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } //! Single node parameter propagation //! Smaller step... Only do a single node for parameter propagation AstNode* V3Width::widthParamsEdit (AstNode* nodep) { UINFO(4,__FUNCTION__<<": "<= 6); } verilator-3.916/src/V3EmitC.cpp0000664000177100017500000025266013205574202016240 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 VL_INCLUDE_UNORDERED_SET #include "V3Global.h" #include "V3String.h" #include "V3EmitC.h" #include "V3EmitCBase.h" #include "V3Number.h" #define VL_VALUE_STRING_MAX_WIDTH 8192 // We use a static char array in VL_VALUE_STRING #define EMITC_NUM_CONSTW 8 // Number of VL_CONST_W_*X's in verilated.h (IE VL_CONST_W_8X is last) //###################################################################### // 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, const string& vfmt, char fmtLetter); void emitVarDecl(AstVar* nodep, const string& prefixIfImp); typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_PAR, EVL_ALL} EisWhich; void emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp); void emitVarCtors(); bool emitSimpleOk(AstNodeMath* nodep); void emitIQW(AstNode* nodep) { // Other abbrevs: "C"har, "S"hort, "F"loat, "D"ouble, stri"N"g puts (nodep->isString() ? "N" : nodep->isWide() ? "W" : nodep->isQuad() ? "Q" : "I"); } void emitScIQW(AstVar* nodep) { if (!nodep->isSc()) nodep->v3fatalSrc("emitting SystemC operator on non-SC variable"); puts (nodep->isScBigUint() ? "SB" : nodep->isScUint() ? "SU" : nodep->isScBv() ? "SW" : (nodep->isScQuad() ? "SQ" : "SI")); } void emitOpName(AstNode* nodep, const string& format, AstNode* lhsp, AstNode* rhsp, AstNode* thsp); void emitDeclArrayBrackets(AstVar* nodep) { // This isn't very robust and may need cleanup for other data types for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp; arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } } void emitTypedefs(AstNode* firstp) { bool first = true; for (AstNode* loopp=firstp; loopp; loopp = loopp->nextp()) { if (AstTypedef* nodep = loopp->castTypedef()) { if (nodep->attrPublic()) { if (first) { first = false; puts("\n// TYPEDEFS\n"); puts("// That were declared public\n"); } else { puts("\n"); } if (AstEnumDType* adtypep = nodep->dtypep()->skipRefToEnump()->castEnumDType()) { if (adtypep->width()>64) { putsDecoration("// enum "+nodep->name()+" // Ignored: Too wide for C++\n"); } else { puts("enum "+nodep->name()+" {\n"); for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) { puts(itemp->name()); puts(" = "); itemp->valuep()->iterateAndNext(*this); if (itemp->nextp()->castEnumItem()) puts(","); puts("\n"); } puts("};\n"); } } } } } } // VISITORS virtual void visit(AstNodeAssign* nodep) { bool paren = true; bool decind = false; if (AstSel* selp=nodep->lhsp()->castSel()) { if (selp->widthMin()==1) { putbs("VL_ASSIGNBIT_"); emitIQW(selp->fromp()); if (nodep->rhsp()->isAllOnesV()) { puts("O("); } else { puts("I("); } puts(cvtToStr(nodep->widthMin())+","); selp->lsbp()->iterateAndNext(*this); puts(", "); selp->fromp()->iterateAndNext(*this); puts(", "); } else { putbs("VL_ASSIGNSEL_"); emitIQW (selp->fromp()); puts("II"); emitIQW(nodep->rhsp()); puts("("); puts(cvtToStr(nodep->widthMin())+","); selp->lsbp()->iterateAndNext(*this); puts(", "); selp->fromp()->iterateAndNext(*this); puts(", "); } } else if (AstVar* varp = AstVar::scVarRecurse(nodep->lhsp())) { putbs("VL_ASSIGN_"); // Set a systemC variable emitScIQW(varp); emitIQW(nodep); puts("("); puts(cvtToStr(nodep->widthMin())+","); nodep->lhsp()->iterateAndNext(*this); puts(", "); } else if (AstVar* varp = AstVar::scVarRecurse(nodep->rhsp())) { putbs("VL_ASSIGN_"); // Get a systemC variable emitIQW(nodep); emitScIQW(varp); puts("("); puts(cvtToStr(nodep->widthMin())+","); nodep->lhsp()->iterateAndNext(*this); puts(", "); } else if (nodep->isWide() && nodep->lhsp()->castVarRef() && !nodep->rhsp()->castCMath() && !nodep->rhsp()->castVarRef() && !nodep->rhsp()->castArraySel()) { // Wide functions assign into the array directly, don't need separate assign statement m_wideTempRefp = nodep->lhsp()->castVarRef(); paren = false; } else if (nodep->isWide()) { putbs("VL_ASSIGN_W("); puts(cvtToStr(nodep->widthMin())+","); nodep->lhsp()->iterateAndNext(*this); puts(", "); } else { paren = false; nodep->lhsp()->iterateAndNext(*this); puts(" "); ofp()->blockInc(); decind = true; if (!nodep->rhsp()->castConst()) ofp()->putBreak(); puts("= "); } nodep->rhsp()->iterateAndNext(*this); if (paren) puts(")"); if (decind) ofp()->blockDec(); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstAlwaysPublic*) { } virtual void visit(AstCCall* nodep) { 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) { // In V3Case... nodep->v3fatalSrc("Case statements should have been reduced out"); } virtual void visit(AstComment* nodep) { putsDecoration((string)"// "+nodep->name()+" at "+nodep->fileline()->ascii()+"\n"); nodep->iterateChildren(*this); } virtual void visit(AstCoverDecl* nodep) { puts("__vlCoverInsert("); // As Declared in emitCoverageDecl puts("&(vlSymsp->__Vcoverage["); puts(cvtToStr(nodep->dataDeclThisp()->binNum())); puts("])"); // If this isn't the first instantiation of this module under this // design, don't really count the bucket, and rely on verilator_cov to // aggregate counts. This is because Verilator combines all // hiearchies itself, and if verilator_cov also did it, you'd end up // with (number-of-instant) times too many counts in this bin. puts(", first"); // Enable, passed from __Vconfigure parameter puts(", "); putsQuoted(nodep->fileline()->filename()); puts(", "); puts(cvtToStr(nodep->fileline()->lineno())); puts(", "); puts(cvtToStr(nodep->column())); puts(", "); putsQuoted((nodep->hier()!=""?".":"")+nodep->hier()); puts(", "); putsQuoted(nodep->page()); puts(", "); putsQuoted(nodep->comment()); puts(");\n"); } virtual void visit(AstCoverInc* nodep) { puts("++(vlSymsp->__Vcoverage["); puts(cvtToStr(nodep->declp()->dataDeclThisp()->binNum())); puts("]);\n"); } virtual void visit(AstCReturn* nodep) { puts("return ("); nodep->lhsp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstDisplay* nodep) { 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) { // For use under AstCCalls for dpiImports. ScopeNames under displays are handled in AstDisplay if (!nodep->dpiExport()) { // this is where the DPI import context scope is set string scope = nodep->scopeDpiName(); putbs("(&(vlSymsp->__Vscope_"+scope+"))"); } } virtual void visit(AstSFormat* nodep) { displayNode(nodep, nodep->fmtp()->scopeNamep(), nodep->fmtp()->text(), nodep->fmtp()->exprsp(), false); } virtual void visit(AstSFormatF* nodep) { displayNode(nodep, nodep->scopeNamep(), nodep->text(), nodep->exprsp(), false); } virtual void visit(AstFScanF* nodep) { displayNode(nodep, NULL, nodep->text(), nodep->exprsp(), true); } virtual void visit(AstSScanF* nodep) { displayNode(nodep, NULL, nodep->text(), nodep->exprsp(), true); } virtual void visit(AstValuePlusArgs* nodep) { puts("VL_VALUEPLUSARGS_IN"); emitIQW(nodep->outp()); puts("("); puts(cvtToStr(nodep->outp()->widthMin())); puts(","); emitCvtPackStr(nodep->searchp()); puts(","); putbs(""); nodep->outp()->iterateAndNext(*this); puts(")"); } virtual void visit(AstTestPlusArgs* nodep) { puts("VL_TESTPLUSARGS_I("); putsQuoted(nodep->text()); puts(")"); } virtual void visit(AstFGetS* nodep) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { puts("goto __Vlabel"+cvtToStr(nodep->labelp()->labelNum())+";\n"); } virtual void visit(AstJumpLabel* nodep) { puts("{\n"); nodep->stmtsp()->iterateAndNext(*this); puts("}\n"); puts("__Vlabel"+cvtToStr(nodep->labelNum())+": ;\n"); } virtual void visit(AstWhile* nodep) { 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) { 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) { puts("VL_STOP_MT("); putsQuoted(nodep->fileline()->filename()); puts(","); puts(cvtToStr(nodep->fileline()->lineno())); puts(",\"\");\n"); } virtual void visit(AstFinish* nodep) { puts("VL_FINISH_MT("); putsQuoted(nodep->fileline()->filename()); puts(","); puts(cvtToStr(nodep->fileline()->lineno())); puts(",\"\");\n"); } virtual void visit(AstText* nodep) { if (nodep->tracking()) { puts(nodep->text()); } else { ofp()->putsNoTracking(nodep->text()); } } virtual void visit(AstCStmt* nodep) { putbs(""); nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstCMath* nodep) { putbs(""); nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstUCStmt* nodep) { putsDecoration("// $c statement at "+nodep->fileline()->ascii()+"\n"); nodep->bodysp()->iterateAndNext(*this); puts("\n"); } virtual void visit(AstUCFunc* nodep) { puts("\n"); putsDecoration("// $c function at "+nodep->fileline()->ascii()+"\n"); nodep->bodysp()->iterateAndNext(*this); puts("\n"); } // Operators virtual void visit(AstNodeTermop* nodep) { emitOpName(nodep, nodep->emitC(), NULL, NULL, NULL); } virtual void visit(AstNodeUniop* nodep) { 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) { 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) { if (nodep->lhsp()->isWide()) { visit(nodep->castNodeUniop()); } else { putbs("VL_REDXOR_"); puts(cvtToStr(nodep->lhsp()->dtypep()->widthPow2())); puts("("); nodep->lhsp()->iterateAndNext(*this); puts(")"); } } virtual void visit(AstMulS* nodep) { 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()); } virtual void visit(AstPow* nodep) { if (nodep->widthWords() > VL_MULS_MAX_WORDS) { nodep->v3error("Unsupported: Power of "<width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h"); } visit(nodep->castNodeBiop()); } virtual void visit(AstPowSS* nodep) { if (nodep->widthWords() > VL_MULS_MAX_WORDS) { nodep->v3error("Unsupported: Power of "<width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h"); } visit(nodep->castNodeBiop()); } virtual void visit(AstPowSU* nodep) { if (nodep->widthWords() > VL_MULS_MAX_WORDS) { nodep->v3error("Unsupported: Power of "<width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h"); } visit(nodep->castNodeBiop()); } virtual void visit(AstPowUS* nodep) { if (nodep->widthWords() > VL_MULS_MAX_WORDS) { nodep->v3error("Unsupported: Power of "<width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h"); } visit(nodep->castNodeBiop()); } virtual void visit(AstCCast* nodep) { // 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) { // 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) { // Note ASSIGN checks for this on a LHS emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->thsp()); } virtual void visit(AstReplicate* nodep) { if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) { if (((int)nodep->rhsp()->castConst()->toUInt() * nodep->lhsp()->widthMin()) != nodep->widthMin()) nodep->v3fatalSrc("Replicate non-constant or width miscomputed"); puts("VL_REPLICATE_"); emitIQW(nodep); puts("OI("); puts(cvtToStr(nodep->widthMin())); if (nodep->lhsp()) { puts(","+cvtToStr(nodep->lhsp()->widthMin())); } if (nodep->rhsp()) { puts(","+cvtToStr(nodep->rhsp()->widthMin())); } puts(","); nodep->lhsp()->iterateAndNext(*this); puts(", "); nodep->rhsp()->iterateAndNext(*this); puts(")"); } else { emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), NULL); } } virtual void visit(AstStreamL* nodep) { // Attempt to use a "fast" stream function for slice size = power of 2 if (!nodep->isWide()) { uint32_t isPow2 = nodep->rhsp()->castConst()->num().countOnes() == 1; uint32_t sliceSize = nodep->rhsp()->castConst()->toUInt(); if (isPow2 && sliceSize <= (nodep->isQuad() ? sizeof(uint64_t) : sizeof(uint32_t))) { puts("VL_STREAML_FAST_"); emitIQW(nodep); emitIQW(nodep->lhsp()); puts("I("); puts(cvtToStr(nodep->widthMin())); puts(","+cvtToStr(nodep->lhsp()->widthMin())); puts(","+cvtToStr(nodep->rhsp()->widthMin())); puts(","); nodep->lhsp()->iterateAndNext(*this); puts(", "); uint32_t rd_log2 = V3Number::log2b(nodep->rhsp()->castConst()->toUInt()); puts(cvtToStr(rd_log2)+")"); return; } } emitOpName(nodep, "VL_STREAML_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)", nodep->lhsp(), nodep->rhsp(), NULL); } // Terminals virtual void visit(AstVarRef* nodep) { puts(nodep->hiername()); puts(nodep->varp()->name()); } void emitCvtPackStr(AstNode* nodep) { if (AstConst* constp = nodep->castConst()) { putbs("std::string("); putsQuoted(constp->num().toString()); puts(")"); } else { putbs("VL_CVT_PACK_STR_N"); emitIQW(nodep); puts("("); if (nodep->isWide()) { puts(cvtToStr(nodep->widthWords())); // Note argument width, not node width (which is always 32) puts(","); } nodep->iterateAndNext(*this); puts(")"); } } void emitConstant(AstConst* nodep, AstVarRef* assigntop, const string& assignString) { // Put out constant set to the specified variable, or given variable in a string if (nodep->num().isFourState()) { nodep->v3error("Unsupported: 4-state numbers in this context"); } else if (nodep->num().isString()) { putbs("std::string("); putsQuoted(nodep->num().toString()); puts(")"); } else if (nodep->isWide()) { int upWidth = nodep->num().widthMin(); int chunks = 0; if (upWidth > EMITC_NUM_CONSTW*VL_WORDSIZE) { // Output e.g. 8 words in groups of e.g. 8 chunks = (upWidth-1) / (EMITC_NUM_CONSTW*VL_WORDSIZE); upWidth %= (EMITC_NUM_CONSTW*VL_WORDSIZE); if (upWidth == 0) upWidth = (EMITC_NUM_CONSTW*VL_WORDSIZE); } { // Upper e.g. 8 words if (chunks) { putbs("VL_CONSTHI_W_"); puts(cvtToStr(VL_WORDS_I(upWidth))); puts("X("); puts(cvtToStr(nodep->widthMin())); puts(","); puts(cvtToStr(chunks*EMITC_NUM_CONSTW*VL_WORDSIZE)); } else { putbs("VL_CONST_W_"); puts(cvtToStr(VL_WORDS_I(upWidth))); 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(upWidth)-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+chunks*EMITC_NUM_CONSTW))); } puts(")"); } for (chunks--; chunks >= 0; chunks--) { puts(";\n"); putbs("VL_CONSTLO_W_"); puts(cvtToStr(EMITC_NUM_CONSTW)); puts("X("); puts(cvtToStr(chunks*EMITC_NUM_CONSTW*VL_WORDSIZE)); puts(","); if (!assigntop) { puts(assignString); } else if (assigntop->castVarRef()) { puts(assigntop->hiername()); puts(assigntop->varp()->name()); } else { assigntop->iterateAndNext(*this); } for (int word=EMITC_NUM_CONSTW-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+chunks*EMITC_NUM_CONSTW))); } puts(")"); } } else if (nodep->isDouble()) { if (int(nodep->num().toDouble()) == nodep->num().toDouble() && nodep->num().toDouble() < 1000 && nodep->num().toDouble() > -1000) { ofp()->printf("%3.1f", nodep->num().toDouble()); // Force decimal point } else { // Not %g as will not always put in decimal point, so not obvious to compiler // is a real number ofp()->printf("%.17e", nodep->num().toDouble()); } } else if (nodep->isQuad()) { vluint64_t num = nodep->toUQuad(); if (num<10) ofp()->printf("VL_ULL(%" VL_PRI64 "u)", num); else ofp()->printf("VL_ULL(0x%" VL_PRI64 "x)", num); } else { uint32_t num = nodep->toUInt(); // Only 32 bits - llx + long long here just to appease CPP format warning if (num<10) puts(cvtToStr(num)); else ofp()->printf("0x%" VL_PRI64 "x", (vluint64_t)num); // If signed, we'll do our own functions // But must be here, or <= comparisons etc may end up signed puts("U"); } } void emitSetVarConstant(const string& assignString, AstConst* constp) { if (!constp->isWide()) { puts(assignString); puts(" = "); } emitConstant(constp, NULL, assignString); puts(";\n"); } virtual void visit(AstConst* nodep) { if (nodep->isWide()) { if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Constant w/ no temp"); emitConstant(nodep, m_wideTempRefp, ""); m_wideTempRefp = NULL; // We used it, barf if set it a second time } else { emitConstant(nodep, NULL, ""); } } // Just iterate virtual void visit(AstNetlist* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstTopScope* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep) { nodep->iterateChildren(*this); } // NOPs virtual void visit(AstTypedef*) {} virtual void visit(AstPragma*) {} virtual void visit(AstCell*) {} // Handled outside the Visit class virtual void visit(AstVar*) {} // Handled outside the Visit class virtual void visit(AstNodeText*) {} // Handled outside the Visit class virtual void visit(AstTraceDecl*) {} // Handled outside the Visit class virtual void visit(AstTraceInc*) {} // Handled outside the Visit class virtual void visit(AstCFile*) {} // Handled outside the Visit class // Default virtual void visit(AstNode* nodep) { puts((string)"\n???? // "+nodep->prettyTypeName()+"\n"); nodep->iterateChildren(*this); nodep->v3fatalSrc("Unknown node type reached emitter: "<prettyTypeName()); } public: EmitCStmts() { m_suppressSemi = false; m_wideTempRefp = NULL; m_splitSize = 0; m_splitFilenum = 0; } virtual ~EmitCStmts() {} }; //###################################################################### // Internal EmitC implementation class EmitCImp : EmitCStmts { // MEMBERS AstNodeModule* m_modp; vector m_blkChangeDetVec; // All encountered changes in block bool m_slow; // Creating __Slow file bool m_fast; // Creating non __Slow file (or both) //--------------------------------------- // METHODS void doubleOrDetect(AstChangeDet* changep, bool& gotOne) { if (!changep->rhsp()) { if (!gotOne) gotOne = true; else puts(" | "); changep->lhsp()->iterateAndNext(*this); } else { AstNode* lhsp = changep->lhsp(); AstNode* rhsp = changep->rhsp(); static int addDoubleOr = 10; // Determined experimentally as best if (!lhsp->castVarRef() && !lhsp->castArraySel()) changep->v3fatalSrc("Not ref?"); if (!rhsp->castVarRef() && !rhsp->castArraySel()) changep->v3fatalSrc("Not ref?"); for (int word=0; wordlhsp()->widthWords(); word++) { if (!gotOne) { gotOne = true; addDoubleOr = 10; // Determined experimentally as best puts("("); } else if (--addDoubleOr == 0) { puts("|| ("); addDoubleOr = 10; } else { puts(" | ("); } changep->lhsp()->iterateAndNext(*this); if (changep->lhsp()->isWide()) puts("["+cvtToStr(word)+"]"); if (changep->lhsp()->isDouble()) puts(" != "); else puts(" ^ "); changep->rhsp()->iterateAndNext(*this); if (changep->lhsp()->isWide()) puts("["+cvtToStr(word)+"]"); puts(")"); } } } V3OutCFile* newOutCFile(AstNodeModule* modp, bool slow, bool source, int filenum=0) { string filenameNoExt = v3Global.opt.makeDir()+"/"+ modClassName(modp); if (filenum) filenameNoExt += "__"+cvtToStr(filenum); filenameNoExt += (slow ? "__Slow":""); V3OutCFile* ofp = NULL; if (v3Global.opt.lintOnly()) { // Unfortunately we have some lint checks here, so we can't just skip processing. // We should move them to a different stage. string filename = VL_DEV_NULL; newCFile(filename, slow, source); ofp = new V3OutCFile (filename); } else if (optSystemC()) { string filename = filenameNoExt+(source?".cpp":".h"); newCFile(filename, slow, source); ofp = new V3OutScFile (filename); } else { string filename = filenameNoExt+(source?".cpp":".h"); newCFile(filename, slow, source); ofp = new V3OutCFile (filename); } ofp->putsHeader(); if (modp->isTop() && !source) { ofp->puts("// DESCR" "IPTION: Verilator output: Primary design header\n"); ofp->puts("//\n"); ofp->puts("// This header should be included by all source files instantiating the design.\n"); ofp->puts("// The class here is then constructed to instantiate the design.\n"); ofp->puts("// See the Verilator manual for examples.\n"); } else { if (source) { ofp->puts("// DESCR" "IPTION: Verilator output: Design implementation internals\n"); } else { ofp->puts("// DESCR" "IPTION: Verilator output: Design internal header\n"); } ofp->puts("// See "+v3Global.opt.prefix()+".h for the primary calling header\n"); } ofp->puts("\n"); return ofp; } //--------------------------------------- // VISITORS using EmitCStmts::visit; // Suppress hidden overloaded virtual function warnng virtual void visit(AstCFunc* nodep) { // TRACE_* and DPI handled elsewhere if (nodep->funcType().isTrace()) return; if (nodep->dpiImport()) return; if (!(nodep->slow() ? m_slow : m_fast)) return; m_blkChangeDetVec.clear(); splitSizeInc(nodep); puts("\n"); if (nodep->ifdef()!="") puts("#ifdef "+nodep->ifdef()+"\n"); if (nodep->isInline()) puts("VL_INLINE_OPT "); puts(nodep->rtnTypeVoid()); puts(" "); puts(modClassName(m_modp)+"::"+nodep->name() +"("+cFuncArgs(nodep)+") {\n"); // "+" in the debug indicates a print from the model puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+ "); 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()) putsDecoration("// Variables\n"); for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) { if (AstVar* varp=subnodep->castVar()) { if (varp->isFuncReturn()) emitVarDecl(varp, ""); } } emitVarList(nodep->initsp(), EVL_ALL, ""); emitVarList(nodep->stmtsp(), EVL_ALL, ""); nodep->initsp()->iterateAndNext(*this); if (nodep->stmtsp()) putsDecoration("// Body\n"); nodep->stmtsp()->iterateAndNext(*this); if (!m_blkChangeDetVec.empty()) emitChangeDet(); if (nodep->finalsp()) putsDecoration("// Final\n"); nodep->finalsp()->iterateAndNext(*this); // if (!m_blkChangeDetVec.empty()) puts("return __req;\n"); //puts("__Vm_activity = true;\n"); puts("}\n"); if (nodep->ifdef()!="") puts("#endif // "+nodep->ifdef()+"\n"); } void emitChangeDet() { putsDecoration("// Change detection\n"); puts("QData __req = false; // Logically a bool\n"); // But not because it results in faster code bool gotOne = false; for (vector::iterator it = m_blkChangeDetVec.begin(); it != m_blkChangeDetVec.end(); ++it) { AstChangeDet* changep = *it; if (changep->lhsp()) { if (!gotOne) { // Not a clocked block puts("__req |= ("); } else puts("\n"); doubleOrDetect(changep, gotOne); } } if (gotOne) { puts(");\n"); //puts("VL_DEBUG_IF( if (__req) cout<<\"\tCLOCKREQ );"); for (vector::iterator it = m_blkChangeDetVec.begin(); it != m_blkChangeDetVec.end(); ++it) { AstChangeDet* nodep = *it; if (nodep->lhsp()) { puts("VL_DEBUG_IF( if(__req && ("); bool gotOneIgnore = false; doubleOrDetect(nodep, gotOneIgnore); string varname; if (nodep->lhsp()->castVarRef()) { varname = ": "+nodep->lhsp()->castVarRef()->varp()->prettyName(); } puts(")) VL_DBG_MSGF(\" CHANGE: "+nodep->fileline()->ascii() +varname+"\\n\"); );\n"); } } } } virtual void visit(AstChangeDet* nodep) { m_blkChangeDetVec.push_back(nodep); } virtual void visit(AstCReset* nodep) { AstVar* varp = nodep->varrefp()->varp(); emitVarReset(varp); } //--------------------------------------- // ACCESSORS // METHODS // Low level void emitVarReset(AstVar* 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); if (nodep->attrScClocked() && nodep->isInput()) { puts("sc_in_clk "); } 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("> "); } puts(nodep->name()); emitDeclArrayBrackets(nodep); puts(";\n"); } else if (basicp && basicp->isOpaque()) { // strings and other fundamental c types; no VL_ macro can be used puts(nodep->vlArgType(true,false,false)); emitDeclArrayBrackets(nodep); puts(";\n"); } else { // C++ signals if (nodep->isInout()) puts("VL_INOUT"); else if (nodep->isInput()) puts("VL_IN"); else if (nodep->isOutput()) puts("VL_OUT"); else nodep->v3fatalSrc("Unknown type"); if (nodep->isQuad()) puts("64"); else if (nodep->widthMin() <= 8) puts("8"); else if (nodep->widthMin() <= 16) puts("16"); else if (nodep->isWide()) puts("W"); puts("("+nodep->name()); emitDeclArrayBrackets(nodep); // If it's a packed struct/array then nodep->width is the whole thing, msb/lsb is just lowest dimension puts(","+cvtToStr(basicp->lsb()+nodep->width()-1) +","+cvtToStr(basicp->lsb())); if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords())); puts(");\n"); } } else if (basicp && basicp->isOpaque()) { // strings and other fundamental c types puts(nodep->vlArgType(true,false,false)); emitDeclArrayBrackets(nodep); puts(";\n"); } else { // Arrays need a small alignment, but may need different padding after. // For example three VL_SIG8's needs alignment 1 but size 3. if (nodep->isStatic() && prefixIfImp=="") puts("static "); if (nodep->isStatic()) puts("VL_ST_"); else puts("VL_"); if (nodep->widthMin() <= 8) { puts("SIG8("); } else if (nodep->widthMin() <= 16) { puts("SIG16("); } else if (nodep->isQuad()) { puts("SIG64("); } else if (!nodep->isWide()) { puts("SIG("); } else { puts("SIGW("); } if (prefixIfImp!="") { puts(prefixIfImp); puts("::"); } puts(nodep->name()); emitDeclArrayBrackets(nodep); // If it's a packed struct/array then nodep->width is the whole thing, msb/lsb is just lowest dimension puts(","+cvtToStr(basicp->lsb()+nodep->width()-1) +","+cvtToStr(basicp->lsb())); if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords())); puts(");\n"); } } void EmitCStmts::emitVarCtors() { if (!m_ctorVarsVec.empty()) { ofp()->indentInc(); puts("\n"); puts("#if (SYSTEMC_VERSION>20011000)\n"); // SystemC 2.0.1 and newer bool first = true; for (vector::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) { AstVar* varp = *it; bool isArray = !varp->dtypeSkipRefp()->castBasicDType(); if (isArray) { puts("// Skipping array: "); puts(varp->name()); puts("\n"); } else { if (first) { puts(" : "); first=false; } else puts(", "); if (ofp()->exceededWidth()) puts("\n "); puts(varp->name()); puts("("); putsQuoted(varp->name()); puts(")"); } } puts ("\n#endif\n"); ofp()->indentDec(); } } bool EmitCStmts::emitSimpleOk(AstNodeMath* nodep) { // Can we put out a simple (A + B) instead of VL_ADD_III(A,B)? if (nodep->emitSimpleOperator() == "") return false; if (nodep->isWide()) return false; if (nodep->op1p()) { if (nodep->op1p()->isWide()) return false; } if (nodep->op2p()) { if (nodep->op2p()->isWide()) return false; } if (nodep->op3p()) { if (nodep->op3p()->isWide()) return false; } return true; } void EmitCStmts::emitOpName(AstNode* nodep, const string& format, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) { // Look at emitOperator() format for term/uni/dual/triops, // and write out appropriate text. // %n* node // %nq emitIQW on the [node] // %nw width in bits // %nW width in words // %ni iterate // %l* lhsp - if appropriate, then second char as above // %r* rhsp - if appropriate, then second char as above // %t* thsp - if appropriate, then second char as above // %k Potential line break // %P Wide temporary name // , Commas suppressed if the previous field is suppressed string nextComma; bool needComma = false; #define COMMA { if (nextComma!="") { puts(nextComma); nextComma=""; } } putbs(""); for (string::const_iterator pos = format.begin(); pos != format.end(); ++pos) { if (pos[0]==',') { // Remember we need to add one, but don't do yet to avoid ",)" if (needComma) { if (pos[1]==' ') { nextComma=", "; } else nextComma = ","; needComma = false; } if (pos[1]==' ') { ++pos; } // Must do even if no nextComma } else if (pos[0]=='%') { ++pos; bool detail = false; AstNode* detailp = NULL; switch (pos[0]) { case '%': puts("%"); break; case 'k': putbs(""); break; case 'n': detail = true; detailp = nodep; break; case 'l': detail = true; detailp = lhsp; break; case 'r': detail = true; detailp = rhsp; break; case 't': detail = true; detailp = thsp; break; case 'P': if (nodep->isWide()) { if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Op w/ no temp, perhaps missing op in V3EmitC?"); COMMA; puts(m_wideTempRefp->hiername()); puts(m_wideTempRefp->varp()->name()); m_wideTempRefp = NULL; needComma = true; } break; default: nodep->v3fatalSrc("Unknown emitOperator format code: %"<widthMin())); needComma = true; break; case 'W': if (lhsp->isWide()) { COMMA; puts(cvtToStr(lhsp->widthWords())); needComma = true; } break; case 'i': COMMA; if (!detailp) { nodep->v3fatalSrc("emitOperator() references undef node"); } else detailp->iterateAndNext(*this); needComma = true; break; default: nodep->v3fatalSrc("Unknown emitOperator format code: %[nlrt]"< m_argsChar; // Format of each argument to be printed vector m_argsp; // Each argument to be printed vector m_argsFunc; // Function before each argument to be printed EmitDispState() { clear(); } void clear() { m_format = ""; m_argsChar.clear(); m_argsp.clear(); m_argsFunc.clear(); } void pushFormat(const string& fmt) { m_format += fmt; } void pushFormat(char fmt) { m_format += fmt; } void pushArg(char fmtChar, AstNode* nodep, const string& func) { m_argsChar.push_back(fmtChar); m_argsp.push_back(nodep); m_argsFunc.push_back(func); } } emitDispState; void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) { if (emitDispState.m_format == "" && nodep->castDisplay()) { // not fscanf etc, as they need to return value // NOP } else { // Format bool isStmt = false; if (AstFScanF* dispp = nodep->castFScanF()) { isStmt = false; puts("VL_FSCANF_IX("); dispp->filep()->iterate(*this); puts(","); } else if (AstSScanF* dispp = nodep->castSScanF()) { isStmt = false; checkMaxWords(dispp->fromp()); puts("VL_SSCANF_I"); emitIQW(dispp->fromp()); puts("X("); puts(cvtToStr(dispp->fromp()->widthMin())); puts(","); dispp->fromp()->iterate(*this); puts(","); } else if (AstDisplay* dispp = nodep->castDisplay()) { isStmt = true; if (dispp->filep()) { puts("VL_FWRITEF("); dispp->filep()->iterate(*this); puts(","); } else { puts("VL_WRITEF("); } } else if (AstSFormat* dispp = nodep->castSFormat()) { isStmt = true; puts("VL_SFORMAT_X("); puts(cvtToStr(dispp->lhsp()->widthMin())); putbs(","); dispp->lhsp()->iterate(*this); putbs(","); } else if (AstSFormatF* dispp = nodep->castSFormatF()) { isStmt = false; if (dispp) {} puts("VL_SFORMATF_NX("); } else { nodep->v3fatalSrc("Unknown displayEmit node type"); } ofp()->putsQuoted(emitDispState.m_format); // Arguments for (unsigned i=0; i < emitDispState.m_argsp.size(); i++) { puts(","); char fmt = emitDispState.m_argsChar[i]; AstNode* argp = emitDispState.m_argsp[i]; string func = emitDispState.m_argsFunc[i]; ofp()->indentInc(); ofp()->putbs(""); if (func!="") puts(func); if (argp) { if (isScan) puts("&("); else if (fmt == '@') puts("&("); argp->iterate(*this); if (isScan) puts(")"); else if (fmt == '@') puts(")"); } ofp()->indentDec(); } // End puts(")"); if (isStmt) puts(";\n"); else puts(" "); // Prep for next emitDispState.clear(); } } void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, const 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=='#')) { 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->v3warn(WIDTH,dispp->verilogKwd()<<"of %c format of > 8 bit value"); } //string pfmt = "%"+displayFormat(argp, vfmt, fmtLetter)+fmtLetter; string pfmt; if ((fmtLetter=='#' || fmtLetter=='d' || fmtLetter=='t') && !isScan && vfmt == "") { // Size decimal output. Spec says leading spaces, not zeros double mantissabits = argp->widthMin() - ((fmtLetter=='d')?1:0); double maxval = pow(2.0, mantissabits); double dchars = log10(maxval)+1.0; if (fmtLetter=='d') dchars++; // space for sign int nchars = int(dchars); pfmt = string("%") + cvtToStr(nchars) + fmtLetter; } else { pfmt = string("%") + vfmt + fmtLetter; } emitDispState.pushFormat(pfmt); emitDispState.pushArg(' ',NULL,cvtToStr(argp->widthMin())); emitDispState.pushArg(fmtLetter,argp,""); // Next parameter *elistp = (*elistp)->nextp(); } void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, const string& vformat, AstNode* exprsp, bool isScan) { AstNode* elistp = exprsp; // Convert Verilog display to C printf formats // "%0t" becomes "%d" emitDispState.clear(); string vfmt = ""; string::const_iterator pos = vformat.begin(); bool inPct = false; for (; pos != vformat.end(); ++pos) { //UINFO(1,"Parse '"<<*pos<<"' IP"<v3fatalSrc("Display with %m but no AstScopeName"); string suffix = scopenamep->scopePrettySymName(); if (suffix=="") emitDispState.pushFormat("%S"); else emitDispState.pushFormat("%N"); // Add a . when needed emitDispState.pushArg(' ',NULL, "vlSymsp->name()"); emitDispState.pushFormat(suffix); break; } case 'l': { // Better than not compiling emitDispState.pushFormat("----"); break; } default: nodep->v3error("Unknown $display-like format code: %"<v3error("Internal: Extra arguments for $display-like format"); } displayEmit(nodep, isScan); } //###################################################################### // Internal EmitC void EmitCImp::emitVarReset(AstVar* varp) { if (varp->isIO() && m_modp->isTop() && optSystemC()) { // System C top I/O doesn't need loading, as the lower level subinst code does it.} } else if (varp->isParam()) { if (!varp->valuep()) varp->v3fatalSrc("No init for a param?"); // If a simple CONST value we initialize it using an enum // If an ARRAYINIT we initialize it using an initial block similar to a signal //puts("// parameter "+varp->name()+" = "+varp->valuep()->name()+"\n"); } else if (AstInitArray* initarp = varp->valuep()->castInitArray()) { if (AstUnpackArrayDType* arrayp = varp->dtypeSkipRefp()->castUnpackArrayDType()) { if (initarp->defaultp()) { // MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block puts("{ int __Vi=0;"); puts(" for (; __Vi<"+cvtToStr(arrayp->elementsConst())); puts("; ++__Vi) {\n"); emitSetVarConstant(varp->name()+"[__Vi]", initarp->defaultp()->castConst()); puts("}}\n"); } int pos = 0; for (AstNode* itemp = initarp->initsp(); itemp; ++pos, itemp=itemp->nextp()) { int index = initarp->posIndex(pos); if (!initarp->defaultp() && index!=pos) initarp->v3fatalSrc("Not enough values in array initalizement"); emitSetVarConstant(varp->name()+"["+cvtToStr(index)+"]", itemp->castConst()); } } else { varp->v3fatalSrc("InitArray under non-arrayed var"); } } else if (varp->basicp() && varp->basicp()->keyword() == AstBasicDTypeKwd::STRING) { // Constructor deals with it } else { int vects = 0; // This isn't very robust and may need cleanup for other data types for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp; arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) { int vecnum = vects++; if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); string ivar = string("__Vi")+cvtToStr(vecnum); // MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";"); puts(" for (; "+ivar+"<"+cvtToStr(arrayp->elementsConst())); puts("; ++"+ivar+") {\n"); } bool zeroit = (varp->attrFileDescr() // Zero it out, so we don't core dump if never call $fopen || (varp->basicp() && varp->basicp()->isZeroInit()) || (varp->name().size()>=1 && varp->name()[0]=='_' && v3Global.opt.underlineZero()) || (v3Global.opt.xInitial() == "fast" || v3Global.opt.xInitial() == "0")); 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); putsDecoration("// 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 (optSystemC() && modp->isTop()) { puts("VL_SC_CTOR_IMP("+modClassName(modp)+")"); } else { puts("VL_CTOR_IMP("+modClassName(modp)+")"); } emitVarCtors(); puts(" {\n"); emitCellCtors(modp); emitSensitives(); putsDecoration("// Reset internal values\n"); if (modp->isTop()) { if (v3Global.opt.inhibitSim()) puts("__Vm_inhibitSim = false;\n"); puts("\n"); } putsDecoration("// Reset structure values\n"); puts("_ctor_var_reset();\n"); emitTextSection(AstType::atScCtor); 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. if (v3Global.opt.coverage() ) { puts("this->_configure_coverage(vlSymsp, first);\n"); } puts("}\n"); splitSizeInc(10); } void EmitCImp::emitCoverageImp(AstNodeModule* modp) { if (v3Global.opt.coverage() ) { puts("\n// Coverage\n"); // Rather than putting out VL_COVER_INSERT calls directly, we do it via this function // This gets around gcc slowness constructing all of the template arguments. puts("void "+modClassName(m_modp)+"::__vlCoverInsert(uint32_t* countp, bool enable, const char* filenamep, int lineno, int column,\n"); puts( "const char* hierp, const char* pagep, const char* commentp) {\n"); puts( "static uint32_t fake_zero_count = 0;\n"); // static doesn't need save-restore as constant puts( "if (!enable) countp = &fake_zero_count;\n"); // Used for second++ instantiation of identical bin puts( "*countp = 0;\n"); puts( "VL_COVER_INSERT(countp,"); puts( " \"filename\",filenamep,"); puts( " \"lineno\",lineno,"); puts( " \"column\",column,\n"); //puts( "\"hier\",std::string(__VlSymsp->name())+hierp,"); // Need to move hier into scopes and back out if do this puts( "\"hier\",std::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 VHashSha1 hash; for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstVar* varp = nodep->castVar()) { hash.insert(varp->name()); hash.insert(varp->dtypep()->width()); } } ofp()->printf( "vluint64_t __Vcheckval = VL_ULL(0x%" VL_PRI64 "x);\n", hash.digestUInt64()); 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()) { putsDecoration("// 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("#ifdef VL_DEBUG\n"); putsDecoration("// Debug assertions\n"); puts("_eval_debug_assertions();\n"); puts("#endif // VL_DEBUG\n"); putsDecoration("// 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"); } if (v3Global.opt.threads()) { // THREADED-TODO move to per-train uint32_t trainId = 0; putsDecoration("// Train "+cvtToStr(trainId)+" start\n"); puts("VL_DEBUG_IF(VL_DBG_MSGF(\"Train starting, trainId="+cvtToStr(trainId)+"\\n\"););\n"); puts("Verilated::trainId("+cvtToStr(trainId)+");\n"); } putsDecoration("// Evaluate till stable\n"); puts("int __VclockLoop = 0;\n"); puts("QData __Vchange = 1;\n"); puts("while (VL_LIKELY(__Vchange)) {\n"); puts( "VL_DEBUG_IF(VL_DBG_MSGF(\"+ Clock loop\\n\"););\n"); if (v3Global.opt.trace()) { puts("vlSymsp->__Vm_activity = true;\n"); } puts( "_eval(vlSymsp);\n"); puts( "__Vchange = _change_request(vlSymsp);\n"); puts( "if (VL_UNLIKELY(++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit()) +")) VL_FATAL_MT(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n"); puts("}\n"); if (v3Global.opt.threads()) { // THREADED-TODO move to end of all trains on thread puts("Verilated::endOfThreadTrain(vlSymsp->__Vm_evalMsgQp);\n"); } if (v3Global.opt.threads()) { puts("Verilated::endOfEval(vlSymsp->__Vm_evalMsgQp);\n"); } puts("}\n"); splitSizeInc(10); // puts("\nvoid "+modClassName(modp)+"::_eval_initial_loop("+EmitCBaseVisitor::symClassVar()+") {\n"); puts("vlSymsp->__Vm_didInit = true;\n"); puts("_eval_initial(vlSymsp);\n"); if (v3Global.opt.trace()) { puts("vlSymsp->__Vm_activity = true;\n"); } puts( "int __VclockLoop = 0;\n"); puts( "QData __Vchange = 1;\n"); puts( "while (VL_LIKELY(__Vchange)) {\n"); puts( "_eval_settle(vlSymsp);\n"); puts( "_eval(vlSymsp);\n"); puts( "__Vchange = _change_request(vlSymsp);\n"); puts( "if (VL_UNLIKELY(++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit()) +")) VL_FATAL_MT(__FILE__,__LINE__,__FILE__,\"Verilated model didn't DC converge\");\n"); puts( "}\n"); puts("}\n"); splitSizeInc(10); } //---------------------------------------------------------------------- // Top interface/ implementation void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp) { // Put out a list of signal declarations // in order of 0:clocks, 1:vluint8, 2:vluint16, 4:vluint32, 5:vluint64, 6:wide, 7:arrays // This aids cache packing and locality // Largest->smallest reduces the number of pad variables. // But for now, Smallest->largest makes it more likely a small offset will allow access to the signal. for (int isstatic=1; isstatic>=0; isstatic--) { if (prefixIfImp!="" && !isstatic) continue; const int sortmax = 9; for (int sort=0; sortnextp()) { if (AstVar* varp = nodep->castVar()) { bool doit = true; switch (which) { case EVL_ALL: doit = true; break; case EVL_IO: doit = varp->isIO(); break; case EVL_SIG: doit = (varp->isSignal() && !varp->isIO()); break; case EVL_TEMP: doit = (varp->isTemp() && !varp->isIO()); break; case EVL_PAR: doit = (varp->isParam() && !varp->valuep()->castConst()); break; default: v3fatalSrc("Bad Case"); } if (varp->isStatic() ? !isstatic : isstatic) doit=false; if (doit) { int sigbytes = varp->dtypeSkipRefp()->widthAlignBytes(); int sortbytes = sortmax-1; if (varp->isUsedClock() && varp->widthMin()==1) sortbytes = 0; else if (varp->dtypeSkipRefp()->castUnpackArrayDType()) sortbytes=8; else if (varp->basicp() && varp->basicp()->isOpaque()) sortbytes=7; else if (varp->isScBv() || varp->isScBigUint()) sortbytes=6; else if (sigbytes==8) sortbytes=5; else if (sigbytes==4) sortbytes=4; else if (sigbytes==2) sortbytes=2; else if (sigbytes==1) sortbytes=1; if (sort==sortbytes) { emitVarDecl(varp, prefixIfImp); } } } } } } } 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->ifdef()!="") puts("#ifdef "+funcp->ifdef()+"\n"); if (funcp->isStatic()) puts("static "); puts(funcp->rtnTypeVoid()); puts(" "); puts(funcp->name()); puts("("+cFuncArgs(funcp)+");\n"); if (funcp->ifdef()!="") puts("#endif // "+funcp->ifdef()+"\n"); } } } void EmitCImp::emitInt(AstNodeModule* modp) { // Always have this first; gcc has short circuiting if #ifdef is first in a file puts("#ifndef _"+modClassName(modp)+"_H_\n"); puts("#define _"+modClassName(modp)+"_H_\n"); puts("\n"); ofp()->putsIntTopInclude(); if (v3Global.needHeavy()) { puts("#include \"verilated_heavy.h\"\n"); } else { puts("#include \"verilated.h\"\n"); } if (v3Global.opt.savable()) { puts("#include \"verilated_save.h\"\n"); } if (v3Global.opt.coverage()) { puts("#include \"verilated_cov.h\"\n"); if (v3Global.opt.savable()) v3error("--coverage and --savable not supported together"); } if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us puts("#include \""+topClassName()+"__Inlines.h\"\n"); } if (v3Global.dpi()) { // do this before including our main .h file so that any references to // types defined in svdpi.h are available puts("#include \""+ topClassName() +"__Dpi.h\"\n"); } puts("\n"); // Declare foreign instances up front to make C++ happy puts("class "+symClassName()+";\n"); vl_unordered_set didClassName; for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstCell* cellp=nodep->castCell()) { string className = modClassName(cellp->modp()); if (didClassName.find(className)==didClassName.end()) { puts("class "+className+";\n"); didClassName.insert(className); } } } 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"); } ofp()->resetPrivate(); ofp()->putsPrivate(false); // public: { // Instantiated cells bool did = false; for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstCell* cellp=nodep->castCell()) { if (!did) { did = true; putsDecoration("// 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"); } ofp()->putsCellDecl(modClassName(cellp->modp()), cellp->name()); } } } emitTypedefs(modp->stmtsp()); puts("\n// PORTS\n"); if (modp->isTop()) puts("// The application code writes and reads these signals to\n"); if (modp->isTop()) puts("// propagate new values into/out from the Verilated model.\n"); emitVarList(modp->stmtsp(), EVL_IO, ""); puts("\n// LOCAL SIGNALS\n"); if (modp->isTop()) puts("// Internals; generally not touched by application code\n"); emitVarList(modp->stmtsp(), EVL_SIG, ""); puts("\n// LOCAL VARIABLES\n"); if (modp->isTop()) puts("// Internals; generally not touched by application code\n"); emitVarList(modp->stmtsp(), EVL_TEMP, ""); puts("\n// INTERNAL VARIABLES\n"); if (modp->isTop()) puts("// Internals; generally not touched by application code\n"); ofp()->putsPrivate(!modp->isTop()); // private: unless top puts(symClassName()+"* __VlSymsp; // Symbol table\n"); ofp()->putsPrivate(false); // public: if (modp->isTop()) { if (v3Global.opt.inhibitSim()) { puts("bool __Vm_inhibitSim; ///< Set true to disable evaluation of module\n"); } } emitCoverageDecl(modp); // may flip public/private puts("\n// PARAMETERS\n"); if (modp->isTop()) puts("// Parameters marked /*verilator public*/ for use by application code\n"); ofp()->putsPrivate(false); // public: emitVarList(modp->stmtsp(), EVL_PAR, ""); // Only those that are non-CONST for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstVar* varp = nodep->castVar()) { if (varp->isParam() && (varp->isUsedParam() || varp->isSigPublic())) { if (!varp->valuep()) nodep->v3fatalSrc("No init for a param?"); // These should be static const values, however microsloth VC++ doesn't // support them. They also cause problems with GDB under GCC2.95. if (varp->isWide()) { // Unsupported for output putsDecoration("// enum WData "+varp->name()+" //wide"); } else if (!varp->valuep()->castConst()) { // Unsupported for output //putsDecoration("// enum ..... "+varp->name()+" //not simple value, see variable above instead"); } else { puts("enum "); puts(varp->isQuad()?"_QData":"_IData"); puts(""+varp->name()+" { "+varp->name()+" = "); varp->valuep()->iterateAndNext(*this); puts("};"); } puts("\n"); } } } puts("\n// CONSTRUCTORS\n"); ofp()->resetPrivate(); // We don't need a private copy constructor, as VerilatedModule has one for us. ofp()->putsPrivate(true); puts(modClassName(modp)+"& operator= (const "+modClassName(modp)+"&); ///< Copying not allowed\n"); puts(modClassName(modp)+"(const "+modClassName(modp)+"&); ///< 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()) { if (modp->isTop()) puts("/// Trace signals in the model; called by application code\n"); puts("void trace (VerilatedVcdC* tfp, int levels, int options=0);\n"); if (modp->isTop() && optSystemC()) { puts("/// SC tracing; avoid overloaded virtual function lint warning\n"); puts("virtual void trace (sc_trace_file* tfp) const { ::sc_core::sc_module::trace(tfp); }\n"); } } 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; } ///< 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 (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()) { ofp()->putsPrivate(false); // public: 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) {\n" "Verilated::quiesce(); rhs.__Vserialize(os); return os; }\n"); puts("inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, "+modClassName(modp)+"& rhs) {\n" "Verilated::quiesce(); rhs.__Vdeserialize(os); return os; }\n"); puts("\n"); } // finish up h-file puts("#endif // guard\n"); } //---------------------------------------------------------------------- void EmitCImp::emitImp(AstNodeModule* modp) { 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"); } puts("\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); } } // Blocks puts("\n//--------------------\n"); puts("// Internal Methods\n"); } //###################################################################### void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) { // Output a module m_modp = modp; m_slow = slow; m_fast = fast; if (debug()>=5) { UINFO(0," Emitting "<stmtsp(); nodep; nodep = nodep->nextp()) { if (AstCFunc* funcp = nodep->castCFunc()) { if (splitNeeded()) { // Close old file delete m_ofp; m_ofp=NULL; // Open a new file m_ofp = newOutCFile (modp, !m_fast, true/*source*/, splitFilenumInc()); emitImp (modp); } splitSizeInc(10); // Even blank functions get a file with a low csplit mainDoFunc(funcp); } } delete m_ofp; m_ofp=NULL; } //###################################################################### // Tracing routines class EmitCTrace : EmitCStmts { AstCFunc* m_funcp; // Function we're in now bool m_slow; // Making slow file // METHODS void newOutCFile(int filenum) { string filename = (v3Global.opt.makeDir()+"/"+ topClassName() + (m_slow?"__Trace__Slow":"__Trace")); if (filenum) filename += "__"+cvtToStr(filenum); filename += ".cpp"; AstCFile* cfilep = newCFile(filename, m_slow, true/*source*/); cfilep->support(true); if (m_ofp) v3fatalSrc("Previous file not closed"); m_ofp = new V3OutCFile (filename); m_ofp->putsHeader(); m_ofp->puts("// DESCR" "IPTION: Verilator output: Tracing implementation internals\n"); emitTraceHeader(); } void emitTraceHeader() { // Includes puts("#include \"verilated_vcd_c.h\"\n"); puts("#include \""+ symClassName() +".h\"\n"); puts("\n"); } void emitTraceSlow() { puts("\n//======================\n\n"); puts("void "+topClassName()+"::trace ("); 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"); putsDecoration("// 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_MT(__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 later traced files won't break puts("}\n"); splitSizeInc(10); puts("void "+topClassName()+"::traceFull(" +v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n"); putsDecoration("// 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"); putsDecoration("// Callback from vcd->dump()\n"); puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n"); puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n"); puts("if (vlSymsp->getClearActivity()) {\n"); puts("t->traceChgThis (vlSymsp, vcdp, code);\n"); puts("}\n"); puts("}\n"); splitSizeInc(10); puts("\n//======================\n\n"); } bool emitTraceIsScBv(AstTraceInc* nodep) { AstVarRef* varrefp = nodep->valuep()->castVarRef(); if (!varrefp) return false; AstVar* varp = varrefp->varp(); return varp->isSc() && varp->isScBv(); } bool emitTraceIsScBigUint(AstTraceInc* nodep) { AstVarRef* varrefp = nodep->valuep()->castVarRef(); if (!varrefp) return false; AstVar* varp = varrefp->varp(); return varp->isSc() && varp->isScBigUint(); } bool emitTraceIsScUint(AstTraceInc* nodep) { AstVarRef* varrefp = nodep->valuep()->castVarRef(); if (!varrefp) return false; AstVar* varp = varrefp->varp(); return varp->isSc() && varp->isScUint(); } void emitTraceInitOne(AstTraceDecl* nodep) { if (nodep->dtypep()->basicp()->isDouble()) { puts("vcdp->declDouble"); } else if (nodep->isWide()) { puts("vcdp->declArray"); } else if (nodep->isQuad()) { puts("vcdp->declQuad "); } else if (nodep->bitRange().ranged()) { puts("vcdp->declBus "); } else { puts("vcdp->declBit "); } puts("(c+"+cvtToStr(nodep->code())); if (nodep->arrayRange().ranged()) puts("+i*"+cvtToStr(nodep->widthWords())); puts(","); putsQuoted(nodep->showname()); if (nodep->arrayRange().ranged()) { puts(",(i+"+cvtToStr(nodep->arrayRange().lo())+")"); } else { puts(",-1"); } if (!nodep->dtypep()->basicp()->isDouble() // When float/double no longer have widths this can go && nodep->bitRange().ranged()) { puts(","+cvtToStr(nodep->bitRange().left())+","+cvtToStr(nodep->bitRange().right())); } puts(");"); } void emitTraceChangeOne(AstTraceInc* nodep, int arrayindex) { nodep->precondsp()->iterateAndNext(*this); string full = ((m_funcp->funcType() == AstCFuncType::TRACE_FULL || m_funcp->funcType() == AstCFuncType::TRACE_FULL_SUB) ? "full":"chg"); if (nodep->dtypep()->basicp()->isDouble()) { puts("vcdp->"+full+"Double"); } else if (nodep->isWide() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep)) { puts("vcdp->"+full+"Array"); } else if (nodep->isQuad()) { puts("vcdp->"+full+"Quad "); } else if (nodep->declp()->bitRange().ranged()) { puts("vcdp->"+full+"Bus "); } else { puts("vcdp->"+full+"Bit "); } puts("(c+"+cvtToStr(nodep->declp()->code() + ((arrayindex<0) ? 0 : (arrayindex*nodep->declp()->widthWords())))); puts(","); emitTraceValue(nodep, arrayindex); if (!nodep->dtypep()->basicp()->isDouble() // When float/double no longer have widths this can go && (nodep->declp()->bitRange().ranged() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep))) { puts(","+cvtToStr(nodep->declp()->widthMin())); } puts(");\n"); } void emitTraceValue(AstTraceInc* nodep, int arrayindex) { if (nodep->valuep()->castVarRef()) { AstVarRef* varrefp = nodep->valuep()->castVarRef(); AstVar* varp = varrefp->varp(); puts("("); if (emitTraceIsScBigUint(nodep)) puts("(vluint32_t*)"); else if (emitTraceIsScBv(nodep)) puts("VL_SC_BV_DATAP("); varrefp->iterate(*this); // Put var name out // Tracing only supports 1D arrays if (nodep->declp()->arrayRange().ranged()) { if (arrayindex==-2) puts("[i]"); else if (arrayindex==-1) puts("[0]"); else puts("["+cvtToStr(arrayindex)+"]"); } if (varp->isSc()) puts(".read()"); if (emitTraceIsScUint(nodep)) puts(nodep->isQuad() ? ".to_uint64()" : ".to_uint()"); else if (emitTraceIsScBigUint(nodep)) puts(".get_raw()"); else if (emitTraceIsScBv(nodep)) puts(")"); puts(")"); } else { puts("("); nodep->valuep()->iterate(*this); puts(")"); } } // VISITORS using EmitCStmts::visit; // Suppress hidden overloaded virtual function warnng virtual void visit(AstNetlist* nodep) { // Top module only nodep->topModulep()->accept(*this); } virtual void visit(AstNodeModule* nodep) { nodep->iterateChildren(*this); } virtual void visit(AstCFunc* nodep) { 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()) putsDecoration("// Variables\n"); emitVarList(nodep->initsp(), EVL_ALL, ""); nodep->initsp()->iterateAndNext(*this); putsDecoration("// Body\n"); puts("{\n"); nodep->stmtsp()->iterateAndNext(*this); puts("}\n"); if (nodep->finalsp()) putsDecoration("// Final\n"); nodep->finalsp()->iterateAndNext(*this); puts("}\n"); } m_funcp = NULL; } virtual void visit(AstTraceDecl* nodep) { 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) { 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) { } virtual void visit(AstCoverInc* nodep) { } public: explicit 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: "<edgeType()==AstEdgeType::ET_ILLEGAL) { if (!v3Global.opt.bboxUnsup()) { nodep->v3error("Unsupported: Complicated event expression in sensitive activity list"); } return 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) { UINFO(4," TOPSCOPE "<scopep(); if (!m_scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?"); //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) { //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) { AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName()); nodep->replaceWith(cmtp); if (AstNode* stmtsp = nodep->bodysp()) { stmtsp->unlinkFrBackWithNext(); cmtp->addNextHere(stmtsp); } nodep->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstAlwaysPost* nodep) { AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName()); nodep->replaceWith(cmtp); if (AstNode* stmtsp = nodep->bodysp()) { stmtsp->unlinkFrBackWithNext(); cmtp->addNextHere(stmtsp); } nodep->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstCoverToggle* nodep) { //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(); VL_DANGLING(nodep); } virtual void visit(AstInitial* nodep) { AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName()); nodep->replaceWith(cmtp); if (AstNode* stmtsp = nodep->bodysp()) { stmtsp->unlinkFrBackWithNext(); cmtp->addNextHere(stmtsp); } nodep->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstCFunc* nodep) { 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) { // Delete it later; Actives still pointing to it nodep->unlinkFrBack(); pushDeletep(nodep); } void addToEvalLoop(AstNode* stmtsp) { if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body else m_evalFuncp->addStmtsp(stmtsp); // else add to top level function } void addToSettleLoop(AstNode* stmtsp) { if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body else m_settleFuncp->addStmtsp(stmtsp); // else add to top level function } void addToInitial(AstNode* stmtsp) { if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body else m_initFuncp->addStmtsp(stmtsp); // else add to top level function } virtual void visit(AstActive* nodep) { // Careful if adding variables here, ACTIVES can be under other ACTIVES // Need to save and restore any member state in AstUntilStable block if (!m_topScopep || !nodep->stmtsp()) { // Not at the top or empty block... // Only empty blocks should be leftover on the non-top. Killem. if (nodep->stmtsp()) nodep->v3fatalSrc("Non-empty lower active"); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } else { UINFO(4," ACTIVE "<stmtsp()->unlinkFrBackWithNext(); if (nodep->hasClocked()) { // Remember the latest sensitivity so we can compare it next time if (nodep->hasInitial()) nodep->v3fatalSrc("Initial block should not have clock sensitivity"); if (m_lastSenp && nodep->sensesp()->sameTree(m_lastSenp)) { UINFO(4," sameSenseTree\n"); } else { clearLastSen(); m_lastSenp = nodep->sensesp(); // Make a new if statement m_lastIfp = makeActiveIf(m_lastSenp); addToEvalLoop(m_lastIfp); } // Move statements to if m_lastIfp->addIfsp(stmtsp); } else if (nodep->hasInitial()) { // Don't need to: clearLastSen();, as we're adding it to different cfunc // Move statements to function addToInitial(stmtsp); } else if (nodep->hasSettle()) { // Don't need to: clearLastSen();, as we're adding it to different cfunc // Move statements to function addToSettleLoop(stmtsp); } else { // Combo clearLastSen(); // Move statements to function addToEvalLoop(stmtsp); } nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit ClockVisitor(AstNetlist* nodep) { m_modp=NULL; m_activep=NULL; m_evalFuncp = NULL; m_topScopep=NULL; m_lastSenp=NULL; m_lastIfp = NULL; m_scopep = NULL; m_stableNum = 0; m_untilp = NULL; // nodep->accept(*this); } virtual ~ClockVisitor() {} }; //###################################################################### // Clock class functions void V3Clock::clockAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Depth.h0000664000177100017500000000224713205574202015742 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3DEPTH_H_ #define _V3DEPTH_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Depth { public: static void depthAll(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/V3PreProc.cpp0000664000177100017500000014270713205574202016611 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilog::Preproc: Internal implementation of default preprocessor // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2000-2017 by Wilson Snyder. This program is free software; // you can redistribute it and/or modify it under the terms of either the // GNU Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include #include "V3Error.h" #include "V3Global.h" #include "V3File.h" #include "V3PreLex.h" #include "V3PreProc.h" #include "V3PreShell.h" //====================================================================== // Build in LEX script #define yyFlexLexer V3Lexer #include "V3PreLex.yy.cpp" #undef yyFlexLexer //YYSTYPE yylval; //************************************************************************* class V3Define { // Define class. One for each define. //string m_name; // Name of the define (list is keyed by this) FileLine* m_fileline; // Where it was declared string m_value; // Value of define string m_params; // Parameters bool m_cmdline; // Set on command line, don't `undefineall public: V3Define(FileLine* fl, const string& value, const string& params, bool cmdline) : m_fileline(fl), m_value(value), m_params(params), m_cmdline(cmdline) {} FileLine* fileline() const { return m_fileline; } string value() const { return m_value; } string params() const { return m_params; } bool cmdline() const { return m_cmdline; } }; //************************************************************************* class V3DefineRef { // One for each pending define substitution string m_name; // Define last name being defined string m_params; // Define parameter list for next expansion string m_nextarg; // String being built for next argument int m_parenLevel; // Parenthesis counting inside def args (for PARENT not child) vector m_args; // List of define arguments public: string name() const { return m_name; } string params() const { return m_params; } string nextarg() const { return m_nextarg; } void nextarg(const string& value) { m_nextarg = value; } int parenLevel() const { return m_parenLevel; } void parenLevel(int value) { m_parenLevel = value; } vector& args() { return m_args; } V3DefineRef(const string& name, const string& params) : m_name(name), m_params(params), m_parenLevel(0) {} ~V3DefineRef() {} }; //************************************************************************* /// Data for parsing on/off class VPreIfEntry { // One for each pending ifdef/ifndef bool m_on; // Current parse for this ifdef level is "on" bool m_everOn; // Some if term in elsif tree has been on public: bool on() const { return m_on; } bool everOn() const { return m_everOn; } VPreIfEntry(bool on, bool everOn) : m_on(on), m_everOn(everOn || on) {} // Note everOn includes new state ~VPreIfEntry() {} }; //************************************************************************* // Data for a preprocessor instantiation. class V3PreProcImp : public V3PreProc { public: // TYPES typedef std::map DefinesMap; typedef V3InFilter::StrList StrList; // debug() -> see V3PreShellImp::debug; use --debugi-V3PreShell // Defines list DefinesMap m_defines; ///< Map of defines // STATE V3PreProc* m_preprocp; ///< Object we're holding data for V3PreLex* m_lexp; ///< Current lexer state (NULL = closed) stack m_includeStack; ///< Stack of includers above current m_lexp enum ProcState { ps_TOP, ps_DEFNAME_UNDEF, ps_DEFNAME_DEFINE, ps_DEFNAME_IFDEF, ps_DEFNAME_IFNDEF, ps_DEFNAME_ELSIF, ps_DEFFORM, ps_DEFVALUE, ps_DEFPAREN, ps_DEFARG, ps_INCNAME, ps_ERRORNAME, ps_JOIN, ps_STRIFY }; static const char* procStateName(ProcState s) { static const char* states[] = {"ps_TOP", "ps_DEFNAME_UNDEF", "ps_DEFNAME_DEFINE", "ps_DEFNAME_IFDEF", "ps_DEFNAME_IFNDEF", "ps_DEFNAME_ELSIF", "ps_DEFFORM", "ps_DEFVALUE", "ps_DEFPAREN", "ps_DEFARG", "ps_INCNAME", "ps_ERRORNAME", "ps_JOIN", "ps_STRIFY"}; return states[s]; }; stack m_states; ///< Current state of parser int m_off; ///< If non-zero, ifdef level is turned off, don't dump text string m_lastSym; ///< Last symbol name found. string m_formals; ///< Last formals found // For getRawToken/ `line insertion string m_lineCmt; ///< Line comment(s) to be returned bool m_lineCmtNl; ///< Newline needed before inserting lineCmt int m_lineAdd; ///< Empty lines to return to maintain line count bool m_rawAtBol; ///< Last rawToken left us at beginning of line // For getFinalToken bool m_finAhead; ///< Have read a token ahead int m_finToken; ///< Last token read string m_finBuf; ///< Last yytext read bool m_finAtBol; ///< Last getFinalToken left us at beginning of line FileLine* m_finFilelinep; ///< Location of last returned token (internal only) // For stringification string m_strify; ///< Text to be stringified // For defines stack m_defRefs; // Pending definine substitution stack m_ifdefStack; ///< Stack of true/false emitting evaluations unsigned m_defDepth; ///< How many `defines deep bool m_defPutJoin; ///< Insert `` after substitution // For `` join stack m_joinStack; ///< Text on lhs of join // For getline() string m_lineChars; ///< Characters left for next line void v3errorEnd(ostringstream& str) { fileline()->v3errorEnd(str); } const char* tokenName(int tok); void debugToken(int tok, const char* cmtp); void parseTop(); void parseUndef(); private: // Internal methods void endOfOneFile(); string defineSubst(V3DefineRef* refp); bool defExists(const string& name); string defValue(const string& name); string defParams(const string& name); FileLine* defFileline(const string& name); bool commentTokenMatch(string& cmdr, const char* strg); string trimWhitespace(const string& strg, bool trailing); void unputString(const string& strg); void unputDefrefString(const string& strg); void parsingOn() { m_off--; if (m_off<0) fatalSrc("Underflow of parsing cmds"); // addLineComment no longer needed; getFinalToken will correct. } void parsingOff() { m_off++; } int getRawToken(); int getStateToken(); int getFinalToken(string& buf); ProcState state() const { return m_states.top(); } bool stateIsDefname() const { return state()==ps_DEFNAME_UNDEF || state()==ps_DEFNAME_DEFINE || state()==ps_DEFNAME_IFDEF || state()==ps_DEFNAME_IFNDEF || state()==ps_DEFNAME_ELSIF; } void statePush(ProcState state) { m_states.push(state); } void statePop() { m_states.pop(); if (m_states.empty()) { error("InternalError: Pop of parser state with nothing on stack"); m_states.push(ps_TOP); } } void stateChange(ProcState state) { statePop(); statePush(state); } public: // METHODS, called from upper level shell void openFile(FileLine* fl, V3InFilter* filterp, const string& filename); bool isEof() const { return m_lexp->curStreamp()->m_eof; } string getline(); void insertUnreadback(const string& text) { m_lineCmt += text; } void insertUnreadbackAtBol(const string& text); void addLineComment(int enter_exit_level); // METHODS, callbacks virtual void comment(const string& cmt); // Comment detected (if keepComments==2) virtual void include(const string& filename); // Request a include file be processed virtual void undef (const string& name); virtual void undefineall(); virtual void define (FileLine* fl, const string& name, const string& value, const string& params, bool cmdline); virtual string removeDefines(const string& text); // Remove defines in a text string // CONSTRUCTORS V3PreProcImp() : V3PreProc() { m_debug = 0; m_states.push(ps_TOP); m_off = 0; m_lineChars = ""; m_lastSym = ""; m_lineAdd = 0; m_lineCmtNl = false; m_rawAtBol = true; m_finAhead = false; m_finAtBol = true; m_defDepth = 0; m_defPutJoin = false; m_finToken = 0; m_finFilelinep = NULL; m_lexp = NULL; m_preprocp = NULL; } void configure(FileLine* filelinep) { // configure() separate from constructor to avoid calling abstract functions m_preprocp = this; // Silly, but to make code more similar to Verilog-Perl m_finFilelinep = filelinep->create(1); // Create lexer m_lexp = new V3PreLex (this, filelinep); m_lexp->m_keepComments = m_preprocp->keepComments(); m_lexp->m_keepWhitespace = m_preprocp->keepWhitespace(); m_lexp->m_pedantic = m_preprocp->pedantic(); m_lexp->debug(debug()>=5 ? debug() : 0); // See also V3PreProc::debug() method } ~V3PreProcImp() { if (m_lexp) { delete m_lexp; m_lexp = NULL; } } }; //************************************************************************* // Creation V3PreProc* V3PreProc::createPreProc(FileLine* fl) { V3PreProcImp* preprocp = new V3PreProcImp(); preprocp->configure(fl); return preprocp; } //************************************************************************* // Defines void V3PreProcImp::undef(const string& name) { m_defines.erase(name); } void V3PreProcImp::undefineall() { for (DefinesMap::iterator nextit, it = m_defines.begin(); it != m_defines.end(); it=nextit) { nextit = it; ++nextit; if (!it->second.cmdline()) m_defines.erase(it); } } bool V3PreProcImp::defExists(const string& name) { DefinesMap::iterator iter = m_defines.find(name); if (iter == m_defines.end()) return false; return true; } string V3PreProcImp::defValue(const string& name) { DefinesMap::iterator iter = m_defines.find(name); if (iter == m_defines.end()) { fileline()->v3error("Define or directive not defined: `"+name); return ""; } return iter->second.value(); } string V3PreProcImp::defParams(const string& name) { DefinesMap::iterator iter = m_defines.find(name); if (iter == m_defines.end()) { fileline()->v3error("Define or directive not defined: `"+name); return ""; } return iter->second.params(); } FileLine* V3PreProcImp::defFileline(const string& name) { DefinesMap::iterator iter = m_defines.find(name); if (iter == m_defines.end()) return NULL; return iter->second.fileline(); } void V3PreProcImp::define(FileLine* fl, const string& name, const string& value, const string& params, bool cmdline) { UINFO(4,"DEFINE '"<v3warn(REDEFMACRO,"Redefining existing define: "<v3warn(REDEFMACRO,"Previous definition is here, with value: " <v3error("Extra underscore in meta-comment; use /*verilator {...}*/ not /*verilator_{...}*/"); } else if (0==(strncmp(cp,"synopsys",strlen("synopsys")))) { cp+=strlen("synopsys"); synth = true; if (*cp == '_') fileline()->v3error("Extra underscore in meta-comment; use /*synopsys {...}*/ not /*synopsys_{...}*/"); } else if (0==(strncmp(cp,"cadence",strlen("cadence")))) { cp+=strlen("cadence"); synth = true; } else if (0==(strncmp(cp,"pragma",strlen("pragma")))) { cp+=strlen("pragma"); synth = true; } else if (0==(strncmp(cp,"ambit synthesis",strlen("ambit synthesis")))) { cp+=strlen("ambit synthesis"); synth = true; } else { return; } if (*cp && !isspace(*cp)) return; while (isspace(*cp)) cp++; const char* ep = cp+strlen(cp); if (ep>cp && (ep[-1]=='/' || cp[-2]=='*')) ep-=2; while (ep>cp && (isspace(ep[-1]))) ep--; string cmd (cp, ep-cp); string::size_type pos; while ((pos=cmd.find("\"")) != string::npos) cmd.replace(pos, 1, " "); while ((pos=cmd.find("\t")) != string::npos) cmd.replace(pos, 1, " "); while ((pos=cmd.find(" ")) != string::npos) cmd.replace(pos, 2, " "); if (synth) { if (v3Global.opt.assertOn()) { // one_hot, one_cold, (full_case, parallel_case) if (commentTokenMatch(cmd/*ref*/, "full_case")) { insertUnreadback ("/*verilator full_case*/"); } if (commentTokenMatch(cmd/*ref*/, "parallel_case")) { insertUnreadback ("/*verilator parallel_case*/"); } //if (commentTokenMatch(cmd/*ref*/, "one_hot")) { // insertUnreadback ("/*verilator one_hot*/ "+cmd+";"); //} //if (commentTokenMatch(cmd/*ref*/, "one_cold")) { // insertUnreadback ("/*verilator one_cold*/ "+cmd+";"); //} // else ignore the comment we don't recognize } // else no assertions } else if ((pos=cmd.find("public_flat_rw")) != string::npos) { // "/*verilator public_flat_rw @(foo) */" -> "/*verilator public_flat_rw*/ @(foo)" cmd = cmd.substr(pos+strlen("public_flat_rw")); while (isspace(cmd[0])) cmd = cmd.substr(1); if ((pos=cmd.find("*/")) != string::npos) cmd.replace(pos, 2, ""); insertUnreadback ("/*verilator public_flat_rw*/ "+cmd+" /**/"); } else { insertUnreadback ("/*verilator "+cmd+"*/"); } } //************************************************************************* // VPreProc Methods. FileLine* V3PreProc::fileline() { V3PreProcImp* idatap = static_cast(this); return idatap->m_lexp->m_tokFilelinep; } //********************************************************************** // Parser Utilities const char* V3PreProcImp::tokenName(int tok) { switch (tok) { case VP_BACKQUOTE : return("BACKQUOTE"); case VP_COMMENT : return("COMMENT"); case VP_DEFARG : return("DEFARG"); case VP_DEFFORM : return("DEFFORM"); case VP_DEFINE : return("DEFINE"); case VP_DEFREF : return("DEFREF"); case VP_DEFREF_JOIN : return("DEFREF_JOIN"); case VP_DEFVALUE : return("DEFVALUE"); case VP_ELSE : return("ELSE"); case VP_ELSIF : return("ELSIF"); case VP_ENDIF : return("ENDIF"); case VP_EOF : return("EOF"); case VP_ERROR : return("ERROR"); case VP_IFDEF : return("IFDEF"); case VP_IFNDEF : return("IFNDEF"); case VP_JOIN : return("JOIN"); case VP_INCLUDE : return("INCLUDE"); case VP_LINE : return("LINE"); case VP_STRIFY : return("STRIFY"); case VP_STRING : return("STRING"); case VP_SYMBOL : return("SYMBOL"); case VP_SYMBOL_JOIN : return("SYMBOL_JOIN"); case VP_TEXT : return("TEXT"); case VP_UNDEF : return("UNDEF"); case VP_UNDEFINEALL : return("UNDEFINEALL"); case VP_WHITE : return("WHITE"); default: return("?"); } } void V3PreProcImp::unputString(const string& strg) { // Note: The preliminary call in ::openFile bypasses this function // We used to just m_lexp->unputString(strg.c_str()); // However this can lead to "flex scanner push-back overflow" // so instead we scan from a temporary buffer, then on EOF return. // This is also faster than the old scheme, amazingly. if (m_lexp->m_bufferState!=m_lexp->currentBuffer()) { fatalSrc("bufferStack missing current buffer; will return incorrectly"); // Hard to debug lost text as won't know till much later } m_lexp->scanBytes(strg); } void V3PreProcImp::unputDefrefString(const string& strg) { int multiline = 0; for (size_t i=0; icurStreamp()->m_ignNewlines += multiline; // Must be after unput - applies to new stream } string V3PreProcImp::trimWhitespace(const string& strg, bool trailing) { // Remove leading whitespace string out = strg; string::size_type leadspace = 0; while (out.length() > leadspace && isspace(out[leadspace])) leadspace++; if (leadspace) out.erase(0,leadspace); // Remove trailing whitespace if (trailing) { string::size_type trailspace = 0; while (out.length() > trailspace && isspace(out[out.length()-1-trailspace])) trailspace++; // Don't remove \{space_or_newline} if (trailspace && out.length() > trailspace && out[out.length()-1-trailspace]=='\\') trailspace--; if (trailspace) out.erase(out.length()-trailspace,trailspace); } return out; } string V3PreProcImp::defineSubst(V3DefineRef* refp) { // Substitute out defines in a define reference. // (We also need to call here on non-param defines to handle `") // We could push the define text back into the lexer, but that's slow // and would make recursive definitions and parameter handling nasty. // // Note we parse the definition parameters and value here. If a // parametrized define is used many, many times, we could cache the // parsed result. UINFO(4,"defineSubstIn `"<name()<<" "<params()<args().size(); i++) { UINFO(4,"defineArg["<args()[i]<<"'"<name()); UINFO(4,"defineValue '"< argValueByName; { // Parse argument list into map unsigned numArgs=0; string argName; int paren = 1; // (), {} and [] can use same counter, as must be matched pair per spec string token; bool quote = false; bool haveDefault = false; // Note there's a leading ( and trailing ), so parens==1 is the base parsing level string params = refp->params(); // Must keep str in scope to get pointer const char* cp=params.c_str(); if (*cp == '(') cp++; for (; *cp; cp++) { //UINFO(4," Parse Paren="<args().size() > numArgs) { // A call `def( a ) must be equivelent to `def(a ), so trimWhitespace // At one point we didn't trim trailing whitespace, but this confuses `" string arg = trimWhitespace(refp->args()[numArgs], true); if (arg != "") valueDef = arg; } else if (!haveDefault) { error("Define missing argument '"+argName+"' for: "+refp->name()+"\n"); return " `"+refp->name()+" "; } numArgs++; } argValueByName[argName] = valueDef; // Prepare for next argName = ""; token = ""; haveDefault = false; continue; } else if (*cp=='=') { haveDefault = true; argName = token; token = ""; continue; } } if (cp[0]=='\\' && cp[1]) { token += cp[0]; // \{any} Put out literal next character token += cp[1]; cp++; continue; } if (!quote) { if (*cp=='(' || *cp=='{' || *cp=='[') paren++; else if (*cp==')' || *cp=='}' || *cp==']') paren--; } if (*cp=='"') quote=!quote; if (*cp) token += *cp; } if (refp->args().size() > numArgs // `define X() is ok to call with nothing && !(refp->args().size()==1 && numArgs==0 && trimWhitespace(refp->args()[0],false)=="")) { error("Define passed too many arguments: "+refp->name()+"\n"); return " `"+refp->name()+" "; } } string out = ""; { // Parse substitution define using arguments string argName; bool quote = false; bool backslashesc = false; // In \.....{space} block // Note we go through the loop once more at the NULL end-of-string for (const char* cp=value.c_str(); (*cp) || argName!=""; cp=(*cp?cp+1:cp)) { //UINFO(4, "CH "<<*cp<<" an "<::iterator iter = argValueByName.find(argName); if (iter != argValueByName.end()) { // Substitute string subst = iter->second; if (subst == "") { // Normally `` is removed later, but with no token after, we're otherwise // stuck, so remove proceeding `` if (out.size()>=2 && out.substr(out.size()-2) == "``") { out = out.substr(0, out.size()-2); } } else { 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 // See also removal in empty substitutes above } 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 (state()==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(state()), (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(); // 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(); VL_DANGLING(refp); if (m_defRefs.empty()) { statePop(); if (state() == ps_JOIN) { // Handle {left}```FOO(ARG) where `FOO(ARG) might be empty if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``"); string lhs = m_joinStack.top(); m_joinStack.pop(); out = lhs+out; UINFO(5,"``-end-defarg Out:"<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 || tok==VP_TEXT || tok==VP_WHITE) { string rtn; rtn.assign(yyourtext(),yyourleng()); refp->nextarg(refp->nextarg()+rtn); goto next_tok; } else { error((string)"Expecting ) or , to end argument list for define reference. Found: "+tokenName(tok)); statePop(); goto next_tok; } } case ps_INCNAME: { if (tok==VP_STRING) { statePop(); m_lastSym.assign(yyourtext(),yyourleng()); UINFO(4,"Include "< stateChange(ps_INCNAME); // Still m_lexp->pushStateIncFilename(); goto next_tok; } else if (tok==VP_DEFREF || tok==VP_STRIFY) { // Expand it, then state will come back here break; } else { statePop(); error((string)"Expecting include filename. Found: "+tokenName(tok)+"\n"); goto next_tok; } } case ps_ERRORNAME: { if (tok==VP_STRING) { if (!m_off) { m_lastSym.assign(yyourtext(),yyourleng()); error(m_lastSym); } statePop(); goto next_tok; } else { error((string)"Expecting `error string. Found: "+tokenName(tok)+"\n"); statePop(); goto next_tok; } } case ps_JOIN: { if (tok==VP_SYMBOL || tok==VP_TEXT) { if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``"); string lhs = m_joinStack.top(); m_joinStack.pop(); UINFO(5,"`` LHS:"< V3PreProc::DEFINE_RECURSION_LEVEL_MAX) { error("Recursive `define substitution: `"+name); goto next_tok; } // Substitute if (!defExists(name)) { // Not found, return original string as-is m_defDepth = 0; UINFO(4,"Defref `"< not_defined"<defSubstitute(out); if (m_defRefs.empty()) { // Just output the substitution if (state() == ps_JOIN) { // Handle {left}```FOO where `FOO might be empty if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``"); string lhs = m_joinStack.top(); m_joinStack.pop(); out = lhs+out; UINFO(5,"``-end-defref Out:"<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"); // FALLTHRU goto next_tok; // but not really, above fatal catches it, but if add goto, static analysis complains } case VP_ERROR: { statePush(ps_ERRORNAME); goto next_tok; } case VP_EOF: if (!m_ifdefStack.empty()) { error("`ifdef not terminated at EOF\n"); } return tok; case VP_UNDEFINEALL: if (!m_off) { UINFO(4,"Undefineall "<=5) { string bufcln = V3PreLex::cleanDbgStrg(buf); fprintf (stderr,"%d: FIN: %-10s: %s\n", m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str()); } // Track `line const char* bufp = buf.c_str(); while (*bufp == '\n') bufp++; if ((tok == VP_TEXT || tok == VP_LINE) && 0==strncmp(bufp,"`line ",6)) { int enter; m_finFilelinep->lineDirective(bufp, enter/*ref*/); } else { if (m_finAtBol && !(tok==VP_TEXT && buf=="\n") && m_preprocp->lineDirectives()) { if (int outBehind = m_lexp->m_tokFilelinep->lineno() - m_finFilelinep->lineno()) { if (debug()>=5) fprintf(stderr,"%d: FIN: readjust, fin at %d request at %d\n", m_lexp->m_tokFilelinep->lineno(), m_finFilelinep->lineno(), m_lexp->m_tokFilelinep->lineno()); m_finFilelinep = m_finFilelinep->create(m_lexp->m_tokFilelinep->filename(),m_lexp->m_tokFilelinep->lineno()); if (outBehind > 0 && outBehind <= (int)V3PreProc::NEWLINES_VS_TICKLINE) { // Output stream is behind, send newlines to get back in sync // (Most likely because we're completing a disabled `endif) if (m_preprocp->keepWhitespace()) { buf = string(outBehind,'\n'); return VP_TEXT; } } else { // Need to backup, use `line buf = m_finFilelinep->lineDirectiveStrg(0); return VP_LINE; } } } // Track newlines in prep for next token for (string::iterator cp=buf.begin(); cp!=buf.end(); ++cp) { if (*cp == '\n') { m_finAtBol = true; m_finFilelinep->linenoIncInPlace(); // Increment in place to avoid new/delete calls. It's private data. } else { m_finAtBol = false; } } } m_finAhead = false; // Consumed the token return tok; } string V3PreProcImp::getline() { // Get a single line from the parse stream. Buffer unreturned text until the newline. if (isEof()) return ""; const char* rtnp; bool gotEof = false; while (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n')) && !gotEof) { string buf; int tok = getFinalToken(buf/*ref*/); if (debug()>=5) { string bufcln = V3PreLex::cleanDbgStrg(buf); fprintf (stderr,"%d: GETFETC: %-10s: %s\n", m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str()); } if (tok==VP_EOF) { // Add a final newline, if the user forgot the final \n. if (m_lineChars != "" && m_lineChars[m_lineChars.length()-1] != '\n') { m_lineChars.append("\n"); } gotEof = true; } else { m_lineChars.append(buf); } } // Make new string with data up to the newline. int len = rtnp-m_lineChars.c_str()+1; string theLine(m_lineChars, 0, len); m_lineChars = m_lineChars.erase(0,len); // Remove returned characters if (debug()>=4) { string lncln = V3PreLex::cleanDbgStrg(theLine); fprintf (stderr,"%d: GETLINE: %s\n", m_lexp->m_tokFilelinep->lineno(), lncln.c_str()); } return theLine; } verilator-3.916/src/V3Subst.h0000664000177100017500000000230213205574202015766 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Config.h0000664000177100017500000000242013205574202016074 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Configuration Files // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2010-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CONFIG_H_ #define _V3CONFIG_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.h" #include "V3FileLine.h" //###################################################################### class V3Config { public: static void addIgnore(V3ErrorCode code, bool on, string filename, int min, int max); static void applyIgnores(FileLine* filelinep); }; #endif // Guard verilator-3.916/src/V3EmitCInlines.cpp0000664000177100017500000000516313205574202017554 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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" //###################################################################### class EmitCInlines : EmitCBaseVisitor { // STATE // METHODS void emitInt(); // VISITORS virtual void visit(AstBasicDType* nodep) { if (nodep->keyword() == AstBasicDTypeKwd::STRING) { v3Global.needHeavy(true); // #include via verilated_heavy.h when we create symbol file } } // NOPs virtual void visit(AstNodeStmt*) {} // Default virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } //--------------------------------------- // ACCESSORS public: explicit 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"); // Placeholder - v3Global.needHInlines(true) currently not used puts("//======================\n\n"); puts("#endif // guard\n"); } //###################################################################### // EmitC class functions void V3EmitC::emitcInlines() { UINFO(2,__FUNCTION__<<": "< #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, const 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, bool on, string filename, int min, int max) { if (filename=="*") { FileLine::globalWarnOff(code,!on); } else { V3ConfigIgnores::singleton().addIgnore(code, filename, min, on); if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, !on); } } void V3Config::applyIgnores(FileLine* filelinep) { V3ConfigIgnores::singleton().applyIgnores(filelinep); } verilator-3.916/src/V3String.cpp0000664000177100017500000002351213205574202016475 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Options parsing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 "V3Global.h" #include "V3String.h" #include "V3Error.h" size_t VName::s_minLength = 32; size_t VName::s_maxLength = 0; // Disabled //###################################################################### // 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; } string VString::quotePercent(const string& str) { string out; for (string::const_iterator pos = str.begin(); pos != str.end(); ++pos) { if (*pos == '%') out += '%'; out += *pos; } return out; } //###################################################################### // VHashSha1 static inline uint32_t sha1Rotl32(uint32_t lhs, uint32_t rhs) VL_ATTR_ALWINLINE; static inline uint32_t sha1Rotl32(uint32_t lhs, uint32_t rhs) { return ((lhs << rhs) | (lhs >> (32 - rhs))); } static inline void sha1Block(uint32_t* h, uint32_t* w) VL_ATTR_ALWINLINE; static inline void sha1Block(uint32_t* h, uint32_t* w) { #define SHA1ITER(func, roundConst) do { \ uint32_t t = sha1Rotl32(a, 5) + (func) + e + (roundConst) + w[round]; \ e = d; d = c; c = sha1Rotl32(b, 30); b = a; a = t; \ } while (0) uint32_t a = h[0]; uint32_t b = h[1]; uint32_t c = h[2]; uint32_t d = h[3]; uint32_t e = h[4]; int round = 0; for (; round < 16; ++round) { SHA1ITER((b & c) | (~b & d), 0x5a827999); } for (; round < 20; ++round) { w[round] = sha1Rotl32((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); SHA1ITER((b & c) | (~b & d), 0x5a827999); } for (; round < 40; ++round) { w[round] = sha1Rotl32((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); SHA1ITER(b ^ c ^ d, 0x6ed9eba1); } for (; round < 60; ++round) { w[round] = sha1Rotl32((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); SHA1ITER((b & c) | (b & d) | (c & d), 0x8f1bbcdc); } for (; round < 80; ++round) { w[round] = sha1Rotl32((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); SHA1ITER(b ^ c ^ d, 0xca62c1d6); } h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e; #undef SHA1ITER } void VHashSha1::insert(const void* datap, size_t length) { UASSERT(!m_final, "Called VHashSha1::insert after finalized the hash value"); m_totLength += length; string tempData; int chunkLen; const uint8_t* chunkp; if (m_remainder=="") { chunkLen = length; chunkp = (const uint8_t*)datap; } else { // If there are large inserts it would be more efficient to avoid this copy // by copying bytes in the loop below from either m_remainder or the data // as appropriate. tempData = m_remainder + string((const char*)datap,length); chunkLen = tempData.length(); chunkp = (const uint8_t*)tempData.data(); } // See wikipedia SHA-1 algorithm summary uint32_t w[80]; // Round buffer, [0..15] are input data, rest used by rounds int posBegin = 0; // Position in buffer for start of this block int posEnd = 0; // Position in buffer for end of this block // Process complete 64-byte blocks while (posBegin <= chunkLen - 64) { posEnd = posBegin + 64; // 64 byte round input data, being careful to swap on big, keep on little for (int roundByte = 0; posBegin < posEnd; posBegin += 4) { w[roundByte++] = ((uint32_t) chunkp[posBegin + 3] | (((uint32_t) chunkp[posBegin + 2]) << 8) | (((uint32_t) chunkp[posBegin + 1]) << 16) | (((uint32_t) chunkp[posBegin]) << 24)); } sha1Block(m_inthash, w); } m_remainder = string((const char*)(chunkp+posBegin), chunkLen-posEnd); } void VHashSha1::finalize() { if (!m_final) { // Make sure no 64 byte blocks left insert(""); m_final = true; // Process final possibly non-complete 64-byte block uint32_t w[80]; // Round buffer, [0..15] are input data, rest used by rounds for (int i=0; i<16; ++i) w[i] = 0; size_t blockPos = 0; for (; blockPos < m_remainder.length(); ++blockPos) { w[blockPos >> 2] |= ((uint32_t) m_remainder[blockPos]) << ((3 - (blockPos & 3)) << 3); } w[blockPos >> 2] |= 0x80 << ((3 - (blockPos & 3)) << 3); if (m_remainder.length() >= 56) { sha1Block(m_inthash, w); for (int i=0; i<16; ++i) w[i] = 0; } w[15] = m_totLength << 3; sha1Block(m_inthash, w); m_remainder.clear(); } } string VHashSha1::digestBinary() { finalize(); string out; out.reserve(20); for (size_t i=0; i<20; ++i) { out[i] = (m_inthash[i >> 2] >> (((3 - i) & 0x3) << 3)) & 0xff; } return out; } uint64_t VHashSha1::digestUInt64() { const string& binhash = digestBinary(); uint64_t out = 0; for (size_t byte=0; byte>4) & 0xf ]; out += digits[ (binhash[byte]>>0) & 0xf ]; } return out; } string VHashSha1::digestSymbol() { // Make a symbol name from hash. Similar to base64, however base 64 // has + and / for last two digits, but need C symbol, and we also // avoid conflicts with use of _, so use "AB" at the end. // Thus this function is non-reversable. static const char digits[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"; const string& binhash = digestBinary(); string out; out.reserve(28); int pos = 0; for (; pos < (160/8) - 2; pos += 3) { out += digits[((binhash[pos] >> 2) & 0x3f)]; out += digits[((binhash[pos] & 0x3) << 4) | ((int) (binhash[pos + 1] & 0xf0) >> 4)]; out += digits[((binhash[pos + 1] & 0xf) << 2) | ((int) (binhash[pos + 2] & 0xc0) >> 6)]; out += digits[((binhash[pos + 2] & 0x3f))]; } if (0) { // Not needed for 160 bit hash out += digits[((binhash[pos] >> 2) & 0x3f)]; out += digits[((binhash[pos] & 0x3) << 4)]; } else { out += digits[((binhash[pos] >> 2) & 0x3f)]; out += digits[((binhash[pos] & 0x3) << 4) | ((int) (binhash[pos + 1] & 0xf0) >> 4)]; out += digits[((binhash[pos + 1] & 0xf) << 2)]; } return out; } void VHashSha1::selfTestOne(const string& data, const string& data2, const string& exp, const string& exp64) { VHashSha1 digest (data); if (data2!="") digest.insert(data2); if (digest.digestHex() != exp) { cerr << "%Error: When hashing '"< #include #include #include #include #include #include #include "V3Global.h" #include "V3PreShell.h" #include "V3PreProc.h" #include "V3File.h" #include "V3Parse.h" #include "V3Os.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: "<filename()), "Cannot find include file: "); } bool preprocOpen (FileLine* fl, V3InFilter* filterp, const string& modname, const string& lastpath, const string& errmsg) { // Error message or "" to suppress // Returns true if successful // Try a pure name in case user has a bogus `filename they don't expect string filename = v3Global.opt.filePath (fl, modname, lastpath, errmsg); if (filename=="") { // Allow user to put `defined names on the command line instead of filenames, // then convert them properly. string ppmodname = s_preprocp->removeDefines (modname); filename = v3Global.opt.filePath (fl, ppmodname, lastpath, 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.916/src/V3Number.h0000664000177100017500000003714113205624356016135 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3NUMBER_H_ #define _V3NUMBER_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.h" #include "V3FileLine.h" //============================================================================ class V3Number { // Large 4-state number handling int m_width; // Width as specified/calculated. bool m_sized:1; // True if the user specified the width, else we track it. bool m_signed:1; // True if signed value bool m_double:1; // True if double real value bool m_isString:1; // True if string bool m_fromString:1; // True if from string literal bool m_autoExtend:1; // True if SystemVerilog extend-to-any-width FileLine* m_fileline; vector m_value; // The Value, with bit 0 being in bit 0 of this vector (unless X/Z) vector m_valueX; // Each bit is true if it's X or Z, 10=z, 11=x string m_stringVal; // If isString, the value of the string // METHODS V3Number& setSingleBits(char value); V3Number& setString(const string& str) { m_isString=true; m_stringVal=str; return *this; } void opCleanThis(bool warnOnTruncation = false); 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; uint32_t mask = (1UL<<(bit&31)); if (value=='0' || value==0) { m_value [bit/32] &= ~mask; m_valueX[bit/32] &= ~mask; } else if (value=='1'|| value==1) { m_value [bit/32] |= mask; m_valueX[bit/32] &= ~mask; } else if (value=='z'|| value==2) { m_value [bit/32] &= ~mask; m_valueX[bit/32] |= mask; } else { // X m_value [bit/32] |= mask; m_valueX[bit/32] |= mask; } } private: char bitIs (int bit) const { if (bit>=m_width || bit<0) { // We never sign extend return '0'; } return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0) | ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); } char bitIsExtend (int bit, int lbits) const { // lbits usually = width, but for C optimizations width=32_bits, lbits = 32_or_less if (bit<0) return '0'; UASSERT(lbits<=m_width, "Extend of wrong size"); if (bit>=lbits) { bit = lbits ? lbits-1 : 0; // We do sign extend return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0) | ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); } return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0) | ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); } bool bitIs0 (int bit) const { if (bit<0) return false; if (bit>=m_width) return !bitIsXZ(m_width-1); return ( (m_value[bit/32] & (1UL<<(bit&31)))==0 && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); } bool bitIs1 (int bit) const { if (bit<0) return false; if (bit>=m_width) return false; return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); } bool bitIs1Extend (int bit) const { if (bit<0) return false; if (bit>=m_width) return bitIs1Extend(m_width-1); return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); } bool bitIsX (int bit) const { if (bit<0) return false; if (bit>=m_width) return bitIsZ(m_width-1); return ( (m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); } bool bitIsXZ(int bit) const { if (bit<0) return false; if (bit>=m_width) return bitIsXZ(m_width-1); return ( (m_valueX[bit/32] & (1UL<<(bit&31)))); } bool bitIsZ (int bit) const { if (bit<0) return false; if (bit>=m_width) return bitIsZ(m_width-1); return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); } uint32_t bitsValue(int lsb, int nbits) const { uint32_t v=0; for (int bitn=0; bitn0b11, if 3->0b111 etc // ACCESSORS string ascii(bool prefixed=true, bool cleanVerilog=false) const; static string quoteNameControls(const string& namein); // Add backslash quotes to strings string displayed(FileLine* fl, const string& format) const; static bool displayedFmtLegal(char format); // Is this a valid format letter? int width() const { return m_width; } int widthMin() const; // Minimum width that can represent this number (~== log2(num)+1) bool sized() const { return m_sized; } bool autoExtend() const { return m_autoExtend; } bool isFromString() const { return m_fromString; } bool isSigned() const { return m_signed; } // Only correct for parsing of numbers from strings, otherwise not used (use AstConst::isSigned()) bool isDouble() const { return m_double; } // Only correct for parsing of numbers from strings, otherwise not used (use AstConst::isSigned()) void isDouble(bool flag) { m_double=flag; } // Only if have 64 bit value loaded, and want to indicate it's real bool isString() const { return m_isString; } void isString(bool flag) { m_isString=flag; } bool isNegative() const { return bitIs1(width()-1); } bool isFourState() const { for (int i=0;i> (8*(byte&3))) & 0xff; } uint32_t countOnes() const; uint32_t mostSetBitP1() const; // Highest bit set plus one, IE for 16 return 5, for 0 return 0. // Operators bool operator<(const V3Number& rhs) const { return isLtXZ(rhs); } // STATICS static int log2b(uint32_t num); typedef V3Number& (*UniopFuncp)(V3Number&); typedef V3Number& (*BiopFuncp) (V3Number&, V3Number&); // MATH // "this" is the output, as we need the output width before some computations V3Number& isTrue (const V3Number& lhs); V3Number& opBitsNonX(const V3Number& lhs); // 0/1->1, X/Z->0 V3Number& opBitsOne (const V3Number& lhs); // 1->1, 0/X/Z->0 V3Number& opBitsXZ (const V3Number& lhs); // 0/1->0, X/Z->1 V3Number& opBitsZ (const V3Number& lhs); // Z->1, 0/1/X->0 V3Number& opBitsNonZ(const V3Number& lhs); // Z->0, 0/1/X->1 // V3Number& opAssign (const V3Number& lhs); V3Number& opExtendS (const V3Number& lhs, uint32_t lbits); // Sign extension V3Number& opRedOr (const V3Number& lhs); V3Number& opRedAnd (const V3Number& lhs); V3Number& opRedXor (const V3Number& lhs); V3Number& opRedXnor (const V3Number& lhs); V3Number& opCountOnes(const V3Number& lhs); V3Number& opIsUnknown(const V3Number& lhs); V3Number& opOneHot (const V3Number& lhs); V3Number& opOneHot0 (const V3Number& lhs); V3Number& opCLog2 (const V3Number& lhs); V3Number& opClean (const V3Number& lhs, uint32_t bits); V3Number& opConcat (const V3Number& lhs, const V3Number& rhs); V3Number& opRepl (const V3Number& lhs, const V3Number& rhs); V3Number& opRepl (const V3Number& lhs, uint32_t rhs); V3Number& opStreamL (const V3Number& lhs, const V3Number& rhs); V3Number& opSel (const V3Number& lhs, const V3Number& rhs, const V3Number& ths); V3Number& opSel (const V3Number& lhs, uint32_t rhs, uint32_t ths); V3Number& opSelInto (const V3Number& lhs, const V3Number& lsb, int width); V3Number& opSelInto (const V3Number& lhs, int lsb, int width); V3Number& opCond (const V3Number& lhs, const V3Number& rhs, const V3Number& ths); V3Number& opCaseEq (const V3Number& lhs, const V3Number& rhs); V3Number& opCaseNeq (const V3Number& lhs, const V3Number& rhs); V3Number& opWildEq (const V3Number& lhs, const V3Number& rhs); V3Number& opWildNeq (const V3Number& lhs, const V3Number& rhs); V3Number& opBufIf1 (const V3Number& lhs, const V3Number& rhs); // "standard" math V3Number& opNot (const V3Number& lhs); V3Number& opLogNot (const V3Number& lhs); V3Number& opLogAnd (const V3Number& lhs, const V3Number& rhs); V3Number& opLogOr (const V3Number& lhs, const V3Number& rhs); V3Number& opLogIf (const V3Number& lhs, const V3Number& rhs); V3Number& opLogIff (const V3Number& lhs, const V3Number& rhs); V3Number& opAbsS (const V3Number& lhs); V3Number& opNegate (const V3Number& lhs); V3Number& opAdd (const V3Number& lhs, const V3Number& rhs); V3Number& opSub (const V3Number& lhs, const V3Number& rhs); V3Number& opMul (const V3Number& lhs, const V3Number& rhs); V3Number& opMulS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opDiv (const V3Number& lhs, const V3Number& rhs); V3Number& opDivS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opModDiv (const V3Number& lhs, const V3Number& rhs); V3Number& opModDivS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opPow (const V3Number& lhs, const V3Number& rhs, bool lsign=false, bool rsign=false); V3Number& opPowSU (const V3Number& lhs, const V3Number& rhs); // Signed lhs, unsigned rhs V3Number& opPowSS (const V3Number& lhs, const V3Number& rhs); // Signed lhs, signed rhs V3Number& opPowUS (const V3Number& lhs, const V3Number& rhs); // Unsigned lhs, signed rhs V3Number& opAnd (const V3Number& lhs, const V3Number& rhs); V3Number& opChangeXor(const V3Number& lhs, const V3Number& rhs); V3Number& opXor (const V3Number& lhs, const V3Number& rhs); V3Number& opXnor (const V3Number& lhs, const V3Number& rhs); V3Number& opOr (const V3Number& lhs, const V3Number& rhs); V3Number& opRotR (const V3Number& lhs, const V3Number& rhs); V3Number& opRotL (const V3Number& lhs, const V3Number& rhs); V3Number& opShiftR (const V3Number& lhs, const V3Number& rhs); V3Number& opShiftRS (const V3Number& lhs, const V3Number& rhs, uint32_t lbits); // Arithmetic w/carry V3Number& opShiftL (const V3Number& lhs, const V3Number& rhs); // Comparisons V3Number& opEq (const V3Number& lhs, const V3Number& rhs); V3Number& opNeq (const V3Number& lhs, const V3Number& rhs); V3Number& opGt (const V3Number& lhs, const V3Number& rhs); V3Number& opGtS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opGte (const V3Number& lhs, const V3Number& rhs); V3Number& opGteS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opLt (const V3Number& lhs, const V3Number& rhs); V3Number& opLtS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opLte (const V3Number& lhs, const V3Number& rhs); V3Number& opLteS (const V3Number& lhs, const V3Number& rhs); // Signed // "D" - double (aka real) math V3Number& opIToRD (const V3Number& lhs); V3Number& opRToIS (const V3Number& lhs); V3Number& opRToIRoundS (const V3Number& lhs); V3Number& opRealToBits (const V3Number& lhs); V3Number& opBitsToRealD(const V3Number& lhs); V3Number& opNegateD (const V3Number& lhs); V3Number& opAddD (const V3Number& lhs, const V3Number& rhs); V3Number& opSubD (const V3Number& lhs, const V3Number& rhs); V3Number& opMulD (const V3Number& lhs, const V3Number& rhs); V3Number& opDivD (const V3Number& lhs, const V3Number& rhs); V3Number& opPowD (const V3Number& lhs, const V3Number& rhs); // Comparisons V3Number& opEqD (const V3Number& lhs, const V3Number& rhs); V3Number& opNeqD (const V3Number& lhs, const V3Number& rhs); V3Number& opGtD (const V3Number& lhs, const V3Number& rhs); V3Number& opGteD (const V3Number& lhs, const V3Number& rhs); V3Number& opLtD (const V3Number& lhs, const V3Number& rhs); V3Number& opLteD (const V3Number& lhs, const V3Number& rhs); // "N" - string operations V3Number& opConcatN (const V3Number& lhs, const V3Number& rhs); V3Number& opReplN (const V3Number& lhs, const V3Number& rhs); V3Number& opReplN (const V3Number& lhs, uint32_t rhs); V3Number& opEqN (const V3Number& lhs, const V3Number& rhs); V3Number& opNeqN (const V3Number& lhs, const V3Number& rhs); V3Number& opGtN (const V3Number& lhs, const V3Number& rhs); V3Number& opGteN (const V3Number& lhs, const V3Number& rhs); V3Number& opLtN (const V3Number& lhs, const V3Number& rhs); V3Number& opLteN (const V3Number& lhs, const V3Number& rhs); }; inline ostream& operator<<(ostream& os, const V3Number& rhs) { return os< #include #include #include #include "V3Global.h" #include "V3Branch.h" #include "V3Ast.h" //###################################################################### // Branch state, as a visitor of each AstNode class BranchVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstFTask::user1() -> int. Number of references AstUser1InUse m_inuser1; // TYPES typedef vector CFuncVec; // STATE int m_likely; // Excuses for branch likely taken int m_unlikely; // Excuses for branch likely not taken CFuncVec m_cfuncsp; // List of all tasks // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void reset() { m_likely = false; m_unlikely = false; } void checkUnlikely(AstNode* nodep) { if (nodep->isUnlikely()) { UINFO(4," UNLIKELY: "<ifsp()->iterateAndNext(*this); int ifLikely = m_likely; int ifUnlikely = m_unlikely; // Do else reset(); nodep->elsesp()->iterateAndNext(*this); int elseLikely = m_likely; int elseUnlikely = m_unlikely; // Compute int likeness = ifLikely - ifUnlikely - (elseLikely - elseUnlikely); if (likeness>0) { nodep->branchPred(AstBranchPred::BP_LIKELY); } else if (likeness<0) { nodep->branchPred(AstBranchPred::BP_UNLIKELY); } // else leave unknown } m_likely = lastLikely; m_unlikely = lastUnlikely; } virtual void visit(AstCCall* nodep) { checkUnlikely(nodep); nodep->funcp()->user1Inc(); nodep->iterateChildren(*this); } virtual void visit(AstCFunc* nodep) { checkUnlikely(nodep); m_cfuncsp.push_back(nodep); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep) { checkUnlikely(nodep); nodep->iterateChildren(*this); } // METHODS void calc_tasks() { for (CFuncVec::iterator it=m_cfuncsp.begin(); it!=m_cfuncsp.end(); ++it) { AstCFunc* nodep = *it; if (!nodep->dontInline()) { nodep->isInline(true); } } } public: // CONSTUCTORS explicit BranchVisitor(AstNetlist* nodep) { reset(); nodep->iterateChildren(*this); calc_tasks(); } virtual ~BranchVisitor() {} }; //###################################################################### // Branch class functions void V3Branch::branchAll(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "< #include #include #include #include "V3Global.h" #include "V3Unroll.h" #include "V3Stats.h" #include "V3Const.h" #include "V3Ast.h" #include "V3Simulate.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 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"); // // 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"); 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 // This check shouldn't be needed when using V3Simulate // however, for repeat loops, the loop variable is auto-generated // and the initp statements will reference a variable outside of the initp scope // alas, failing to simulate. AstConst* constInitp = initAssp->rhsp()->castConst(); if (!constInitp) return cantUnroll(nodep, "non-constant initializer"); // // 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"); // if (m_forVscp) { UINFO(8, " Loop Variable: "<=9) nodep->dumpTree(cout,"- for: "); if (!m_generate) { AstAssign *incpAssign = incp->castAssign(); if (!canSimulate(incpAssign->rhsp())) return cantUnroll(incp, "Unable to simulate increment"); if (!canSimulate(condp)) return cantUnroll(condp, "Unable to simulate condition"); // Check whether to we actually want to try and unroll. int loops; if (!countLoops(initAssp, condp, incp, unrollCount(), loops)) return cantUnroll(nodep, "Unable to simulate loop"); // Less than 10 statements in the body? int bodySize = 0; int bodyLimit = v3Global.opt.unrollStmts(); if (loops>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"); } } // Finally, we can do it if (!forUnroller(nodep, initAssp, condp, precondsp, incp, bodysp)) { return cantUnroll(nodep, "Unable to unroll loop"); } VL_DANGLING(nodep); // Cleanup return true; } bool canSimulate(AstNode *nodep) { SimulateVisitor simvis; AstNode* clone = nodep->cloneTree(true); simvis.mainCheckTree(clone); return simvis.optimizable(); } bool simulateTree(AstNode *nodep, const V3Number *loopValue, AstNode *dtypep, V3Number &outNum) { AstNode* clone = nodep->cloneTree(true); if (!clone) { nodep->v3fatalSrc("Failed to clone tree"); return false; } if (loopValue) { m_varValuep = new AstConst (nodep->fileline(), *loopValue); // Iteration requires a back, so put under temporary node AstBegin* tempp = new AstBegin (nodep->fileline(), "[EditWrapper]", clone); m_varModeReplace = true; tempp->stmtsp()->iterateAndNext(*this); m_varModeReplace = false; clone = tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp = NULL; pushDeletep(m_varValuep); m_varValuep = NULL; } SimulateVisitor simvis; simvis.mainParamEmulate(clone); if (!simvis.optimizable()) { UINFO(3, "Unable to simulate" << endl); if (debug()>=9) nodep->dumpTree(cout,"- _simtree: "); return false; } // Fetch the result V3Number* res = simvis.fetchNumberNull(clone); if (!res) { UINFO(3, "No number returned from simulation" << endl); return false; } // Patch up datatype if (dtypep) { AstConst new_con (clone->fileline(), *res); new_con.dtypeFrom(dtypep); outNum = new_con.num(); return true; } outNum = *res; return true; } bool countLoops(AstAssign *initp, AstNode *condp, AstNode *incp, int max, int &outLoopsr) { outLoopsr = 0; V3Number loopValue = V3Number(initp->fileline()); if (!simulateTree(initp->rhsp(), NULL, initp, loopValue)) { return false; } while (1) { V3Number res = V3Number(initp->fileline()); if (!simulateTree(condp, &loopValue, NULL, res)) { return false; } if (!res.isEqOne()) { break; } outLoopsr++; // Run inc AstAssign* incpass = incp->castAssign(); V3Number newLoopValue = V3Number(initp->fileline()); if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) { return false; } loopValue.opAssign(newLoopValue); if (outLoopsr > max) { return false; } } return true; } bool forUnroller(AstNode* nodep, AstAssign* initp, AstNode* condp, AstNode* precondsp, AstNode* incp, AstNode* bodysp) { UINFO(9, "forUnroller "<fileline()); if (!simulateTree(initp->rhsp(), NULL, initp, loopValue)) { return false; } AstNode* stmtsp = NULL; if (initp) { initp->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(); stmtsp = AstNode::addNextNull(stmtsp, precondsp); } if (bodysp) { bodysp->unlinkFrBackWithNext(); stmtsp = AstNode::addNextNull(stmtsp, bodysp); // Maybe null if no body } if (incp && !nodep->castGenFor()) { // Generates don't need to increment loop index incp->unlinkFrBackWithNext(); stmtsp = AstNode::addNextNull(stmtsp, incp); // Maybe null if no body } // Mark variable to disable some later warnings m_forVarp->usedLoopIdx(true); AstNode* newbodysp = NULL; ++m_statLoops; if (stmtsp) { int times = 0; while (1) { UINFO(8," Looping "<fileline()); if (!simulateTree(condp, &loopValue, NULL, res)) { nodep->v3error("Loop unrolling failed."); return false; } if (!res.isEqOne()) { 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(); VL_DANGLING(tempp); } 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); } pushDeletep(m_varValuep); m_varValuep=NULL; 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 "<castAssign(); V3Number newLoopValue = V3Number(nodep->fileline()); if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) { nodep->v3error("Loop unrolling failed"); return false; } loopValue.opAssign(newLoopValue); } } } // Replace the FOR() if (newbodysp) nodep->replaceWith(newbodysp); else nodep->unlinkFrBack(); if (bodysp) { pushDeletep(bodysp); VL_DANGLING(bodysp); } if (precondsp) { pushDeletep(precondsp); VL_DANGLING(precondsp); } if (initp) { pushDeletep(initp); VL_DANGLING(initp); } if (incp && !incp->backp()) { pushDeletep(incp); VL_DANGLING(incp); } if (debug()>=9 && newbodysp) newbodysp->dumpTree(cout,"- _new: "); return true; } virtual void visit(AstWhile* nodep) { 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); VL_DANGLING(initp); } 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); VL_DANGLING(incp); } 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); VL_DANGLING(nodep); // Did replacement } } } virtual void visit(AstGenFor* nodep) { 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(); VL_DANGLING(nodep); } else if (forUnrollCheck(nodep, nodep->initsp(), NULL, nodep->condp(), nodep->incsp(), nodep->bodysp())) { pushDeletep(nodep); VL_DANGLING(nodep); // Did replacement } else { nodep->v3error("For loop doesn't have genvar index, or is malformed"); } } } virtual void visit(AstNodeFor* nodep) { 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(AstVarRef* nodep) { 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()) { AstNode* newconstp = m_varValuep->cloneTree(false); nodep->replaceWith(newconstp); pushDeletep(nodep); } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { 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; // nodep->accept(*this); } virtual ~UnrollVisitor() { V3Stats::addStatSum("Optimizations, Unrolled Loops", m_statLoops); V3Stats::addStatSum("Optimizations, Unrolled Iterations", m_statIters); } }; //###################################################################### // Unroll class functions void V3Unroll::unrollAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Unroll::unrollGen(AstNodeFor* nodep, string beginName) { UINFO(2,__FUNCTION__<<": "<, or >= // // Signed values are always sign extended on promotion or right shift, // even if assigning to a unsigned. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Cast.h" #include "V3Ast.h" //###################################################################### // Cast state, as a visitor of each AstNode class CastVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstNode::user() // bool. Indicates node is of known size AstUser1InUse m_inuser1; // STATE // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void insertCast(AstNode* nodep, int needsize) { // We'll insert ABOVE passed node UINFO(4," NeedCast "<unlinkFrBack(&relinkHandle); // AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize, nodep->widthMin()); relinkHandle.relink(castp); //if (debug()>8) castp->dumpTree(cout,"-castins: "); // insureLower32Cast(castp); nodep->user1(1); // Now must be of known size } int castSize (AstNode* nodep) { if (nodep->isQuad()) return VL_QUADSIZE; else if (nodep->width()<=8) return 8; else if (nodep->width()<=16) return 16; else return VL_WORDSIZE; } void insureCast(AstNode* nodep) { if (castSize(nodep->backp()) != castSize(nodep) || !nodep->user1()) { insertCast(nodep, castSize(nodep->backp())); } } void insureLower32Cast(AstCCast* nodep) { // If we have uint64 = CAST(uint64(x)) then the upcasting // really needs to be CAST(uint64(CAST(uint32(x))). // Otherwise a (uint64)(a>b) would return wrong value, as // less than has undeterministic signedness. if (nodep->isQuad() && !nodep->lhsp()->isQuad() && !nodep->lhsp()->castCCast()) { insertCast(nodep->lhsp(), VL_WORDSIZE); } } // VISITORS virtual void visit(AstNodeUniop* nodep) { nodep->iterateChildren(*this); nodep->user1(nodep->lhsp()->user1()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); } virtual void visit(AstNodeBiop* nodep) { 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) { 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) { nodep->iterateChildren(*this); insureLower32Cast(nodep); nodep->user1(1); } virtual void visit(AstNegate* nodep) { 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) { if (!nodep->lvalue() && !nodep->backp()->castCCast() && nodep->backp()->castNodeMath() && !nodep->backp()->castArraySel() && nodep->backp()->width() && castSize(nodep) != castSize(nodep->varp())) { // Cast vars to IData first, else below has upper bits wrongly set // CData x=3; out = (QData)(x<<30); insertCast (nodep, castSize(nodep)); } nodep->user1(1); } virtual void visit(AstConst* nodep) { // 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) {} //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit CastVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~CastVisitor() {} }; //###################################################################### // Cast class functions void V3Cast::castAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/config_rev.h0000664000177100017500000000011013206352670016575 0ustar wsnyderwsnyderstatic const char* const DTVERSION_rev = "verilator_3_914-65-g0478dbd"; verilator-3.916/src/V3File.cpp0000664000177100017500000006213113205574202016106 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include #if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) # define INFILTER_PIPE // Allow pipe filtering. Needs fork() #endif #ifdef HAVE_STAT_NSEC // i.e. Linux 2.6, from configure # define VL_STAT_CTIME_NSEC(stat) ((stat).st_ctim.tv_nsec) // Nanoseconds # define VL_STAT_MTIME_NSEC(stat) ((stat).st_mtim.tv_nsec) // Nanoseconds #else # define VL_STAT_CTIME_NSEC(stat) (0) # define VL_STAT_MTIME_NSEC(stat) (0) #endif #ifdef INFILTER_PIPE # include #endif #include "V3Global.h" #include "V3File.h" #include "V3Os.h" #include "V3PreShell.h" #include "V3Ast.h" // If change this code, run a test with the below size set very small //#define INFILTER_IPC_BUFSIZ 16 #define INFILTER_IPC_BUFSIZ 64*1024 // For debug, try this as a small number #define INFILTER_CACHE_MAX 64*1024 // Maximum bytes to cache if same file read twice //###################################################################### // V3File Internal state class V3FileDependImp { // TYPES class DependFile { // A single file bool m_target; // True if write, else read string m_filename; // Filename struct stat m_stat; // Stat information public: DependFile(const string& filename, bool target) : m_target(target), m_filename(filename) { m_stat.st_ctime = 0; 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 cstime() const { return m_stat.st_ctime; } // Seconds time_t cnstime() const { return VL_STAT_CTIME_NSEC(m_stat); } // Nanoseconds time_t mstime() const { return m_stat.st_mtime; } // Seconds time_t mnstime() const { return VL_STAT_MTIME_NSEC(m_stat); } // Nanoseconds void loadStats() { if (!m_stat.st_mtime) { string fn = filename(); int err = stat(fn.c_str(), &m_stat); if (err!=0) { m_stat.st_mtime = 1; // Not a error... This can occur due to `line directives in the .vpp files UINFO(1,"-Info: File not statable: "< m_filenameSet; // Files generated (elim duplicates) set m_filenameList; // Files sourced/generated static string stripQuotes(const string& in) { string pretty = in; string::size_type pos; while ((pos=pretty.find("\"")) != string::npos) pretty.replace(pos, 1, "_"); while ((pos=pretty.find("\n")) != string::npos) pretty.replace(pos, 1, "_"); return pretty; } public: // ACCESSOR METHODS void addSrcDepend(const string& filename) { if (m_filenameSet.find(filename) == m_filenameSet.end()) { m_filenameSet.insert(filename); DependFile df (filename, false); df.loadStats(); // Get size now, in case changes during the run m_filenameList.insert(df); } } void addTgtDepend(const string& filename) { if (m_filenameSet.find(filename) == m_filenameSet.end()) { m_filenameSet.insert(filename); m_filenameList.insert(DependFile (filename, true)); } } void writeDepend(const string& filename); void writeTimes(const string& filename, const string& cmdline); bool checkTimes(const string& filename, const string& cmdline); }; V3FileDependImp dependImp; // Depend implementation class //###################################################################### // V3FileDependImp inline void V3FileDependImp::writeDepend(const string& filename) { const vl_unique_ptr ofp (V3File::new_ofstream(filename)); if (ofp->fail()) v3fatalSrc("Can't write "<::iterator iter=m_filenameList.begin(); iter!=m_filenameList.end(); ++iter) { if (iter->target()) { *ofp<filename()<<" "; } } *ofp<<" : "; *ofp<::iterator iter=m_filenameList.begin(); iter!=m_filenameList.end(); ++iter) { if (!iter->target()) { *ofp<filename()<<" "; } } *ofp<::iterator iter=m_filenameList.begin(); iter!=m_filenameList.end(); ++iter) { if (!iter->target()) { *ofp<filename()<<":"< ofp (V3File::new_ofstream(filename)); if (ofp->fail()) v3fatalSrc("Can't write "<::iterator iter=m_filenameList.begin(); iter!=m_filenameList.end(); ++iter) { // Read stats of files we create after we're done making them (execpt for this file, of course) DependFile* dfp = (DependFile*)&(*iter); V3Options::fileNfsFlush(dfp->filename()); dfp->loadStats(); off_t showSize = iter->size(); ino_t showIno = iter->ino(); if (dfp->filename() == filename) { showSize=0; showIno=0; } // We're writing it, so need to ignore it *ofp<<(iter->target()?"T":"S")<<" "; *ofp<<" "<cstime(); *ofp<<" "<cnstime(); *ofp<<" "<mstime(); *ofp<<" "<mnstime(); *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 chkCstime; *ifp>>chkCstime; time_t chkCnstime; *ifp>>chkCnstime; time_t chkMstime; *ifp>>chkMstime; time_t chkMnstime; *ifp>>chkMnstime; char quote; *ifp>>quote; string chkFilename; getline(*ifp, chkFilename, '"'); V3Options::fileNfsFlush(chkFilename); struct stat chkStat; int err = stat(chkFilename.c_str(), &chkStat); if (err!=0) { UINFO(2," --check-times failed: missing "< 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; } // cppcheck-suppress unusedFunction unusedPrivateFunction string readFilterLine() { // Slow, but we don't need it much UINFO(9,"readFilterLine\n"); string line; while (!m_readEof) { StrList outl; readBlocks(m_readFd, 1, outl); string onechar = listString(outl); line += onechar; if (onechar == "\n") { if (line == "\n") { line=""; continue; } else break; } } UINFO(6,"filter-line-in: "<=6) { UINFO(6,"filter-out: "<offset) { errno = 0; int got = write (m_writeFd, (out.c_str())+offset, out.length()-offset); //UINFO(9,"WR GOT g "<< got<<" e "<0) offset += got; else if (errno == EINTR || errno == EAGAIN #ifdef EWOULDBLOCK || errno == EWOULDBLOCK #endif ) { // cppcheck-suppress obsoleteFunctionsusleep checkFilter(false); usleep(1000); continue; } else break; } } // Start the filter void start(const string& command) { if (command=="") { m_pid = 0; // Disabled } else { startFilter(command); } } void startFilter(const string& command) { if (command=="") {} // Prevent Unused #ifdef INFILTER_PIPE int fd_stdin[2], fd_stdout[2]; static const int P_RD = 0; static const int P_WR = 1; if (pipe(fd_stdin) != 0 || pipe(fd_stdout) != 0) { v3fatal("--pipe-filter: Can't pipe: "<"<"<second); return true; } if (!readContents(filename, outl)) return false; if (listSize(outl) < INFILTER_CACHE_MAX) { // Cache small files (only to save space) // It's quite common to `include "timescale" thousands of times // This isn't so important if it's just a open(), but filtering can be slow m_contentsMap.insert(make_pair(filename,listString(outl))); } return true; } size_t listSize(StrList& sl) { size_t out = 0; for (StrList::iterator it=sl.begin(); it!=sl.end(); ++it) { out += it->length(); } return out; } string listString(StrList& sl) { string out; for (StrList::iterator it=sl.begin(); it!=sl.end(); ++it) { out += *it; } return out; } // CONSTRUCTORS explicit 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_blockIndent = v3Global.opt.decoration() ? 4 : 1; m_commaWidth = v3Global.opt.decoration() ? 50 : 150; } //---------------------------------------------------------------------- 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 && m_lang!=LA_XML) { // 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-m_blockIndent/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-=m_blockIndent; break; case '<': if (m_lang==LA_XML) { if (cp[1] == '/') levels-=m_blockIndent; } break; case 'e': if (m_lang==LA_VERILOG && tokenEnd(cp)) { levels-=m_blockIndent; } 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(); if (v3Global.opt.decoration()) { m_parenVec.push(m_column); // Line up continuation with open paren, plus one indent } else { m_parenVec.push(m_indentLevel*m_blockIndent); // Line up continuation with block+1 } 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 string& strg) { // Quote \ and " for use inside C programs // Don't use to quote a filename for #include - #include doesn't \ escape. putcNoTracking('"'); string quoted = V3Number::quoteNameControls(strg); for (string::const_iterator cp=quoted.begin(); cp!=quoted.end(); ++cp) { putcNoTracking (*cp); } putcNoTracking('"'); } void V3OutFormatter::putsNoTracking (const string& strg) { // Don't track {}'s, probably because it's a $display format string for (string::const_iterator cp=strg.begin(); cp!=strg.end(); ++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); } //---------------------------------------------------------------------- // Simple wrappers void V3OutFormatter::printf (const char *fmt...) { char sbuff[5000]; va_list ap; va_start(ap,fmt); vsprintf(sbuff,fmt,ap); va_end(ap); this->puts(sbuff); } //###################################################################### // V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code. V3OutFile::V3OutFile(const string& filename, V3OutFormatter::Language lang) : V3OutFormatter(filename, lang) { if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) { v3fatal("Cannot write "< #include #include #include #include #include "V3Global.h" #include "V3Stats.h" #include "V3Ast.h" #include "V3File.h" // This visitor does not edit nodes, and is called at error-exit, so should use constant iterators #include "V3AstConstOnly.h" //###################################################################### // Stats class functions class StatsVisitor : public AstNVisitor { private: // NODE STATE/TYPES typedef map NameMap; // Number of times a name appears // STATE string m_stage; // Name of the stage we are scanning /// m_fast = true: Counting only critical branch of fastpath /// m_fast = false: Counting every node, ignoring structure of program bool m_fast; AstCFunc* m_cfuncp; // Current CFUNC V3Double0 m_statInstrLong; // Instruction count bool m_counting; // Currently counting double m_instrs; // Current instr count (for determining branch direction) 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, non-slow() eval functions only vector m_statVarWidths; // Variables of given width vector m_statVarWidthNames; // Var names of given width V3Double0 m_statVarArray; // Statistic tracking V3Double0 m_statVarBytes; // Statistic tracking V3Double0 m_statVarClock; // Statistic tracking V3Double0 m_statVarScpBytes; // Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } 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) { allNodes(nodep); if (!m_fast) { nodep->iterateChildrenConst(*this); } else { for (AstNode* searchp = nodep->stmtsp(); searchp; searchp=searchp->nextp()) { if (AstCFunc* funcp = searchp->castCFunc()) { if (funcp->name() == "_eval") { m_instrs=0; m_counting = true; funcp->iterateChildrenConst(*this); m_counting = false; } } } } } virtual void visit(AstVar* nodep) { allNodes(nodep); nodep->iterateChildrenConst(*this); if (m_counting && nodep->dtypep()) { if (nodep->isUsedClock()) ++m_statVarClock; if (nodep->dtypeSkipRefp()->castUnpackArrayDType()) ++m_statVarArray; else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes(); if (int(m_statVarWidths.size()) <= nodep->width()) { m_statVarWidths.resize(nodep->width()+5); if (v3Global.opt.statsVars()) m_statVarWidthNames.resize(nodep->width()+5); } ++ m_statVarWidths.at(nodep->width()); string pn = nodep->prettyName(); if (v3Global.opt.statsVars()) { NameMap& nameMapr = m_statVarWidthNames.at(nodep->width()); if (nameMapr.find(pn) != nameMapr.end()) { nameMapr[pn]++; } else { nameMapr[pn]=1; } } } } virtual void visit(AstVarScope* nodep) { allNodes(nodep); nodep->iterateChildrenConst(*this); if (m_counting) { if (nodep->varp()->dtypeSkipRefp()->castBasicDType()) { m_statVarScpBytes += nodep->varp()->dtypeSkipRefp()->widthTotalBytes(); } } } virtual void visit(AstNodeIf* nodep) { UINFO(4," IF i="<condp()->iterateAndNextConst(*this); // Track prediction if (m_counting) { ++m_statPred[nodep->branchPred()]; } if (!m_fast) { // Count everything nodep->iterateChildrenConst(*this); } else { // See which path we want to take // Need to do even if !m_counting because maybe determining upstream if/else double ifInstrs = 0.0; double elseInstrs = 0.0; if (nodep->branchPred() != AstBranchPred::BP_UNLIKELY) { // Check if double prevInstr = m_instrs; bool prevCounting = m_counting; { m_counting = false; m_instrs = 0.0; nodep->ifsp()->iterateAndNextConst(*this); ifInstrs = m_instrs; } m_instrs = prevInstr; m_counting = prevCounting; } if (nodep->branchPred() != AstBranchPred::BP_LIKELY) { // Check else double prevInstr = m_instrs; bool prevCounting = m_counting; { m_counting = false; m_instrs = 0.0; nodep->elsesp()->iterateAndNextConst(*this); elseInstrs = m_instrs; } m_instrs = prevInstr; m_counting = prevCounting; } // Now collect the stats if (m_counting) { if (ifInstrs >= elseInstrs) { nodep->ifsp()->iterateAndNextConst(*this); } else { nodep->elsesp()->iterateAndNextConst(*this); } } } } // While's we assume evaluate once. //virtual void visit(AstWhile* nodep) { virtual void visit(AstCCall* nodep) { allNodes(nodep); nodep->iterateChildrenConst(*this); if (m_fast) { // Enter the function and trace it nodep->funcp()->accept(*this); } } virtual void visit(AstCFunc* nodep) { m_cfuncp = nodep; allNodes(nodep); nodep->iterateChildrenConst(*this); m_cfuncp = NULL; } virtual void visit(AstNode* nodep) { allNodes(nodep); nodep->iterateChildrenConst(*this); } public: // CONSTRUCTORS StatsVisitor(AstNetlist* nodep, const string& stage, bool fast) : m_stage(stage), m_fast(fast) { UINFO(9,"Starting stats, fast="<accept(*this); } virtual ~StatsVisitor() { // Done. Publish statistics V3Stats::addStat(m_stage, "Instruction count, TOTAL", m_statInstr); V3Stats::addStat(m_stage, "Instruction count, fast critical", 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!=0.0) { V3Stats::addStat(m_stage, "Var space, scoped, bytes", m_statVarScpBytes); } for (unsigned i=0; ifirst; V3Stats::addStat(m_stage, os.str(), it->second); } } else { ostringstream os; os<<"Vars, width "< #include #include #include #include "V3Global.h" #include "V3Localize.h" #include "V3Stats.h" #include "V3Ast.h" //###################################################################### // Localize base class class LocalizeBaseVisitor : public AstNVisitor { protected: // NODE STATE // Cleared on entire tree // AstVar::user1p() -> CFunc which references the variable // AstVar::user2() -> VarFlags. Flag state // AstVar::user4() -> AstVarRef*. First place signal set; must be first assignment // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // TYPES union VarFlags { // Per-variable flags // Used in user()'s so initializes to all zeros struct { int m_notOpt:1; // NOT optimizable int m_notStd:1; // NOT optimizable if a non-blocktemp signal int m_stdFuncAsn:1; // Found simple assignment int m_done:1; // Removed }; uint32_t m_flags; VarFlags(AstNode* nodep) { m_flags = nodep->user2(); } void setNodeFlags(AstNode* nodep) { nodep->user2(m_flags); } }; }; //###################################################################### // Localize class functions class LocalizeDehierVisitor : public LocalizeBaseVisitor { private: // NODE STATE/TYPES // See above // METHODS virtual void visit(AstVarRef* nodep) { VarFlags flags (nodep->varp()); if (flags.m_done) { nodep->hiername(""); // Remove this-> nodep->hierThis(true); } } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit 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()->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) { nodep->iterateChildren(*this); moveVars(); } virtual void visit(AstCFunc* nodep) { 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) { 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(); 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) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS explicit LocalizeVisitor(AstNetlist* nodep) { m_cfuncp = NULL; nodep->accept(*this); } virtual ~LocalizeVisitor() { V3Stats::addStat("Optimizations, Vars localized", m_statLocVars); } }; //###################################################################### // Localize class functions void V3Localize::localizeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.916/src/V3SenTree.h0000664000177100017500000001007713205574202016243 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Block's Transformations: // // Note this can be called multiple times. // Create a IBLOCK(initial), SBLOCK(combo) // ALWAYS: Remove any-edges from sense list // If no POS/NEG in senselist, Fold into SBLOCK(combo) // Else fold into SBLOCK(sequent). // OPTIMIZE: When support async clocks, fold into that block if possible // INITIAL: Move into IBLOCK // WIRE: Move into SBLOCK(combo) // //************************************************************************* #ifndef _V3SENTREE_H_ #define _V3SENTREE_H_ #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Ast.h" //###################################################################### // Collect SenTrees under the entire scope // And provide functions to find/add a new one class SenTreeFinder : public AstNVisitor { private: // STATE AstTopScope* m_topscopep; // Top scope to add statement to vector m_treesp; // List of sensitive blocks, for folding // VISITORS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual void visit(AstNodeModule* nodep) { // Only do the top if (nodep->isTop()) { nodep->iterateChildren(*this); } } virtual void visit(AstTopScope* nodep) { m_topscopep = nodep; nodep->iterateChildren(*this); // Don't clear topscopep, the namer persists beyond this visit } virtual void visit(AstScope* nodep) { // But no SenTrees under TopScope's scope } // Memorize existing block names virtual void visit(AstActive* nodep) { // Don't grab SenTrees under Actives, only those that are global (under Scope directly) nodep->iterateChildren(*this); } virtual void visit(AstSenTree* nodep) { m_treesp.push_back(nodep); } // Empty visitors, speed things up virtual void visit(AstNodeStmt* nodep) { } virtual void visit(AstNode* nodep) { 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.916/src/V3Const.cpp0000664000177100017500000034456313205574202016331 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Constant folding // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 "V3String.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) { if (nodep->varp()) nodep->varp()->user4(1); } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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) { if (nodep->varp() && nodep->varp()->user4()) m_found = true; } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit ConstVarFindVisitor(AstNode* nodep) { m_found = false; nodep->iterateAndNext(*this); } virtual ~ConstVarFindVisitor() {} // METHODS bool found() const { return m_found; } }; //###################################################################### // Const state, as a visitor of each AstNode class ConstVisitor : public AstNVisitor { private: // NODE STATE // ** only when m_warn/m_doExpensive is set. If state is needed other times, // ** must track down everywhere V3Const is called and make sure no overlaps. // AstVar::user4p -> Used by ConstVarMarkVisitor/ConstVarFindVisitor // AstJumpLabel::user4 -> bool. Set when AstJumpGo uses this label // STATE bool m_params; // If true, propogate parameterized and true numbers only bool m_required; // If true, must become a constant bool m_wremove; // Inside scope, no assignw removal bool m_warn; // Output warnings bool m_doExpensive; // Enable computationally expensive optimizations bool m_doNConst; // Enable non-constant-child simplifications bool m_doShort; // Remove expressions that short circuit bool m_doV; // Verilog, not C++ conversion bool m_doGenerate; // Postpone width checking inside generate AstNodeModule* m_modp; // Current module AstArraySel* m_selp; // Current select AstNode* m_scopep; // Current scope AstAttrOf* m_attrp; // Current attribute // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } bool operandConst (AstNode* nodep) { return (nodep->castConst()); } bool operandAsvConst (AstNode* nodep) { // BIASV(CONST, BIASV(CONST,...)) -> BIASV( BIASV_CONSTED(a,b), ...) AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv(); if (!bnodep) return false; if (!bnodep->lhsp()->castConst()) return false; AstNodeBiComAsv* rnodep = bnodep->rhsp()->castNodeBiComAsv(); if (!rnodep) return false; if (rnodep->type() != bnodep->type()) return false; if (rnodep->width() != bnodep->width()) return false; if (rnodep->lhsp()->width() != bnodep->lhsp()->width()) return false; if (!rnodep->lhsp()->castConst()) return false; return true; } bool operandAsvSame (AstNode* nodep) { // BIASV(SAMEa, BIASV(SAMEb,...)) -> BIASV( BIASV(SAMEa,SAMEb), ...) AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv(); if (!bnodep) return false; AstNodeBiComAsv* rnodep = bnodep->rhsp()->castNodeBiComAsv(); if (!rnodep) return false; if (rnodep->type() != bnodep->type()) return false; if (rnodep->width() != bnodep->width()) return false; return operandsSame(bnodep->lhsp(), rnodep->lhsp()); } bool operandAsvLUp (AstNode* nodep) { // BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r)) // // Example of how this is useful: // BIASV(BIASV(CONSTa,b...),BIASV(CONSTc,d...)) // hits operandAsvUp // BIASV(CONSTa,BIASV(b...,BIASV(CONSTc,d...))) // hits operandAsvUp // BIASV(CONSTa,BIASV(CONSTc,BIASV(c...,d...))) // hits operandAsvConst // BIASV(BIASV(CONSTa,CONSTc),BIASV(c...,d...))) // hits normal constant propagation // BIASV(CONST_a_c,BIASV(c...,d...))) // // Idea for the future: All BiComAsvs could be lists, sorted by if they're constant AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv(); if (!bnodep) return false; AstNodeBiComAsv* lnodep = bnodep->lhsp()->castNodeBiComAsv(); if (!lnodep) return false; if (lnodep->type() != bnodep->type()) return false; if (lnodep->width() != bnodep->width()) return false; return lnodep->lhsp()->castConst(); } bool operandAsvRUp (AstNode* nodep) { // BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr)) AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv(); if (!bnodep) return false; AstNodeBiComAsv* rnodep = bnodep->rhsp()->castNodeBiComAsv(); if (!rnodep) return false; if (rnodep->type() != bnodep->type()) return false; if (rnodep->width() != bnodep->width()) return false; return rnodep->lhsp()->castConst(); } static bool operandSubAdd(AstNode* nodep) { // SUB( ADD(CONSTx,y), CONSTz) -> ADD(SUB(CONSTx,CONSTz), y) AstNodeBiop* np = nodep->castNodeBiop(); AstNodeBiop* lp = np->lhsp()->castNodeBiop(); return (lp && lp->lhsp()->castConst() && np->rhsp()->castConst() && lp->width()==np->width()); } static bool operandAndOrSame(AstNode* nodep) { // OR( AND(VAL,x), AND(VAL,y)) -> AND(VAL,OR(x,y)) // OR( AND(x,VAL), AND(y,VAL)) -> AND(OR(x,y),VAL) AstNodeBiop* np = nodep->castNodeBiop(); AstNodeBiop* lp = np->lhsp()->castNodeBiop(); AstNodeBiop* rp = np->rhsp()->castNodeBiop(); return (lp && rp && lp->width()==rp->width() && lp->type()==rp->type() && (operandsSame(lp->lhsp(),rp->lhsp()) || operandsSame(lp->rhsp(),rp->rhsp()))); } static bool matchOrAndNot(AstNodeBiop* nodep) { // AstOr{$a, AstAnd{AstNot{$b}, $c}} if $a.width1, $a==$b => AstOr{$a,$c} // Someday we'll sort the biops completely and this can be simplified // This often results from our simplified clock generation: // if (rst) ... else if (enable)... -> OR(rst,AND(!rst,enable)) AstNode* ap; AstNodeBiop* andp; if (nodep->lhsp()->castAnd()) { andp=nodep->lhsp()->castAnd(); ap=nodep->rhsp(); } else if (nodep->rhsp()->castAnd()) { andp=nodep->rhsp()->castAnd(); ap=nodep->lhsp(); } else return false; AstNodeUniop* notp; AstNode* cp; if (andp->lhsp()->castNot()) { notp=andp->lhsp()->castNot(); cp=andp->rhsp(); } else if (andp->rhsp()->castNot()) { notp=andp->rhsp()->castNot(); cp=andp->lhsp(); } else return false; AstNode* bp = notp->lhsp(); if (!operandsSame(ap, bp)) return false; // Do it cp->unlinkFrBack(); andp->unlinkFrBack()->deleteTree(); VL_DANGLING(andp); VL_DANGLING(notp); // Replace whichever branch is now dangling if (nodep->rhsp()) nodep->lhsp(cp); else nodep->rhsp(cp); return true; } static bool operandShiftSame(AstNode* nodep) { AstNodeBiop* np = nodep->castNodeBiop(); { AstShiftL* lp = np->lhsp()->castShiftL(); AstShiftL* rp = np->rhsp()->castShiftL(); if (lp && rp) { return (lp->width() == rp->width() && lp->lhsp()->width() == rp->lhsp()->width() && operandsSame(lp->rhsp(), rp->rhsp())); } } { AstShiftR* lp = np->lhsp()->castShiftR(); AstShiftR* rp = np->rhsp()->castShiftR(); if (lp && rp) { return (lp->width() == rp->width() && lp->lhsp()->width() == rp->lhsp()->width() && operandsSame(lp->rhsp(), rp->rhsp())); } } return false; } bool operandHugeShiftL(AstNodeBiop* nodep) { return (nodep->rhsp()->castConst() && !nodep->rhsp()->castConst()->num().isFourState() && nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->width()) && isTPure(nodep->lhsp())); } bool operandHugeShiftR(AstNodeBiop* nodep) { return (nodep->rhsp()->castConst() && !nodep->rhsp()->castConst()->num().isFourState() && nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->lhsp()->width()) && isTPure(nodep->lhsp())); } bool operandIsTwo(AstNode* nodep) { return (nodep->castConst() && !nodep->castConst()->num().isFourState() && nodep->width() <= VL_QUADSIZE && nodep->castConst()->toUQuad()==2); } bool operandIsTwostate(AstNode* nodep) { return (nodep->castConst() && !nodep->castConst()->num().isFourState()); } bool operandIsPowTwo(AstNode* nodep) { if (!operandIsTwostate(nodep)) return false; return (1==nodep->castConst()->num().countOnes()); } bool operandShiftOp(AstNodeBiop* nodep) { if (!nodep->rhsp()->castConst()) return false; AstNodeBiop* lhsp = nodep->lhsp()->castNodeBiop(); if (!lhsp || !(lhsp->castAnd()||lhsp->castOr()||lhsp->castXor())) return false; if (nodep->width()!=lhsp->width()) return false; if (nodep->width()!=lhsp->lhsp()->width()) return false; if (nodep->width()!=lhsp->rhsp()->width()) return false; return true; } bool operandShiftShift(AstNodeBiop* nodep) { // We could add a AND though. AstNodeBiop* lhsp = nodep->lhsp()->castNodeBiop(); if (!lhsp || !(lhsp->castShiftL()||lhsp->castShiftR())) return false; // We can only get rid of a<>c or a<rhsp()->castConst() && lhsp->rhsp()->castConst())) return false; if (nodep->rhsp()->castConst()->num().isFourState() || lhsp->rhsp()->castConst()->num().isFourState()) return false; if (nodep->width()!=lhsp->width()) return false; if (nodep->width()!=lhsp->lhsp()->width()) return false; return true; } bool operandWordOOB(AstWordSel* nodep) { // V3Expand may make a arraysel that exceeds the bounds of the array // It was an expression, then got constified. In reality, the WordSel // must be wrapped in a Cond, that will be false. return (nodep->rhsp()->castConst() && nodep->fromp()->castNodeVarRef() && !nodep->fromp()->castNodeVarRef()->lvalue() && ((int)(nodep->rhsp()->castConst()->toUInt()) >= nodep->fromp()->castNodeVarRef()->varp()->widthWords())); } bool operandSelFull(AstSel* nodep) { return (nodep->lsbp()->castConst() && nodep->widthp()->castConst() && nodep->lsbConst()==0 && (int)nodep->widthConst()==nodep->fromp()->width()); } 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()); VL_DANGLING(nodep); 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); VL_DANGLING(nodep); return true; } bool operandSelShiftLower(AstSel* nodep) { // AND({a}, SHIFTR({b}, {c})) is often shorthand in C for Verilog {b}[{c} :+ {a}] // becomes thought other optimizations // SEL(SHIFTR({a},{b}),{lsb},{width}) -> SEL({a},{lsb+b},{width}) AstShiftR* shiftp = nodep->fromp()->castShiftR(); if (!(m_doV && shiftp && shiftp->rhsp()->castConst() && nodep->lsbp()->castConst() && nodep->widthp()->castConst() )) return false; AstNode* ap = shiftp->lhsp(); AstConst* bp = shiftp->rhsp()->castConst(); AstConst* lp = nodep->lsbp()->castConst(); if (bp->isWide() || bp->num().isFourState() || bp->num().isNegative() || lp->isWide() || lp->num().isFourState() || lp->num().isNegative()) return false; int newLsb = lp->toSInt() + bp->toSInt(); if (newLsb + nodep->widthConst() > ap->width()) return false; // UINFO(9, "SEL(SHIFTR(a,b),l,w) -> SEL(a,l+b,w)\n"); if (debug()>=9) nodep->dumpTree(cout,"SEL(SH)-in:"); AstSel* newp = new AstSel(nodep->fileline(), ap->unlinkFrBack(), newLsb, nodep->widthConst()); newp->dtypeFrom(nodep); if (debug()>=9) newp->dumpTree(cout,"SEL(SH)-ou:"); nodep->replaceWith(newp); VL_DANGLING(nodep); return true; } bool operandBiExtendConstShrink(AstNodeBiop* nodep) { // Loop unrolling favors standalone compares // EQ(const{width32}, EXTEND(xx{width3})) -> EQ(const{3}, xx{3}) // The constant must have zero bits (+ 1 if signed) or compare // would be incorrect. See also operandBiExtendConst 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(); VL_DANGLING(constp); if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-ou:"); return true; } bool operandBiExtendConstOver(AstNodeBiop* nodep) { // EQ(const{width32}, EXTEND(xx{width3})) -> constant // When the constant has non-zero bits above the extend it's a constant. // Avoids compiler warning 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; return true; } AstNode* afterComment(AstNode* nodep) { // Ignore comments, such as to determine if a AstIf is empty. // nodep may be null, if so return null. while (nodep && nodep->castComment()) { nodep = nodep->nextp(); } return nodep; } bool isTPure(AstNode* nodep) { // Pure checks - if this node and all nodes under it are free of // side effects can do this optimization // Eventually we'll recurse through tree when unknown, memoizing results so far, // but for now can disable en-mass until V3Purify takes effect. return m_doShort || nodep->castVarRef() || nodep->castConst(); } // Extraction checks bool warnSelect(AstSel* nodep) { if (m_doGenerate) { // Never checked yet V3Width::widthParamsEdit(nodep); nodep->iterateChildren(*this); // May need "constifying" } // Find range of dtype we are selecting from // Similar code in V3Unknown::AstSel bool doit = true; if (m_warn && nodep->lsbp()->castConst() && nodep->widthp()->castConst() && doit) { int maxDeclBit = nodep->declRange().hiMaxSelect()*nodep->declElWidth() + (nodep->declElWidth()-1); if (nodep->lsbp()->castConst()->num().isFourState() || nodep->widthp()->castConst()->num().isFourState()) { nodep->v3error("Selection index is constantly unknown or tristated: " "lsb="<lsbp()->name()<<" width="<widthp()->name()); // Replacing nodep will make a mess above, so we replace the offender replaceZero(nodep->lsbp()); } else if (nodep->declRange().ranged() && (nodep->msbConst() > maxDeclBit || nodep->lsbConst() > maxDeclBit)) { // See also warning in V3Width // Must adjust by element width as declRange() is in number of elements nodep->v3warn(SELRANGE, "Selection index out of range: " <<(nodep->msbConst()/nodep->declElWidth()) <<":"<<(nodep->lsbConst()/nodep->declElWidth()) <<" outside "<declRange().hiMaxSelect()<<":0" <<(nodep->declRange().lo()>=0 ? "" :(" (adjusted +"+cvtToStr(-nodep->declRange().lo()) +" to account for negative lsb)"))); UINFO(1," Related Raw index is "<msbConst()<<":"<lsbConst()<castConst() && node2p->castConst()) { return node1p->sameGateTree(node2p); } else if (node1p->castVarRef() && node2p->castVarRef()) { // Avoid comparing widthMin's, which results in lost optimization attempts // If cleanup sameGateTree to be smarter, this can be restored. //return node1p->sameGateTree(node2p); return node1p->same(node2p); } else { return false; } } bool ifSameAssign(AstNodeIf* nodep) { AstNodeAssign* ifp = nodep->ifsp()->castNodeAssign(); AstNodeAssign* elsep = nodep->elsesp()->castNodeAssign(); if (!ifp || ifp->nextp()) return false; // Must be SINGLE statement if (!elsep || elsep->nextp()) return false; if (ifp->type() != elsep->type()) return false; // Can't mix an assigndly and an assign if (!ifp->lhsp()->sameGateTree(elsep->lhsp())) return false; if (!ifp->rhsp()->gateTree()) return false; if (!elsep->rhsp()->gateTree()) return false; return true; } bool operandIfIf(AstNodeIf* nodep) { if (nodep->elsesp()) return false; AstNodeIf* lowerIfp = nodep->ifsp()->castNodeIf(); if (!lowerIfp || lowerIfp->nextp()) return false; if (nodep->type() != lowerIfp->type()) return false; if (afterComment(lowerIfp->elsesp())) return false; return true; } bool ifConcatMergeableBiop(AstNode* nodep) { return (nodep->castAnd() || nodep->castOr() || nodep->castXor() || nodep->castXnor()); } bool ifAdjacentSel(AstSel* lhsp, AstSel* rhsp) { if (!v3Global.opt.oAssemble()) return false; // opt disabled if (!lhsp || !rhsp) return false; AstNode* lfromp = lhsp->fromp(); AstNode* rfromp = rhsp->fromp(); if (!lfromp || !rfromp || !lfromp->sameGateTree(rfromp)) return false; AstConst* lstart = lhsp->lsbp()->castConst(); AstConst* rstart = rhsp->lsbp()->castConst(); AstConst* lwidth = lhsp->widthp()->castConst(); AstConst* rwidth = rhsp->widthp()->castConst(); if (!lstart || !rstart || !lwidth || !rwidth) return false; // too complicated int rend = (rstart->toSInt() + rwidth->toSInt()); if (rend == lstart->toSInt()) return true; return false; } bool ifMergeAdjacent(AstNode* lhsp, AstNode* rhsp) { // called by concatmergeable to determine if {lhsp, rhsp} make sense if (!v3Global.opt.oAssemble()) return false; // opt disabled // two same varref if (operandsSame(lhsp, rhsp)) return true; AstSel* lselp = lhsp->castSel(); AstSel* rselp = rhsp->castSel(); // a[i:0] a if (lselp && !rselp && rhsp->sameGateTree(lselp->fromp())) rselp = new AstSel(rhsp->fileline(), rhsp->cloneTree(false), 0, rhsp->width()); // a[i:j] {a[j-1:k], b} if (lselp && !rselp && rhsp->castConcat()) return ifMergeAdjacent(lhsp, rhsp->castConcat()->lhsp()); // a a[msb:j] if (rselp && !lselp && lhsp->sameGateTree(rselp->fromp())) lselp = new AstSel(lhsp->fileline(), lhsp->cloneTree(false), 0, lhsp->width()); // {b, a[j:k]} a[k-1:i] if (rselp && !lselp && lhsp->castConcat()) return ifMergeAdjacent(lhsp->castConcat()->rhsp(), rhsp); if (!lselp || !rselp) return false; // a[a:b] a[b-1:c] are adjacent AstNode* lfromp = lselp->fromp(); AstNode* rfromp = rselp->fromp(); if (!lfromp || !rfromp || !lfromp->sameGateTree(rfromp)) return false; AstConst* lstart = lselp->lsbp()->castConst(); AstConst* rstart = rselp->lsbp()->castConst(); AstConst* lwidth = lselp->widthp()->castConst(); AstConst* rwidth = rselp->widthp()->castConst(); if (!lstart || !rstart || !lwidth || !rwidth) return false; // too complicated int rend = (rstart->toSInt() + rwidth->toSInt()); // a[i:j] a[j-1:k] if (rend == lstart->toSInt()) return true; // a[i:0] a[msb:j] if (rend == rfromp->width() && lstart->toSInt() == 0) return true; return false; } bool concatMergeable(AstNode* lhsp, AstNode* rhsp) { // determine if {a OP b, c OP d} => {a, c} OP {b, d} is advantagous if (!v3Global.opt.oAssemble()) return false; // opt disabled if (lhsp->type() != rhsp->type()) return false; if (!ifConcatMergeableBiop(lhsp)) return false; AstNodeBiop* lp = lhsp->castNodeBiop(); AstNodeBiop* rp = rhsp->castNodeBiop(); if (!lp || !rp) return false; // {a[]&b[], a[]&b[]} bool lad = ifMergeAdjacent(lp->lhsp(), rp->lhsp()); bool rad = ifMergeAdjacent(lp->rhsp(), rp->rhsp()); if (lad && rad) return true; // {a[] & b[]&c[], a[] & b[]&c[]} else if (lad && concatMergeable(lp->rhsp(), rp->rhsp())) return true; // {a[]&b[] & c[], a[]&b[] & c[]} else if (rad && concatMergeable(lp->lhsp(), rp->lhsp())) return true; else { // {(a[]&b[])&(c[]&d[]), (a[]&b[])&(c[]&d[])} if (concatMergeable(lp->lhsp(), rp->lhsp()) && concatMergeable(lp->rhsp(), rp->rhsp())) return true; } return false; } //---------------------------------------- // Constant Replacement functions. // These all take a node, delete its tree, and replaces it with a constant void replaceNum (AstNode* oldp, const V3Number& num) { // Replace oldp node with a constant set to specified value UASSERT (oldp, "Null old\n"); if (oldp->castConst() && !oldp->castConst()->num().isFourState()) { oldp->v3fatalSrc("Already constant??"); } 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(); VL_DANGLING(oldp); } void replaceNum (AstNode* nodep, uint32_t val) { V3Number num (nodep->fileline(), nodep->width(), val); replaceNum(nodep, num); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } void replaceZero(AstNode* nodep) { replaceNum(nodep, 0); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } else { AstNode* newp = new AstAnd(nodep->fileline(), new AstConst(nodep->fileline(), 0), checkp->unlinkFrBack()); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } } void replaceAllOnes (AstNode* nodep) { V3Number ones (nodep->fileline(), nodep->width(), 0); ones.setMask(nodep->width()); replaceNum(nodep, ones); VL_DANGLING(nodep); } void replaceConst(AstNodeUniop* nodep) { V3Number num (nodep->fileline(), nodep->width()); nodep->numberOperate(num, nodep->lhsp()->castConst()->num()); UINFO(4,"UNICONST -> "<fileline(), nodep->width()); nodep->numberOperate(num, nodep->lhsp()->castConst()->num(), nodep->rhsp()->castConst()->num()); UINFO(4,"BICONST -> "<fileline(), nodep->width()); nodep->numberOperate(num, nodep->lhsp()->castConst()->num(), nodep->rhsp()->castConst()->num(), nodep->thsp()->castConst()->num()); UINFO(4,"TRICONST -> "<fileline(), AstConst::String(), num); if (debug()>5) oldp->dumpTree(cout," const_old: "); if (debug()>5) newp->dumpTree(cout," _new: "); oldp->replaceWith(newp); oldp->deleteTree(); VL_DANGLING(oldp); } //---------------------------------------- // 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(); VL_DANGLING(nodep); } //! Replace a ternary node with its RHS after iterating //! Used with short-circuting, where the RHS has not yet been iterated. void replaceWIteratedRhs(AstNodeTriop* nodep) { if (AstNode *rhsp = nodep->rhsp()) rhsp->iterateAndNext(*this); replaceWChild(nodep, nodep->rhsp()); // May have changed } //! Replace a ternary node with its THS after iterating //! Used with short-circuting, where the THS has not yet been iterated. void replaceWIteratedThs(AstNodeTriop* nodep) { if (AstNode *thsp = nodep->thsp()) thsp->iterateAndNext(*this); replaceWChild(nodep, nodep->thsp()); // May have changed } void replaceWLhs(AstNodeUniop* nodep) { // Keep LHS, remove RHS replaceWChild(nodep, nodep->lhsp()); } void replaceWLhs(AstNodeBiop* nodep) { // Keep LHS, remove RHS replaceWChild(nodep, nodep->lhsp()); } void replaceWRhs(AstNodeBiop* nodep) { // Keep RHS, remove LHS replaceWChild(nodep, nodep->rhsp()); } void replaceAsv (AstNodeBiop* nodep) { // BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c) // BIASV(SAMEa, BIASV(SAMEb, c)) -> BIASV( BIASV(SAMEa,SAMEb), c) //nodep->dumpTree(cout, " repAsvConst_old: "); AstNode* ap = nodep->lhsp(); AstNodeBiop* rp = nodep->rhsp()->castNodeBiop(); AstNode* bp = rp->lhsp(); AstNode* cp = rp->rhsp(); ap->unlinkFrBack(); bp->unlinkFrBack(); cp->unlinkFrBack(); rp->unlinkFrBack(); nodep->lhsp(rp); nodep->rhsp(cp); rp->lhsp(ap); rp->rhsp(bp); if (rp->lhsp()->castConst() && rp->rhsp()->castConst()) replaceConst(rp); //nodep->dumpTree(cout, " repAsvConst_new: "); } void replaceAsvLUp (AstNodeBiop* nodep) { // BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r)) AstNodeBiop* lp = nodep->lhsp()->unlinkFrBack()->castNodeBiop(); AstNode* llp = lp->lhsp()->unlinkFrBack(); AstNode* lrp = lp->rhsp()->unlinkFrBack(); AstNode* rp = nodep->rhsp()->unlinkFrBack(); nodep->lhsp(llp); nodep->rhsp(lp); lp->lhsp(lrp); lp->rhsp(rp); //nodep->dumpTree(cout, " repAsvLUp_new: "); } void replaceAsvRUp (AstNodeBiop* nodep) { // BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr)) AstNode* lp = nodep->lhsp()->unlinkFrBack(); AstNodeBiop* rp = nodep->rhsp()->unlinkFrBack()->castNodeBiop(); AstNode* rlp = rp->lhsp()->unlinkFrBack(); AstNode* rrp = rp->rhsp()->unlinkFrBack(); nodep->lhsp(rlp); nodep->rhsp(rp); rp->lhsp(lp); rp->rhsp(rrp); //nodep->dumpTree(cout, " repAsvRUp_new: "); } void replaceAndOr (AstNodeBiop* nodep) { // OR (AND (CONSTll,lr), AND(CONSTrl==ll,rr)) -> AND (CONSTll, OR(lr,rr)) // OR (AND (CONSTll,lr), AND(CONSTrl, rr=lr)) -> AND (OR(ll,rl), rr) // nodep ^lp ^llp ^lrp ^rp ^rlp ^rrp // (Or/And may also be reversed) AstNodeBiop* lp = nodep->lhsp()->unlinkFrBack()->castNodeBiop(); AstNode* llp = lp->lhsp()->unlinkFrBack(); AstNode* lrp = lp->rhsp()->unlinkFrBack(); AstNodeBiop* rp = nodep->rhsp()->unlinkFrBack()->castNodeBiop(); AstNode* rlp = rp->lhsp()->unlinkFrBack(); AstNode* rrp = rp->rhsp()->unlinkFrBack(); nodep->replaceWith(lp); if (operandsSame(llp,rlp)) { lp->lhsp(llp); lp->rhsp(nodep); nodep->lhsp(lrp); nodep->rhsp(rrp); rp->deleteTree(); rlp->deleteTree(); } else if (operandsSame(lrp, rrp)) { lp->lhsp(nodep); lp->rhsp(rrp); nodep->lhsp(llp); nodep->rhsp(rlp); rp->deleteTree(); lrp->deleteTree(); } else { nodep->v3fatalSrc("replaceAndOr on something operandAndOrSame shouldn't have matched"); } //nodep->dumpTree(cout, " repAndOr_new: "); } void replaceShiftSame (AstNodeBiop* nodep) { // Or(Shift(ll,CONSTlr),Shift(rl,CONSTrr==lr)) -> Shift(Or(ll,rl),CONSTlr) // (Or/And may also be reversed) AstNodeBiop* lp = nodep->lhsp()->unlinkFrBack()->castNodeBiop(); AstNode* llp = lp->lhsp()->unlinkFrBack(); AstNode* lrp = lp->rhsp()->unlinkFrBack(); AstNodeBiop* rp = nodep->rhsp()->unlinkFrBack()->castNodeBiop(); AstNode* rlp = rp->lhsp()->unlinkFrBack(); AstNode* rrp = rp->rhsp()->unlinkFrBack(); nodep->replaceWith(lp); lp->lhsp(nodep); lp->rhsp(lrp); nodep->lhsp(llp); nodep->rhsp(rlp); rp->deleteTree(); rrp->deleteTree(); //nodep->dumpTree(cout, " repShiftSame_new: "); } void replaceConcatSel(AstConcat* nodep) { // {a[1], a[0]} -> a[1:0] AstSel* lselp = nodep->lhsp()->unlinkFrBack()->castSel(); AstSel* rselp = nodep->rhsp()->unlinkFrBack()->castSel(); int lstart = lselp->lsbConst(); int lwidth = lselp->widthConst(); int rstart = rselp->lsbConst(); int rwidth = rselp->widthConst(); if ((rstart + rwidth) != lstart) nodep->v3fatalSrc("tried to merge two selects which are not adjacent"); AstSel* newselp = new AstSel(lselp->fromp()->fileline(), rselp->fromp()->cloneTree(false), rstart, lwidth+rwidth); UINFO(5, "merged two adjacent sel "<replaceWith(newselp); lselp->deleteTree(); VL_DANGLING(lselp); rselp->deleteTree(); VL_DANGLING(rselp); nodep->deleteTree(); VL_DANGLING(nodep); } void replaceConcatMerge(AstConcat* nodep) { AstNodeBiop* lp = nodep->lhsp()->castNodeBiop(); AstNodeBiop* rp = nodep->rhsp()->castNodeBiop(); AstNode* llp = lp->lhsp()->cloneTree(false); AstNode* lrp = lp->rhsp()->cloneTree(false); AstNode* rlp = rp->lhsp()->cloneTree(false); AstNode* rrp = rp->rhsp()->cloneTree(false); if (concatMergeable(lp, rp)) { AstConcat* newlp = new AstConcat(rlp->fileline(), llp, rlp); AstConcat* newrp = new AstConcat(rrp->fileline(), lrp, rrp); // use the lhs to replace the parent concat lp->lhsp()->replaceWith(newlp); lp->rhsp()->replaceWith(newrp); lp->dtypeChgWidthSigned(newlp->width(), newlp->width(), AstNumeric::fromBool(true)); UINFO(5, "merged "<< nodep <unlinkFrBack()->deleteTree(); VL_DANGLING(rp); nodep->replaceWith(lp->unlinkFrBack()); nodep->deleteTree(); VL_DANGLING(nodep); lp->lhsp()->accept(*this); lp->rhsp()->accept(*this); } else nodep->v3fatalSrc("tried to merge two Concat which are not adjacent"); } void replaceExtend (AstNode* nodep, AstNode* arg0p) { // -> EXTEND(nodep) // like a AstExtend{$rhsp}, but we need to set the width correctly from base node arg0p->unlinkFrBack(); AstNode* newp = (nodep->castExtendS() ? static_cast(new AstExtendS(nodep->fileline(), arg0p)) : static_cast(new AstExtend (nodep->fileline(), arg0p))); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } void replaceShiftOp (AstNodeBiop* nodep) { UINFO(5,"SHIFT(AND(a,b),CONST)->AND(SHIFT(a,CONST),SHIFT(b,CONST)) "<unlinkFrBack(&handle); AstNodeBiop* lhsp = nodep->lhsp()->castNodeBiop(); lhsp->unlinkFrBack(); AstNode* shiftp = nodep->rhsp()->unlinkFrBack(); AstNode* ap = lhsp->lhsp()->unlinkFrBack(); AstNode* bp = lhsp->rhsp()->unlinkFrBack(); AstNodeBiop* shift1p = nodep; AstNodeBiop* shift2p = nodep->cloneTree(true); shift1p->lhsp(ap); shift1p->rhsp(shiftp->cloneTree(true)); shift2p->lhsp(bp); shift2p->rhsp(shiftp); AstNodeBiop* newp = lhsp; newp->lhsp(shift1p); newp->rhsp(shift2p); handle.relink(newp); newp->accept(*this); // Further reduce, either node may have more reductions. } void replaceShiftShift (AstNodeBiop* nodep) { UINFO(4,"SHIFT(SHIFT(a,s1),s2)->SHIFT(a,ADD(s1,s2)) "<=9) nodep->dumpTree(cout, " repShiftShift_old: "); AstNodeBiop* lhsp = nodep->lhsp()->castNodeBiop(); lhsp->unlinkFrBack(); AstNode* ap = lhsp->lhsp()->unlinkFrBack(); AstNode* shift1p = lhsp->rhsp()->unlinkFrBack(); AstNode* shift2p = nodep->rhsp()->unlinkFrBack(); // Shift1p and shift2p may have different sizes, both are self-determined so sum with infinite width if (nodep->type()==lhsp->type()) { int shift1 = shift1p->castConst()->toUInt(); int shift2 = shift2p->castConst()->toUInt(); int newshift = shift1+shift2; shift1p->deleteTree(); VL_DANGLING(shift1p); shift2p->deleteTree(); VL_DANGLING(shift2p); nodep->lhsp(ap); nodep->rhsp(new AstConst(nodep->fileline(), newshift)); nodep->accept(*this); // Further reduce, either node may have more reductions. } else { // We know shift amounts are constant, but might be a mixed left/right shift int shift1 = shift1p->castConst()->toUInt(); if (lhsp->castShiftR()) shift1=-shift1; int shift2 = shift2p->castConst()->toUInt(); if (nodep->castShiftR()) shift2=-shift2; int newshift = shift1+shift2; shift1p->deleteTree(); VL_DANGLING(shift1p); shift2p->deleteTree(); VL_DANGLING(shift2p); 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(); VL_DANGLING(nodep); //newp->dumpTree(cout, " repShiftShift_new: "); newp->accept(*this); // Further reduce, either node may have more reductions. } lhsp->deleteTree(); VL_DANGLING(lhsp); } bool replaceAssignMultiSel(AstNodeAssign* nodep) { // Multiple assignments to sequential bits can be concated // ASSIGN(SEL(a),aq), ASSIGN(SEL(a+1),bq) -> ASSIGN(SEL(a:b),CONCAT(aq,bq) // ie. assign var[2]=a, assign var[3]=b -> assign var[3:2]={b,a} if (!m_modp) return false; // Skip if we're not const'ing an entire module (IE doing only one assign, etc) AstSel* sel1p = nodep->lhsp()->castSel(); if (!sel1p) return false; AstNodeAssign* nextp = nodep->nextp()->castNodeAssign(); if (!nextp) return false; if (nodep->type() != nextp->type()) return false; AstSel* sel2p = nextp->lhsp()->castSel(); if (!sel2p) return false; AstVarRef* varref1p = sel1p->fromp()->castVarRef(); if (!varref1p) return false; AstVarRef* varref2p = sel2p->fromp()->castVarRef(); if (!varref2p) return false; if (!varref1p->sameGateTree(varref2p)) return false; AstConst* con1p = sel1p->lsbp()->castConst(); if (!con1p) return false; AstConst* con2p = sel2p->lsbp()->castConst(); if (!con2p) return false; // We need to make sure there's no self-references involved in either // assignment. For speed, we only look 3 deep, then give up. if (!varNotReferenced(nodep->rhsp(), varref1p->varp())) return false; if (!varNotReferenced(nextp->rhsp(), varref2p->varp())) return false; // Swap? if (( con1p->toSInt() != con2p->toSInt() + sel2p->width()) &&(con2p->toSInt() != con1p->toSInt() + sel1p->width())) return false; bool lsbFirstAssign = (con1p->toUInt() < con2p->toUInt()); // If the user already has nice 32-bit divisions, keep them to aid later subdivision //if (VL_BITBIT_I(con1p->toUInt()) == 0) return false; UINFO(4,"replaceAssignMultiSel "<dumpTree(cout, "comb1: "); //nextp->dumpTree(cout, "comb2: "); AstNode* rhs1p = nodep->rhsp()->unlinkFrBack(); AstNode* rhs2p = nextp->rhsp()->unlinkFrBack(); AstNode* newp; if (lsbFirstAssign) { newp = nodep->cloneType (new AstSel(sel1p->fileline(), varref1p->unlinkFrBack(), sel1p->lsbConst(), sel1p->width() + sel2p->width()), new AstConcat(rhs1p->fileline(), rhs2p, rhs1p)); } else { newp = nodep->cloneType (new AstSel(sel1p->fileline(), varref1p->unlinkFrBack(), sel2p->lsbConst(), sel1p->width() + sel2p->width()), new AstConcat(rhs1p->fileline(), rhs1p, rhs2p)); } //pnewp->dumpTree(cout, "conew: "); nodep->replaceWith(newp); nodep->deleteTree(); nextp->unlinkFrBack()->deleteTree(); return true; } bool varNotReferenced(AstNode* nodep, AstVar* varp, int level=0) { // Return true if varp never referenced under node. // Return false if referenced, or tree too deep to be worth it, or side effects if (!nodep) return true; if (level>2) return false; if (nodep->isPure()) return false; // For example a $fgetc can't be reordered if (nodep->castNodeVarRef() && nodep->castNodeVarRef()->varp()==varp) return false; return (varNotReferenced (nodep->nextp(),varp,level+1) && varNotReferenced(nodep->op1p(),varp,level+1) && varNotReferenced(nodep->op2p(),varp,level+1) && varNotReferenced(nodep->op3p(),varp,level+1) && varNotReferenced(nodep->op4p(),varp,level+1)); } bool replaceNodeAssign(AstNodeAssign* nodep) { if (nodep->lhsp()->castVarRef() && nodep->rhsp()->castVarRef() && nodep->lhsp()->castVarRef()->sameNoLvalue(nodep->rhsp()->castVarRef()) && !nodep->castAssignDly()) { // X = X. Quite pointless, though X <= X may override another earlier assignment if (nodep->castAssignW()) { nodep->v3error("Wire inputs its own output, creating circular logic (wire x=x)"); return false; // Don't delete the assign, or V3Gate will freak out } else { nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); 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); newp = AstNode::addNext(newp, asn1ap); newp = AstNode::addNext(newp, 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 newp = AstNode::addNext(newp, asn1ap); newp = AstNode::addNext(newp, asn2ap); newp = AstNode::addNext(newp, asn1bp); newp = AstNode::addNext(newp, asn2bp); } if (debug()>=9 && newp) newp->dumpTreeAndNext(cout," _new: "); nodep->addNextHere(newp); // Cleanup nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); conp->deleteTree(); VL_DANGLING(conp); // Further reduce, either node may have more reductions. return true; } else if (m_doV && nodep->rhsp()->castStreamR()) { // The right-streaming operator on rhs of assignment does not // change the order of bits. Eliminate stream but keep its lhsp // Unlink the stuff AstNode* srcp = nodep->rhsp()->castStreamR()->lhsp()->unlinkFrBack(); AstNode* sizep = nodep->rhsp()->castStreamR()->rhsp()->unlinkFrBack(); AstNode* streamp = nodep->rhsp()->castStreamR()->unlinkFrBack(); nodep->rhsp(srcp); // Cleanup sizep->deleteTree(); VL_DANGLING(sizep); streamp->deleteTree(); VL_DANGLING(streamp); // Further reduce, any of the nodes may have more reductions. return true; } else if (m_doV && nodep->lhsp()->castStreamL()) { // Push the stream operator to the rhs of the assignment statement int dWidth = nodep->lhsp()->castStreamL()->lhsp()->width(); int sWidth = nodep->rhsp()->width(); // Unlink the stuff AstNode* dstp = nodep->lhsp()->castStreamL()->lhsp()->unlinkFrBack(); AstNode* streamp = nodep->lhsp()->castStreamL()->unlinkFrBack(); AstNode* srcp = nodep->rhsp()->unlinkFrBack(); // Connect the rhs to the stream operator and update its width streamp->castStreamL()->lhsp(srcp); streamp->dtypeSetLogicSized((srcp->width()), (srcp->widthMin()), AstNumeric::UNSIGNED); // Shrink the RHS if necessary if (sWidth > dWidth) { streamp = new AstSel(streamp->fileline(), streamp, sWidth-dWidth, dWidth); } // Link the nodes back in nodep->lhsp(dstp); nodep->rhsp(streamp); return true; } else if (m_doV && nodep->lhsp()->castStreamR()) { // The right stream operator on lhs of assignment statement does // not reorder bits. However, if the rhs is wider than the lhs, // then we select bits from the left-most, not the right-most. int dWidth = nodep->lhsp()->castStreamR()->lhsp()->width(); int sWidth = nodep->rhsp()->width(); // Unlink the stuff AstNode* dstp = nodep->lhsp()->castStreamR()->lhsp()->unlinkFrBack(); AstNode* sizep = nodep->lhsp()->castStreamR()->rhsp()->unlinkFrBack(); AstNode* streamp = nodep->lhsp()->castStreamR()->unlinkFrBack(); AstNode* srcp = nodep->rhsp()->unlinkFrBack(); if (sWidth > dWidth) { srcp = new AstSel(streamp->fileline(), srcp, sWidth-dWidth, dWidth); } nodep->lhsp(dstp); nodep->rhsp(srcp); // Cleanup sizep->deleteTree(); VL_DANGLING(sizep); streamp->deleteTree(); VL_DANGLING(streamp); // Further reduce, any of the nodes may have more reductions. return true; } else if (replaceAssignMultiSel(nodep)) { return true; } return false; } // Boolean replacements bool operandBoolShift(AstNode* nodep) { // boolean test of AND(const,SHIFTR(x,const)) -> test of AND(SHIFTL(x,const), x) if (!nodep->castAnd()) return false; if (!nodep->castAnd()->lhsp()->castConst()) return false; if (!nodep->castAnd()->rhsp()->castShiftR()) return false; AstShiftR* shiftp = nodep->castAnd()->rhsp()->castShiftR(); if (!shiftp->rhsp()->castConst()) return false; if ((uint32_t)(nodep->width()) <= shiftp->rhsp()->castConst()->toUInt()) return false; return true; } void replaceBoolShift(AstNode* nodep) { if (debug()>=9) nodep->dumpTree(cout," bshft_old: "); AstConst* andConstp = nodep->castAnd()->lhsp()->castConst(); AstNode* fromp = nodep->castAnd()->rhsp()->castShiftR()->lhsp()->unlinkFrBack(); AstConst* shiftConstp = nodep->castAnd()->rhsp()->castShiftR()->rhsp()->castConst(); V3Number val (andConstp->fileline(), andConstp->width()); val.opShiftL(andConstp->num(), shiftConstp->num()); AstAnd* newp = new AstAnd(nodep->fileline(), new AstConst(nodep->fileline(), val), fromp); newp->dtypeSetLogicSized(nodep->width(), nodep->width(), AstNumeric::UNSIGNED); // widthMin no longer applicable if different C-expanded width nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); 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); VL_DANGLING(nodep); } } //---------------------------------------- // VISITORS virtual void visit(AstNetlist* nodep) { // Iterate modules backwards, in bottom-up order. That's faster nodep->iterateChildrenBackwards(*this); } virtual void visit(AstNodeModule* nodep) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCFunc* nodep) { // 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) { // 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(); VL_DANGLING(bcConcp); } 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(); VL_DANGLING(abConcp); } } // Special cases virtual void visit(AstConst* nodep) {} // Already constant virtual void visit(AstCell* nodep) { if (m_params) { nodep->paramsp()->iterateAndNext(*this); } else { nodep->iterateChildren(*this); } } virtual void visit(AstPin* nodep) { 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(); VL_DANGLING(lsb1p); lsb2p->deleteTree(); VL_DANGLING(lsb2p); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } bool operandSelReplicate(AstSel* nodep) { // SEL(REPLICATE(from,rep),lsb,width) => SEL(from,0,width) as long as SEL's width <= b's width AstReplicate* repp = nodep->fromp()->castReplicate(); AstNode* fromp = repp->lhsp(); AstConst* lsbp = nodep->lsbp()->castConst(); if (!lsbp) return false; AstNode* widthp = nodep->widthp(); if (!widthp->castConst()) return false; if (!fromp->width()) nodep->v3fatalSrc("Not widthed"); if ((lsbp->toUInt() / fromp->width()) != ((lsbp->toUInt()+nodep->width()-1) / fromp->width())) return false; // fromp->unlinkFrBack(); 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(); VL_DANGLING(nodep); return true; } bool operandRepRep(AstReplicate* nodep) { // REPLICATE(REPLICATE2(from2,cnt2),cnt1) => REPLICATE(from2,(cnt1+cnt2)) AstReplicate* rep2p = nodep->lhsp()->castReplicate(); AstNode* from2p = rep2p->lhsp(); AstConst* cnt1p = nodep->rhsp()->castConst(); if (!cnt1p) return false; AstConst* cnt2p = rep2p->rhsp()->castConst(); if (!cnt2p) return false; // from2p->unlinkFrBack(); cnt1p->unlinkFrBack(); cnt2p->unlinkFrBack(); AstReplicate* newp = new AstReplicate(nodep->fileline(), from2p, cnt1p->toUInt()*cnt2p->toUInt()); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); return true; } bool operandConcatSame(AstConcat* nodep) { // CONCAT(fromp,fromp) -> REPLICATE(fromp,1+1) // CONCAT(REP(fromp,cnt1),fromp) -> REPLICATE(fromp,cnt1+1) // CONCAT(fromp,REP(fromp,cnt1)) -> REPLICATE(fromp,1+cnt1) // CONCAT(REP(fromp,cnt1),REP(fromp,cnt2)) -> REPLICATE(fromp,cnt1+cnt2) AstNode* from1p = nodep->lhsp(); uint32_t cnt1 = 1; AstNode* from2p = nodep->rhsp(); uint32_t cnt2 = 1; if (from1p->castReplicate()) { AstConst* cnt1p = from1p->castReplicate()->rhsp()->castConst(); if (!cnt1p) return false; from1p = from1p->castReplicate()->lhsp(); cnt1 = cnt1p->toUInt(); } if (from2p->castReplicate()) { AstConst* cnt2p = from2p->castReplicate()->rhsp()->castConst(); if (!cnt2p) return false; from2p = from2p->castReplicate()->lhsp(); cnt2 = cnt2p->toUInt(); } if (!operandsSame(from1p,from2p)) return false; // from1p->unlinkFrBack(); AstReplicate* newp = new AstReplicate(nodep->fileline(), from1p, cnt1+cnt2); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); return true; } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } virtual void visit(AstAttrOf* nodep) { AstAttrOf* oldAttr = m_attrp; m_attrp = nodep; nodep->iterateChildren(*this); m_attrp = oldAttr; } virtual void visit(AstArraySel* nodep) { nodep->bitp()->iterateAndNext(*this); if (nodep->bitp()->castConst() && nodep->fromp()->castVarRef() // Need to make sure it's an array object so don't mis-allow a constant (bug509.) && nodep->fromp()->castVarRef()->varp() && nodep->fromp()->castVarRef()->varp()->valuep()->castInitArray()) { m_selp = nodep; // Ask visit(AstVarRef) to replace varref with const } nodep->fromp()->iterateAndNext(*this); if (nodep->fromp()->castConst()) { // It did. if (!m_selp) { nodep->v3error("Illegal assignment of constant to unpacked array"); } else { AstNode* fromp = nodep->fromp()->unlinkFrBack(); nodep->replaceWith(fromp); if (fromp->dtypep()->skipRefp()->castNodeArrayDType()) { // Strip off array to find what array references fromp->dtypeFrom(fromp->dtypep()->skipRefp()->castNodeArrayDType()->subDTypep()); } } } m_selp = NULL; } virtual void visit(AstNodeVarRef* nodep) { nodep->iterateChildren(*this); if (!nodep->varp()) nodep->v3fatalSrc("Not linked"); bool did=false; if (m_doV && nodep->varp()->valuep() && !m_attrp) { //if (debug()) valuep->dumpTree(cout," visitvaref: "); nodep->varp()->valuep()->iterateAndNext(*this); // May change nodep->varp()->valuep() AstNode* valuep = nodep->varp()->valuep(); if (!nodep->lvalue() && ((!m_params // Can reduce constant wires into equations && m_doNConst && v3Global.opt.oConst() && !(nodep->varp()->isFuncLocal() // Default value, not a "known" constant for this usage && nodep->varp()->isInput()) && !nodep->varp()->noSubst() && !nodep->varp()->isSigPublic()) || nodep->varp()->isParam())) { if (operandConst(valuep)) { const V3Number& num = valuep->castConst()->num(); //UINFO(2,"constVisit "<<(void*)valuep<<" "<castInitArray()) { AstInitArray* initarp = valuep->castInitArray(); uint32_t bit = m_selp->bitConst(); int pos = 0; AstNode* itemp = initarp->initsp(); for (; itemp; ++pos, itemp=itemp->nextp()) { uint32_t index = initarp->posIndex(pos); if (index == bit) break; if (index > bit) { if (initarp->defaultp()) { itemp = initarp->defaultp(); } else { initarp->v3fatalSrc("Not enough values in array initalizement"); } } } if (itemp->castConst()) { const V3Number& num = itemp->castConst()->num(); //UINFO(2,"constVisit "<<(void*)valuep<<" "<castInitArray() && nodep->backp()->castPin()) { // Allow parameters to pass arrays // Earlier recursion of InitArray made sure each array value is constant // This exception is fairly fragile, i.e. doesn't support arrays of arrays or other stuff AstNode* newp = valuep->cloneTree(false); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); did = true; } } } if (!did && m_required) { nodep->v3error("Expecting expression to be constant, but variable isn't const: "<varp()->prettyName()); } } virtual void visit(AstEnumItemRef* nodep) { 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); VL_DANGLING(nodep); 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) { // 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) { 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(); VL_DANGLING(nodep); } else { nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } } else { // Otherwise it may compute a result that needs to settle out nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Combo())); nodep->deleteTree(); VL_DANGLING(nodep); } } 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(); VL_DANGLING(sensp); } else if (!m_doNConst // Deal with later when doNConst missing && (nodep->sensp()->castEnumItemRef() || nodep->sensp()->castConst())) { } else if (nodep->isIllegal()) { // Deal with later } else { if (nodep->hasVar() && !nodep->varrefp()) nodep->v3fatalSrc("Null sensitivity variable"); } } virtual void visit(AstSenGate* nodep) { 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(); VL_DANGLING(nodep); } else { nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } } else { UINFO(4,"SENGATE(SENITEM,0)->ALWAYS SENITEM"<sensesp()->unlinkFrBack(); nodep->replaceWith(senitemp); nodep->deleteTree(); VL_DANGLING(nodep); } } } 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; // Or rarely, different data types if (litemp->varrefp()->dtypep() < ritemp->varrefp()->dtypep()) return true; if (litemp->varrefp()->dtypep() > ritemp->varrefp()->dtypep()) 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 first, less general last) if (litemp->edgeType() < ritemp->edgeType()) return true; if (litemp->edgeType() > ritemp->edgeType()) return false; } return false; } }; virtual void visit(AstSenTree* nodep) { 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(); VL_DANGLING(gatep); VL_DANGLING(senp); } } } } } } // Sort the sensitivity names so "posedge a or b" and "posedge b or a" end up together. // Also, remove duplicate assignments, and fold POS&NEGs into ANYEDGEs // Make things a little faster; check first if we need a sort for (AstNodeSenItem* nextp, * senp = nodep->sensesp()->castNodeSenItem(); senp; senp=nextp) { nextp=senp->nextp()->castNodeSenItem(); // cppcheck-suppress unassignedVariable // cppcheck bug SenItemCmp cmp; if (nextp && !cmp(senp, nextp)) { // Something's out of order, sort it senp = NULL; vector vec; for (AstNodeSenItem* senp = nodep->sensesp()->castNodeSenItem(); senp; senp=senp->nextp()->castNodeSenItem()) { vec.push_back(senp); } stable_sort(vec.begin(), vec.end(), SenItemCmp()); for (vector::iterator it=vec.begin(); it!=vec.end(); ++it) { (*it)->unlinkFrBack(); } for (vector::iterator it=vec.begin(); it!=vec.end(); ++it) { nodep->addSensesp(*it); } break; } } // Pass2, remove dup edges for (AstNodeSenItem* nextp, * senp = nodep->sensesp()->castNodeSenItem(); senp; senp=nextp) { nextp=senp->nextp()->castNodeSenItem(); AstNodeSenItem* cmpp = nextp; AstSenItem* litemp = senp->castSenItem(); AstSenItem* ritemp = cmpp->castSenItem(); if (litemp && ritemp) { if ((litemp->varrefp() && ritemp->varrefp() && litemp->varrefp()->sameGateTree(ritemp->varrefp())) || (!litemp->varrefp() && !ritemp->varrefp())) { // We've sorted in the order ANY, BOTH, POS, NEG, so we don't need to try opposite orders if (( litemp->edgeType()==AstEdgeType::ET_ANYEDGE) // ANY or {BOTH|POS|NEG} -> ANY || (litemp->edgeType()==AstEdgeType::ET_BOTHEDGE) // BOTH or {POS|NEG} -> BOTH || (litemp->edgeType()==AstEdgeType::ET_POSEDGE // POS or NEG -> BOTH && ritemp->edgeType()==AstEdgeType::ET_NEGEDGE) || (litemp->edgeType()==ritemp->edgeType()) // Identical edges ) { // Fix edge of old node if (litemp->edgeType()==AstEdgeType::ET_POSEDGE && ritemp->edgeType()==AstEdgeType::ET_NEGEDGE) litemp->edgeType(AstEdgeType::ET_BOTHEDGE); // Remove redundant node ritemp->unlinkFrBack()->deleteTree(); VL_DANGLING(ritemp); VL_DANGLING(cmpp); // Try to collapse again nextp=litemp; } } } } //nodep->dumpTree(cout,"ssou: "); } } //----- // Zero elimination virtual void visit(AstNodeAssign* nodep) { nodep->iterateChildren(*this); if (m_doNConst && replaceNodeAssign(nodep)) return; } virtual void visit(AstAssignAlias* nodep) { // Don't perform any optimizations, keep the alias around } virtual void visit(AstAssignVarScope* nodep) { // Don't perform any optimizations, the node won't be linked yet } virtual void visit(AstAssignW* nodep) { 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(); VL_DANGLING(nodep); // 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) { 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } 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(); VL_DANGLING(nodep); } else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting && operandIfIf(nodep)) { UINFO(9,"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(); VL_DANGLING(lowerIfp); } else if (operandBoolShift(nodep->condp())) { replaceBoolShift(nodep->condp()); } } } virtual void visit(AstDisplay* nodep) { // DISPLAY(SFORMAT(text1)),DISPLAY(SFORMAT(text2)) -> DISPLAY(SFORMAT(text1+text2)) nodep->iterateChildren(*this); if (stmtDisplayDisplay(nodep)) return; } bool stmtDisplayDisplay(AstDisplay* nodep) { // DISPLAY(SFORMAT(text1)),DISPLAY(SFORMAT(text2)) -> DISPLAY(SFORMAT(text1+text2)) if (!m_modp) return false; // Don't optimize under single statement if (!nodep->backp()) return false; AstDisplay* prevp = nodep->backp()->castDisplay(); if (!prevp) return false; if (!((prevp->displayType() == nodep->displayType()) || (prevp->displayType() == AstDisplayType::DT_WRITE && nodep->displayType() == AstDisplayType::DT_DISPLAY) || (prevp->displayType() == AstDisplayType::DT_DISPLAY && nodep->displayType() == AstDisplayType::DT_WRITE))) return false; if ((prevp->filep() && !nodep->filep()) || (!prevp->filep() && nodep->filep()) || !prevp->filep()->sameTree(nodep->filep())) return false; if (!prevp->fmtp() || prevp->fmtp()->nextp() || !nodep->fmtp() || nodep->fmtp()->nextp()) return false; // We don't merge scopeNames as might be different scopes (late in process) // We don't merge arguments as might need to later print warnings with right line numbers AstSFormatF* pformatp = prevp->fmtp(); if (!pformatp || pformatp->exprsp() || pformatp->scopeNamep()) return false; AstSFormatF* nformatp = nodep->fmtp(); if (!nformatp || nformatp->exprsp() || nformatp->scopeNamep()) return false; // UINFO(9,"DISPLAY(SF({a})) DISPLAY(SF({b})) -> DISPLAY(SF({a}+{b}))"<displayType() == AstDisplayType::DT_DISPLAY) { prevp->displayType(AstDisplayType::DT_WRITE); pformatp->text(pformatp->text()+"\n"); } // We can't replace prev() as the edit tracking iterators will get confused. // So instead we edit the prev note itself. if (prevp->addNewline()) pformatp->text(pformatp->text()+"\n"); pformatp->text(pformatp->text()+nformatp->text()); if (!prevp->addNewline() && nodep->addNewline()) { pformatp->text(pformatp->text()+"\n"); } nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); return true; } virtual void visit(AstSFormatF* nodep) { // Substitute constants into displays. The main point of this is to // simplify assertion methodologies which call functions with display's. // This eliminates a pile of wide temps, and makes the C a whole lot more readable. nodep->iterateChildren(*this); bool anyconst = false; for (AstNode* argp = nodep->exprsp(); argp; argp=argp->nextp()) { if (argp->castConst()) { anyconst=true; break; } } if (m_doNConst && anyconst) { //UINFO(9," Display in "<text()<exprsp(); string text = nodep->text(); for (string::const_iterator it = text.begin(); it!=text.end(); ++it) { char ch = *it; if (!inPct && ch=='%') { inPct = true; fmt = ch; } else if (inPct && (isdigit(ch) || ch=='.')) { fmt += ch; } else if (inPct) { inPct = false; fmt += ch; switch (tolower(ch)) { case '%': break; // %% - just output a % case 'm': break; // %m - auto insert "name" case 'l': break; // %l - auto insert "library" 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(nodep->fileline(), fmt); UINFO(9," DispConst: "< "<unlinkFrBack()->deleteTree(); VL_DANGLING(argp); } argp=nextp; } break; } // switch newFormat += fmt; } else { newFormat += ch; } } if (newFormat != nodep->text()) { nodep->text(newFormat); UINFO(9," Display out "<exprsp() && nodep->name().find("%") == string::npos && !nodep->hidden()) { // Just a simple constant string - the formatting is pointless replaceConstString(nodep, nodep->name()); VL_DANGLING(nodep); } } virtual void visit(AstFuncRef* nodep) { nodep->iterateChildren(*this); if (m_params) { // Only parameters force us to do constant function call propagation replaceWithSimulation(nodep); } } virtual void visit(AstArg* nodep) { // replaceWithSimulation on the Arg's parent FuncRef replaces these nodep->iterateChildren(*this); } virtual void visit(AstWhile* nodep) { 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(); VL_DANGLING(nodep); } else if (operandBoolShift(nodep->condp())) { replaceBoolShift(nodep->condp()); } } } virtual void visit(AstInitArray* nodep) { // Constant if all children are constant nodep->iterateChildren(*this); } // These are converted by V3Param. Don't constify as we don't want the from() VARREF to disappear, if any // If output of a presel didn't get consted, chances are V3Param didn't visit properly virtual void visit(AstNodePreSel* nodep) {} // Ignored, can eliminate early virtual void visit(AstSysIgnore* nodep) { nodep->iterateChildren(*this); if (m_doNConst) { nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } } // Simplify virtual void visit(AstBasicDType* nodep) { nodep->iterateChildren(*this); nodep->cvtRangeConst(); } //----- // Jump elimination virtual void visit(AstJumpGo* nodep) { nodep->iterateChildren(*this); if (m_doExpensive) { nodep->labelp()->user4(true); } } virtual void visit(AstJumpLabel* nodep) { // 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(); VL_DANGLING(nodep); } } //----- // Below lines are magic expressions processed by astgen // TREE_SKIP_VISIT("AstNODETYPE") # Rename normal visit to visitGen and don't iterate //----- TREE_SKIP_VISIT("ArraySel"); //----- // "AstNODETYPE { # bracket not paren // $accessor_name, ... // # ,, gets replaced with a , rather than && // }" # bracket not paren // ,"what to call" // // Where "what_to_call" is: // "function to call" // "AstREPLACEMENT_TYPE{ $accessor }" // "! # Print line number when matches, so can see operations // "NEVER" # Print error message // "DONE" # Process of matching did the transform already // In the future maybe support more complicated match & replace: // ("AstOr {%a, AstAnd{AstNot{%b}, %c}} if %a.width1 if %a==%b", "AstOr{%a,%c}; %b.delete"); // Lhs/rhs would be implied; for non math operations you'd need $lhsp etc. // Lint Checks // v--- *1* These ops are always first, as we warn before replacing // v--- *V* This op is a verilog op, only in m_doV mode // v--- *C* This op works on all constant children, allowed in m_doConst mode // v--- *S* This op specifies a type should use short-circuting of its lhs op TREEOP1("AstSel{warnSelect(nodep)}", "NEVER"); // Generic constants on both side. Do this first to avoid other replacements TREEOPC("AstNodeBiop {$lhsp.castConst, $rhsp.castConst}", "replaceConst(nodep)"); TREEOPC("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque()}", "replaceConst(nodep)"); // Zero on one side or the other TREEOP ("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstAnd {$lhsp.isZero, $rhsp, isTPure($rhsp)}", "replaceZero(nodep)"); // Can't use replaceZeroChkPure as we make this pattern in ChkPure // This visit function here must allow for short-circuiting. TREEOPS("AstLogAnd {$lhsp.isZero}", "replaceZero(nodep)"); TREEOP ("AstLogAnd{$lhsp.isZero, $rhsp}", "replaceZero(nodep)"); // This visit function here must allow for short-circuiting. TREEOPS("AstLogOr {$lhsp.isOne}", "replaceNum(nodep, 1)"); TREEOP ("AstLogOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstDiv {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstDivS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstMul {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstMulS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstPow {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule TREEOP ("AstPowSS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule TREEOP ("AstPowSU {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule TREEOP ("AstPowUS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule TREEOP ("AstPow {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstPowSU {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstPowUS {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstPowSU {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstShiftL{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstShiftR{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstShiftRS{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstXnor {$lhsp.isZero, $rhsp}", "AstNot{$rhsp}"); TREEOP ("AstSub {$lhsp.isZero, $rhsp}", "AstNegate{$rhsp}"); TREEOP ("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstAnd {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)"); TREEOP ("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)"); TREEOP ("AstLogOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstMul {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)"); TREEOP ("AstMulS {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)"); TREEOP ("AstOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstShiftL{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstShiftR{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstShiftRS{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstSub {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstXor {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstXnor {$lhsp, $rhsp.isZero}", "AstNot{$lhsp}"); // Non-zero on one side or the other TREEOP ("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstOr {$lhsp.isAllOnes, $rhsp, isTPure($rhsp)}", "replaceWLhs(nodep)"); //->allOnes TREEOP ("AstLogOr {$lhsp.isNeqZero, $rhsp}", "replaceNum(nodep,1)"); TREEOP ("AstAnd {$lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)"); TREEOP ("AstLogAnd{$lhsp, $rhsp.isNeqZero}", "replaceWLhs(nodep)"); TREEOP ("AstOr {$lhsp, $rhsp.isAllOnes, isTPure($lhsp)}", "replaceWRhs(nodep)"); //->allOnes TREEOP ("AstLogOr {$lhsp, $rhsp.isNeqZero, isTPure($lhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}"); TREEOP ("AstXnor {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstMulS {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstDiv {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)"); TREEOP ("AstDivS {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)"); TREEOP ("AstMul {operandIsPowTwo($lhsp), $rhsp}", "replaceMulShift(nodep)"); // a*2^n -> a< a>>n TREEOP ("AstPow {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<castAdd()->lhsp(),$rhsp}, $lhsp->castAdd()->rhsp()}"); // ((a+x)-y) -> (a+(x-y)) // Trinary ops // Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump! TREEOP ("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)"); TREEOP ("AstNodeCond{$condp.isNeqZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr1p)"); TREEOPC("AstNodeCond{$condp.isZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr2p)"); TREEOPC("AstNodeCond{$condp.isNeqZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr1p)"); TREEOP ("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)"); // This visit function here must allow for short-circuiting. TREEOPS("AstCond {$lhsp.isZero}", "replaceWIteratedThs(nodep)"); TREEOPS("AstCond {$lhsp.isNeqZero}", "replaceWIteratedRhs(nodep)"); TREEOP ("AstCond{$condp.castNot, $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}"); TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstLogOr {$condp, $expr2p}"); // a?1:b == a||b TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstLogAnd{$condp, $expr1p}"); // a?b:0 == a&&b TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstLogOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a||b TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstLogAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&&b TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())"); // Prefer constants on left, since that often needs a shift, it lets constant red remove the shift TREEOP ("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)"); TREEOP ("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)"); TREEOP ("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)"); TREEOP ("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)"); TREEOP ("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)"); TREEOP ("AstLt {!$lhsp.castConst,$rhsp.castConst}", "AstGt {$rhsp,$lhsp}"); TREEOP ("AstLtS {!$lhsp.castConst,$rhsp.castConst}", "AstGtS {$rhsp,$lhsp}"); TREEOP ("AstLte {!$lhsp.castConst,$rhsp.castConst}", "AstGte {$rhsp,$lhsp}"); TREEOP ("AstLteS {!$lhsp.castConst,$rhsp.castConst}", "AstGteS{$rhsp,$lhsp}"); TREEOP ("AstGt {!$lhsp.castConst,$rhsp.castConst}", "AstLt {$rhsp,$lhsp}"); TREEOP ("AstGtS {!$lhsp.castConst,$rhsp.castConst}", "AstLtS {$rhsp,$lhsp}"); TREEOP ("AstGte {!$lhsp.castConst,$rhsp.castConst}", "AstLte {$rhsp,$lhsp}"); TREEOP ("AstGteS {!$lhsp.castConst,$rhsp.castConst}", "AstLteS{$rhsp,$lhsp}"); // v--- *1* as These ops are always first, as we warn before replacing TREEOP1("AstLt {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,0)"); TREEOP1("AstGte {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,1)"); TREEOP1("AstGt {$lhsp.isZero, $rhsp}", "replaceNumSigned(nodep,0)"); TREEOP1("AstLte {$lhsp.isZero, $rhsp}", "replaceNumSigned(nodep,1)"); TREEOP1("AstGt {$lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,0)"); TREEOP1("AstLte {$lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)"); TREEOP1("AstLt {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,0)"); TREEOP1("AstGte {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)"); // Two level bubble pushing TREEOP ("AstNot {$lhsp.castNot, $lhsp->width()==$lhsp->castNot()->lhsp()->width()}", "replaceWChild(nodep, $lhsp->op1p())"); // NOT(NOT(x))->x TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->op1p())"); // LOGNOT(LOGNOT(x))->x TREEOPV("AstNot {$lhsp.castEqCase, $lhsp.width1}","AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castEqWild, $lhsp.width1}","AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEqWild}", "AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeqWild, $lhsp.width1}","AstEqWild {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castNeqWild}", "AstEqWild {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castNeq}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castLt, $lhsp.width1}", "AstGte {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castLt}", "AstGte {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castLtS, $lhsp.width1}", "AstGteS{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castLtS}", "AstGteS{$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castLte, $lhsp.width1}", "AstGt {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castLte}", "AstGt {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castLteS, $lhsp.width1}", "AstGtS {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castLteS}", "AstGtS {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castGt, $lhsp.width1}", "AstLte {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castGt}", "AstLte {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castGtS, $lhsp.width1}", "AstLteS{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castGtS}", "AstLteS{$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castGte, $lhsp.width1}", "AstLt {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castGte}", "AstLt {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castGteS, $lhsp.width1}", "AstLtS {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castGteS}", "AstLtS {$lhsp->op1p(),$lhsp->op2p()}"); // Not common, but avoids compiler warnings about over shifting TREEOP ("AstShiftL{operandHugeShiftL(nodep)}", "replaceZero(nodep)"); TREEOP ("AstShiftR{operandHugeShiftR(nodep)}", "replaceZero(nodep)"); TREEOP ("AstShiftL{operandShiftOp(nodep)}", "replaceShiftOp(nodep)"); TREEOP ("AstShiftR{operandShiftOp(nodep)}", "replaceShiftOp(nodep)"); TREEOP ("AstShiftL{operandShiftShift(nodep)}", "replaceShiftShift(nodep)"); TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)"); TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)"); // Compress out EXTENDs to appease loop unroller TREEOPV("AstEq {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE"); TREEOPV("AstNeq {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE"); TREEOPV("AstGt {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE"); TREEOPV("AstGte {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE"); TREEOPV("AstLt {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE"); TREEOPV("AstLte {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE"); TREEOPV("AstEq {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceZero(nodep)"); TREEOPV("AstNeq {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceNum(nodep,1)"); TREEOPV("AstGt {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceNum(nodep,1)"); TREEOPV("AstGte {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceNum(nodep,1)"); TREEOPV("AstLt {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceZero(nodep)"); TREEOPV("AstLte {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceZero(nodep)"); // Identical operands on both sides // AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules // AstAdd->ShiftL(#,1) but uncommon TREEOP ("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)"); TREEOP ("AstChangeXor{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)"); TREEOP ("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstXnor {operandsSame($lhsp,,$rhsp)}", "replaceAllOnes(nodep)"); TREEOP ("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X. TREEOP ("AstEqD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X. TREEOP ("AstEqN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X. TREEOP ("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstGtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstGtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstGteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstGteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstLteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstLteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstNeqD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstNeqN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)"); TREEOP ("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)"); ///=== Verilog operators // Comparison against 1'b0/1'b1; must be careful about widths. // These use Not, so must be Verilog only TREEOPV("AstEq {$rhsp.width1, $lhsp.isZero, $rhsp}", "AstNot{$rhsp}"); TREEOPV("AstEq {$lhsp.width1, $lhsp, $rhsp.isZero}", "AstNot{$lhsp}"); TREEOPV("AstEq {$rhsp.width1, $lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)"); TREEOPV("AstEq {$lhsp.width1, $lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)"); TREEOPV("AstNeq {$rhsp.width1, $lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOPV("AstNeq {$lhsp.width1, $lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOPV("AstNeq {$rhsp.width1, $lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}"); TREEOPV("AstNeq {$lhsp.width1, $lhsp, $rhsp.isAllOnes}", "AstNot{$lhsp}"); TREEOPV("AstLt {$rhsp.width1, $lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); // Because not signed #s TREEOPV("AstGt {$lhsp.width1, $lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); // Because not signed #s // Useful for CONDs added around ARRAYSEL's in V3Case step TREEOPV("AstLte {$lhsp->width()==$rhsp->width(), $rhsp.isAllOnes}", "replaceNum(nodep,1)"); // Simplify reduction operators // This also gets &{...,0,....} => const 0 (Common for unused_ok signals) TREEOPV("AstRedAnd{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)"); TREEOPV("AstRedOr {$lhsp, $lhsp.width1}", "replaceWLhs(nodep)"); TREEOPV("AstRedXor{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)"); TREEOPV("AstRedAnd{$lhsp.castConcat}", "AstAnd{AstRedAnd{$lhsp->castConcat()->lhsp()}, AstRedAnd{$lhsp->castConcat()->rhsp()}}"); // &{a,b} => {&a}&{&b} TREEOPV("AstRedOr {$lhsp.castConcat}", "AstOr {AstRedOr {$lhsp->castConcat()->lhsp()}, AstRedOr {$lhsp->castConcat()->rhsp()}}"); // |{a,b} => {|a}|{|b} TREEOPV("AstRedXor{$lhsp.castConcat}", "AstXor{AstRedXor{$lhsp->castConcat()->lhsp()}, AstRedXor{$lhsp->castConcat()->rhsp()}}"); // ^{a,b} => {^a}^{^b} TREEOPV("AstRedAnd{$lhsp.castExtend, $lhsp->width() > $lhsp->castExtend()->lhsp()->width()}", "replaceZero(nodep)"); // &{0,...} => 0 Prevents compiler limited range error TREEOPV("AstRedOr {$lhsp.castExtend}", "AstRedOr {$lhsp->castExtend()->lhsp()}"); TREEOPV("AstRedXor{$lhsp.castExtend}", "AstRedXor{$lhsp->castExtend()->lhsp()}"); TREEOPV("AstOneHot{$lhsp.width1}", "replaceWLhs(nodep)"); TREEOPV("AstOneHot0{$lhsp.width1}", "replaceNum(nodep,1)"); // Binary AND/OR is faster than logical and/or (usually) TREEOPV("AstLogAnd{$lhsp.width1, $rhsp.width1, isTPure($lhsp), isTPure($rhsp)}", "AstAnd{$lhsp,$rhsp}"); TREEOPV("AstLogOr {$lhsp.width1, $rhsp.width1, isTPure($lhsp), isTPure($rhsp)}", "AstOr{$lhsp,$rhsp}"); TREEOPV("AstLogNot{$lhsp.width1, isTPure($lhsp)}", "AstNot{$lhsp}"); // CONCAT(CONCAT({a},{b}),{c}) -> CONCAT({a},CONCAT({b},{c})) // CONCAT({const},CONCAT({const},{c})) -> CONCAT((constifiedCONC{const|const},{c})) TREEOPV("AstConcat{operandConcatMove(nodep)}", "moveConcat(nodep)"); TREEOPV("AstConcat{$lhsp.isZero, $rhsp}", "replaceExtend(nodep, nodep->rhsp())"); // CONCAT(a[1],a[0]) -> a[1:0] TREEOPV("AstConcat{$lhsp.castSel, $rhsp.castSel, ifAdjacentSel($lhsp->castSel(),,$rhsp->castSel())}", "replaceConcatSel(nodep)"); TREEOPV("AstConcat{ifConcatMergeableBiop($lhsp), concatMergeable($lhsp,,$rhsp)}", "replaceConcatMerge(nodep)"); // Common two-level operations that can be simplified TREEOP ("AstAnd {$lhsp.castOr, $rhsp.castOr, operandAndOrSame(nodep)}", "replaceAndOr(nodep)"); TREEOP ("AstOr {$lhsp.castAnd,$rhsp.castAnd,operandAndOrSame(nodep)}", "replaceAndOr(nodep)"); TREEOP ("AstOr {matchOrAndNot(nodep)}", "DONE"); TREEOP ("AstAnd {operandShiftSame(nodep)}", "replaceShiftSame(nodep)"); TREEOP ("AstOr {operandShiftSame(nodep)}", "replaceShiftSame(nodep)"); TREEOP ("AstXor {operandShiftSame(nodep)}", "replaceShiftSame(nodep)"); // "AstXnor{operandShiftSame(nodep)}", // Cannot ShiftSame as the shifted-in zeros might create a one // Note can't simplify a extend{extends}, extends{extend}, as the sign bits end up in the wrong places TREEOPV("AstExtend {$lhsp.castExtend}", "replaceExtend(nodep, nodep->lhsp()->castExtend()->lhsp())"); TREEOPV("AstExtendS{$lhsp.castExtendS}", "replaceExtend(nodep, nodep->lhsp()->castExtendS()->lhsp())"); TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs TREEOPV("AstReplicateN{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs TREEOPV("AstReplicate{$lhsp.castReplicate, operandRepRep(nodep)}", "DONE"); // {2{3{lhs}}}->{6{lhs}} TREEOPV("AstConcat{operandConcatSame(nodep)}", "DONE"); // {a,a}->{2{a}}, {a,2{a}}->{3{a}, etc // 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"); TREEOPV("AstSel{$fromp.castShiftR, operandSelShiftLower(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.castConst, operandSelReplicate(nodep) }", "DONE"); // 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) { // Default: Just iterate if (m_required) { if (nodep->castNodeDType() || nodep->castRange()) { // Ignore dtypes for parameter type pins } else { 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 explicit ConstVisitor(ProcMode pmode) { m_params = false; m_required = false; m_doExpensive = false; m_doNConst = false; m_doShort = true; // Presently always done m_doV = false; m_doGenerate = false; // Inside generate conditionals m_warn = false; m_wremove = true; // Overridden in visitors m_modp = NULL; m_selp = NULL; m_scopep = NULL; m_attrp = NULL; // switch (pmode) { case PROC_PARAMS: m_doV = true; m_doNConst = true; m_params = true; m_required = true; break; case PROC_GENERATE: m_doV = true; m_doNConst = true; m_params = true; m_required = true; m_doGenerate = true; break; case PROC_LIVE: break; case PROC_V_WARN: m_doV = true; m_doNConst = true; m_warn = true; break; case PROC_V_NOWARN: m_doV = true; m_doNConst = true; break; case PROC_V_EXPENSIVE: m_doV = true; m_doNConst = true; m_doExpensive = true; break; case PROC_CPP: m_doV = false; m_doNConst = true; break; default: v3fatalSrc("Bad case"); break; } } virtual ~ConstVisitor() {} AstNode* mainAcceptEdit(AstNode* nodep) { // Operate starting at a random place return nodep->iterateSubtreeReturnEdits(*this); } }; //###################################################################### // Const class functions //! Force this cell node's parameter list to become a constant //! @return Pointer to the edited node. AstNode* V3Const::constifyParamsEdit(AstNode* nodep) { //if (debug()>0) nodep->dumpTree(cout," forceConPRE : "); // Resize even if the node already has a width, because buried in the tree // we may have a node we just created with signing, etc, that isn't sized yet. // Make sure we've sized everything first nodep = V3Width::widthParamsEdit(nodep); ConstVisitor visitor(ConstVisitor::PROC_PARAMS); if (AstVar* varp=nodep->castVar()) { // If a var wants to be constified, it's really a param, and // we want the value to be constant. We aren't passed just the // init value because we need widthing above to handle the var's type. if (varp->valuep()) visitor.mainAcceptEdit(varp->valuep()); } else { nodep = visitor.mainAcceptEdit(nodep); } // Because we do edits, nodep links may get trashed and core dump this. //if (debug()>0) nodep->dumpTree(cout," forceConDONE: "); return nodep; } //! Force this cell node's parameter list to become a constant inside generate. //! If we are inside a generated "if", "case" or "for", we don't want to //! trigger warnings when we deal with the width. It is possible that these //! are spurious, existing within sub-expressions that will not actually be //! generated. Since such occurrences, must be constant, in order to be //! someting a generate block can depend on, we can wait until later to do the //! width check. //! @return Pointer to the edited node. AstNode* V3Const::constifyGenerateParamsEdit(AstNode* nodep) { //if (debug()>0) nodep->dumpTree(cout," forceConPRE : "); // Resize even if the node already has a width, because buried in the tree // we may have a node we just created with signing, etc, that isn't sized // yet. // Make sure we've sized everything first nodep = V3Width::widthGenerateParamsEdit(nodep); ConstVisitor visitor(ConstVisitor::PROC_GENERATE); if (AstVar* varp=nodep->castVar()) { // If a var wants to be constified, it's really a param, and // we want the value to be constant. We aren't passed just the // init value because we need widthing above to handle the var's type. if (varp->valuep()) visitor.mainAcceptEdit(varp->valuep()); } else { nodep = visitor.mainAcceptEdit(nodep); } // Because we do edits, nodep links may get trashed and core dump this. //if (debug()>0) nodep->dumpTree(cout," forceConDONE: "); return nodep; } void V3Const::constifyAllLint(AstNetlist* nodep) { // Only call from Verilator.cpp, as it uses user#'s UINFO(2,__FUNCTION__<<": "<= 3); } void V3Const::constifyCpp(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } AstNode* V3Const::constifyEdit(AstNode* nodep) { ConstVisitor visitor (ConstVisitor::PROC_V_NOWARN); nodep = visitor.mainAcceptEdit(nodep); return nodep; } void V3Const::constifyAllLive(AstNetlist* nodep) { // Only call from Verilator.cpp, as it uses user#'s // This only pushes constants up, doesn't make any other edits // IE doesn't prune dead statements, as we need to do some usability checks after this UINFO(2,__FUNCTION__<<": "<= 3); } void V3Const::constifyAll(AstNetlist* nodep) { // Only call from Verilator.cpp, as it uses user#'s UINFO(2,__FUNCTION__<<": "<= 3); } AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) { ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE); nodep = visitor.mainAcceptEdit(nodep); return nodep; } verilator-3.916/src/V3Active.cpp0000664000177100017500000003567713205574202016461 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity active domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Active's Transformations: // // Note this can be called multiple times. // Create a IACTIVE(initial), SACTIVE(combo) // ALWAYS: Remove any-edges from sense list // If no POS/NEG in senselist, Fold into SACTIVE(combo) // Else fold into SACTIVE(sequent). // OPTIMIZE: When support async clocks, fold into that active if possible // INITIAL: Move into IACTIVE // WIRE: Move into SACTIVE(combo) // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Active.h" #include "V3Ast.h" #include "V3EmitCBase.h" #include "V3Const.h" //***** See below for main transformation engine //###################################################################### // Collect existing active names class ActiveBaseVisitor : public AstNVisitor { protected: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; class ActiveNamer : public ActiveBaseVisitor { private: typedef std::map ActiveNameMap; // STATE AstScope* m_scopep; // Current scope to add statement to AstActive* m_iActivep; // For current scope, the IActive we're building AstActive* m_cActivep; // For current scope, the SActive(combo) we're building vector m_activeVec; // List of sensitive actives, for folding // METHODS void addActive(AstActive* nodep) { if (!m_scopep) nodep->v3fatalSrc("NULL scope"); m_scopep->addActivep(nodep); } // VISITORS virtual void visit(AstScope* nodep) { 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) { // Simplify sensitivity list V3Const::constifyExpensiveEdit(nodep); VL_DANGLING(nodep); } // Empty visitors, speed things up virtual void visit(AstNodeStmt* nodep) { } //-------------------- // Default virtual void visit(AstNode* nodep) { // Default: Just iterate nodep->iterateChildren(*this); } // METHODS public: AstScope* scopep() { return m_scopep; } AstActive* getCActive(FileLine* fl) { if (!m_cActivep) { m_cActivep = new AstActive(fl, "combo", new AstSenTree(fl, new AstSenItem(fl,AstSenItem::Combo()))); m_cActivep->sensesStorep(m_cActivep->sensesp()); addActive(m_cActivep); } return m_cActivep; } AstActive* getIActive(FileLine* fl) { if (!m_iActivep) { m_iActivep = new AstActive(fl, "initial", new AstSenTree(fl, new AstSenItem(fl,AstSenItem::Initial()))); m_iActivep->sensesStorep(m_iActivep->sensesp()); addActive(m_iActivep); } return m_iActivep; } AstActive* getActive(FileLine* fl, AstSenTree* sensesp) { // Return a sentree in this scope that matches given sense list. // Not the fastest, but scopes tend to have few clocks AstActive* activep = NULL; //sitemsp->dumpTree(cout," Lookingfor: "); for (vector::iterator it = m_activeVec.begin(); it!=m_activeVec.end(); ++it) { activep = *it; if (activep) { // Not deleted // Compare the list AstSenTree* asenp = activep->sensesp(); if (asenp->sameTree(sensesp)) { UINFO(8," Found ACTIVE "<cloneTree(false); activep = new AstActive(fl, "sequent", newsenp); activep->sensesStorep(activep->sensesp()); UINFO(8," New ACTIVE "<accept(*this); } }; //###################################################################### // Active AssignDly replacement functions class ActiveDlyVisitor : public ActiveBaseVisitor { public: enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL, CT_LATCH }; private: CheckType m_check; // Combo logic or other AstNode* m_alwaysp; // Always we're under AstNode* m_assignp; // In assign // VISITORS virtual void visit(AstAssignDly* nodep) { if (m_check != CT_SEQ) { // Convert to a non-delayed assignment UINFO(5," ASSIGNDLY "<v3warn(INITIALDLY,"Delayed assignments (<=) in initial or final block; suggest blocking assignments (=)."); } else if (m_check == CT_LATCH) { // Suppress. Shouldn't matter that the interior of the latch races } else { nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=)."); } AstNode* newp = new AstAssign (nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } } virtual void visit(AstAssign* nodep) { if (m_check == CT_SEQ) { AstNode* las = m_assignp; m_assignp = nodep; nodep->lhsp()->iterateAndNext(*this); m_assignp = las; } } virtual void visit(AstVarRef* nodep) { 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) { 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) { // Create required actives and add to scope UINFO(4," SCOPE "<iterateChildren(*this); } virtual void visit(AstActive* nodep) { // Actives are being formed, so we can ignore any already made } virtual void visit(AstInitial* nodep) { // Relink to IACTIVE, unless already under it UINFO(4," INITIAL "<fileline()); nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); } virtual void visit(AstAssignAlias* nodep) { // Relink to CACTIVE, unless already under it UINFO(4," ASSIGNW "<fileline()); nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); } virtual void visit(AstAssignW* nodep) { // Relink to CACTIVE, unless already under it UINFO(4," ASSIGNW "<fileline()); nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); } virtual void visit(AstCoverToggle* nodep) { // Relink to CACTIVE, unless already under it UINFO(4," COVERTOGGLE "<fileline()); nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); } virtual void visit(AstFinal* nodep) { // Relink to CFUNC for the final UINFO(4," FINAL "<bodysp()) { // Empty, Kill it. nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); 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(); VL_DANGLING(nodep); } // METHODS void visitAlways(AstNode* nodep, AstSenTree* oldsensesp, VAlwaysKwd kwd) { // Move always to appropriate ACTIVE based on its sense list if (oldsensesp && oldsensesp->sensesp() && oldsensesp->sensesp()->castSenItem() && oldsensesp->sensesp()->castSenItem()->isNever()) { // Never executing. Kill it. if (oldsensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated."); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); return; } // Read sensitivitues m_itemCombo = false; m_itemSequent = false; if (oldsensesp) oldsensesp->iterateAndNext(*this); bool combo = m_itemCombo; bool sequent = m_itemSequent; if (!combo && !sequent) combo=true; // If no list, Verilog 2000: always @ (*) if (combo && sequent) { if (!v3Global.opt.bboxUnsup()) { nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list"); } sequent = false; } AstActive* wantactivep = NULL; if (combo && !sequent) { // Combo: Relink to ACTIVE(combo) wantactivep = m_namer.getCActive(nodep->fileline()); } else { // Sequential: Build a ACTIVE(name) // OPTIMIZE: We could substitute a constant for things in the sense list, for example // always (posedge RESET) { if (RESET).... } we know RESET is true. // Summarize a long list of combo inputs as just "combo" #ifndef __COVERITY__ // Else dead code on next line. if (combo) oldsensesp->addSensesp (new AstSenItem(nodep->fileline(),AstSenItem::Combo())); #endif wantactivep = m_namer.getActive(nodep->fileline(), oldsensesp); } // Delete sensitivity list if (oldsensesp) { oldsensesp->unlinkFrBackWithNext()->deleteTree(); VL_DANGLING(oldsensesp); } // Move node to new active nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); // Warn and/or convert any delayed assignments if (combo && !sequent) { if (kwd == VAlwaysKwd::ALWAYS_LATCH) { ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_LATCH); } else { ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_COMBO); } } else if (!combo && sequent) { ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_SEQ); } } virtual void visit(AstAlways* nodep) { // 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(); VL_DANGLING(nodep); return; } visitAlways(nodep, nodep->sensesp(), nodep->keyword()); } virtual void visit(AstAlwaysPublic* nodep) { // Move always to appropriate ACTIVE based on its sense list UINFO(4," ALWPub "<=9) nodep->dumpTree(cout," Alw: "); visitAlways(nodep, nodep->sensesp(), VAlwaysKwd::ALWAYS); } virtual void visit(AstSenGate* nodep) { 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) { 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(); VL_DANGLING(nodep); } 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) {} virtual void visit(AstVarScope* nodep) {} //-------------------- virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit ActiveVisitor(AstNetlist* nodep) { m_scopeFinalp = NULL; m_itemCombo = false; m_itemSequent = false; nodep->accept(*this); } virtual ~ActiveVisitor() {} }; //###################################################################### // Active class functions void V3Active::activeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3ParseImp.cpp0000664000177100017500000001431013205574202016743 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // Overview of files involved in parsing // V3Parse.h External consumer interface to V3ParseImp // V3ParseImp Internals to parser, common to across flex & bison // V3ParseGrammar Wrapper that includes V3ParseBison // V3ParseBison Bison output // V3ParseLex Wrapper that includes lex output // V3Lexer.yy.cpp Flex output //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Error.h" #include "V3Global.h" #include "V3Os.h" #include "V3Ast.h" #include "V3File.h" #include "V3ParseImp.h" #include "V3PreShell.h" //====================================================================== // Globals V3ParseImp* V3ParseImp::s_parsep = NULL; int V3ParseSym::s_anonNum = 0; //###################################################################### // Read class functions V3ParseImp::~V3ParseImp() { for (deque::iterator it = m_stringps.begin(); it != m_stringps.end(); ++it) { delete (*it); } m_stringps.clear(); for (deque::iterator it = m_numberps.begin(); it != m_numberps.end(); ++it) { delete (*it); } m_numberps.clear(); lexDestroy(); parserClear(); if (debug()>=9) { UINFO(0,"~V3ParseImp\n"); symp()->dump(cout, "-vpi: "); } } size_t V3ParseImp::ppInputToLex(char* buf, size_t max_size) { size_t got = 0; while (got < max_size // Haven't got enough && !m_ppBuffers.empty()) { // And something buffered string front = m_ppBuffers.front(); m_ppBuffers.pop_front(); size_t len = front.length(); if (len > (max_size-got)) { // Front string too big string remainder = front.substr(max_size-got); front = front.substr(0, max_size-got); m_ppBuffers.push_front(remainder); // Put back remainder for next time len = (max_size-got); } strncpy(buf+got, front.c_str(), len); got += len; } if (debug()>=9) { string out = string(buf,got); cout<<" inputToLex got="<ext+ options since it was first ecountered. FileLine *modfileline = new FileLine (modfilename, 0); modfileline->language(v3Global.opt.fileLanguage(modfilename)); ppPushText((string)"`begin_keywords \""+modfileline->language().ascii()+"\"\n"); } // Preprocess into m_ppBuffer bool ok = V3PreShell::preproc(fileline, modfilename, m_filterp, this, errmsg); if (!ok) { if (errmsg != "") return; // Threw error already // Create fake node for later error reporting AstNodeModule* nodep = new AstNotFoundModule(fileline, modname); v3Global.rootp()->addModulep(nodep); return; } if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) { // Create output file with all the preprocessor output we buffered up string vppfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_"+modname+".vpp"; ofstream* ofp = NULL; ostream* osp; bool noblanks = v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine(); if (v3Global.opt.preprocOnly()) { osp = &cout; } else { osp = ofp = V3File::new_ofstream(vppfilename); } if (osp->fail()) { fileline->v3error("Cannot write preprocessor output: "+vppfilename); return; } else { for (deque::iterator it = m_ppBuffers.begin(); it!=m_ppBuffers.end(); ++it) { if (noblanks) { bool blank = true; for (string::iterator its = it->begin(); its != it->end(); ++its) { if (!isspace(*its) && *its!='\n') { blank=false; break; } } if (blank) continue; } *osp << *it; } if (ofp) { ofp->close(); delete ofp; VL_DANGLING(ofp); } } } // Parse it if (!v3Global.opt.preprocOnly()) { lexFile (modfilename); } else { m_ppBuffers.clear(); } } 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) { if (text != "") impp->ppPushText(text); } verilator-3.916/src/V3Options.cpp0000664000177100017500000013356113205574202016670 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Options parsing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #ifndef _WIN32 # include #endif #include #include #include #include #include #include #include #include #include "V3Global.h" #include "V3String.h" #include "V3Os.h" #include "V3Options.h" #include "V3Error.h" #include "V3File.h" #include "V3PreShell.h" #include "config_rev.h" //###################################################################### // V3 Internal state class V3OptionsImp { public: // TYPES typedef std::map > DirMap; // Directory listing // STATE list m_allArgs; // List of every argument encountered list m_incDirUsers; // Include directories (ordered) set m_incDirUserSet; // Include directories (for removing duplicates) list m_incDirFallbacks; // Include directories (ordered) set m_incDirFallbackSet; // Include directories (for removing duplicates) map m_langExts; // Language extension map list m_libExtVs; // Library extensions (ordered) set m_libExtVSet; // Library extensions (for removing duplicates) DirMap m_dirMap; // Directory listing // ACCESSOR METHODS void addIncDirUser(const string& incdir) { if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) { m_incDirUserSet.insert(incdir); m_incDirUsers.push_back(incdir); m_incDirFallbacks.remove(incdir); // User has priority over Fallback m_incDirFallbackSet.erase(incdir); // User has priority over Fallback } } void addIncDirFallback(const string& incdir) { if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) { // User has priority over Fallback if (m_incDirFallbackSet.find(incdir) == m_incDirFallbackSet.end()) { m_incDirFallbackSet.insert(incdir); m_incDirFallbacks.push_back(incdir); } } } void addLangExt(const string& langext, const V3LangCode& lc) { // New language extension replaces any pre-existing one. (void)m_langExts.erase(langext); m_langExts[langext] = lc; } void addLibExtV(const string& libext) { if (m_libExtVSet.find(libext) == m_libExtVSet.end()) { m_libExtVSet.insert(libext); m_libExtVs.push_back(libext); } } V3OptionsImp() {} ~V3OptionsImp() {} }; void V3Options::addIncDirUser(const string& incdir) { m_impp->addIncDirUser(incdir); } void V3Options::addIncDirFallback(const string& incdir) { m_impp->addIncDirFallback(incdir); } void V3Options::addLangExt(const string& langext, const V3LangCode& lc) { m_impp->addLangExt(langext, lc); } void V3Options::addLibExtV(const string& libext) { m_impp->addLibExtV(libext); } void V3Options::addDefine(const string& defline, bool allowPlus) { // Split +define+foo=value into the appropriate parts and parse // Optional + says to allow multiple defines on the line // + is not quotable, as other simulators do not allow that string left = defline; while (left != "") { string def = left; string::size_type pos; if (allowPlus && ((pos=left.find("+")) != string::npos)) { left = left.substr(pos+1); def.erase(pos); } else { left = ""; } string value; if ((pos=def.find("=")) != string::npos) { value = def.substr(pos+1); def.erase(pos); } V3PreShell::defineCmdLine(def,value); } } void V3Options::addParameter(const string& paramline, bool allowPlus) { // Split +define+foo=value into the appropriate parts and parse // Optional + says to allow multiple defines on the line // + is not quotable, as other simulators do not allow that string left = paramline; while (left != "") { string param = left; string::size_type pos; if (allowPlus && ((pos=left.find("+")) != string::npos)) { left = left.substr(pos+1); param.erase(pos); } else { left = ""; } string value; if ((pos=param.find("=")) != string::npos) { value = param.substr(pos+1); param.erase(pos); } UINFO(4,"Add parameter"<second; m_parameters.erase(m_parameters.find(name)); return value; } void V3Options::checkParameters() { if (!m_parameters.empty()) { stringstream msg; msg << "Parameters from the command line were not found in the design:"; for (map::iterator it = m_parameters.begin(); it != m_parameters.end(); ++it) { msg << " " << it->first; } v3fatal(msg.str()<m_allArgs.push_back(arg); } string V3Options::allArgsString() { string out; for (list::iterator it=m_impp->m_allArgs.begin(); it!=m_impp->m_allArgs.end(); ++it) { if (out != "") out += " "; out += *it; } return out; } //###################################################################### // V3LangCode class functions V3LangCode::V3LangCode (const char* textp) { // Return code for given string, or ERROR, which is a bad code for (int codei=V3LangCode::L_ERROR; codei0) ::close(fd); } } string V3Options::fileExists (const string& filename) { // Surprisingly, for VCS and other simulators, this process // is quite slow; presumably because of re-reading each directory // many times. So we read a whole dir at once and cache it string dir = V3Os::filenameDir(filename); string basename = V3Os::filenameNonDir(filename); V3OptionsImp::DirMap::iterator diriter = m_impp->m_dirMap.find(dir); if (diriter == m_impp->m_dirMap.end()) { // Read the listing m_impp->m_dirMap.insert(make_pair(dir, set() )); diriter = m_impp->m_dirMap.find(dir); set* setp = &(diriter->second); if (DIR* dirp = opendir(dir.c_str())) { while (struct dirent* direntp = readdir(dirp)) { setp->insert(direntp->d_name); } closedir(dirp); } } // Find it set* filesetp = &(diriter->second); set::iterator fileiter = filesetp->find(basename); if (fileiter == filesetp->end()) { return ""; // Not found } // Check if it is a directory, ignore if so string filenameOut = V3Os::filenameFromDirBase (dir, basename); if (!fileStatNormal(filenameOut)) return ""; // Directory return filenameOut; } string V3Options::filePathCheckOneDir(const string& modname, const string& dirname) { for (list::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) { string fn = V3Os::filenameFromDirBase(dirname, modname+*extIter); string exists = fileExists(fn); if (exists!="") { // Strip ./, it just looks ugly if (exists.substr(0,2)=="./") exists.erase(0,2); return exists; } } return ""; } string V3Options::filePath (FileLine* fl, const string& modname, const string& lastpath, 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; } if (m_relativeIncludes) { string exists = filePathCheckOneDir(modname, lastpath); if (exists!="") return V3Os::filenameRealPath(exists); } // Warn and return not found if (errmsg != "") { fl->v3error(errmsg+modname); filePathLookedMsg(fl, modname); } return ""; } void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) { static bool shown_notfound_msg = false; if (!shown_notfound_msg) { shown_notfound_msg = true; if (m_impp->m_incDirUsers.empty()) { fl->v3error("This may be because there's no search path specified with -I."<v3error("Looked in:"<::iterator dirIter=m_impp->m_incDirUsers.begin(); dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) { for (list::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) { string fn = V3Os::filenameFromDirBase(*dirIter,modname+*extIter); fl->v3error(" "<::iterator dirIter=m_impp->m_incDirFallbacks.begin(); dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) { for (list::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) { string fn = V3Os::filenameFromDirBase(*dirIter,modname+*extIter); fl->v3error(" "<::iterator it = m_impp->m_langExts.find(ext); if (it != m_impp->m_langExts.end()) { return it->second; } } return m_defaultLanguage; } //###################################################################### // Environment string V3Options::getenvBuiltins(const string& var) { if (var == "PERL") return getenvPERL(); else if (var == "SYSTEMC") return getenvSYSTEMC(); else if (var == "SYSTEMC_ARCH") return getenvSYSTEMC_ARCH(); else if (var == "SYSTEMC_INCLUDE") return getenvSYSTEMC_INCLUDE(); else if (var == "SYSTEMC_LIBDIR") return getenvSYSTEMC_LIBDIR(); else if (var == "VERILATOR_ROOT") return getenvVERILATOR_ROOT(); else { return V3Os::getenvStr(var,""); } } string V3Options::getenvPERL() { return V3Os::getenvStr("PERL","perl"); } string V3Options::getenvSYSTEMC() { string var = V3Os::getenvStr("SYSTEMC",""); if (var == "" && string(DEFENV_SYSTEMC) != "") { var = DEFENV_SYSTEMC; V3Os::setenvStr("SYSTEMC", var, "Hardcoded at build time"); } return var; } string V3Options::getenvSYSTEMC_ARCH() { string var = V3Os::getenvStr("SYSTEMC_ARCH",""); if (var == "" && string(DEFENV_SYSTEMC_ARCH) != "") { var = DEFENV_SYSTEMC_ARCH; V3Os::setenvStr("SYSTEMC_ARCH", var, "Hardcoded at build time"); } if (var == "") { #if defined (__MINGW32__) // Hardcoded with MINGW current version. Would like a better way. string sysname = "MINGW32_NT-5.0"; var = "mingw32"; #elif defined (_WIN32) string sysname = "WIN32"; var = "win32"; #else struct utsname uts; uname(&uts); string sysname = VString::downcase(uts.sysname); // aka 'uname -s' if (VString::wildmatch(sysname.c_str(), "*solaris*")) { var = "gccsparcOS5"; } else if (VString::wildmatch(sysname.c_str(), "*cygwin*")) { var ="cygwin"; } else { var = "linux"; } #endif V3Os::setenvStr("SYSTEMC_ARCH", var,"From sysname '"+sysname+"'"); } return var; } string V3Options::getenvSYSTEMC_INCLUDE() { string var = V3Os::getenvStr("SYSTEMC_INCLUDE",""); if (var == "" && string(DEFENV_SYSTEMC_INCLUDE) != "") { var = DEFENV_SYSTEMC_INCLUDE; V3Os::setenvStr("SYSTEMC_INCLUDE", var, "Hardcoded at build time"); } if (var == "") { string sc = getenvSYSTEMC(); if (sc != "") var = sc+"/include"; } // Only correct or check it if we really need the value if (v3Global.opt.usingSystemCLibs()) { if (var == "") { v3fatal("Need $SYSTEMC_INCLUDE in environment or when Verilator configured\n" "Probably System-C isn't installed, see http://www.systemc.org\n"); } } return var; } string V3Options::getenvSYSTEMC_LIBDIR() { string var = V3Os::getenvStr("SYSTEMC_LIBDIR",""); if (var == "" && string(DEFENV_SYSTEMC_LIBDIR) != "") { var = DEFENV_SYSTEMC_LIBDIR; V3Os::setenvStr("SYSTEMC_LIBDIR", var, "Hardcoded at build time"); } if (var == "") { string sc = getenvSYSTEMC(); string arch = getenvSYSTEMC_ARCH(); if (sc != "" && arch != "") var = sc+"/lib-"+arch; } // Only correct or check it if we really need the value if (v3Global.opt.usingSystemCLibs()) { if (var == "") { v3fatal("Need $SYSTEMC_LIBDIR in environment or when Verilator configured\n" "Probably System-C isn't installed, see http://www.systemc.org\n"); } } return var; } string V3Options::getenvVERILATOR_ROOT() { string var = V3Os::getenvStr("VERILATOR_ROOT",""); if (var == "" && string(DEFENV_VERILATOR_ROOT) != "") { var = DEFENV_VERILATOR_ROOT; V3Os::setenvStr("VERILATOR_ROOT", var, "Hardcoded at build time"); } if (var == "") { v3fatal("$VERILATOR_ROOT needs to be in environment\n"); } return var; } //###################################################################### // V3 Options accessors string V3Options::version() { string ver = DTVERSION; ver += " rev "+cvtToStr(DTVERSION_rev); return ver; } void V3Options::throwSigsegv() { #if !(defined(VL_CPPCHECK) || defined(__clang_analyzer__)) char* zp=NULL; *zp=0; // Intentional core dump, ignore warnings here #endif } //###################################################################### // V3 Options utilities string V3Options::argString (int argc, char** argv) { // Return list of arguments as simple string string opts; for (int i=0; i=1) m_prefix = string("V")+V3Os::filenameNonExt(*(vFilesList.begin())); if (modPrefix()=="") m_modPrefix = prefix(); // Find files in makedir addIncDirFallback(makeDir()); } //====================================================================== bool V3Options::onoff(const char* sw, const char* arg, bool& flag) { // if sw==arg, then return true (found it), and flag=true // if sw=="-no-arg", then return true (found it), and flag=false // if sw=="-noarg", then return true (found it), and flag=false // else return false if (arg[0]!='-') v3fatalSrc("OnOff switches must have leading dash"); if (0==strcmp(sw,arg)) { flag=true; return true; } else if (0==strncmp(sw,"-no",3) && (0==strcmp(sw+3,arg+1))) { flag=false; return true; } else if (0==strncmp(sw,"-no-",4) && (0==strcmp(sw+4,arg+1))) { flag=false; return true; } return false; } bool V3Options::suffixed(const string& sw, const char* arg) { if (strlen(arg) > sw.length()) return false; return (0==strcmp(sw.c_str()+sw.length()-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: "< 65) fl->v3fatal("--pins-bv maximum is 65: "<v3fatal("--threads must be >= 0: "<v3fatal("Unknown setting for --x-assign: "<v3fatal("Unknown setting for --x-initial: "<v3fatal ("Invalid Option: "< ifp (V3File::new_ifstream(filename)); if (ifp->fail()) { fl->v3error("Cannot open -f command file: "+filename); return; } string whole_file; bool inCmt = false; while (!ifp->eof()) { string line; getline(*ifp, line); // Strip simple comments string oline; // cppcheck-suppress StlMissingComparison for (string::const_iterator pos = line.begin(); pos != line.end(); ++pos) { if (inCmt) { if (*pos=='*' && *(pos+1)=='/') { inCmt = false; ++pos; } } else if (*pos=='/' && *(pos+1)=='/') { break; // Ignore to EOL } else if (*pos=='/' && *(pos+1)=='*') { inCmt = true; // cppcheck-suppress StlMissingComparison ++pos; } else { oline += *pos; } } whole_file += oline + " "; } whole_file += "\n"; // So string match below is simplified if (inCmt) fl->v3error("Unterminated /* comment inside -f file."); fl = new FileLine(filename, 0); // Split into argument list and process // Note we don't respect quotes. It seems most simulators dont. // Woez those that expect it; we'll at least complain. if (whole_file.find("\"") != string::npos) { fl->v3error("Double quotes in -f files cause unspecified behavior."); } // Strip off arguments and parse into words vector args; string::size_type startpos = 0; while (startpos < whole_file.length()) { while (isspace(whole_file[startpos])) ++startpos; string::size_type endpos = startpos; while (endpos < whole_file.length() && !isspace(whole_file[endpos])) ++endpos; if (startpos != endpos) { string arg (whole_file, startpos, endpos-startpos); args.reserve(args.size()+1); args.push_back(arg); } startpos = endpos; } // Path string optdir = (rel ? V3Os::filenameDir(filename) : "."); // Convert to argv style arg list and parse them char* argv [args.size()+1]; for (unsigned i=0; isecond = level; } else { m_debugSrcs.insert(make_pair(srcfile,level)); } } int V3Options::debugSrcLevel(const string& srcfile_path, int default_level) { // For simplicity, calling functions can just use __FILE__ for srcfile. // That means though we need to cleanup the filename from ../Foo.cpp -> Foo string srcfile = V3Os::filenameNonDirExt(srcfile_path); DebugSrcMap::iterator iter = m_debugSrcs.find(srcfile); if (iter!=m_debugSrcs.end()) { return iter->second; } else { return default_level; } } void V3Options::setDumpTreeLevel(const string& srcfile, int level) { DebugSrcMap::iterator iter = m_dumpTrees.find(srcfile); if (iter!=m_dumpTrees.end()) { iter->second = level; } else { m_dumpTrees.insert(make_pair(srcfile,level)); } } int V3Options::dumpTreeLevel(const string& srcfile_path) { // For simplicity, calling functions can just use __FILE__ for srcfile. // That means though we need to cleanup the filename from ../Foo.cpp -> Foo string srcfile = V3Os::filenameNonDirExt(srcfile_path); DebugSrcMap::iterator iter = m_dumpTrees.find(srcfile); if (iter!=m_dumpTrees.end()) { return iter->second; } else { return m_dumpTree; } } void V3Options::optimize(int level) { // Set all optimizations to on/off bool flag = level > 0; m_oAcycSimp = flag; m_oCase = flag; m_oCombine = flag; m_oConst = flag; m_oExpand = flag; m_oFlopGater = flag; m_oGate = flag; m_oInline = flag; m_oLife = flag; m_oLifePost = flag; m_oLocalize = flag; m_oReorder = flag; m_oSplit = flag; m_oSubst = flag; m_oSubstConst = flag; m_oTable = flag; m_oDedupe = flag; m_oAssemble = flag; // And set specific optimization levels if (level >= 3) { m_inlineMult = -1; // Maximum inlining } } verilator-3.916/src/V3GraphAlg.h0000664000177100017500000000322713205574202016362 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3WidthCommit.h0000664000177100017500000001416013205574202017123 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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. /// This step is only called on real V3Width, not intermediate e.g. widthParams class WidthRemoveVisitor : public AstNVisitor { private: // VISITORS virtual void visit(AstSigned* nodep) { replaceWithSignedVersion(nodep, nodep->lhsp()->unlinkFrBack()); VL_DANGLING(nodep); } virtual void visit(AstUnsigned* nodep) { replaceWithSignedVersion(nodep, nodep->lhsp()->unlinkFrBack()); VL_DANGLING(nodep); } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } void replaceWithSignedVersion(AstNode* nodep, AstNode* newp) { UINFO(6," Replace "<replaceWith(newp); newp->dtypeFrom(nodep); pushDeletep(nodep); VL_DANGLING(nodep); } public: // CONSTRUCTORS WidthRemoveVisitor() {} virtual ~WidthRemoveVisitor() {} AstNode* mainAcceptEdit(AstNode* nodep) { return nodep->iterateSubtreeReturnEdits(*this); } }; //###################################################################### // Now that all widthing is complete, // Copy all width() to widthMin(). V3Const expects this class WidthCommitVisitor : public AstNVisitor { // NODE STATE // AstVar::user1p -> bool, processed AstUser1InUse m_inuser1; public: // METHODS static AstConst* newIfConstCommitSize (AstConst* nodep) { if (((nodep->dtypep()->width() != nodep->num().width()) || !nodep->num().sized()) && !nodep->num().isString()) { // Need to force the number from unsized to sized V3Number num (nodep->fileline(), nodep->dtypep()->width()); num.opAssign(nodep->num()); num.isSigned(nodep->isSigned()); AstConst* newp = new AstConst(nodep->fileline(), num); newp->dtypeFrom(nodep); return newp; } else { return NULL; } } private: // METHODS void editDType(AstNode* nodep) { // Edit dtypes for this node nodep->dtypep(editOneDType(nodep->dtypep())); } AstNodeDType* editOneDType(AstNodeDType* nodep) { // See if the dtype/refDType can be converted to a standard one // This reduces the number of dtypes in the system, and since // dtypep() figures into sameTree() results in better optimizations if (!nodep) return NULL; // Recurse to handle the data type, as may change the size etc of this type if (!nodep->user1()) nodep->accept(*this); // Look for duplicate if (AstBasicDType* bdtypep = nodep->castBasicDType()) { AstBasicDType* newp = nodep->findInsertSameDType(bdtypep); if (newp != bdtypep && debug()>=9) { UINFO(9,"dtype replacement "); nodep->dumpSmall(cout); cout<<" ----> "; newp->dumpSmall(cout); cout<dtypep()) nodep->v3fatalSrc("No dtype"); nodep->dtypep()->accept(*this); // Do datatype first if (AstConst* newp = newIfConstCommitSize(nodep)) { nodep->replaceWith(newp); AstNode* oldp = nodep; nodep = newp; //if (debug()>4) oldp->dumpTree(cout," fixConstSize_old: "); //if (debug()>4) newp->dumpTree(cout," _new: "); pushDeletep(oldp); VL_DANGLING(oldp); } editDType(nodep); } virtual void visit(AstNodeDType* nodep) { visitIterateNodeDType(nodep); } virtual void visit(AstNodeClassDType* nodep) { if (nodep->user1SetOnce()) return; // Process once visitIterateNodeDType(nodep); nodep->clearCache(); } virtual void visit(AstParamTypeDType* nodep) { if (nodep->user1SetOnce()) return; // Process once visitIterateNodeDType(nodep); // Move to type table as all dtype pointers must resolve there nodep->unlinkFrBack(); // Make non-child v3Global.rootp()->typeTablep()->addTypesp(nodep); } 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) { // This check could go anywhere after V3Param nodep->v3fatalSrc("Presels should have been removed before this point"); } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); editDType(nodep); } public: // CONSTUCTORS explicit 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.916/src/V3Gate.h0000664000177100017500000000226113205574202015552 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Delayed.cpp0000664000177100017500000004626613205574202016611 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 // 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 typedef std::map ScopeVecMap; ScopeVecMap m_scopeVecMap; // Next var number for each scope // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void markVarUsage(AstVarScope* nodep, uint32_t flags) { //UINFO(4," MVU "<user5( nodep->user5() | flags ); if ((nodep->user5() & VU_DLY) && (nodep->user5() & VU_NONDLY)) { nodep->v3warn(BLKANDNBLK,"Unsupported: Blocked and non-blocking assignments to same variable: "<varp()->prettyName()); } } AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/, AstNodeDType* newdtypep) { // Because we've already scoped it, we may need to add both the AstVar and the AstVarScope if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped"); AstVar* varp; AstNodeModule* addmodp = oldvarscp->scopep()->modp(); // We need a new AstVar, but only one for all scopes, to match the new AstVarScope VarMap::iterator it = m_modVarMap.find(make_pair(addmodp,name)); if (it != m_modVarMap.end()) { // Created module's AstVar earlier under some other scope varp = it->second; } else { if (newdtypep) { varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, newdtypep); } else if (width==0) { varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp()); varp->dtypeFrom(oldvarscp); } else { // Used for vset and dimensions, so can zero init varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, VFlagBitPacked(), width); } addmodp->addStmtp(varp); m_modVarMap.insert(make_pair(make_pair(addmodp, name), varp)); } AstVarScope* varscp = new AstVarScope (oldvarscp->fileline(), oldvarscp->scopep(), varp); oldvarscp->scopep()->addVarp(varscp); return varscp; } AstActive* createActivePost(AstVarRef* varrefp) { AstActive* newactp = new AstActive (varrefp->fileline(), "sequentdly", m_activep->sensesp()); m_activep->addNext(newactp); return newactp; } void checkActivePost(AstVarRef* varrefp, AstActive* oldactivep) { // Check for MULTIDRIVEN, and if so make new sentree that joins old & new sentree if (!oldactivep) varrefp->v3fatalSrc("<= old dly assignment not put under sensitivity block"); if (oldactivep->sensesp() != m_activep->sensesp()) { if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN) && !varrefp->varp()->user2()) { varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks with different clocking: "<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->dtypep()->skipRefp()->castUnpackArrayDType()) nodep->v3fatalSrc("ArraySel with unpacked arrays 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"); if (!varrefp->varScopep()) varrefp->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp"); varrefp->unlinkFrBack(); AstVar* oldvarp = varrefp->varp(); int modVecNum = m_scopeVecMap[varrefp->varScopep()]++; // deque dimreadps; // Read value for each dimension of assignment for (unsigned dimension=0; dimensioncastConst()) { // bit = const, can just use it dimreadps.push_front(dimp); } else { string bitvarname = (string("__Vdlyvdim")+cvtToStr(dimension) +"__"+oldvarp->shortName()+"__v"+cvtToStr(modVecNum)); AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, dimp->width(), NULL); AstAssign* bitassignp = new AstAssign (nodep->fileline(), new AstVarRef(nodep->fileline(), bitvscp, true), dimp); nodep->addNextHere(bitassignp); dimreadps.push_front(new AstVarRef(nodep->fileline(), bitvscp, false)); } } // //=== Bitselect: __Vdlyvlsb__ AstNode* bitreadp=NULL; // Code to read Vdlyvlsb if (bitselp) { AstNode* lsbvaluep = bitselp->lsbp()->unlinkFrBack(); if (bitselp->fromp()->castConst()) {// vlsb = constant, can just push constant into where we use it bitreadp = lsbvaluep; } else { string bitvarname = (string("__Vdlyvlsb__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum)); AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, lsbvaluep->width(), NULL); AstAssign* bitassignp = new AstAssign (nodep->fileline(), new AstVarRef(nodep->fileline(), bitvscp, true), lsbvaluep); nodep->addNextHere(bitassignp); bitreadp = new AstVarRef(nodep->fileline(), bitvscp, false); } } // //=== Value: __Vdlyvval__ AstNode* valreadp; // Code to read Vdlyvval if (nodep->rhsp()->castConst()) { // vval = constant, can just push constant into where we use it valreadp = nodep->rhsp()->unlinkFrBack(); } else { string valvarname = (string("__Vdlyvval__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum)); AstVarScope* valvscp = createVarSc(varrefp->varScopep(), valvarname, 0, nodep->rhsp()->dtypep()); newlhsp = new AstVarRef(nodep->fileline(), valvscp, true); valreadp = new AstVarRef(nodep->fileline(), valvscp, false); } // //=== Setting/not setting boolean: __Vdlyvset__ AstVarScope* setvscp; AstAssignPre* setinitp = NULL; if (nodep->user3p()) { // Simplistic optimization. If the previous statement in same scope was also a =>, // then we told this nodep->user3 we can use its Vdlyvset rather than making a new one. // This is good for code like: // for (i=0; i<5; i++) vector[i] <= something; setvscp = nodep->user3p()->castVarScope(); ++m_statSharedSet; } else { // Create new one string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum)); setvscp = createVarSc(varrefp->varScopep(), setvarname, 1, NULL); setinitp = new AstAssignPre (nodep->fileline(), new AstVarRef(nodep->fileline(), setvscp, true), new AstConst(nodep->fileline(), 0)); AstAssign* setassignp = new AstAssign (nodep->fileline(), new AstVarRef(nodep->fileline(), setvscp, true), new AstConst(nodep->fileline(), V3Number(nodep->fileline(),1,true))); nodep->addNextHere(setassignp); } if (m_nextDlyp) { // Tell next assigndly it can share the variable m_nextDlyp->user3p(setvscp); } // // Create ALWAYSPOST for delayed variable // We add all logic to the same block if it's for the same memory // This insures that multiple assignments to the same memory will result // in correctly ordered code - the last assignment must be last. // It also has the nice side effect of assisting cache locality. AstNode* selectsp = varrefp; for (int dimension=int(dimreadps.size())-1; dimension>=0; --dimension) { selectsp = new AstArraySel(nodep->fileline(), selectsp, dimreadps[dimension]); } if (bitselp) { selectsp = new AstSel(nodep->fileline(), selectsp, bitreadp, bitselp->widthp()->cloneTree(false)); } // Build "IF (changeit) ... UINFO(9," For "<varScopep()->user4p()->castAlwaysPost(); if (finalp) { AstActive* oldactivep = finalp->user2p()->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() == setvscp) { // Optimize as above; if sharing Vdlyvset *ON SAME VARIABLE*, // we can share the IF statement too postLogicp = finalp->user4p()->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) { //VV***** We reset all userp() on the netlist m_modVarMap.clear(); nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep) { UINFO(4," MOD "<iterateChildren(*this); } virtual void visit(AstCFunc* nodep) { m_cfuncp = nodep; nodep->iterateChildren(*this); m_cfuncp = NULL; } virtual void visit(AstActive* nodep) { 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) { 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(BLKLOOPINIT,"Unsupported: Delayed assignment to array inside for loops (non-delayed is ok - see docs)"); if (newlhsp) { nodep->lhsp(newlhsp); } else { nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } lhsp->deleteTree(); VL_DANGLING(lhsp); } else { nodep->iterateChildren(*this); } m_inDly = false; m_nextDlyp = NULL; } virtual void visit(AstVarRef* nodep) { 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"); AstVarScope* dlyvscp = oldvscp->user1p()->castVarScope(); if (dlyvscp) { // Multiple use of delayed variable AstActive* oldactivep = dlyvscp->user2p()->castActive(); checkActivePost(nodep, oldactivep); } if (!dlyvscp) { // First use of this delayed variable string newvarname = (string("__Vdly__")+nodep->varp()->shortName()); dlyvscp = createVarSc(oldvscp, newvarname, 0, NULL); AstNodeAssign* prep = new AstAssignPre (nodep->fileline(), new AstVarRef(nodep->fileline(), dlyvscp, true), new AstVarRef(nodep->fileline(), oldvscp, false)); AstNodeAssign* postp = new AstAssignPost (nodep->fileline(), new AstVarRef(nodep->fileline(), oldvscp, true), new AstVarRef(nodep->fileline(), dlyvscp, false)); postp->lhsp()->user2(true); // Don't detect this assignment oldvscp->user1p(dlyvscp); // So we can find it later // Make new ACTIVE with identical sensitivity tree AstActive* newactp = createActivePost(nodep); dlyvscp->user2p(newactp); newactp->addStmtsp(prep); // Add to FRONT of statements newactp->addStmtsp(postp); } AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, true); newrefp->user2(true); // No reason to do it again nodep->replaceWith(newrefp); nodep->deleteTree(); VL_DANGLING(nodep); } else if (!m_inDly && nodep->lvalue()) { //UINFO(9,"NBA "<varScopep(), VU_NONDLY); } } } } virtual void visit(AstNodeFor* nodep) { nodep->v3fatalSrc("For statements should have been converted to while statements in V3Begin"); } virtual void visit(AstWhile* nodep) { bool oldloop = m_inLoop; m_inLoop = true; nodep->iterateChildren(*this); m_inLoop = oldloop; } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit DelayedVisitor(AstNetlist* nodep) { m_inDly = false; m_activep=NULL; m_cfuncp=NULL; m_nextDlyp=NULL; m_inLoop = false; m_inInitial = false; nodep->accept(*this); } virtual ~DelayedVisitor() { V3Stats::addStat("Optimizations, Delayed shared-sets", m_statSharedSet); } }; //###################################################################### // Delayed class functions void V3Delayed::delayedAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3EmitCSyms.cpp0000664000177100017500000005533413205574202017113 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include "V3Global.h" #include "V3EmitC.h" #include "V3EmitCBase.h" #include "V3LanguageWords.h" //###################################################################### // Symbol table emitting class EmitCSyms : EmitCBaseVisitor { // NODE STATE // Cleared on Netlist // AstNodeModule::user1() -> bool. Set true __Vconfigure called AstUser1InUse m_inuser1; // TYPES struct ScopeNameData { string m_symName; string m_prettyName; ScopeNameData(const string& symName, const string& prettyName) : m_symName(symName), m_prettyName(prettyName) {} }; struct ScopeFuncData { AstScopeName* m_scopep; AstCFunc* m_funcp; AstNodeModule* m_modp; ScopeFuncData(AstScopeName* scopep, AstCFunc* funcp, AstNodeModule* modp) : m_scopep(scopep), m_funcp(funcp), m_modp(modp) {} }; struct ScopeVarData { string m_scopeName; string m_varBasePretty; AstVar* m_varp; AstNodeModule* m_modp; AstScope* m_scopep; ScopeVarData(const string& scopeName, const string& varBasePretty, AstVar* varp, AstNodeModule* modp, AstScope* scopep) : m_scopeName(scopeName), m_varBasePretty(varBasePretty), m_varp(varp), m_modp(modp), m_scopep(scopep) {} }; typedef map ScopeFuncs; typedef map ScopeVars; typedef map ScopeNames; typedef pair ScopeModPair; typedef pair ModVarPair; struct CmpName { inline bool operator () (const ScopeModPair& lhsp, const ScopeModPair& rhsp) const { return lhsp.first->name() < rhsp.first->name(); } }; struct CmpDpi { inline bool operator () (const AstCFunc* lhsp, const AstCFunc* rhsp) const { if (lhsp->dpiImport() != rhsp->dpiImport()) { // cppcheck-suppress comparisonOfFuncReturningBoolError return lhsp->dpiImport() < rhsp->dpiImport(); } return lhsp->name() < rhsp->name(); } }; // STATE AstCFunc* m_funcp; // Current function AstNodeModule* m_modp; // Current module vector m_scopes; // Every scope by module vector m_dpis; // DPI functions vector m_modVars; // Each public {mod,var} ScopeNames m_scopeNames; // Each unique AstScopeName ScopeFuncs m_scopeFuncs; // Each {scope,dpi-export-func} ScopeVars m_scopeVars; // Each {scope,public-var} V3LanguageWords m_words; // Reserved word detector int m_coverBins; // Coverage bin number int m_labelNum; // Next label number // METHODS void emitSymHdr(); void emitSymImp(); void emitDpiHdr(); void emitDpiImp(); void nameCheck(AstNode* nodep) { // Prevent GCC compile time error; name check all things that reach C++ code if (nodep->name() != "") { string rsvd = m_words.isKeyword(nodep->name()); if (rsvd != "") { // Generally V3Name should find all of these and throw SYMRSVDWORD. // We'll still check here because the compiler errors resulting if we miss this warning are SO nasty nodep->v3error("Symbol matching "+rsvd+" reserved word reached emitter, should have hit SYMRSVDWORD: '"<prettyName()<<"'"); } } } void varsExpand() { // We didn'e have all m_scopes loaded when we encountered variables, so expand them now // It would be less code if each module inserted its own variables. // Someday. For now public isn't common. for (vector::iterator itsc = m_scopes.begin(); itsc != m_scopes.end(); ++itsc) { AstScope* scopep = itsc->first; AstNodeModule* smodp = itsc->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 dpos = whole.rfind("__DOT__"); if (dpos != string::npos) { scpName = whole.substr(0,dpos); varBase = whole.substr(dpos+strlen("__DOT__")); } else { varBase = whole; } //UINFO(9,"For "<name()<<" - "<name()<<" Scp "<name(), ScopeVarData(scpSym, varBasePretty, varp, modp, scopep))); } } } } // VISITORS virtual void visit(AstNetlist* nodep) { // 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) { nameCheck(nodep); m_modp = nodep; m_labelNum = 0; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstScope* nodep) { nameCheck(nodep); m_scopes.push_back(make_pair(nodep, m_modp)); } virtual void visit(AstScopeName* nodep) { string name = nodep->scopeSymName(); //UINFO(9,"scnameins sp "<name()<<" sp "<scopePrettySymName()<<" ss "<scopePrettySymName()))); } 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))); } else { if (m_scopeNames.find(nodep->scopeDpiName()) == m_scopeNames.end()) { m_scopeNames.insert(make_pair(nodep->scopeDpiName(), ScopeNameData(nodep->scopeDpiName(), nodep->scopePrettyDpiName()))); } } } virtual void visit(AstVar* nodep) { nameCheck(nodep); nodep->iterateChildren(*this); if (nodep->isSigUserRdPublic() && !nodep->isParam()) { // The VPI functions require a pointer to allow modification, but parameters are constants m_modVars.push_back(make_pair(m_modp, nodep)); } } virtual void visit(AstCoverDecl* nodep) { // 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) { nodep->labelNum(++m_labelNum); nodep->iterateChildren(*this); } virtual void visit(AstCFunc* nodep) { nameCheck(nodep); if (nodep->dpiImport() || nodep->dpiExportWrapper()) { m_dpis.push_back(nodep); } m_funcp = nodep; nodep->iterateChildren(*this); m_funcp = NULL; } // NOPs virtual void visit(AstConst*) {} // Default virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } //--------------------------------------- // ACCESSORS public: explicit 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"); ofp()->putsIntTopInclude(); 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"); puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert. if (v3Global.opt.trace()) { puts("bool __Vm_activity; ///< Used by trace routines to determine change occurred\n"); } puts("bool __Vm_didInit;\n"); 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"); } } if (m_coverBins) { puts("\n// COVERAGE\n"); puts("uint32_t __Vcoverage["); puts(cvtToStr(m_coverBins)); puts("];\n"); } { // Scope names bool did = false; for (ScopeNames::iterator it = m_scopeNames.begin(); it != m_scopeNames.end(); ++it) { if (!did) { did = true; puts("\n// SCOPE NAMES\n"); } 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"); if (v3Global.opt.trace()) { 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 if (v3Global.opt.trace()) { puts("\t, __Vm_activity(false)\n"); } puts("\t, __Vm_didInit(false)\n"); puts("\t// Setup submodule names\n"); char comma=','; for (vector::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) { AstScope* scopep = it->first; AstNodeModule* modp = it->second; if (modp->isTop()) { } else { string nameDl = scopep->nameDotless(); ofp()->printf("\t%c %-30s ", comma, nameDl.c_str()); puts("(Verilated::catName(topp->name(),"); // The "." is added by catName putsQuoted(scopep->prettyName()); puts("))\n"); comma=','; } } puts("{\n"); puts("// Pointer to top level\n"); puts("TOPp = topp;\n"); puts("// Setup each module's pointers to their submodules\n"); for (vector::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) { AstScope* scopep = it->first; AstNodeModule* modp = it->second; if (!modp->isTop()) { string arrow = scopep->name(); string::size_type pos; while ((pos=arrow.find(".")) != string::npos) { arrow.replace(pos, 1, "->"); } if (arrow.substr(0,5) == "TOP->") arrow.replace(0,5,"TOPp->"); ofp()->printf("%-30s ", arrow.c_str()); puts(" = &"); puts(scopep->nameDotless()+";\n"); } } puts("// Setup each module's pointer back to symbol table (for public functions)\n"); puts("TOPp->__Vconfigure(this, true);\n"); for (vector::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) { AstScope* scopep = it->first; AstNodeModule* modp = it->second; if (!modp->isTop()) { // first is used by AstCoverDecl's call to __vlCoverInsert bool first = !modp->user1(); modp->user1(true); puts(scopep->nameDotless()+".__Vconfigure(this, " +(first?"true":"false") +");\n"); } } { // Setup scope names bool did = false; for (ScopeNames::iterator it = m_scopeNames.begin(); it != m_scopeNames.end(); ++it) { if (!did) { did = true; puts("// Setup scope names\n"); } 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 if (v3Global.opt.trace()) { 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; //============================================================================ // Parser YYSType, e.g. for parser's yylval // 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 int token; // Read token, aka tok 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; // aheadval is valid V3ParseBisonYYSType m_aheadVal; // ahead token value V3ParseBisonYYSType m_curBisonVal; // current token for error reporting V3ParseBisonYYSType m_prevBisonVal; // previous token for error reporting 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 string m_tag; // Contents (if any) of current verilator tag AstNode* m_tagNodep; // Points to the node to set to m_tag or NULL to not set. public: // Note these are an exception to using the filename as the debug type static int debugBison() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel("bison"); return level; } static int debugFlex() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel("flex"); return level; } static int debug() { return debugBison() ? debugFlex() : 0; } // Functions called by lex rules: int yylexThis(); static bool optFuture(const string& flag) { return v3Global.opt.isFuture(flag); } void ppline (const char* text); void linenoInc() { fileline()->linenoInc(); } void verilatorCmtLint(const char* text, bool on); void verilatorCmtLintSave(); void verilatorCmtLintRestore(); void verilatorCmtBad(const char* text); void tag(const char* text); void tagNodep(AstNode* nodep) { m_tagNodep = nodep; } AstNode* tagNodep() const { return m_tagNodep;} static double parseDouble(const char* text, size_t length, bool* successp = NULL); void pushBeginKeywords(int state) { m_inBeginKwd++; m_lastVerilogState=state; } bool popBeginKeywords() { if (m_inBeginKwd) { m_inBeginKwd--; return true; } else return false; } int lastVerilogState() const { return m_lastVerilogState; } static const char* tokenName(int tok); void ppPushText(const string& text) { m_ppBuffers.push_back(text); } size_t ppInputToLex(char* buf, size_t max_size); static V3ParseImp* parsep() { return s_parsep; } // TODO: Many of these functions are the old interface; they'd be better as non-static // and called as READP->newString(...) etc. string* newString(const string& text) { // Allocate a string, remembering it so we can reclaim storage at lex end string* strp = new string (text); m_stringps.push_back(strp); return strp; } string* newString(const char* text) { // Allocate a string, remembering it so we can reclaim storage at lex end string* strp = new string (text); m_stringps.push_back(strp); return strp; } string* newString(const char* text, size_t length) { string* strp = new string (text, length); m_stringps.push_back(strp); return strp; } V3Number* newNumber(FileLine* fl, const char* text) { V3Number* nump = new V3Number (fl, text); m_numberps.push_back(nump); return nump; } // Return next token, for bison, since bison isn't class based, use a global THIS FileLine* fileline() const { return m_fileline; } AstNetlist* rootp() const { return m_rootp; } FileLine* copyOrSameFileLine() { return fileline()->copyOrSameFileLine(); } bool inCellDefine() const { return m_inCellDefine; } void inCellDefine(bool flag) { m_inCellDefine = flag; } bool inLibrary() const { return m_inLibrary; } // Interactions with parser int bisonParse(); // Interactions with lexer void lexNew(int debug); void lexDestroy(); void statePop(); // Parser -> lexer communication static int stateVerilogRecent(); // Parser -> lexer communication int prevLexToken() { return m_prevLexToken; } // Parser -> lexer communication size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf,max_size); } const V3ParseBisonYYSType curBisonVal() const { return m_curBisonVal; } const V3ParseBisonYYSType prevBisonVal() const { return m_prevBisonVal; } //==== Symbol tables V3ParseSym* symp() { return m_symp; } public: // CONSTRUCTORS 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_curBisonVal.token = 0; m_prevBisonVal.token = 0; // m_aheadVal not used as m_ahead = false, and not all compilers support initing it m_tagNodep = NULL; } ~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(); void lexToken(); // Internal; called from lexToBison }; #endif // Guard verilator-3.916/src/V3Changed.cpp0000664000177100017500000002543413205574202016565 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Changed's Transformations: // // Each module: // Each combo block // For each variable that comes from combo block and is generated AFTER a usage // Add __Vlast_{var} to local section, init to current value (just use array?) // Change = if any var != last. // If a signal is used as a clock in this module or any // module *below*, and it isn't a input to this module, // we need to indicate a new clock has been created. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Ast.h" #include "V3Changed.h" #include "V3EmitCBase.h" //###################################################################### class ChangedState { public: // STATE AstNodeModule* m_topModp; // Top module AstScope* m_scopetopp; // Scope under TOPSCOPE AstCFunc* m_chgFuncp; // Change function we're building AstCFunc* m_tlChgFuncp; // Top level change function we're building int m_numStmts; // Number of statements added to m_chgFuncp int m_funcNum; // Number of change functions emitted ChangedState() { m_topModp = NULL; m_chgFuncp = NULL; m_scopetopp = NULL; m_tlChgFuncp = NULL; m_numStmts = 0; m_funcNum = 0; } ~ChangedState() {} void maybeCreateChgFuncp() { // Don't create an extra function call if splitting is disabled if (!v3Global.opt.outputSplitCFuncs()) { m_chgFuncp = m_tlChgFuncp; return; } if (!m_chgFuncp || v3Global.opt.outputSplitCFuncs() < m_numStmts) { m_chgFuncp = new AstCFunc(m_scopetopp->fileline(), "_change_request_" + cvtToStr(++m_funcNum), m_scopetopp, "QData"); m_chgFuncp->argTypes(EmitCBaseVisitor::symClassVar()); m_chgFuncp->symProlog(true); m_chgFuncp->declPrivate(true); m_scopetopp->addActivep(m_chgFuncp); // Add a top call to it AstCCall* callp = new AstCCall(m_scopetopp->fileline(), m_chgFuncp); callp->argTypes("vlSymsp"); if (!m_tlChgFuncp->stmtsp()) { m_tlChgFuncp->addStmtsp(new AstCReturn(m_scopetopp->fileline(), callp)); } else { AstCReturn* returnp = m_tlChgFuncp->stmtsp()->castCReturn(); if (!returnp) m_scopetopp->v3fatalSrc("Lost CReturn in top change function"); // This is currently using AstLogOr which will shortcut the evaluation if // any function returns true. This is likely what we want and is similar to the logic already in use // inside V3EmitC, however, it also means that verbose logging may miss to print change detect variables. AstNode* newp = new AstCReturn(m_scopetopp->fileline(), new AstLogOr(m_scopetopp->fileline(), callp, returnp->lhsp()->unlinkFrBack())); returnp->replaceWith(newp); returnp->deleteTree(); VL_DANGLING(returnp); } m_numStmts = 0; } } }; //###################################################################### // Utility visitor to find elements to be compared class ChangedInsertVisitor : public AstNVisitor { private: // STATE ChangedState* m_statep; // Shared state across visitors AstVarScope* m_vscp; // Original (non-change) variable we're change-detecting AstVarScope* m_newvscp; // New (change detect) variable we're change-detecting AstNode* m_varEqnp; // Original var's equation to get var value AstNode* m_newLvEqnp; // New var's equation to read value AstNode* m_newRvEqnp; // New var's equation to set value uint32_t m_detects; // # detects created // CONSTANTS enum MiscConsts { DETECTARRAY_MAX_INDEXES = 256 // How many indexes before error // Ok to increase this, but may result in much slower model }; void newChangeDet() { if (++m_detects > DETECTARRAY_MAX_INDEXES) { m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect more than "<prettyName()<warnMore() <<"... Could recompile with DETECTARRAY_MAX_INDEXES increased"<maybeCreateChgFuncp(); AstChangeDet* changep = new AstChangeDet (m_vscp->fileline(), m_varEqnp->cloneTree(true), m_newRvEqnp->cloneTree(true), false); m_statep->m_chgFuncp->addStmtsp(changep); AstAssign* initp = new AstAssign (m_vscp->fileline(), m_newLvEqnp->cloneTree(true), m_varEqnp->cloneTree(true)); m_statep->m_chgFuncp->addFinalsp(initp); EmitCBaseCounterVisitor visitor(initp); m_statep->m_numStmts += visitor.count(); } virtual void visit(AstBasicDType* nodep) { newChangeDet(); } virtual void visit(AstPackArrayDType* nodep) { newChangeDet(); } virtual void visit(AstUnpackArrayDType* nodep) { for (int index=0; index < nodep->elementsConst(); ++index) { AstNode* origVEp = m_varEqnp; AstNode* origNLEp = m_newLvEqnp; AstNode* origNREp = m_newRvEqnp; m_varEqnp = new AstArraySel(nodep->fileline(), m_varEqnp->cloneTree(true), index); m_newLvEqnp = new AstArraySel(nodep->fileline(), m_newLvEqnp->cloneTree(true), index); m_newRvEqnp = new AstArraySel(nodep->fileline(), m_newRvEqnp->cloneTree(true), index); nodep->subDTypep()->skipRefp()->accept(*this); m_varEqnp->deleteTree(); m_newLvEqnp->deleteTree(); m_newRvEqnp->deleteTree(); m_varEqnp = origVEp; m_newLvEqnp = origNLEp; m_newRvEqnp = origNREp; } } virtual void visit(AstNodeClassDType* nodep) { if (nodep->packedUnsup()) { newChangeDet(); } else { if (debug()) nodep->dumpTree(cout,"-DETECTARRAY-class-"); m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<varp()->prettyName()); } } virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); if (debug()) nodep->dumpTree(cout,"-DETECTARRAY-general-"); m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<varp()->prettyName()); } public: // CONSTUCTORS ChangedInsertVisitor(AstVarScope* vscp, ChangedState* statep) { m_statep = statep; m_vscp = vscp; m_detects = 0; { AstVar* varp = m_vscp->varp(); string newvarname = "__Vchglast__"+m_vscp->scopep()->nameDotless()+"__"+varp->shortName(); // Create: VARREF(_last) // ASSIGN(VARREF(_last), VARREF(var)) // ... // CHANGEDET(VARREF(_last), VARREF(var)) AstVar* newvarp = new AstVar (varp->fileline(), AstVarType::MODULETEMP, newvarname, varp); m_statep->m_topModp->addStmtp(newvarp); m_newvscp = new AstVarScope(m_vscp->fileline(), m_statep->m_scopetopp, newvarp); m_statep->m_scopetopp->addVarp(m_newvscp); m_varEqnp = new AstVarRef(m_vscp->fileline(), m_vscp, false); m_newLvEqnp = new AstVarRef(m_vscp->fileline(), m_newvscp, true); m_newRvEqnp = new AstVarRef(m_vscp->fileline(), m_newvscp, false); } vscp->dtypep()->skipRefp()->accept(*this); m_varEqnp->deleteTree(); m_newLvEqnp->deleteTree(); m_newRvEqnp->deleteTree(); } virtual ~ChangedInsertVisitor() {} }; //###################################################################### // Changed state, as a visitor of each AstNode class ChangedVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstVarScope::user1() -> bool. True indicates processed AstUser1InUse m_inuser1; // STATE ChangedState* m_statep; // Shared state across visitors // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void genChangeDet(AstVarScope* vscp) { vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<isTop()) { m_statep->m_topModp = nodep; } nodep->iterateChildren(*this); } virtual void visit(AstTopScope* nodep) { UINFO(4," TS "<scopep(); if (!scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?"); m_statep->m_scopetopp = scopep; // Create a wrapper change detection function that calls each change detection function m_statep->m_tlChgFuncp = new AstCFunc(nodep->fileline(), "_change_request", scopep, "QData"); m_statep->m_tlChgFuncp->argTypes(EmitCBaseVisitor::symClassVar()); m_statep->m_tlChgFuncp->symProlog(true); m_statep->m_tlChgFuncp->declPrivate(true); m_statep->m_scopetopp->addActivep(m_statep->m_tlChgFuncp); // Each change detection function needs at least one AstChangeDet // to ensure that V3EmitC outputs the necessary code. m_statep->maybeCreateChgFuncp(); m_statep->m_chgFuncp->addStmtsp(new AstChangeDet(nodep->fileline(), NULL, NULL, false)); nodep->iterateChildren(*this); } virtual void visit(AstVarScope* nodep) { if (nodep->isCircular()) { UINFO(8," CIRC "<user1SetOnce()) { genChangeDet(nodep); } } } virtual void visit(AstNodeMath* nodep) { // Short-circuit } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ChangedVisitor(AstNetlist* nodep, ChangedState* statep) { m_statep = statep; nodep->accept(*this); } virtual ~ChangedVisitor() {} }; //###################################################################### // Changed class functions void V3Changed::changedAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3PreLex.l0000664000177100017500000005363013205574202016103 0ustar wsnyderwsnyder%option noyywrap align interactive %option stack %option noc++ %option prefix="V3PreLex" %{ /************************************************************************** * DESCRIPTION: Verilator: Flex verilog preprocessor * * Code available from: http://www.veripool.org/verilator * ************************************************************************** * * Copyright 2003-2017 by Wilson Snyder. This program is free software; * you can redistribute it and/or modify it under the terms of either the * GNU Lesser General Public License Version 3 or the Perl Artistic License * Version 2.0. * * Verilator is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * ************************************************************************** * Do not use Flex in C++ mode. It has bugs with yyunput() which result in * lost characters. **************************************************************************/ #include "V3PreProc.h" #include "V3PreLex.h" V3PreLex* V3PreLex::s_currentLexp = NULL; // Current lexing point #define LEXP V3PreLex::s_currentLexp #define YY_INPUT(buf,result,max_size) \ result = LEXP->inputToLex(buf,max_size); // Accessors, because flex keeps changing the type of yyleng char* yyourtext() { return yytext; } size_t yyourleng() { return yyleng; } void yyourtext(const char* textp, size_t size) { yytext=(char*)textp; yyleng=size; } // Prevent conflicts from perl version static void linenoInc() {LEXP->linenoInc();} static bool pedantic() { return LEXP->m_pedantic; } static void yyerror(char* msg) { LEXP->curFilelinep()->v3error(msg); } static void yyerrorf(const char* msg) { LEXP->curFilelinep()->v3error(msg); } static void appendDefValue(const char* t, size_t l) { LEXP->appendDefValue(t,l); } /**********************************************************************/ %} %x CMTONEM %x CMTBEGM %x CMTMODE %x STRMODE %x DEFFPAR %x DEFFORM %x DEFVAL %x DEFCMT %x STRIFY %x ARGMODE %x INCMODE %x PRTMODE /* drop: Drop Ctrl-Z - can't pass thru or may EOF the output too soon */ ws [ \t\f\r] wsn [ \t\f] crnl [\r]*[\n] quote [\"] tickquote [`][\"] /* Where we use symb/symbdef, we must also look for a `` join */ /* Note in the preprocessor \ESCaped is *not* always special; mantis1537/bug441 */ symb ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n]+) symbdef ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n`]+) word [a-zA-Z0-9_]+ drop [\032] /**************************************************************/ %% ^{ws}*"`line"{ws}+.*{crnl} { LEXP->lineDirective(yytext); return(VP_LINE); } /* Special directives we recognize */ "`define" { return(VP_DEFINE); } "`else" { return(VP_ELSE); } "`elsif" { return(VP_ELSIF); } "`endif" { return(VP_ENDIF); } "`ifdef" { return(VP_IFDEF); } "`ifndef" { return(VP_IFNDEF); } "`include" { return(VP_INCLUDE); } "`undef" { return(VP_UNDEF); } "`undefineall" { return(VP_UNDEFINEALL); } "`error" { if (!pedantic()) return (VP_ERROR); else return(VP_DEFREF); } "`__FILE__" { static string rtnfile; rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename(); rtnfile += '"'; yytext=(char*)rtnfile.c_str(); yyleng = rtnfile.length(); return (VP_STRING); } "`__LINE__" { static char buf[10]; sprintf(buf, "%d",LEXP->curFilelinep()->lineno()); yytext = buf; yyleng = strlen(yytext); return (VP_TEXT); } /* Pass-through strings */ {quote} { yy_push_state(STRMODE); yymore(); } <> { linenoInc(); yyerrorf("EOF in unterminated string"); yyleng=0; yyterminate(); } {crnl} { linenoInc(); yyerrorf("Unterminated string"); BEGIN(INITIAL); } {word} { yymore(); } [^\"\\] { yymore(); } [\\]{crnl} { linenoInc(); yymore(); } [\\]{wsn}+{crnl} { yyless(1); LEXP->curFilelinep()->v3warn(BSSPACE, "Backslash followed by whitespace, perhaps the whitespace is accidental?"); } [\\]. { yymore(); } {quote} { yy_pop_state(); if (LEXP->m_parenLevel || LEXP->m_defQuote) { LEXP->m_defQuote=false; appendDefValue(yytext,yyleng); yyleng=0; } else return (VP_STRING); } /* Stringification */ {tickquote} { yy_push_state(STRIFY); return VP_STRIFY; } <> { linenoInc(); yyerrorf("EOF in unterminated '\""); yyleng=0; yyterminate(); } "`\\`\"" { return VP_BACKQUOTE; } {quote} { yy_push_state(STRMODE); yymore(); } {tickquote} { yy_pop_state(); return VP_STRIFY; } {symbdef} { return (VP_SYMBOL); } {symbdef}`` { yyleng-=2; return (VP_SYMBOL_JOIN); } "`"{symbdef} { return (VP_DEFREF); } "`"{symbdef}`` { yyleng-=2; return (VP_DEFREF_JOIN); } `` { yyleng-=2; return (VP_JOIN); } {crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); } {wsn}+ { return (VP_WHITE); } {drop} { } [\r] { } . { return (VP_TEXT); } /* Protected blocks */ "`protected" { yy_push_state(PRTMODE); yymore(); } <> { linenoInc(); yyerrorf("EOF in `protected"); yyleng=0; yyterminate(); } {crnl} { linenoInc(); return VP_TEXT; } . { yymore(); } "`endprotected" { yy_pop_state(); return VP_TEXT; } /* Pass-through include <> filenames */ <> { linenoInc(); yyerrorf("EOF in unterminated include filename"); yyleng=0; yyterminate(); } {crnl} { linenoInc(); yyerrorf("Unterminated include filename"); BEGIN(INITIAL); } [^\>\\] { yymore(); } [\\]. { 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 */ [\\]{wsn}+{crnl} { yyless(1); LEXP->curFilelinep()->v3warn(BSSPACE, "Backslash followed by whitespace, perhaps the whitespace is accidental?"); } [\\]{crnl} { linenoInc(); appendDefValue((char*)"\\\n",2); } /* Include return so can maintain output line count */ {quote} { LEXP->m_defQuote=true; yy_push_state(STRMODE); yymore(); } /* Legal only in default values */ "`\\`\"" { appendDefValue(yytext,yyleng); } /* Maybe illegal, otherwise in default value */ {tickquote} { appendDefValue(yytext,yyleng); } /* Maybe illegal, otherwise in default value */ [{\[] { LEXP->m_formalLevel++; appendDefValue(yytext,yyleng); } [}\]] { LEXP->m_formalLevel--; appendDefValue(yytext,yyleng); } [^\/\*\n\r\\(){}\[\]\"]+ | [\\][^\n\r] | . { appendDefValue(yytext,yyleng); } /* Reading definition value (declaration of a define's text) */ "/*" { LEXP->m_defCmtSlash=false; yy_push_state(DEFCMT); yymore(); } /* Special comment parser */ "//"[^\n\r]*[\\]{crnl} { linenoInc(); appendDefValue((char*)"\n",1); } /* Spec says // not part of define value */ "//"[^\n\r]* { return (VP_COMMENT);} {drop} { } <> { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return (VP_DEFVALUE); } /* Technically illegal, but people complained */ {crnl} { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return (VP_DEFVALUE); } [\\]{wsn}+{crnl} { yyless(1); LEXP->curFilelinep()->v3warn(BSSPACE, "Backslash followed by whitespace, perhaps the whitespace is accidental?"); } [\\]{crnl} { linenoInc(); appendDefValue((char*)"\\\n",2); } /* Return, AND \ is part of define value */ {quote} { LEXP->m_defQuote=true; yy_push_state(STRMODE); yymore(); } [^\/\*\n\r\\\"]+ | [\\][^\n\r] | . { appendDefValue(yytext,yyleng); } /* Comments inside define values - if embedded get added to define value per spec */ /* - if no \{crnl} ending then the comment belongs to the next line, as a non-embedded comment */ /* - if all but (say) 3rd line is missing \ then it's indeterminate */ "*/" { yy_pop_state(); appendDefValue(yytext,yyleng); } [\\]{wsn}+{crnl} { yyless(1); LEXP->curFilelinep()->v3warn(BSSPACE, "Backslash followed by whitespace, perhaps the whitespace is accidental?"); } [\\]{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 inside the () of an argument 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 */ `` { appendDefValue(yytext,yyleng); } /* defref in defref - outer macro expands first */ [^\/\*\n\r\\(,){}\[\]\"`]+ | . { appendDefValue(yytext,yyleng); } /* One line comments. */ "//"{ws}*{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return (VP_WHITE); } "//" { yy_push_state(CMTONEM); yymore(); } [^\n\r]* { yy_pop_state(); return (VP_COMMENT); } /* C-style comments. */ /**** See also DEFCMT */ /* We distinguish between the start of a comment, and later, to look for prefix comments (deprecated) */ "/*" { yy_push_state(CMTMODE); yymore(); } {ws}+ { yymore(); } "*/" { yy_pop_state(); return(VP_COMMENT); } {crnl} { linenoInc(); yymore(); } <> { yyerrorf("EOF in '/* ... */' block comment\n"); yyleng=0; yyterminate(); } {word} { yymore(); } . { BEGIN CMTMODE; yymore(); } /* beginning in comment */ . { yymore(); } /* Define calls */ /* symbdef prevents normal lex rules from making `\`"foo a symbol {`"foo} instead of a BACKQUOTE */ "`"{symbdef} { return (VP_DEFREF); } "`"{symbdef}`` { yyleng-=2; return (VP_DEFREF_JOIN); } /* Generics */ {crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); } <> { yyterminate(); } /* A "normal" EOF */ {symb} { return (VP_SYMBOL); } {symb}`` { yyleng-=2; return (VP_SYMBOL_JOIN); } `` { yyleng-=2; return (VP_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 //###################################################################### 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_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 BLKLOOPINIT, // Delayed assignment to array inside for loops BLKSEQ, // Blocking assignments in sequential block BSSPACE, // Backslash space CASEINCOMPLETE, // Case statement has missing values CASEOVERLAP, // Case statements overlap CASEWITHX, // Case with X values CASEX, // Casex CDCRSTLOGIC, // Logic in async reset path CLKDATA, // Clock used as data CMPCONST, // Comparison is constant due to limited range COLONPLUS, // :+ instead of +: COMBDLY, // Combinatorial delayed assignment DEFPARAM, // Style: Defparam DECLFILENAME, // Declaration doesn't match filename ENDLABEL, // End lable name mismatch GENCLK, // Generated Clock IFDEPTH, // If statements too deep IMPERFECTSCH, // Imperfect schedule (disabled by default) IMPLICIT, // Implicit wire IMPURE, // Impure function not being inlined INCABSPATH, // Include has absolute path INITIALDLY, // Initial delayed statement LITENDIAN, // Little bit endian vector MODDUP, // Duplicate module MULTIDRIVEN, // Driven from multiple blocks PINMISSING, // Cell pin not specified PINNOCONNECT, // Cell pin not connected PINCONNECTEMPTY,// Cell pin connected by name with empty reference: ".name()" (can be used to mark unused pins) REALCVT, // Real conversion REDEFMACRO, // Redefining existing define macro SELRANGE, // Selection index out of range STMTDLY, // Delayed statement SYMRSVDWORD, // Symbol is Reserved Word SYNCASYNCNET, // Mixed sync + async reset UNDRIVEN, // No drivers UNOPT, // Unoptimizable block UNOPTFLAT, // Unoptimizable block after flattening UNPACKED, // Unsupported unpacked UNSIGNED, // Comparison is constant due to unsigned arithmetic UNUSED, // No receivers USERERROR, // Elaboration time $error USERFATAL, // Elaboration time $fatal USERINFO, // Elaboration time $info USERWARN, // Elaboration time $warning 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) {} // cppcheck-suppress noExplicitConstructor inline V3ErrorCode (en _e) : m_e(_e) {} explicit 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 "DETECTARRAY", "MULTITOP", "TASKNSVAR", // Warnings " EC_FIRST_WARN", "ALWCOMBORDER", "ASSIGNDLY", "ASSIGNIN", "BLKANDNBLK", "BLKLOOPINIT", "BLKSEQ", "BSSPACE", "CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CLKDATA", "CMPCONST", "COLONPLUS", "COMBDLY", "DEFPARAM", "DECLFILENAME", "ENDLABEL", "GENCLK", "IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE", "INCABSPATH", "INITIALDLY", "LITENDIAN", "MODDUP", "MULTIDRIVEN", "PINMISSING", "PINNOCONNECT", "PINCONNECTEMPTY", "REALCVT", "REDEFMACRO", "SELRANGE", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNPACKED", "UNSIGNED", "UNUSED", "USERERROR", "USERFATAL", "USERINFO", "USERWARN", "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==BLKLOOPINIT || m_e==IMPURE || m_e==MODDUP); } // Warnings to mention manual bool mentionManual() const { return ( m_e==EC_FATALSRC || m_e==SYMRSVDWORD || pretendError() ); } // Warnings that are lint only bool lintError() const { return ( m_e==ALWCOMBORDER || m_e==BSSPACE || m_e==CASEINCOMPLETE || m_e==CASEOVERLAP || m_e==CASEWITHX || m_e==CASEX || m_e==CMPCONST || m_e==COLONPLUS || m_e==ENDLABEL || m_e==IMPLICIT || m_e==LITENDIAN || m_e==PINMISSING || m_e==REALCVT || m_e==UNSIGNED || m_e==WIDTH); } // Warnings that are style only bool styleError() const { return ( m_e==ASSIGNDLY // More than style, but for backward compatibility || m_e==BLKSEQ || m_e==DEFPARAM || m_e==DECLFILENAME || m_e==INCABSPATH || m_e==PINCONNECTEMPTY || m_e==PINNOCONNECT || m_e==SYNCASYNCNET || m_e==UNDRIVEN || m_e==UNUSED || m_e==VARHIDDEN ); } }; inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (V3ErrorCode::en lhs, V3ErrorCode rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, V3ErrorCode rhs) { return os< MessagesSet; typedef void (*ErrorExitCb)(void); private: static bool s_describedWarnings; // Told user how to disable warns static bool s_describedEachWarn[V3ErrorCode::_ENUM_MAX]; // Told user specifics about this warning static bool s_pretendError[V3ErrorCode::_ENUM_MAX]; // Pretend this warning is an error static int s_debugDefault; // Option: --debugi Default debugging level static int s_errorLimit; // Option: --error-limit Number of errors before exit static bool s_warnFatal; // Option: --warnFatal Warnings are fatal static int s_errCount; // Error count static int s_warnCount; // Warning count static int s_tellManual; // Tell user to see manual, 0=not yet, 1=doit, 2=disable static ostringstream s_errorStr; // Error string being formed static V3ErrorCode s_errorCode; // Error string being formed will abort static bool s_errorSuppressed; // Error being formed should be suppressed static MessagesSet s_messages; // What errors we've outputted static ErrorExitCb s_errorExitCb; // Callback when error occurs for dumping enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors V3Error() { cerr<<("Static class"); abort(); } public: // CONSTRUCTORS // ACCESSORS static void debugDefault(int level) { s_debugDefault = level; } static int debugDefault() { return s_debugDefault; } static void errorLimit(int level) { s_errorLimit = level; } static int errorLimit() { return s_errorLimit; } static void warnFatal(bool flag) { s_warnFatal = flag; } static bool warnFatal() { return s_warnFatal; } static string msgPrefix(); // returns %Error/%Warn static int errorCount() { return s_errCount; } static int warnCount() { return s_warnCount; } static int errorOrWarnCount() { return errorCount()+warnCount(); } // METHODS static void incErrors(); static void incWarnings() { s_warnCount++; } static void init(); static void abortIfErrors() { if (errorCount()) abortIfWarnings(); } static void abortIfWarnings(); static void suppressThisWarning(); // Suppress next %Warn if user has it off static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; } static bool isError(V3ErrorCode code, bool supp); static string lineStr (const char* filename, int lineno); static V3ErrorCode errorCode() { return s_errorCode; } static void errorExitCb(ErrorExitCb cb) { s_errorExitCb = cb; } // When printing an error/warning, print prefix for multiline message static string warnMore(); // Internals for v3error()/v3fatal() macros only // Error end takes the string stream to output, be careful to seek() as needed static void v3errorPrep(V3ErrorCode code) { s_errorStr.str(""); s_errorCode=code; s_errorSuppressed=false; } static ostringstream& v3errorStr() { return s_errorStr; } static void vlAbort(); static void v3errorEnd(ostringstream& sstr); // static, but often overridden in classes. }; // Global versions, so that if the class doesn't define a operator, we get the functions anyways. inline int debug() { return V3Error::debugDefault(); } inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); } inline void v3errorEndFatal(ostringstream& sstr) { V3Error::v3errorEnd(sstr); assert(0); VL_UNREACHABLE } // Theses allow errors using << operators: v3error("foo"<<"bar"); // Careful, you can't put () around msg, as you would in most macro definitions // Note the commas are the comma operator, not separating arguments. These are needed to insure // evaluation order as otherwise we couldn't insure v3errorPrep is called first. #define v3warnCode(code,msg) v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<=(level))) { cout<<"- "<=(level))) { cout< std::string cvtToStr (const T& t) { ostringstream os; os< //###################################################################### // Symbol table for parsing class V3ParseSym { // TYPES typedef vector SymStack; private: // MEMBERS static int s_anonNum; // Number of next anonymous object (parser use only) VSymGraph m_syms; // Graph of symbol tree VSymEnt* m_symTableNextId; // Symbol table for next lexer lookup (parser use only) VSymEnt* m_symCurrentp; // Active symbol table for additions/lookups SymStack m_sympStack; // Stack of upper nodes with pending symbol tables public: // CONSTRUCTORS explicit V3ParseSym(AstNetlist* rootp) : m_syms(rootp) { s_anonNum = 0; // Number of next anonymous object pushScope(findNewTable(rootp)); m_symTableNextId = NULL; m_symCurrentp = symCurrentp(); } ~V3ParseSym() {} private: // METHODS static VSymEnt* getTable(AstNode* nodep) { if (!nodep->user4p()) nodep->v3fatalSrc("Current symtable not found"); return nodep->user4u().toSymEnt(); } 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); if (foundp) return foundp->nodep(); else return NULL; } void importItem(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); } void exportItem(AstNode* packagep, const string& id_or_star) { // Export from this the remote package::id_or_star VSymEnt* symp = getTable(packagep); if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE packagep->v3fatalSrc("Export package not found"); return; } symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star); } void exportStarStar(AstNode* packagep) { // Export *::* from remote packages symCurrentp()->exportStarStar(&m_syms); } }; #endif // Guard verilator-3.916/src/V3LinkCells.cpp0000664000177100017500000004600713205574202017113 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 VL_INCLUDE_UNORDERED_SET #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(); } // Recursive modules get space for maximum recursion virtual uint32_t rankAdder() const { return m_modp->recursiveClone() ? (1+v3Global.opt.moduleRecursionDepth()) : 1; } }; class LibraryVertex : public V3GraphVertex { public: explicit 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("Unsupported: Recursive multiple modules (module instantiates something leading back to itself): " <modp()->prettyName()); vvertexp->modp()->v3error("Note self-recursion (module instantiating itself directly) is supported."); 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 // AstNodeModule::user2p() // AstNodeModule* clone used for de-recursing // AstCell::user1p() // ==V3NodeModule* if done, != if unprocessed // AstCell::user2() // bool clone renaming completed // Allocated across all readFiles in V3Global::readFiles: // AstNode::user4p() // VSymEnt* Package and typedef symbol names AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // 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 vl_unordered_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->user1u().toGraphVertex()); } AstNodeModule* findModuleSym(const string& modName) { VSymEnt* foundp = m_mods.rootp()->findIdFallback(modName); if (!foundp) return NULL; else return foundp->nodep()->castNodeModule(); } AstNodeModule* resolveModule(AstNode* nodep, const string& modName) { AstNodeModule* modp = findModuleSym(modName); 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 = findModuleSym(modName); 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->recursiveClone() && !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) { // 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) { // 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) { // 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) { // Cell: Resolve its filename. If necessary, parse it. // Execute only once. Complication is that cloning may result in user1 being set (for pre-clone) // so check if user1() matches the m_mod, if 0 never did it, if !=, it is an unprocessed clone bool cloned = (nodep->user1p() && nodep->user1p()!=m_modp); if (nodep->user1p()==m_modp) return; // AstBind and AstNodeModule may call a cell twice nodep->user1p(m_modp); // if (!nodep->modp() || cloned) { UINFO(4,"Link Cell: "<modName()); if (cellmodp) { if (cellmodp == m_modp || cellmodp->user2p() == m_modp) { UINFO(1,"Self-recursive module "<recursive(true); nodep->recursive(true); if (!cellmodp->recursiveClone()) { // In the non-Vrcm, which needs to point to Vrcm flavor // // Make a clone which this cell points to // Later, the clone's cells will also point clone'd name // This lets us link the XREFs between the (uncloned) children so // they don't point to the same module which would // break parameter resolution. AstNodeModule* otherModp = cellmodp->user2p()->castNodeModule(); if (!otherModp) { otherModp = cellmodp->cloneTree(false); otherModp->name(otherModp->name()+"__Vrcm"); otherModp->user1p(NULL); // Need new vertex otherModp->user2p(cellmodp); otherModp->recursiveClone(true); // user1 etc will retain its pre-clone value cellmodp->user2p(otherModp); v3Global.rootp()->addModulep(otherModp); new V3GraphEdge(&m_graph, vertex(cellmodp), vertex(otherModp), 1, false); } cellmodp = otherModp; nodep->modp(cellmodp); } else { // In the Vrcm, which needs to point back to Vrcm flavor // The cell already has the correct resolution (to Vrcm) nodep->modp(cellmodp); // We don't create a V3GraphEdge (as it would be circular) } } else { // Non-recursive // Track module depths, so can sort list from parent down to children nodep->modp(cellmodp); new V3GraphEdge(&m_graph, vertex(m_modp), vertex(cellmodp), 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(); VL_DANGLING(pinp); } } // 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()) { nodep->modName(nodep->modp()->name()); // Note what pins exist vl_unordered_set ports; // Symbol table of all connected port names for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells"); if (!pinp->exprp()) { if (pinp->name().substr(0, 11) == "__pinNumber") { pinp->v3warn(PINNOCONNECT,"Cell pin is not connected: "<prettyName()); } else { pinp->v3warn(PINCONNECTEMPTY,"Cell pin connected by name with empty reference: "<prettyName()); } } if (ports.find(pinp->name()) == ports.end()) { ports.insert(pinp->name()); } } // We search ports, rather than in/out declarations as they aren't resolved yet, // and it's easier to do it now than in V3LinkDot when we'd need to repeat steps. for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) { if (AstPort* portp = portnodep->castPort()) { if (ports.find(portp->name()) == ports.end() && ports.find("__pinNumber"+cvtToStr(portp->pinNum())) == ports.end()) { if (pinStar) { UINFO(9," need .* PORT "<fileline(),0,portp->name(), new AstParseRef(nodep->fileline(), AstParseRefExp::PX_TEXT, portp->name(), NULL, NULL)); 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->ifacep(NULL); // cellp overrides // In the case of arrayed interfaces, we replace cellp when de-arraying in V3Inst idtypep->cellp(nodep); // Only set when real parent cell known. AstVar* varp; if (nodep->rangep()) { AstNodeArrayDType* arrp = new AstUnpackArrayDType(nodep->fileline(),VFlagChildDType(), idtypep, nodep->rangep()->cloneTree(true)); varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName, VFlagChildDType(), arrp); } else { 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(); AstNodeModule* foundp = findModuleSym(nodep->name()); 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); VL_DANGLING(nodep); } 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.916/src/V3Clean.h0000664000177100017500000000224213205574202015713 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Expand.cpp0000664000177100017500000010513213205574202016445 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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(); VL_DANGLING(nodep); } 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) "<dtypep()->skipRefp()->castUnpackArrayDType()) nodep->v3fatalSrc("ArraySel with unpacked arrays 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) { 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); VL_DANGLING(nodep); } } 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) { 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); VL_DANGLING(nodep); } else { // Long/Quad from Long/Quad UINFO(8," SEL->SHIFT "<fromp()->unlinkFrBack(); AstNode* lsbp = nodep->lsbp()->unlinkFrBack(); if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCCast(nodep->fileline(), fromp, nodep); AstNode* newp = new AstShiftR (nodep->fileline(), fromp, dropCondBound(lsbp), fromp->width()); // {large}>>32 requires 64-bit shift operation; then cast newp->dtypeFrom(fromp); if (!nodep->isQuad() && fromp->isQuad()) { newp = new AstCCast (newp->fileline(), newp, nodep); } newp->dtypeFrom(nodep); replaceWithDelete(nodep,newp); VL_DANGLING(nodep); } } 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(); VL_DANGLING(rhsp); destp->deleteTree(); VL_DANGLING(destp); } else { UINFO(8," ASSIGNSEL(const,narrow) "<isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep); AstNode* oldvalp = destp->cloneTree(true); fixCloneLvalue(oldvalp); if (!ones) oldvalp = new AstAnd (lhsp->fileline(), new AstConst (lhsp->fileline(), maskold), oldvalp); AstNode* newp = new AstOr (lhsp->fileline(), oldvalp, new AstShiftL (lhsp->fileline(), rhsp, new AstConst (lhsp->fileline(), lsb), destp->width())); newp = new AstAssign (nodep->fileline(), destp, newp); insertBefore(nodep,newp); } return true; } else { // non-const RHS if (destwide && lhsp->widthConst()==1) { UINFO(8," ASSIGNSEL(varlsb,wide,1bit) "<rhsp()->unlinkFrBack(); AstNode* destp = lhsp->fromp()->unlinkFrBack(); AstNode* oldvalp = new AstWordSel (lhsp->fileline(), destp->cloneTree(true), newSelBitWord(lhsp->lsbp(), 0)); fixCloneLvalue(oldvalp); if (!ones) oldvalp = new AstAnd (lhsp->fileline(), new AstNot (lhsp->fileline(), new AstShiftL (lhsp->fileline(), new AstConst (nodep->fileline(),1), // newSelBitBit may exceed the MSB of this variable. // That's ok as we'd just AND with a larger value, // but oldval would clip the upper bits to sanity newSelBitBit(lhsp->lsbp()), VL_WORDSIZE)), oldvalp); // Restrict the shift amount to 0-31, see bug804. AstNode* shiftp = new AstAnd(nodep->fileline(), lhsp->lsbp()->cloneTree(true), new AstConst(nodep->fileline(), VL_WORDSIZE-1)); AstNode* newp = new AstOr (lhsp->fileline(), oldvalp, new AstShiftL (lhsp->fileline(), rhsp, shiftp, VL_WORDSIZE)); newp = new AstAssign (nodep->fileline(), new AstWordSel (nodep->fileline(), destp, newSelBitWord(lhsp->lsbp(), 0)), newp); insertBefore(nodep,newp); return true; } else if (destwide) { UINFO(8," ASSIGNSEL(varlsb,wide) -- NoOp -- "<dumpTree(cout,"- old: "); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* destp = lhsp->fromp()->unlinkFrBack(); AstNode* oldvalp = destp->cloneTree(true); fixCloneLvalue(oldvalp); V3Number maskwidth (nodep->fileline(), destp->widthMin()); for (int bit=0; bit<(int)lhsp->widthConst(); bit++) maskwidth.setBit(bit,1); if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep); if (!ones) oldvalp = new AstAnd (lhsp->fileline(), new AstNot (lhsp->fileline(), new AstShiftL (lhsp->fileline(), new AstConst (nodep->fileline(), maskwidth), lhsp->lsbp()->cloneTree(true), destp->width())), oldvalp); AstNode* newp = new AstOr (lhsp->fileline(), oldvalp, new AstShiftL (lhsp->fileline(), rhsp, lhsp->lsbp()->cloneTree(true), destp->width())); newp = new AstAssign (nodep->fileline(), destp, newp); //newp->dumpTree(cout,"- new: "); insertBefore(nodep,newp); return true; } } } virtual void visit(AstConcat* nodep) { 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); VL_DANGLING(nodep); } } 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) { 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); VL_DANGLING(nodep); } } 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) { 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } } virtual void visit(AstEq* nodep) { visitEqNeq (nodep); } virtual void visit(AstNeq* nodep) { visitEqNeq (nodep); } virtual void visit(AstRedOr* nodep) { 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } } virtual void visit(AstRedAnd* nodep) { 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); VL_DANGLING(nodep); } else { UINFO(8," REDAND->EQ "<lhsp()->unlinkFrBack(); AstNode* newp = new AstEq (nodep->fileline(), new AstConst (nodep->fileline(), wordMask(lhsp)), lhsp); replaceWithDelete(nodep,newp); VL_DANGLING(nodep); } } virtual void visit(AstRedXor* nodep) { 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) { if (nodep->user1SetOnce()) return; // Process once m_stmtp = nodep; nodep->iterateChildren(*this); bool did = false; if (nodep->isWide() && ((nodep->lhsp()->castVarRef() || nodep->lhsp()->castArraySel())) && !AstVar::scVarRecurse(nodep->lhsp()) // Need special function for SC && !AstVar::scVarRecurse(nodep->rhsp())) { if (AstConst* rhsp = nodep->rhsp()->castConst()) { did = expandWide(nodep,rhsp); } else if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) { did = expandWide(nodep,rhsp); } else if (AstSel* rhsp = nodep->rhsp()->castSel()) { did = expandWide(nodep,rhsp); } else if (AstArraySel* rhsp = nodep->rhsp()->castArraySel()) { did = expandWide(nodep,rhsp); } else if (AstConcat* rhsp = nodep->rhsp()->castConcat()) { did = expandWide(nodep,rhsp); } else if (AstReplicate* rhsp = nodep->rhsp()->castReplicate()) { did = expandWide(nodep,rhsp); } else if (AstAnd* rhsp = nodep->rhsp()->castAnd()) { did = expandWide(nodep,rhsp); } else if (AstOr* rhsp = nodep->rhsp()->castOr()) { did = expandWide(nodep,rhsp); } else if (AstNot* rhsp = nodep->rhsp()->castNot()) { did = expandWide(nodep,rhsp); } else if (AstXor* rhsp = nodep->rhsp()->castXor()) { did = expandWide(nodep,rhsp); } else if (AstXnor* rhsp = nodep->rhsp()->castXnor()) { did = expandWide(nodep,rhsp); } else if (AstNodeCond* rhsp = nodep->rhsp()->castNodeCond()) { did = expandWide(nodep,rhsp); } } else if (AstSel* lhsp = nodep->lhsp()->castSel()) { did = expandLhs(nodep,lhsp); } // Cleanup common code if (did) { nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } m_stmtp = NULL; } //-------------------- // Default: Just iterate virtual void visit(AstVar*) {} // Don't hit varrefs under vars virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit ExpandVisitor(AstNetlist* nodep) { m_stmtp=NULL; nodep->accept(*this); } virtual ~ExpandVisitor() {} }; //---------------------------------------------------------------------- // Top loop //###################################################################### // Expand class functions void V3Expand::expandAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3Inline.cpp0000664000177100017500000005721713205574202016456 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add temporaries, such as for inline nodes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Inline's Transformations: // // Each module: // Look for CELL... PRAGMA INLINE_MODULE // Replicate the cell's module // Convert pins to wires that make assignments // Rename vars to include cell name // Insert cell's module statements into the upper module // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Inline.h" #include "V3Inst.h" #include "V3Stats.h" #include "V3Ast.h" // CONFIG static const int INLINE_MODS_SMALLER = 100; // If a mod is < this # nodes, can always inline it //###################################################################### // Inline state, as a visitor of each AstNode class InlineMarkVisitor : public AstNVisitor { private: // NODE STATE // Output // AstNodeModule::user1() // OUTPUT: bool. User request to inline this module // Internal state (can be cleared after this visit completes) // AstNodeModule::user2() // CIL_*. Allowed to automatically inline module // AstNodeModule::user3() // int. Number of cells referencing this module // AstNodeModule::user4() // int. Statements in module AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; AstUser4InUse m_inuser4; // For the user2 field: enum {CIL_NOTHARD=0, // Inline not supported CIL_NOTSOFT, // Don't inline unless user overrides CIL_MAYBE, // Might inline CIL_USER}; // Pragma suggests inlining // STATE AstNodeModule* m_modp; // Current module V3Double0 m_statUnsup; // Statistic tracking typedef vector ModVec; ModVec m_allMods; // All modules, in top-down order. // Within the context of a given module, LocalInstanceMap maps // from child modules to the count of each child's local instantiations. typedef map LocalInstanceMap; // We keep a LocalInstanceMap for each module in the design map m_instances; // 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) { m_modp = nodep; m_allMods.push_back(nodep); m_modp->user2(CIL_MAYBE); m_modp->user4(0); // statement count 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); m_modp = NULL; } virtual void visit(AstCell* nodep) { nodep->modp()->user3Inc(); // Inc refs m_instances[m_modp][nodep->modp()]++; nodep->iterateChildren(*this); } virtual void visit(AstPragma* nodep) { if (nodep->pragType() == AstPragmaType::INLINE_MODULE) { //UINFO(0,"PRAG MARK "<v3error("Inline pragma not under a module"); } else if (m_modp->user2() == CIL_MAYBE || m_modp->user2() == CIL_NOTSOFT) { m_modp->user2(CIL_USER); } nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); // 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(); VL_DANGLING(nodep); // Remove so don't propagate to upper cell... } else { nodep->iterateChildren(*this); } } virtual void visit(AstVarXRef* nodep) { // Cleanup link until V3LinkDot can correct it nodep->varp(NULL); } virtual void visit(AstNodeFTaskRef* nodep) { // Cleanup link until V3LinkDot can correct it if (!nodep->packagep()) nodep->taskp(NULL); nodep->iterateChildren(*this); } virtual void visit(AstAlways* nodep) { nodep->iterateChildren(*this); m_modp->user4Inc(); // statement count } virtual void visit(AstNodeAssign* nodep) { // Don't count assignments, as they'll likely flatten out // Still need to iterate though to nullify VarXRefs int oldcnt = m_modp->user4(); nodep->iterateChildren(*this); m_modp->user4(oldcnt); } virtual void visit(AstNetlist* nodep) { // Build user2, user3, and user4 for all modules. // Also build m_allMods and m_instances. nodep->iterateChildren(*this); // Iterate through all modules in bottom-up order. // Make a final inlining decision for each. for (ModVec::reverse_iterator it=m_allMods.rbegin(); it!=m_allMods.rend(); ++it) { AstNodeModule* modp = *it; // If we're going to inline some modules into this one, // update user4 (statement count) to reflect that: int statements = modp->user4(); LocalInstanceMap& localsr = m_instances[modp]; for (LocalInstanceMap::iterator it = localsr.begin(); it != localsr.end(); ++it) { AstNodeModule* childp = it->first; if (childp->user1()) { // inlining child statements += (childp->user4() * it->second); } } modp->user4(statements); int allowed = modp->user2(); int refs = modp->user3(); // Should we automatically inline this module? // inlineMult = 2000 by default. // If a mod*#refs is < this # nodes, can inline it bool doit = ((allowed == CIL_USER) || ((allowed == CIL_MAYBE) && (refs==1 || statements < INLINE_MODS_SMALLER || v3Global.opt.inlineMult() < 1 || refs*statements < v3Global.opt.inlineMult()))); // Packages aren't really "under" anything so they confuse this algorithm if (modp->castPackage()) doit = false; UINFO(4, " Inline="<user1(doit); } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); if (m_modp) { m_modp->user4Inc(); // Inc statement count } } public: // CONSTUCTORS explicit InlineMarkVisitor(AstNode* nodep) { m_modp = NULL; nodep->accept(*this); } virtual ~InlineMarkVisitor() { V3Stats::addStat("Optimizations, Inline unsupported", m_statUnsup); // Done with these, are not outputs AstNode::user2ClearTree(); AstNode::user3ClearTree(); AstNode::user4ClearTree(); } }; //###################################################################### // 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) { nodep->user4p(nodep->clonep()); } // Accelerate virtual void visit(AstNodeStmt* nodep) {} virtual void visit(AstNodeMath* nodep) {} virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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: typedef std::set RenamedInterfacesSet; // NODE STATE // Input: // See InlineVisitor // STATE RenamedInterfacesSet m_renamedInterfaces; // Name of renamed interface variables 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) { // 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) { // 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(AstModule* nodep) { m_renamedInterfaces.clear(); nodep->iterateChildren(*this); } virtual void visit(AstVar* nodep) { if (nodep->user2p()) { // Make an assignment, so we'll trace it properly // user2p is either a const or a var. AstConst* exprconstp = nodep->user2p()->castConst(); AstVarRef* exprvarrefp = nodep->user2p()->castVarRef(); UINFO(8,"connectto: "<user2p()<v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up"); } 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()); } } // Iterate won't hit AstIfaceRefDType directly as it is no longer underneath the module if (AstIfaceRefDType* ifacerefp = nodep->dtypep()->castIfaceRefDType()) { m_renamedInterfaces.insert(nodep->name()); // Each inlined cell that contain an interface variable need to copy the IfaceRefDType and point it to // the newly cloned interface cell. AstIfaceRefDType* newdp = ifacerefp->cloneTree(false)->castIfaceRefDType(); nodep->dtypep(newdp); ifacerefp->addNextHere(newdp); // Relink to point to newly cloned cell if (newdp->cellp()) { if (AstCell* newcellp = newdp->cellp()->user4p()->castCell()) { newdp->cellp(newcellp); newdp->cellName(newcellp->name()); // Tag the old ifacerefp to ensure it leaves no stale reference to the inlined cell. newdp->user5(false); ifacerefp->user5(true); } } } // Variable under the inline cell, need to rename to avoid conflicts // Also clear I/O bits, as it is now local. string name = m_cellp->name() + "__DOT__" + nodep->name(); if (!nodep->isFuncLocal()) nodep->inlineAttrReset(name); if (!m_cellp->isTrace()) nodep->trace(false); if (debug()>=9) { nodep->dumpTree(cout,"varchanged:"); } if (debug()>=9 && nodep->valuep()) { nodep->valuep()->dumpTree(cout,"varchangei:"); } nodep->iterateChildren(*this); } virtual void visit(AstNodeFTask* nodep) { // 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) { // 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) { 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()->castConst(); AstVarRef* exprvarrefp = nodep->varp()->user2p()->castVarRef(); if (exprconstp) { nodep->replaceWith(exprconstp->cloneTree(true)); nodep->deleteTree(); VL_DANGLING(nodep); return; } else if (exprvarrefp) { nodep->varp( exprvarrefp->varp() ); } else { nodep->v3fatalSrc("Null connection?"); } } nodep->name(nodep->varp()->name()); nodep->iterateChildren(*this); } virtual void visit(AstVarXRef* nodep) { // 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); if (m_renamedInterfaces.count(nodep->dotted())) { nodep->dotted(m_cellp->name() + "__DOT__" + nodep->dotted()); } nodep->iterateChildren(*this); } virtual void visit(AstNodeFTaskRef* nodep) { // 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); if (m_renamedInterfaces.count(nodep->dotted())) { nodep->dotted(m_cellp->name() + "__DOT__" + nodep->dotted()); } UINFO(8," "<iterateChildren(*this); } // Not needed, as V3LinkDot doesn't care about typedefs //virtual void visit(AstRefDType* nodep) {} virtual void visit(AstScopeName* nodep) { // If there's a %m in the display text, we add a special node that will contain the name() // Similar code in V3Begin // To keep correct visual order, must add before other Text's AstNode* afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeAttrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name())); if (afterp) nodep->scopeAttrp(afterp); afterp = nodep->scopeEntrp(); if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeEntrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name())); if (afterp) nodep->scopeEntrp(afterp); nodep->iterateChildren(*this); } virtual void visit(AstCoverDecl* nodep) { // Fix path in coverage statements nodep->hier(m_cellp->prettyName() + (nodep->hier()!="" ? ".":"") + nodep->hier()); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep) { 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 // AstIfaceRefDType::user5p() // Whether the cell pointed to by this AstIfaceRefDType has been inlined // 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 AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; AstUser4InUse m_inuser4; AstUser5InUse m_inuser5; // 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) { // Iterate modules backwards, in bottom-up order. Required! nodep->iterateChildrenBackwards(*this); } virtual void visit(AstIfaceRefDType* nodep) { if (nodep->user5()) { // The cell has been removed so let's make sure we don't leave a reference to it // This dtype may still be in use by the AstAssignVarScope created earlier // but that'll get cleared up later nodep->cellp(NULL); } } virtual void visit(AstNodeModule* nodep) { m_modp = nodep; nodep->iterateChildren(*this); } virtual void visit(AstCell* nodep) { 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(); if (!pinNewVarp) pinOldVarp->v3fatalSrc("Cloning failed"); AstNode* connectRefp = pinp->exprp(); if (!connectRefp->castConst() && !connectRefp->castVarRef()) { pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up"); } 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(); VL_DANGLING(newmodp); // Clear any leftover ports, etc nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); if (debug()>=9) { m_modp->dumpTree(cout,"donemod:"); } } } //-------------------- virtual void visit(AstNodeMath* nodep) {} // Accelerate virtual void visit(AstNodeStmt* nodep) {} // Accelerate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit 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(); VL_DANGLING(modp); } } V3Global::dumpCheckGlobalTree("inline", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } verilator-3.916/src/V3ActiveTop.h0000664000177100017500000000230513205574202016567 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Unknown.cpp0000664000177100017500000004403713205622627016700 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add Unknown assigns // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Unknown's Transformations: // // Each module: // TBD: Eliminate tristates by adding __in, __inen, __en wires in parallel // Need __en in changed list if a signal is on the LHS of a assign // Constants: // RHS, Replace 5'bx_1_x with a module global we init to a random value // CONST(5'bx_1_x) -> VARREF(_{numberedtemp}) // -> VAR(_{numberedtemp}) // -> INITIAL(VARREF(_{numberedtemp}), OR(5'bx_1_x,AND(random,5'b0_1_x)) // OPTIMIZE: Must not collapse this initial back into the equation. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Unknown.h" #include "V3Ast.h" #include "V3Const.h" #include "V3Stats.h" //###################################################################### class UnknownVisitor : public AstNVisitor { private: // NODE STATE // Cleared on Netlist // AstSel::user() -> bool. Set true if already processed // AstArraySel::user() -> bool. Set true if already processed // AstNode::user2p() -> AstIf* Inserted if assignment for conditional AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // STATE AstNodeModule* m_modp; // Current module bool m_constXCvt; // Convert X's V3Double0 m_statUnkVars; // Statistic tracking AstAssignW* m_assignwp; // Current assignment AstAssignDly* m_assigndlyp; // Current assignment // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void replaceBoundLvalue(AstNode* nodep, AstNode* condp) { // Spec says a out-of-range LHS SEL results in a NOP. // This is a PITA. We could: // 1. IF(...) around an ASSIGN, // but that would break a "foo[TOO_BIG]=$fopen(...)". // 2. Hack to extend the size of the output structure // by one bit, and write to that temporary, but never read it. // That makes there be two widths() and is likely a bug farm. // 3. Make a special SEL to choose between the real lvalue // and a temporary NOP register. // 4. Assign to a temp, then IF that assignment. // This is suspected to be nicest to later optimizations. // 4 seems best but breaks later optimizations. 3 was tried, // but makes a mess in the emitter as lvalue switching is needed. So 4. // SEL(...) -> temp // if (COND(LTE(bit<=maxlsb))) ASSIGN(SEL(...)),temp) if (m_assignwp) { // Wire assigns must become always statements to deal with insertion // of multiple statements. Perhaps someday make all wassigns into always's? UINFO(5," IM_WireRep "<convertToAlways(); pushDeletep(m_assignwp); m_assignwp=NULL; } bool needDly = (m_assigndlyp != NULL); if (m_assigndlyp) { // Delayed assignments become normal assignments, // then the temp created becomes the delayed assignment AstNode* newp = new AstAssign(m_assigndlyp->fileline(), m_assigndlyp->lhsp()->unlinkFrBackWithNext(), m_assigndlyp->rhsp()->unlinkFrBackWithNext()); m_assigndlyp->replaceWith(newp); pushDeletep(m_assigndlyp); m_assigndlyp=NULL; } AstNode* prep = nodep; // Scan back to put the condlvalue above all selects (IE top of the lvalue) while (prep->backp()->castNodeSel() || prep->backp()->castSel()) { prep=prep->backp(); } FileLine* fl = nodep->fileline(); VL_DANGLING(nodep); // 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()->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 ? static_cast (new AstAssignDly(fl, prep, new AstVarRef(fl, varp, false))) : static_cast (new AstAssign (fl, prep, new AstVarRef(fl, varp, false)))), 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) { UINFO(4," MOD "<iterateChildren(*this); m_modp = NULL; } virtual void visit(AstAssignDly* nodep) { m_assigndlyp = nodep; nodep->iterateChildren(*this); VL_DANGLING(nodep); // May delete nodep. m_assigndlyp = NULL; } virtual void visit(AstAssignW* nodep) { m_assignwp = nodep; nodep->iterateChildren(*this); VL_DANGLING(nodep); // May delete nodep. m_assignwp = NULL; } virtual void visit(AstCaseItem* nodep) { 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) { 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); VL_DANGLING(nodep); 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(); VL_DANGLING(lhsp); rhsp->deleteTree(); VL_DANGLING(rhsp); } else { if (nodep->castEqCase()) newp = new AstEq (nodep->fileline(), lhsp, rhsp); else newp = new AstNeq (nodep->fileline(), lhsp, rhsp); } nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); // 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); VL_DANGLING(nodep); 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(); VL_DANGLING(rhsp); } nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); // Iterate tree now that we may have gotten rid of the compare newp->iterateChildren(*this); } } virtual void visit(AstEqCase* nodep) { visitEqNeqCase(nodep); } virtual void visit(AstNeqCase* nodep) { visitEqNeqCase(nodep); } virtual void visit(AstEqWild* nodep) { visitEqNeqWild(nodep); } virtual void visit(AstNeqWild* nodep) { visitEqNeqWild(nodep); } virtual void visit(AstIsUnknown* nodep) { 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(); VL_DANGLING(nodep); } virtual void visit(AstConst* nodep) { 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(); VL_DANGLING(nodep); 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(); VL_DANGLING(nodep); } } } virtual void visit(AstSel* nodep) { nodep->iterateChildren(*this); if (!nodep->user1SetOnce()) { // Guard against reading/writing past end of bit vector array AstNode* basefromp = AstArraySel::baseFromp(nodep); bool lvalue = false; if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { lvalue = varrefp->lvalue(); } // Find range of dtype we are selecting from // Similar code in V3Const::warnSelect int maxmsb = nodep->fromp()->dtypep()->width()-1; if (debug()>=9) nodep->dumpTree(cout,"sel_old: "); V3Number maxmsbnum (nodep->fileline(), nodep->lsbp()->width(), maxmsb); // If (maxmsb >= selected), we're in bound AstNode* condp = new AstGte (nodep->fileline(), new AstConst(nodep->fileline(), maxmsbnum), nodep->lsbp()->cloneTree(false)); // See if the condition is constant true (e.g. always in bound due to constant select) // Note below has null backp(); the Edit function knows how to deal with that. condp = V3Const::constifyEdit(condp); if (condp->isOne()) { // We don't need to add a conditional; we know the existing expression is ok condp->deleteTree(); } else if (!lvalue) { // SEL(...) -> COND(LTE(bit<=maxmsb), ARRAYSEL(...), {width{1'bx}}) AstNRelinker replaceHandle; nodep->unlinkFrBack(&replaceHandle); V3Number xnum (nodep->fileline(), nodep->width()); xnum.setAllBitsX(); AstNode* newp = new AstCondBound (nodep->fileline(), condp, nodep, new AstConst(nodep->fileline(), xnum)); if (debug()>=9) newp->dumpTree(cout," _new: "); // Link in conditional replaceHandle.relink(newp); // Added X's, tristate them too newp->accept(*this); } else { // lvalue replaceBoundLvalue(nodep, condp); } } } // visit(AstSliceSel) not needed as its bounds are constant and checked // in V3Width. virtual void visit(AstArraySel* nodep) { 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"); } // Find range of dtype we are selecting from int declElements = -1; AstNodeDType* dtypep = nodep->fromp()->dtypep()->skipRefp(); if (!dtypep) nodep->v3fatalSrc("Select of non-selectable type"); if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { declElements = adtypep->elementsConst(); } else { nodep->v3error("Select from non-array "<prettyTypeName()); } if (debug()>=9) nodep->dumpTree(cout,"arraysel_old: "); V3Number widthnum (nodep->fileline(), nodep->bitp()->width(), declElements-1); // See if the condition is constant true AstNode* condp = new AstGte (nodep->fileline(), new AstConst(nodep->fileline(), widthnum), nodep->bitp()->cloneTree(false)); // Note below has null backp(); the Edit function knows how to deal with that. condp = V3Const::constifyEdit(condp); if (condp->isOne()) { // We don't need to add a conditional; we know the existing expression is ok condp->deleteTree(); } else if (!lvalue && !nodep->backp()->castArraySel()) { // Too complicated and slow if mid-multidimension // ARRAYSEL(...) -> COND(LT(bitunlinkFrBack(&replaceHandle); V3Number xnum (nodep->fileline(), nodep->width()); if (nodep->isString()) { xnum = V3Number(V3Number::String(), nodep->fileline(), ""); } else { xnum.setAllBitsX(); } AstNode* newp = new AstCondBound (nodep->fileline(), condp, nodep, new AstConst(nodep->fileline(), xnum)); if (debug()>=9) newp->dumpTree(cout," _new: "); // Link in conditional, can blow away temp xor replaceHandle.relink(newp); // Added X's, tristate them too newp->accept(*this); } else if (!lvalue) { // Mid-multidimension read, just use zero // ARRAYSEL(...) -> ARRAYSEL(COND(LT(bitbitp()->unlinkFrBack(&replaceHandle); V3Number zeronum (nodep->fileline(), bitp->width(), 0); AstNode* newp = new AstCondBound (bitp->fileline(), condp, bitp, new AstConst(bitp->fileline(), zeronum)); // Added X's, tristate them too if (debug()>=9) newp->dumpTree(cout," _new: "); replaceHandle.relink(newp); newp->accept(*this); } else { // lvalue replaceBoundLvalue(nodep, condp); } } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit UnknownVisitor(AstNetlist* nodep) { m_modp = NULL; m_assigndlyp = NULL; m_assignwp = NULL; m_constXCvt = false; nodep->accept(*this); } virtual ~UnknownVisitor() { V3Stats::addStat("Unknowns, variables created", m_statUnkVars); } }; //###################################################################### // Unknown class functions void V3Unknown::unknownAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/flexfix0000775000177100017500000000372513205574202015711 0ustar wsnyderwsnyder#!/usr/bin/perl -w ###################################################################### # # Copyright 2002-2017 by Wilson Snyder. Verilator is free software; you # can redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ###################################################################### # DESCRIPTION: Edits flex output to get around various broken flex issues. my $Opt_Prefix = $ARGV[0] or die "%Error: No prefix specified,"; foreach my $line () { # Fix flex 2.6.0 warning $line =~ s/\(\(int\) \(\(yy_n_chars\) \+ number_to_move\) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size\)/((int) ((yy_n_chars) + number_to_move) > (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size)/g; $line =~ s/ number_to_move == YY_MORE_ADJ / (int)number_to_move == (int)YY_MORE_ADJ /; # 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.916/src/V3LinkDot.cpp0000664000177100017500000027555213205574202016610 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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" #include "V3ParseImp.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 // AstNodeModule::user2() // bool. Currently processing for recursion check // ... Note maybe more than one, as can be multiple hierarchy places // AstVarScope::user2p() // AstVarScope*. Base alias for AstInline of this signal // AstVar::user2p() // AstFTask*. If a function variable, the task that links to the variable // AstVar::user4() // bool. True if port set for this variable // AstBegin::user4() // bool. Did name processing // AstNodeModule::user4() // bool. Live module AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser4InUse m_inuser4; public: // ENUMS // In order of priority, compute first ... compute last enum SAMNum { SAMN_MODPORT, SAMN_IFTOP, SAMN__MAX }; // Values for m_scopeAliasMap private: // TYPES typedef multimap NameScopeSymMap; typedef map ScopeAliasMap; typedef set > ImplicitNameSet; typedef vector IfaceVarSyms; typedef vector > IfaceModSyms; static LinkDotState* s_errorThisp; // Last self, for error reporting only // MEMBERS VSymGraph m_syms; // Symbol table VSymEnt* m_dunitEntp; // $unit entry NameScopeSymMap m_nameScopeSymMap; // Map of scope referenced by non-pretty textual name ImplicitNameSet m_implicitNameSet; // For [module][signalname] if we can implicitly create it ScopeAliasMap m_scopeAliasMap[SAMN__MAX]; // Map of aliases IfaceVarSyms m_ifaceVarSyms; // List of AstIfaceRefDType's to be imported IfaceModSyms m_ifaceModSyms; // List of AstIface+Symbols to be processed bool m_forPrimary; // First link bool m_forPrearray; // Compress cell__[array] refs bool m_forScopeCreation; // Remove VarXRefs for V3Scope public: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void dump(const string& nameComment="linkdot", bool force=false) { if (debug()>=6 || force) { string filename = v3Global.debugFilename(nameComment)+".txt"; const vl_unique_ptr logp (V3File::new_ofstream(filename)); if (logp->fail()) v3fatalSrc("Can't write "<first<<" ("<first->nodep()->typeName() <<") <- "<second<<" "<second->nodep()<preErrorDump(); } void preErrorDump() { static bool diddump = false; if (!diddump && v3Global.opt.dumpTree()) { diddump = true; dump("linkdot-preerr",true); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("linkdot-preerr.tree")); } } // CONSTRUCTORS LinkDotState(AstNetlist* rootp, VLinkDotStep step) : m_syms(rootp) { UINFO(4,__FUNCTION__<<": "<castVar()) return "variable"; else if (nodep->castCell()) return "cell"; else if (nodep->castTask()) return "task"; else if (nodep->castFunc()) return "function"; else if (nodep->castBegin()) return "block"; else if (nodep->castIface()) return "interface"; else if (nodep->castParamTypeDType()) return "parameter type"; else return nodep->prettyTypeName(); } VSymEnt* rootEntp() const { return m_syms.rootp(); } VSymEnt* dunitEntp() const { return m_dunitEntp; } void checkDuplicate(VSymEnt* lookupSymp, AstNode* nodep, const string& name) { // Lookup the given name under current symbol table // Insert if not found // Report error if there's a duplicate // // Note we only check for conflicts at the same level; it's ok if one block hides another // We also wouldn't want to not insert it even though it's lower down VSymEnt* foundp = lookupSymp->findIdFlat(name); AstNode* fnodep = foundp ? foundp->nodep() : NULL; if (!fnodep) { // Not found, will add in a moment. } else if (nodep==fnodep) { // Already inserted. // Good. } else if (foundp->imported()) { // From package // We don't throw VARHIDDEN as if the import is later the symbol table's import wouldn't warn } else if (nodep->castBegin() && fnodep->castBegin() && nodep->castBegin()->generate()) { // Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks // See t_gen_forif.v for an example. } else { UINFO(4,"name "<name UINFO(4,"Var1 "<type() == fnodep->type()) { nodep->v3error("Duplicate declaration of "<prettyName()<warnMore()<<"... Location of original declaration"); } else { nodep->v3error("Unsupported in C: "<prettyName()<warnMore()<<"... Location of original declaration"); } } } void insertDUnit(AstNetlist* nodep) { // $unit on top scope VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTdunit se"<<(void*)symp<parentp(rootEntp()); // Needed so backward search can find name of top module symp->fallbackp(NULL); rootEntp()->insert("$unit ",symp); // Space so can never name conflict with user code // if (m_dunitEntp) nodep->v3fatalSrc("Call insertDUnit only once"); m_dunitEntp = symp; } VSymEnt* insertTopCell(AstNodeModule* nodep, const string& scopename) { // Only called on the module at the very top of the hierarchy VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTtop se"<<(void*)symp<<" "<parentp(rootEntp()); // Needed so backward search can find name of top module symp->fallbackp(dunitEntp()); // Needed so can find $unit stuff nodep->user1p(symp); checkDuplicate(rootEntp(), nodep, nodep->origName()); rootEntp()->insert(nodep->origName(),symp); if (forScopeCreation()) m_nameScopeSymMap.insert(make_pair(scopename, symp)); return symp; } VSymEnt* insertCell(VSymEnt* abovep, VSymEnt* modSymp, AstCell* nodep, const string& scopename) { if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTcel se"<<(void*)symp<<" "<reinsert(nodep->name(), symp); } if (forScopeCreation()) m_nameScopeSymMap.insert(make_pair(scopename, symp)); return symp; } VSymEnt* insertInline(VSymEnt* abovep, VSymEnt* modSymp, AstCellInline* nodep, const string& basename) { // A fake point in the hierarchy, corresponding to an inlined module // This refrences to another Sym, and eventually resolves to a module with a prefix if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTinl se"<<(void*)symp<<" "<user1p(symp); checkDuplicate(abovep, nodep, nodep->name()); abovep->reinsert(basename, symp); if (abovep != modSymp && !modSymp->findIdFlat(nodep->name())) { // If it's foo_DOT_bar, we need to be able to find it under that too. modSymp->reinsert(nodep->name(), symp); } return symp; } VSymEnt* insertBlock(VSymEnt* abovep, const string& name, AstNode* nodep, AstPackage* packagep) { // A fake point in the hierarchy, corresponding to a begin or function/task block // After we remove begins these will go away // Note we fallback to the symbol table of the parent, as we want to find variables there // However, cells walk the graph, so cells will appear under the begin/ftask itself if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTblk se"<<(void*)symp<<" above=se"<<(void*)abovep<<" node="<parentp(abovep); symp->packagep(packagep); symp->fallbackp(abovep); nodep->user1p(symp); if (name != "") { checkDuplicate(abovep, nodep, name); } // Duplicates are possible, as until resolve generates might have 2 same cells under an if abovep->reinsert(name, symp); return symp; } VSymEnt* insertSym(VSymEnt* abovep, const string& name, AstNode* nodep, AstPackage* packagep) { if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTsym se"<<(void*)symp<<" name='"<name()); if (it == m_nameScopeSymMap.end()) { nodep->v3fatalSrc("Scope never assigned a symbol entry?"); } return it->second; } void implicitOkAdd(AstNodeModule* nodep, const string& varname) { // Mark the given variable name as being allowed to be implicitly declared if (nodep) { ImplicitNameSet::iterator it = m_implicitNameSet.find(make_pair(nodep,varname)); if (it == m_implicitNameSet.end()) { m_implicitNameSet.insert(make_pair(nodep,varname)); } } } bool implicitOk(AstNodeModule* nodep, const string& varname) { return nodep && (m_implicitNameSet.find(make_pair(nodep,varname)) != m_implicitNameSet.end()); } // Track and later recurse interface modules void insertIfaceModSym(AstIface* nodep, VSymEnt* symp) { m_ifaceModSyms.push_back(make_pair(nodep, symp)); } void computeIfaceModSyms(); // Track and later insert interface references void insertIfaceVarSym(VSymEnt* symp) { // Where sym is for a VAR of dtype IFACEREFDTYPE m_ifaceVarSyms.push_back(symp); } // Iface for a raw or arrayed iface static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) { AstIfaceRefDType* ifacerefp = nodep->castIfaceRefDType(); if (!ifacerefp) { if (AstUnpackArrayDType* arrp = nodep->castUnpackArrayDType()) { ifacerefp = arrp->subDTypep()->castIfaceRefDType(); } } return ifacerefp; } void computeIfaceVarSyms() { for (IfaceVarSyms::iterator it = m_ifaceVarSyms.begin(); it != m_ifaceVarSyms.end(); ++it) { VSymEnt* varSymp = *it; AstVar* varp = varSymp ? varSymp->nodep()->castVar() : NULL; UINFO(9, " insAllIface se"<<(void*)varSymp<<" "<subDTypep()); if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!"); if (!ifacerefp->ifaceViaCellp()) { if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if made mistake ifacerefp->v3error("Cannot find file containing interface: "<ifaceName())); continue; } else { ifacerefp->v3fatalSrc("Unlinked interface"); } } else if (ifacerefp->ifaceViaCellp()->dead()) { ifacerefp->v3error("Parent cell's interface is not found: "<ifaceName())); continue; } VSymEnt* ifaceSymp = getNodeSym(ifacerefp->ifaceViaCellp()); VSymEnt* ifOrPortSymp = ifaceSymp; // Link Modport names to the Modport Node under the Interface if (ifacerefp->isModport()) { VSymEnt* foundp = ifaceSymp->findIdFallback(ifacerefp->modportName()); bool ok = false; if (foundp) { if (AstModport* modportp = foundp->nodep()->castModport()) { UINFO(4,"Link Modport: "<modportp(modportp); ifOrPortSymp = foundp; ok = true; } } if (!ok) ifacerefp->v3error("Modport not found under interface '" <prettyName(ifacerefp->ifaceName()) <<"': "<prettyName(ifacerefp->modportName())); } // Alias won't expand until interfaces and modport names are known; see notes at top insertScopeAlias(SAMN_IFTOP, varSymp, ifOrPortSymp); } m_ifaceVarSyms.clear(); } void insertScopeAlias(SAMNum samn, VSymEnt* lhsp, VSymEnt* rhsp) { // Track and later insert scope aliases; an interface referenced by a child cell connecting to that interface // Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell UINFO(9," insertScopeAlias se"<<(void*)lhsp<<" se"<<(void*)rhsp<nodep()->castCell() && !rhsp->nodep()->castCell()->modp()->castIface()) { rhsp->nodep()->v3fatalSrc("Got a non-IFACE alias RHS"); } m_scopeAliasMap[samn].insert(make_pair(lhsp, rhsp)); } void computeScopeAliases() { UINFO(9,"computeIfaceAliases\n"); for (int samn=0; samnfirst; VSymEnt* srcp = lhsp; while (1) { // Follow chain of aliases up to highest level non-alias ScopeAliasMap::iterator it2 = m_scopeAliasMap[samn].find(srcp); if (it2 != m_scopeAliasMap[samn].end()) { srcp = it2->second; continue; } else break; } UINFO(9," iiasa: Insert alias se"<nodep()->typeName() <<") <- se"<nodep()<importFromIface(symsp(), srcp); // Allow access to objects not permissible to be listed in a modport if (srcp->nodep()->castModport()) { lhsp->importFromIface(symsp(), srcp->parentp(), true); } } //m_scopeAliasMap[samn].clear(); // Done with it, but put into debug file } } private: VSymEnt* findWithAltFallback(VSymEnt* symp, const string& name, const string& altname) { VSymEnt* findp = symp->findIdFallback(name); if (findp) return findp; if (altname != "") { UINFO(8," alt fallback\n"); findp = symp->findIdFallback(altname); } return findp; } public: VSymEnt* findDotted(VSymEnt* lookupSymp, const string& dotname, string& baddot, VSymEnt*& okSymp) { // Given a dotted hierarchy name, return where in scope it is // Note when dotname=="" we just fall through and return lookupSymp UINFO(8," dottedFind se"<<(void*)lookupSymp<<" '"<nodep()->castCell() : NULL; // Replicated below AstCellInline* inlinep = lookupSymp ? lookupSymp->nodep()->castCellInline() : NULL; // 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 { bool crossedCell = false; // Crossed a cell boundary while (lookupSymp) { lookupSymp = lookupSymp->parentp(); cellp = lookupSymp ? lookupSymp->nodep()->castCell() : NULL; // Replicated above inlinep = lookupSymp ? lookupSymp->nodep()->castCellInline() : NULL; // 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; if (crossedCell && lookupSymp->nodep()->castVar()) { UINFO(9,"\t\tNot found but matches var name in parent "<symPrefix()=="") ? "" : " as ") <<((lookupSymp->symPrefix()=="") ? "" : lookupSymp->symPrefix()+dotname) <<" at se"<symPrefix(); VSymEnt* foundp = NULL; while (!foundp) { foundp = lookupSymp->findIdFallback(prefix + dotname); // Might be NULL if (prefix == "") { break; } prefix = removeLastInlineScope(prefix); } 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 bool m_inRecursion; // Inside a recursive module 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(); } virtual AstConst* parseParamLiteral(FileLine* fl, string literal) { bool success = false; if (literal[0] == '"') { // This is a string string v = literal.substr(1, literal.find('"', 1) - 1); V3Number n(V3Number::VerilogStringLiteral(), fl, v); return new AstConst(fl,n); } else if ((literal.find(".") != string::npos) || (literal.find("e") != string::npos)) { // This may be a real double v = V3ParseImp::parseDouble(literal.c_str(), literal.length(), &success); if (success) { return new AstConst(fl, AstConst::RealDouble(), v); } } if (!success) { // This is either an integer or an error // We first try to convert it as C literal. If strtol returns // 0 this is either an error or 0 was parsed. But in any case // we will try to parse it as a verilog literal, hence having // the false negative for 0 is okay. If anything remains in // the string after the number, this is invalid C and we try // the Verilog literal parser. char* endp; int v = strtol(literal.c_str(), &endp, 0); if ((v != 0) && (endp[0] == 0)) { // C literal V3Number n(fl, 32, v); return new AstConst(fl, n); } else { // Try a Verilog literal (fatals if not) V3Number n(fl, literal.c_str()); return new AstConst(fl, n); } } return NULL; } // VISITs virtual void visit(AstNetlist* nodep) { // 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) {} virtual void visit(AstNodeModule* nodep) { // 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 && nodep->user2()) { nodep->v3error("Unsupported: Identically recursive module (module instantiates itself, without changing parameters): " <origName())); } else if (doit) { UINFO(4," 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 "<user2(true); nodep->iterateChildren(*this); nodep->user2(false); 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) { UINFO(5," CELL under "<recursive() && m_inRecursion) return; nodep->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; bool oldRecursion = m_inRecursion; // 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; m_inRecursion = nodep->recursive(); // We don't report NotFoundModule, as may be a unused module in a generate if (nodep->modp()) nodep->modp()->accept(*this); } m_scope = oldscope; m_beginp = oldbeginp; m_modSymp = oldModSymp; m_curSymp = oldCurSymp; m_paramNum = oldParamNum; m_inRecursion = oldRecursion; } virtual void visit(AstCellInline* nodep) { 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) { nodep->user1p(m_curSymp); nodep->iterateChildren(*this); } virtual void visit(AstGenerate* nodep) { // 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) { 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) { // NodeTask: Remember its name for later resolution UINFO(5," "<v3fatalSrc("Function/Task not under module?"); // 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) { // Var: Remember its name for later resolution if (!m_curSymp || !m_modSymp) nodep->v3fatalSrc("Var not under module?"); 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(); VL_DANGLING(nodep); } 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) { if (m_statep->forPrimary() && nodep->isGParam() && (m_statep->rootEntp()->nodep() == m_modSymp->parentp()->nodep())) { // This is the toplevel module. Check for command line overwrites of parameters // We first search if the parameter is overwritten and then replace it with a // new value. It will keep the same FileLine information. if (v3Global.opt.hasParameter(nodep->name())) { AstVar* newp = new AstVar(nodep->fileline(), AstVarType(AstVarType::GPARAM), nodep->name(), nodep); string svalue = v3Global.opt.parameter(nodep->name()); if (AstNode* valuep = parseParamLiteral(nodep->fileline(), svalue)) { newp->valuep(valuep); UINFO(9," replace parameter "<replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); nodep = newp; } } } 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); } AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(nodep->subDTypep()); if (ifacerefp) { // Can't resolve until interfaces and modport names are known; see notes at top m_statep->insertIfaceVarSym(insp); } } } } virtual void visit(AstTypedef* nodep) { // Remember its name for later resolution if (!m_curSymp) nodep->v3fatalSrc("Typedef not under module?"); nodep->iterateChildren(*this); m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep); } virtual void visit(AstParamTypeDType* nodep) { if (!m_curSymp) nodep->v3fatalSrc("Parameter type not under module?"); nodep->iterateChildren(*this); m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep); } virtual void visit(AstCFunc* nodep) { // 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) { // 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) { UINFO(4," 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: "<getNodeSym(nodep->packagep()); if (nodep->name()!="*") { VSymEnt* impp = srcp->findIdFlat(nodep->name()); if (!impp) { nodep->v3error("Export object not found: "<packagep()->prettyName()<<"::"<prettyName()); } } m_curSymp->exportFromPackage(m_statep->symsp(), srcp, nodep->name()); UINFO(9," Link Done: "<exportStarStar(m_statep->symsp()); // No longer needed, but can't delete until any multi-instantiated modules are expanded } virtual void visit(AstNode* nodep) { // Default: Just iterate nodep->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) {} virtual void visit(AstNodeModule* nodep) { 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) { // 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) { 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 ? foundp->nodep()->castCell() : NULL; 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(); VL_DANGLING(nodep); } virtual void visit(AstAssignW* nodep) { // 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) { // 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) { // Unsupported gates need implicit creation pinImplicitExprRecurse(nodep); // We're done with implicit gates nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstNode* nodep) { // 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) { // Recurse..., backward as must do packages before using packages nodep->iterateChildrenBackwards(*this); } virtual void visit(AstScope* nodep) { 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) { 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()); if (!dtypep) nodep->v3fatalSrc("Non AstIfaceRefDType on isIfaceRef() var"); UINFO(9,"Iface parent dtype "<cellName(); string baddot; VSymEnt* okSymp; VSymEnt* cellSymp = m_statep->findDotted(m_modSymp, ifcellname, baddot, okSymp); if (!cellSymp) nodep->v3fatalSrc("No symbol for interface cell: " <prettyName(ifcellname)); UINFO(5, " Found interface cell: se"<<(void*)cellSymp<<" "<nodep()<modportName()!="") { VSymEnt* mpSymp = m_statep->findDotted(m_modSymp, ifcellname, baddot, okSymp); if (!mpSymp) { nodep->v3fatalSrc("No symbol for interface modport: " <prettyName(dtypep->modportName())); } else cellSymp = mpSymp; UINFO(5, " Found modport cell: se"<<(void*)cellSymp<<" "<nodep()<insertScopeAlias(LinkDotState::SAMN_IFTOP, varSymp, cellSymp); } } } virtual void visit(AstNodeFTask* nodep) { 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) { // 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) { UINFO(5,"ASSIGNVARSCOPE "<=9) nodep->dumpTree(cout,"-\t\t\t\tavs: "); VSymEnt* rhsSymp; { AstVarRef* refp = nodep->rhsp()->castVarRef(); AstVarXRef* xrefp = nodep->rhsp()->castVarXRef(); if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin"); string inl = (xrefp && xrefp->inlinedDots().size()) ? (xrefp->inlinedDots() + "__DOT__") : ""; VSymEnt* symp = NULL; string scopename; while (!symp) { scopename = refp ? refp->name() : (inl.size() ? (inl + xrefp->name()) : xrefp->name()); string baddot; VSymEnt* okSymp; symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp); if (inl == "") break; inl = LinkDotState::removeLastInlineScope(inl); } if (!symp) UINFO(9,"No symbol for interface alias rhs ("<v3fatalSrc("No symbol for interface alias rhs"); UINFO(5, " Found a linked scope RHS: "<nodep()<lhsp()->castVarXRef(); AstVarRef* refp = nodep->lhsp()->castVarRef(); if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin"); string scopename = refp ? refp->varp()->name() : xrefp->dotted()+"."+xrefp->name(); string baddot; VSymEnt* okSymp; VSymEnt* symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp); if (!symp) nodep->v3fatalSrc("No symbol for interface alias lhs"); UINFO(5, " Found a linked scope LHS: "<nodep()<insertScopeAlias(LinkDotState::SAMN_IFTOP, lhsSymp, rhsSymp); // We have stored the link, we don't need these any more nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } // 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*) {} virtual void visit(AstVar*) {} virtual void visit(AstNodeMath*) {} virtual void visit(AstNode* nodep) { // 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) { // 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) { UINFO(5," fif: "<iterateChildren(*this); if (nodep->isExport()) nodep->v3error("Unsupported: modport export"); VSymEnt* symp = m_curSymp->findIdFallback(nodep->name()); if (!symp) { nodep->v3error("Modport item not found: "<prettyName()); } else if (AstNodeFTask* ftaskp = symp->nodep()->castNodeFTask()) { // Make symbol under modport that points at the _interface_'s var, not the modport. nodep->ftaskp(ftaskp); VSymEnt* subSymp = m_statep->insertSym(m_curSymp, nodep->name(), ftaskp, NULL/*package*/); m_statep->insertScopeAlias(LinkDotState::SAMN_MODPORT, subSymp, symp); } else { nodep->v3error("Modport item is not a function/task: "<prettyName()); } if (m_statep->forScopeCreation()) { // Done with AstModportFTaskRef. // Delete to prevent problems if we dead-delete pointed to ftask nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); } } virtual void visit(AstModportVarRef* nodep) { 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 via the modport. // (Need modport still to test input/output markings) nodep->varp(varp); m_statep->insertSym(m_curSymp, nodep->name(), nodep, 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); VL_DANGLING(nodep); } } virtual void visit(AstNode* nodep) { // 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_unresolved; // Unresolved, needs help from V3Param AstNode* m_unlinkedScope;// Unresolved scope, needs corresponding VarXRef 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 = ""; m_unresolved = false; m_unlinkedScope = NULL; } string ascii() const { static const char* const 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*/); } } AstVar* foundToVarp(const VSymEnt* symp, AstNode* nodep, bool lvalue) { // Return a variable if possible, auto converting a modport to variable if (!symp) { return NULL; } else if (symp->nodep()->castVar()) { return symp->nodep()->castVar(); } else if (symp->nodep()->castModportVarRef()) { AstModportVarRef* snodep = symp->nodep()->castModportVarRef(); AstVar* varp = snodep->varp(); if (lvalue && snodep->isInput()) { nodep->v3error("Attempt to drive input-only modport: "<prettyName()); } // else other simulators don't warn about reading, and IEEE doesn't say illegal return varp; } else { return NULL; } } 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; } void markAndCheckPinDup(AstNode* nodep, AstNode* refp, const char* whatp) { if (refp->user5p() && refp->user5p()!=nodep) { nodep->v3error("Duplicate "<prettyName()<user5p()->warnMore() <<"... Location of original "<user5p(nodep); } } // VISITs virtual void visit(AstNetlist* nodep) { // Recurse..., backward as must do packages before using packages nodep->iterateChildrenBackwards(*this); } virtual void visit(AstTypeTable* nodep) {} virtual void visit(AstNodeModule* nodep) { 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) { 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) { checkNoDot(nodep); if (m_statep->forScopeCreation()) { nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); } } virtual void visit(AstCell* nodep) { // 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) { // Pin: Link to submodule's port checkNoDot(nodep); nodep->iterateChildren(*this); if (!nodep->modVarp()) { if (!m_pinSymp) nodep->v3fatalSrc("Pin not under cell?"); VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name()); const char* whatp = nodep->param() ? "parameter pin" : "pin"; if (!foundp) { if (nodep->name() == "__paramNumber1" && m_cellp->modp()->castPrimitive()) { // Primitive parameter is really a delay we can just ignore nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); return; } nodep->v3error(ucfirst(whatp)<<" not found: "<prettyName()); } else if (AstVar* refp = foundp->nodep()->castVar()) { if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) { nodep->v3error(ucfirst(whatp)<<" is not an in/out/inout/param/interface: "<prettyName()); } else { nodep->modVarp(refp); markAndCheckPinDup(nodep, refp, whatp); } } else if (AstParamTypeDType* refp = foundp->nodep()->castParamTypeDType()) { nodep->modPTypep(refp); markAndCheckPinDup(nodep, refp, whatp); } else { nodep->v3error(ucfirst(whatp)<<" not found: "<prettyName()); } } // Early return() above when deleted } virtual void visit(AstDot* nodep) { // 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_unresolved && (nodep->lhsp()->castCellRef() || nodep->lhsp()->castCellArrayRef())) { m_ds.m_unlinkedScope = nodep->lhsp(); } 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); VL_DANGLING(nodep); } else { // Dot midpoint AstNode* newp = nodep->rhsp()->unlinkFrBack(); if (m_ds.m_unresolved) { AstCellRef* crp = new AstCellRef(nodep->fileline(), nodep->name(), nodep->lhsp()->unlinkFrBack(), newp); newp = crp; } nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); } } if (start) { m_ds = lastStates; } else { m_ds.m_dotp = lastStates.m_dotp; } } virtual void visit(AstParseRef* nodep) { 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_dotPos == DP_NONE); // Save, as m_dotp will be changed 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); VL_DANGLING(nodep); } else { // string expectWhat; bool allowScope = false; bool allowVar = false; if (m_ds.m_dotPos == DP_PACKAGE) { // {package}::{a} AstPackage* packagep = NULL; expectWhat = "scope/variable"; allowScope = true; allowVar = true; if (!m_ds.m_dotp->lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link"); packagep = m_ds.m_dotp->lhsp()->castPackageRef()->packagep(); if (!packagep) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link"); m_ds.m_dotSymp = m_statep->getNodeSym(packagep); m_ds.m_dotPos = DP_SCOPE; } else if (m_ds.m_dotPos == DP_SCOPE) { // {a}.{b}, where {a} maybe a module name // or variable, where dotting into structure member expectWhat = "scope/variable"; allowScope = true; allowVar = true; } else if (m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_FINAL) { expectWhat = "variable"; allowVar = true; } else { UINFO(1,"ds="<v3fatalSrc("Unhandled AstParseRefExp"); } // Lookup VSymEnt* foundp; string baddot; VSymEnt* okSymp = NULL; if (allowScope) { foundp = m_statep->findDotted(m_ds.m_dotSymp, nodep->name(), baddot, okSymp); // Maybe NULL } else { foundp = m_ds.m_dotSymp->findIdFallback(nodep->name()); } if (foundp) UINFO(9," found=se"<<(void*)foundp<<" exp="<name(); m_ds.m_dotSymp = foundp; m_ds.m_dotPos = DP_SCOPE; // Upper AstDot visitor will handle it from here } else if (foundp->nodep()->castCell() && allowVar && m_cellp) { AstCell* cellp = foundp->nodep()->castCell(); if (cellp->modp()->castIface()) { // Interfaces can be referenced like a variable for interconnect 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"; VSymEnt* ifaceSymp = parentEntp->findIdFallback(findName); AstVar* ifaceRefVarp = ifaceSymp ? ifaceSymp->nodep()->castVar() : NULL; 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); VL_DANGLING(nodep); } else if (cellp->modp()->castNotFoundModule()) { cellp->v3error("Cannot find file containing interface: " << AstNode::prettyName(cellp->modp()->name())); } } } else if (AstVar* varp = foundToVarp(foundp, nodep, false)) { AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(varp->subDTypep()); if (ifacerefp) { 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); VL_DANGLING(nodep); } else if (allowVar) { AstNode* newp; if (m_ds.m_dotText != "") { AstVarXRef* refp = new AstVarXRef(nodep->fileline(), nodep->name(), m_ds.m_dotText, false); // lvalue'ness computed later refp->varp(varp); m_ds.m_dotText = ""; if (m_ds.m_unresolved && m_ds.m_unlinkedScope) { newp = new AstUnlinkedRef(nodep->fileline(), refp->castVarXRef(), refp->name(), m_ds.m_unlinkedScope->unlinkFrBack()); m_ds.m_unlinkedScope = NULL; m_ds.m_unresolved = false; } else { newp = refp; } } else { AstVarRef* refp = new AstVarRef(nodep->fileline(), varp, false); // lvalue'ness computed later refp->packagep(foundp->packagep()); newp = refp; } UINFO(9," new "<replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); 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); VL_DANGLING(nodep); } } else if (AstEnumItem* valuep = foundp->nodep()->castEnumItem()) { if (allowVar) { AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep, foundp->packagep()); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); ok = true; m_ds.m_dotText = ""; } } // if (!ok) { // Cells/interfaces can't be implicit bool isCell = foundp ? foundp->nodep()->castCell() != NULL : false; bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText=="" && !isCell); 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); VL_DANGLING(nodep); createImplicitVar (m_curSymp, newp, m_modp, m_modSymp, err); } } } if (start) { m_ds = lastStates; } } virtual void visit(AstVarRef* nodep) { // 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 ? foundToVarp(foundp, nodep, nodep->lvalue()) : NULL) { 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) { // 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 ? foundToVarp(foundp, nodep, nodep->lvalue()) : NULL; nodep->varp(varp); UINFO(7," Resolved "<varp()) { nodep->v3error("Can't find definition of '"<dotted()+"."+nodep->prettyName()); okSymp->cellErrorScopes(nodep); } // V3Inst may have expanded arrays of interfaces to AstVarXRef's even though they are in the same module // detect this and convert to normal VarRefs if (!m_statep->forPrearray() && !m_statep->forScopeCreation()) { if (nodep->dtypep()->castIfaceRefDType()) { AstVarRef* newrefp = new AstVarRef(nodep->fileline(), nodep->varp(), nodep->lvalue()); nodep->replaceWith(newrefp); nodep->deleteTree(); VL_DANGLING(nodep); } } } else { string baddot; VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); AstVarScope* vscp = foundp ? foundp->nodep()->castVarScope() : 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()->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(); VL_DANGLING(nodep); UINFO(9," new "<iterateChildren(*this); } virtual void visit(AstMethodSel* nodep) { // Created here so should already be resolved. DotStates lastStates = m_ds; { m_ds.init(m_curSymp); nodep->iterateChildren(*this); } m_ds = lastStates; } virtual void visit(AstVar* nodep) { 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) { 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) { if (m_ds.m_unresolved && m_ds.m_unlinkedScope) { AstNodeFTaskRef* newftaskp = nodep->cloneTree(false); newftaskp->dotted(m_ds.m_dotText); AstNode* newp = new AstUnlinkedRef(nodep->fileline(), newftaskp, nodep->name(), m_ds.m_unlinkedScope->unlinkFrBack()); m_ds.m_unlinkedScope = NULL; m_ds.m_unresolved = false; nodep->replaceWith(newp); return; } else { nodep->dotted(m_ds.m_dotText); // Maybe "" } } else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) { // Found a Var, everything following is method call. {scope}.{var}.HERE {method} ( ARGS ) AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); AstNode* argsp = NULL; if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext(); AstNode* newp = new AstMethodSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name(), argsp); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); return; } else { checkNoDot(nodep); } if (nodep->packagep() && nodep->taskp()) { // References into packages don't care about cell hierarchy. } else if (!m_modSymp) { UINFO(9,"Dead module for "<taskp(NULL); // Module that is not in hierarchy. We'll be dead code eliminating it later. } else if (nodep->dotted()=="" && nodep->taskp()) { // Earlier should have setup the links // Might be under a BEGIN we're not processing, so don't relink it } else { string baddot; VSymEnt* okSymp = NULL; VSymEnt* dotSymp = m_curSymp; // Start search at module, as a variable of same name under a subtask isn't a relevant hit // // however a function under a begin/end is. So we want begins, but not the function if (nodep->packagep()) { // Look only in specified package dotSymp = m_statep->getNodeSym(nodep->packagep()); } else { if (nodep->inlinedDots()!="") { // Correct for current scope dotSymp = m_modSymp; // Dotted lookup is always relative to module, as maybe variable name lower down with same scope name we want to ignore (t_math_divw) string inl = AstNode::dedotName(nodep->inlinedDots()); UINFO(8,"\t\tInlined "<findDotted(dotSymp, inl, baddot, okSymp); if (!dotSymp) { okSymp->cellErrorScopes(nodep); nodep->v3fatalSrc("Couldn't resolve inlined scope '"<inlinedDots()); } } dotSymp = m_statep->findDotted(dotSymp, nodep->dotted(), baddot, okSymp); // Maybe NULL } VSymEnt* foundp = NULL; AstNodeFTask* taskp = NULL; foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); taskp = foundp ? foundp->nodep()->castNodeFTask() : NULL; // Maybe NULL if (taskp) { nodep->taskp(taskp); nodep->packagep(foundp->packagep()); UINFO(7," Resolved "<v3error("Found definition of '"<prettyName() <<"'"<<" as a "<nodep()->typeName() <<" but expected a task/function"); } else if (nodep->dotted() == "") { nodep->v3error("Can't find definition of task/function: "<prettyName()); } else { nodep->v3error("Can't find definition of '"<dotted()+"."+nodep->prettyName()); okSymp->cellErrorScopes(nodep); } } taskFuncSwapCheck(nodep); } DotStates lastStates = m_ds; { m_ds.init(m_curSymp); nodep->iterateChildren(*this); } m_ds = lastStates; } virtual void visit(AstSelBit* nodep) { if (nodep->user3SetOnce()) return; nodep->lhsp()->iterateAndNext(*this); if (m_ds.m_dotPos == DP_SCOPE) { // Already under dot, so this is {modulepart} DOT {modulepart} UINFO(9," deferring until after a V3Param pass: "<fromp()->iterateAndNext(*this); DotStates lastStates = m_ds; { m_ds.init(m_curSymp); nodep->bitp()->iterateAndNext(*this); nodep->attrp()->iterateAndNext(*this); } m_ds = lastStates; if (m_ds.m_unresolved && m_ds.m_dotPos == DP_SCOPE) { AstNode* exprp = nodep->bitp()->unlinkFrBack(); AstCellArrayRef* newp = new AstCellArrayRef(nodep->fileline(), nodep->fromp()->name(), exprp); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); } } virtual void visit(AstNodePreSel* nodep) { // 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) { // checkNoDot not appropriate, can be under a dot nodep->iterateChildren(*this); } virtual void visit(AstBegin* nodep) { 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) { // 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 ? foundp->nodep()->castTypedef() : NULL) { nodep->refDTypep(defp->subDTypep()); nodep->packagep(foundp->packagep()); } else if (AstParamTypeDType* defp = foundp ? foundp->nodep()->castParamTypeDType() : NULL) { nodep->refDTypep(defp); nodep->packagep(foundp->packagep()); } else { nodep->v3error("Can't find typedef: "<prettyName()); } } nodep->iterateChildren(*this); } virtual void visit(AstDpiExport* nodep) { // 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 ? foundp->nodep()->castNodeFTask() : NULL; 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(); VL_DANGLING(nodep); } virtual void visit(AstPackageImport* nodep) { // No longer needed checkNoDot(nodep); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstPackageExport* nodep) { // No longer needed checkNoDot(nodep); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstPackageExportStarStar* nodep) { // No longer needed checkNoDot(nodep); nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); } virtual void visit(AstCellRef* nodep) { UINFO(5," AstCellRef: "<iterateChildren(*this); } virtual void visit(AstCellArrayRef* nodep) { UINFO(5," AstCellArrayRef: "<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.916/src/V3Coverage.cpp0000664000177100017500000003537613205574202016775 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // COVERAGE TRANSFORMATIONS: // At each IF/(IF else)/CASEITEM, // If there's no coverage off on the block below it, // or a $stop // Insert a COVERDECL node in the module. // (V3Emit reencodes into per-module numbers for emitting.) // Insert a COVERINC node at the end of the statement list // for that if/else/case. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Coverage.h" #include "V3Ast.h" //###################################################################### // Coverage state, as a visitor of each AstNode class CoverageVisitor : public AstNVisitor { private: // TYPES typedef map FileMap; struct ToggleEnt { string m_comment; // Comment for coverage dump AstNode* m_varRefp; // How to get to this element AstNode* m_chgRefp; // How to get to this element ToggleEnt(const string& comment, AstNode* vp, AstNode* cp) : m_comment(comment), m_varRefp(vp), m_chgRefp(cp) {} ~ToggleEnt() {} void cleanup() { m_varRefp->deleteTree(); m_varRefp=NULL; m_chgRefp->deleteTree(); m_chgRefp=NULL; } }; // NODE STATE // Entire netlist: // AstIf::user1() -> bool. True indicates ifelse processed AstUser1InUse m_inuser1; // STATE bool m_checkBlock; // Should this block get covered? AstNodeModule* m_modp; // Current module to add statement to bool m_inToggleOff; // In function/task etc bool m_inModOff; // In module with no coverage FileMap m_fileps; // Column counts for each fileline string m_beginHier; // AstBegin hier name for user coverage points // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } const char* varIgnoreToggle(AstVar* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3TraceDecl::varIgnoreTrace if (!nodep->isToggleCoverable()) return "Not relevant signal type"; if (!v3Global.opt.coverageUnderscore()) { string prettyName = nodep->prettyName(); if (prettyName[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) { 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) { bool oldtog = m_inToggleOff; { m_inToggleOff = true; nodep->iterateChildren(*this); } m_inToggleOff = oldtog; } virtual void visit(AstVar* nodep) { 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); chgVarp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); 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) { // Note not AstNodeIf; other types don't get covered UINFO(4," IF: "<elsesp()->castIf() && !nodep->elsesp()->castIf()->nextp()); if (elsif) nodep->elsesp()->castIf()->user1(true); // nodep->ifsp()->iterateAndNext(*this); if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it UINFO(4," COVER: "<user1()) { nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "elsif")); } else { nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "if")); } } // Don't do empty else's, only empty if/case's if (nodep->elsesp()) { m_checkBlock = true; nodep->elsesp()->iterateAndNext(*this); if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it UINFO(4," COVER: "<addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "v_line", "else")); } } } m_checkBlock = true; // Reset as a child may have cleared it } } virtual void visit(AstCaseItem* nodep) { 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) { 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) { 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(); VL_DANGLING(nodep); } else { if (m_checkBlock) nodep->iterateChildren(*this); } } virtual void visit(AstBegin* nodep) { // 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) { // Default: Just iterate if (m_checkBlock) { nodep->iterateChildren(*this); m_checkBlock = true; // Reset as a child may have cleared it } } public: // CONSTUCTORS explicit CoverageVisitor(AstNetlist* rootp) { // Operate on all modules m_checkBlock = true; m_beginHier = ""; m_inToggleOff = false; m_inModOff = true; rootp->iterateChildren(*this); } virtual ~CoverageVisitor() {} }; //###################################################################### // Coverage class functions void V3Coverage::coverage(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3GraphTest.cpp0000664000177100017500000002770713205574202017142 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph tests // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3Graph.h" #include "V3GraphDfa.h" //###################################################################### //###################################################################### // Test class class V3GraphTest { public: // ***These tests only run with DEBUG ON*** static int debug() { static int level = -1; // Note setting just --debug will not enable this, as we exit when we run the test if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__, 0); return level; } protected: // MEMBERS DfaGraph m_graph; // METHODS - for children virtual void runTest() = 0; // Run the test virtual string name() = 0; // Name of the test // Utilities void dump() { if (debug()>=9) { m_graph.dumpDotFilePrefixed("v3graphtest_"+name()); } } public: V3GraphTest() {} virtual ~V3GraphTest() {} void run() { if (debug()) runTest(); } }; //###################################################################### //###################################################################### // Vertices and nodes class V3GraphTestVertex : public V3GraphVertex { string m_name; public: V3GraphTestVertex(V3Graph* graphp, const 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, const 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, const 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); VNUser L = VNUser::fromInt(0xaa); VNUser R = VNUser::fromInt(0xbb); VNUser Z = VNUser::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::selfTest() { // Execute all of the tests UINFO(2,__FUNCTION__<<": "< #include #include #include #include #include #include #include #include #include #include #include #if defined(WIN32) || defined(__MINGW32__) # include // mkdir #endif #include "V3Global.h" #include "V3String.h" #include "V3Os.h" //###################################################################### // Environment string V3Os::getenvStr(const string& envvar, const string& defaultValue) { if (const char* envvalue = getenv(envvar.c_str())) { return envvalue; } else { return defaultValue; } } void V3Os::setenvStr(const string& envvar, const string& value, const string& why) { if (why != "") { UINFO(1,"export "<(vareq.c_str())); #endif } //###################################################################### // Generic filename utilities string V3Os::filenameFromDirBase (const string& dir, const string& basename) { // Don't return ./{filename} because if filename was absolute, that makes it relative if (dir == ".") return basename; else return dir+"/"+basename; } string V3Os::filenameDir (const string& filename) { string::size_type pos; if ((pos = filename.rfind("/")) != string::npos) { return filename.substr(0,pos); } else { return "."; } } string V3Os::filenameNonDir (const string& filename) { string::size_type pos; if ((pos = filename.rfind("/")) != string::npos) { return filename.substr(pos+1); } else { return filename; } } string V3Os::filenameNonExt (const string& filename) { string base = filenameNonDir(filename); string::size_type pos; if ((pos = base.find(".")) != string::npos) { base.erase(pos); } return base; } string V3Os::filenameSubstitute (const string& filename) { string out; enum { NONE, PAREN, CURLY } brackets = NONE; for (string::size_type pos = 0; pos < filename.length(); ++pos) { if ((filename[pos] == '$') && (pos+1 < filename.length())) { switch (filename[pos+1]) { case '{': brackets = CURLY; break; case '(': brackets = PAREN; break; default: brackets = NONE; break; } if (brackets != NONE) pos = pos+1; string::size_type endpos = pos+1; while (((endpos+1) < filename.length()) && (((brackets==NONE) && (isalnum(filename[endpos+1]) || filename[endpos+1]=='_')) || ((brackets==CURLY) && (filename[endpos+1]!='}')) || ((brackets==PAREN) && (filename[endpos+1]!=')')))) ++endpos; // Catch bracket errors if (((brackets==CURLY) && (filename[endpos+1]!='}')) || ((brackets==PAREN) && (filename[endpos+1]!=')'))) { v3fatal("Unmatched brackets in variable substitution in file: "+filename); } string envvar = filename.substr(pos+1,endpos-pos); const char* envvalue = NULL; if (envvar != "") envvalue = getenv(envvar.c_str()); if (envvalue) { out += envvalue; if (brackets==NONE) pos = endpos; else pos = endpos+1; } else { out += filename[pos]; // *pos == '$' } } else { out += filename[pos]; } } return out; } string V3Os::filenameRealPath(const string& filename) { // Get rid of all the ../ behavior in the middle of the paths. // If there is a ../ that goes down from the 'root' of this path it is preserved. char retpath[PATH_MAX]; if ( #if defined( _MSC_VER ) || defined( __MINGW32__ ) ::_fullpath(retpath,filename.c_str(),PATH_MAX) #else realpath(filename.c_str(), retpath) #endif ) { return string(retpath); } else { return filename; } } bool V3Os::filenameIsRel(const string& filename) { return (filename.length()>0 && filename[0] != '/'); } //###################################################################### // Directory utilities void V3Os::createDir(const string& dirname) { #if defined(_WIN32) || defined(__MINGW32__) mkdir(dirname.c_str()); #else mkdir(dirname.c_str(), 0777); #endif } void V3Os::unlinkRegexp(const string& dir, const string& regexp) { if (DIR* dirp = opendir(dir.c_str())) { while (struct dirent* direntp = readdir(dirp)) { if (VString::wildmatch(direntp->d_name, regexp.c_str())) { string fullname = dir + "/" + string(direntp->d_name); unlink (fullname.c_str()); } } closedir(dirp); } } //###################################################################### // METHODS (performance) uint64_t V3Os::timeUsecs() { #if defined(_WIN32) || defined(__MINGW32__) return 0; #else timeval tv; if (gettimeofday(&tv, NULL) < 0) return 0; return static_cast(tv.tv_sec)*1000000 + tv.tv_usec; #endif } uint64_t V3Os::memUsageBytes() { #if defined(_WIN32) || defined(__MINGW32__) return 0; #else // Highly unportable. Sorry const char* const statmFilename = "/proc/self/statm"; FILE* fp = fopen(statmFilename,"r"); if (!fp) { return 0; } uint64_t size, resident, share, text, lib, data, dt; // All in pages if (7 != fscanf(fp, "%" VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d", &size, &resident, &share, &text, &lib, &data, &dt)) { fclose(fp); return 0; } fclose(fp); return (text + data) * getpagesize(); #endif } verilator-3.916/src/V3WidthSel.cpp0000664000177100017500000005217213205623343016757 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Expression width calculations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3WidthSel's Transformations: // Top down traversal: // Replace SELPLUS/SELMINUS with SEL // Replace SELEXTRACT with SEL // Replace SELBIT with SEL or ARRAYSEL // // This code was once in V3LinkResolve, but little endian bit vectors won't // work that early. It was considered for V3Width and V3Param, but is // fairly ugly both places as the nodes change in too strongly // interconnected ways. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3Width.h" #include "V3Const.h" //###################################################################### // Width state, as a visitor of each AstNode class WidthSelVisitor : public AstNVisitor { private: // IMPORTANT //**** This is not a normal visitor, in that all iteration is instead // done by the caller (V3Width). This avoids duplicating much of the // complicated GenCase/GenFor/Cell/Function call logic that all depends // on if widthing top-down or just for parameters. #define iterateChildren DO_NOT_iterateChildern_IN_V3WidthSel // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void checkConstantOrReplace(AstNode* nodep, const string& message) { // See also V3Width::checkConstantOrReplace // Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us! if (!nodep->castConst()) { nodep->v3error(message); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1)); pushDeletep(nodep); VL_DANGLING(nodep); } } // 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, const 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) { // 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); VL_DANGLING(nodep); } 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) { if (fromRange.littleEndian()) { subp = newSubNeg(fromRange.hi(), subp); } else { 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } if (!rhsp->backp()) { pushDeletep(rhsp); VL_DANGLING(rhsp); } } virtual void visit(AstSelExtract* nodep) { // 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(); vlsint32_t elem = (msb>lsb) ? (msb-lsb+1) : (lsb-msb+1); FromData fromdata = fromDataForArray(nodep, fromp, false); AstNodeDType* ddtypep = fromdata.m_dtypep; VNumRange fromRange = fromdata.m_fromRange; if (ddtypep->castUnpackArrayDType()) { // Slice extraction if (fromRange.elements() == elem && fromRange.lo() == lsb) { // Extracting whole of original array nodep->replaceWith(fromp); pushDeletep(nodep); VL_DANGLING(nodep); } else if (fromRange.elements() == 1) { // Extracting single element AstArraySel* newp = new AstArraySel(nodep->fileline(), fromp, lsbp); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); } else { // Slice AstSliceSel* newp = new AstSliceSel(nodep->fileline(), fromp, VNumRange(VNumRange::LeftRight(), msb, lsb)); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); } } 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()<<"/"< msb) { nodep->v3error("["<width() / fromRange.elements(); AstSel* newp = new AstSel (nodep->fileline(), fromp, new AstMul(nodep->fileline(), newSubLsbOf(lsbp, fromRange), new AstConst(nodep->fileline(), AstConst::Unsized32(), 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } // delete whataver we didn't use in reconstruction if (!fromp->backp()) { pushDeletep(fromp); VL_DANGLING(fromp); } if (!msbp->backp()) { pushDeletep(msbp); VL_DANGLING(msbp); } if (!lsbp->backp()) { pushDeletep(lsbp); VL_DANGLING(lsbp); } } 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); VL_DANGLING(nodep); } 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); VL_DANGLING(nodep); } // delete whataver we didn't use in reconstruction if (!fromp->backp()) { pushDeletep(fromp); VL_DANGLING(fromp); } if (!rhsp->backp()) { pushDeletep(rhsp); VL_DANGLING(rhsp); } if (!widthp->backp()) { pushDeletep(widthp); VL_DANGLING(widthp); } } virtual void visit(AstSelPlus* nodep) { replaceSelPlusMinus(nodep); } virtual void visit(AstSelMinus* nodep) { replaceSelPlusMinus(nodep); } // If adding new visitors, insure V3Width's visit(TYPE) calls into here //-------------------- // Default virtual void visit(AstNode* nodep) { // See notes above; we never iterate nodep->v3fatalSrc("Shouldn't iterate in V3WidthSel"); } public: // CONSTUCTORS WidthSelVisitor() {} AstNode* mainAcceptEdit(AstNode* nodep) { return nodep->iterateSubtreeReturnEdits(*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 explicit TableSimulateVisitor(TableVisitor* cbthis) { m_cbthis = cbthis; } virtual ~TableSimulateVisitor() {} }; //###################################################################### // Table class functions class TableVisitor : public AstNVisitor { private: // NODE STATE // Cleared on each always/assignw // STATE double m_totalBytes; // Total bytes in tables created V3Double0 m_statTablesCre; // Statistic tracking // State cleared on each module AstNodeModule* m_modp; // Current MODULE int m_modTables; // Number of tables created in this module deque m_modTableVscs; // All tables created // State cleared on each scope AstScope* m_scopep; // Current SCOPE // State cleared on each always/assignw bool m_assignDly; // Consists of delayed assignments instead of normal assignments int m_inWidth; // Input table width int m_outWidth; // Output table width deque m_inVarps; // Input variable list deque m_outVarps; // Output variable list deque m_outNotSet; // True if output variable is not set at some point // When creating a table deque m_tableVarps; // Table being created // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } bool treeTest(AstAlways* nodep) { // Process alw/assign tree m_inWidth = 0; m_outWidth = 0; m_inVarps.clear(); m_outVarps.clear(); m_outNotSet.clear(); // Collect stats TableSimulateVisitor chkvis (this); chkvis.mainTableCheck(nodep); m_assignDly = chkvis.isAssignDly(); // Also sets m_inWidth // Also sets m_outWidth // Also sets m_inVarps // Also sets m_outVarps // Calc data storage in bytes size_t chgWidth = m_outVarps.size(); // Width of one change-it-vector if (chgWidth<8) chgWidth = 8; double space = (pow((double)2,((double)(m_inWidth))) *(double)(m_outWidth+chgWidth)); // Instruction count bytes (ok, it's space also not time :) double bytesPerInst = 4; double time = (chkvis.instrCount()*bytesPerInst + chkvis.dataCount()) + 1; // +1 so won't div by zero if (chkvis.instrCount() < TABLE_MIN_NODE_COUNT) { chkvis.clearOptimizable(nodep,"Table has too few nodes involved"); } if (space > TABLE_MAX_BYTES) { chkvis.clearOptimizable(nodep,"Table takes too much space"); } if (space > time * TABLE_SPACE_TIME_MULT) { chkvis.clearOptimizable(nodep,"Table has bad tradeoff"); } if (m_totalBytes > TABLE_TOTAL_BYTES) { chkvis.clearOptimizable(nodep,"Table out of memory"); } if (!m_outWidth || !m_inWidth) { chkvis.clearOptimizable(nodep,"Table has no outputs"); } UINFO(4, " Test: Opt="<<(chkvis.optimizable()?"OK":"NO") <<", Instrs="<varScopep(); if (nodep->lvalue()) { m_outWidth += nodep->varp()->dtypeSkipRefp()->widthTotalBytes(); m_outVarps.push_back(vscp); } else { // We'll make the table with a separate natural alignment for each // output var, so always have char, 16 or 32 bit widths, so use widthTotalBytes m_inWidth += nodep->varp()->width(); // Space for var m_inVarps.push_back(vscp); } } private: void createTable(AstAlways* nodep) { // We've determined this table of nodes is optimizable, do it. ++m_modTables; ++m_statTablesCre; // Index into our table AstVar* indexVarp = new AstVar (nodep->fileline(), AstVarType::BLOCKTEMP, "__Vtableidx" + cvtToStr(m_modTables), VFlagBitPacked(), m_inWidth); m_modp->addStmtp(indexVarp); AstVarScope* indexVscp = new AstVarScope (indexVarp->fileline(), m_scopep, indexVarp); m_scopep->addVarp(indexVscp); // Change it variable FileLine* fl = nodep->fileline(); AstNodeArrayDType* dtypep = new AstUnpackArrayDType (fl, nodep->findBitDType(m_outVarps.size(), m_outVarps.size(), AstNumeric::UNSIGNED), new AstRange (fl, VL_MASK_I(m_inWidth), 0)); v3Global.rootp()->typeTablep()->addTypesp(dtypep); AstVar* chgVarp = new AstVar (fl, AstVarType::MODULETEMP, "__Vtablechg" + cvtToStr(m_modTables), dtypep); chgVarp->isConst(true); chgVarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL)); m_modp->addStmtp(chgVarp); AstVarScope* chgVscp = new AstVarScope (chgVarp->fileline(), m_scopep, chgVarp); m_scopep->addVarp(chgVscp); createTableVars(nodep); AstNode* stmtsp = createLookupInput(nodep, indexVscp); createTableValues(nodep, chgVscp); // Collapse duplicate tables chgVscp = findDuplicateTable(chgVscp); for (deque::iterator it = m_tableVarps.begin(); it!=m_tableVarps.end(); ++it) { *it = findDuplicateTable(*it); } createOutputAssigns(nodep, stmtsp, indexVscp, chgVscp); // Link it in. if (AstAlways* nodeap = nodep->castAlways()) { // Keep sensitivity list, but delete all else nodeap->bodysp()->unlinkFrBackWithNext()->deleteTree(); nodeap->addStmtp(stmtsp); if (debug()>=6) nodeap->dumpTree(cout," table_new: "); } else { nodep->v3fatalSrc("Creating table under unknown node type"); } // Cleanup internal structures m_tableVarps.clear(); } void createTableVars(AstNode* nodep) { // Create table for each output for (deque::iterator it = m_outVarps.begin(); it!=m_outVarps.end(); ++it) { AstVarScope* outvscp = *it; AstVar* outvarp = outvscp->varp(); FileLine* fl = nodep->fileline(); AstNodeArrayDType* dtypep = new AstUnpackArrayDType (fl, outvarp->dtypep(), new AstRange (fl, VL_MASK_I(m_inWidth), 0)); v3Global.rootp()->typeTablep()->addTypesp(dtypep); AstVar* tablevarp = new AstVar (fl, AstVarType::MODULETEMP, "__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(), dtypep); tablevarp->isConst(true); tablevarp->isStatic(true); tablevarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL)); m_modp->addStmtp(tablevarp); AstVarScope* tablevscp = new AstVarScope(tablevarp->fileline(), m_scopep, tablevarp); m_scopep->addVarp(tablevscp); m_tableVarps.push_back(tablevscp); } } AstNode* createLookupInput(AstNode* nodep, AstVarScope* indexVscp) { // Concat inputs into a single temp variable (inside always) // First var in inVars becomes the LSB of the concat AstNode* concatp = NULL; for (deque::iterator it = m_inVarps.begin(); it!=m_inVarps.end(); ++it) { AstVarScope* invscp = *it; AstVarRef* refp = new AstVarRef (nodep->fileline(), invscp, false); if (concatp) { concatp = new AstConcat (nodep->fileline(), refp, concatp); } else concatp = refp; } AstNode* stmtsp = new AstAssign (nodep->fileline(), new AstVarRef (nodep->fileline(), indexVscp, true), concatp); return stmtsp; } void createTableValues(AstAlways* nodep, AstVarScope* chgVscp) { // Create table // There may be a simulation path by which the output doesn't change value. // We could bail on these cases, or we can have a "change it" boolean. // We've choosen the later route, since recirc is common in large FSMs. for (deque::iterator it = m_outVarps.begin(); it!=m_outVarps.end(); ++it) { m_outNotSet.push_back(false); } uint32_t inValueNextInitArray=0; TableSimulateVisitor simvis (this); for (uint32_t inValue=0; inValue <= VL_MASK_I(m_inWidth); inValue++) { // Make a new simulation structure so we can set new input values UINFO(8," Simulating "<::iterator it = m_inVarps.begin(); it!=m_inVarps.end(); ++it) { AstVarScope* invscp = *it; // LSB is first variable, so extract it that way simvis.newNumber(invscp, VL_MASK_I(invscp->width()) & (inValue>>shift)); shift += invscp->width(); // We're just using32 bit arithmetic, because there's no way the input table can be 2^32 bytes! if (shift>31) nodep->v3fatalSrc("shift overflow"); UINFO(8," Input "<name()<<" = "<<*(simvis.fetchNumber(invscp))<v3fatalSrc("Optimizable cleared, even though earlier test run said not: "<fileline(), m_outVarps.size(), 0); for (deque::iterator it = m_outVarps.begin(); it!=m_outVarps.end(); ++it) { AstVarScope* outvscp = *it; V3Number* outnump = simvis.fetchOutNumberNull(outvscp); AstNode* setp; if (!outnump) { UINFO(8," Output "<name()<<" never set\n"); m_outNotSet[outnum] = true; // Value in table is arbitrary, but we need something setp = new AstConst (outvscp->fileline(), V3Number(outvscp->fileline(), outvscp->width(), 0)); } else { UINFO(8," Output "<name()<<" = "<<*outnump<fileline(), *outnump); } // Note InitArray requires us to have the values in inValue order m_tableVarps[outnum]->varp()->valuep()->castInitArray()->addValuep(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()->addValuep(setp); } } // each value } AstVarScope* findDuplicateTable(AstVarScope* vsc1p) { // See if another table we've created is identical, if so use it for both. // (A more 'modern' way would be to instead use V3Hashed::findDuplicate) AstVar* var1p = vsc1p->varp(); for (deque::iterator it = m_modTableVscs.begin(); it!=m_modTableVscs.end(); ++it) { AstVarScope* vsc2p= *it; AstVar* var2p = vsc2p->varp(); if (var1p->width() == var2p->width() && (var1p->dtypep()->arrayUnpackedElements() == var2p->dtypep()->arrayUnpackedElements())) { AstNode* init1p = var1p->valuep()->castInitArray(); AstNode* init2p = var2p->valuep()->castInitArray(); if (init1p->sameGateTree(init2p)) { UINFO(8," Duplicate table var "<iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstAlways* nodep) { UINFO(4," ALWAYS "<iterateChildren(*this); } public: // CONSTRUCTORS explicit TableVisitor(AstNetlist* nodep) { m_modp = NULL; m_modTables = 0; m_scopep = NULL; m_assignDly = 0; m_inWidth = 0; m_outWidth = 0; m_totalBytes = 0; nodep->accept(*this); } virtual ~TableVisitor() { V3Stats::addStat("Optimizations, Tables created", m_statTablesCre); } }; //###################################################################### void TableSimulateVisitor::varRefCb(AstVarRef* nodep) { // Called by checking on each new varref encountered // We cross-call into a TableVisitor function. m_cbthis->simulateVarRefCb(nodep); } //###################################################################### // Table class functions void V3Table::tableAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.916/src/V3LinkLevel.h0000664000177100017500000000250113205574202016554 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LINKLEVEL_H_ #define _V3LINKLEVEL_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3LinkLevel { private: static void wrapTopCell(AstNetlist* nodep); static void wrapTopPackages(AstNetlist* nodep); public: static void modSortByLevel(); static void wrapTop(AstNetlist* nodep); }; #endif // Guard verilator-3.916/src/verilog.l0000664000177100017500000015017413205574202016143 0ustar wsnyderwsnyder/* -*- C++ -*- */ /************************************************************************** * DESCRIPTION: Verilator: Flex input file * * Code available from: http://www.veripool.org/verilator * ************************************************************************** * * Copyright 2003-2017 by Wilson Snyder. Verilator is free software; * you can redistribute it and/or modify it under the terms of either the * GNU Lesser General Public License Version 3 or the Perl Artistic License * Version 2.0. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *************************************************************************/ %option interactive c++ stack noyywrap %{ /* %option nodefault */ #include #include #include #include "V3Number.h" #include "V3ParseImp.h" // Defines YYTYPE; before including bison header #include "V3ParseBison.h" // Generated by bison extern void yyerror(const char*); extern void yyerrorf(const char* format, ...); #define STATE_VERILOG_RECENT S12 // State name for most recent Verilog Version #define PARSEP V3ParseImp::parsep() #define SYMP PARSEP->symp() #define YY_INPUT(buf,result,max_size) \ result = PARSEP->flexPpInputToLex(buf,max_size); //====================================================================== #define NEXTLINE() {PARSEP->linenoInc();} #define LINECHECKS(textp,len) { const char* cp=textp; for (int n=len; n; --n) if (cp[n]=='\n') NEXTLINE(); } #define LINECHECK() LINECHECKS(yytext,yyleng) #define CRELINE() (PARSEP->copyOrSameFileLine()) #define FL { yylval.fl = CRELINE(); } #define RETURN_BBOX_SYS_OR_MSG(msg,yytext) { \ if (!v3Global.opt.bboxSys()) yyerrorf(msg,yytext); \ return yaD_IGNORE; } void V3ParseImp::ppline (const char* textp) { // Handle `line directive int enterExit; fileline()->lineDirective(textp, enterExit/*ref*/); } void V3ParseImp::verilatorCmtLint(const char* textp, bool warnOff) { const char* sp = textp; while (*sp && !isspace(*sp)) sp++; while (*sp && isspace(*sp)) sp++; while (*sp && !isspace(*sp)) sp++; while (*sp && isspace(*sp)) sp++; string msg = sp; string::size_type pos; if ((pos=msg.find("*")) != string::npos) { msg.erase(pos); } if (!(PARSEP->fileline()->warnOff(msg, warnOff))) { if (!PARSEP->optFuture(msg)) { yyerrorf("Unknown verilator lint message code: %s, in %s",msg.c_str(), textp); } } } void V3ParseImp::verilatorCmtLintSave() { m_lintState.push_back(*PARSEP->fileline()); } void V3ParseImp::verilatorCmtLintRestore() { if (m_lintState.empty()) { yyerrorf("/*verilator lint_restore*/ without matching save."); return; } PARSEP->fileline()->warnStateFrom(m_lintState.back()); m_lintState.pop_back(); } void V3ParseImp::verilatorCmtBad(const char* textp) { string cmtparse = textp; if (cmtparse.substr(0,strlen("/*verilator")) == "/*verilator") { cmtparse.replace(0,strlen("/*verilator"), ""); } while (isspace(cmtparse[0])) { cmtparse.replace(0,1, ""); } string cmtname; for (int i=0; isalnum(cmtparse[i]); i++) { cmtname += cmtparse[i]; } if (!PARSEP->optFuture(cmtname)) { yyerrorf("Unknown verilator comment: %s",textp); } } void V3ParseImp::tag(const char* text) { if (m_tagNodep) { string tmp = text + strlen("/*verilator tag "); string::size_type pos; if ((pos=tmp.rfind("*/")) != string::npos) { tmp.erase(pos); } m_tagNodep->tag(tmp); } } // See V3Read.cpp //void V3ParseImp::statePop() { yy_pop_state(); } //====================================================================== void yyerror(const char* errmsg) { PARSEP->fileline()->v3error(errmsg); static const char* const colonmsg = "syntax error, unexpected ::, "; //tokens; if (0==strncmp(errmsg, colonmsg, strlen(colonmsg)) && PARSEP->prevBisonVal().token == yaID__ETC && PARSEP->curBisonVal().token == yP_COLONCOLON) { static int warned = false; if (!warned++) { PARSEP->fileline()->v3error("Perhaps '"+*PARSEP->prevBisonVal().strp +"' is a package which needs to be predeclared? (IEEE 2012 26.3)"); } } } void yyerrorf(const char* format, ...) { const int maxlen = 2000; char msg[maxlen]; va_list ap; va_start(ap,format); VL_VSNPRINTF(msg,maxlen,format,ap); msg[maxlen-1] = '\0'; va_end(ap); yyerror(msg); } /**********************************************************************/ %} %e 2000 %p 5000 %n 2500 %k 1000 %a 15000 %o 25000 %s V95 V01 V05 S05 S09 S12 %s STRING ATTRMODE TABLE %s VA5 SAX VLT %s SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR SYSCDTOR %s IGNORE ws [ \t\f\r]+ wsnr [ \t\f]+ crnl [\r]*[\n] /* identifier */ id [a-zA-Z_][a-zA-Z0-9_$]* /* escaped identifier */ escid \\[^ \t\f\r\n]+ word [a-zA-Z0-9_]+ /* verilog numbers, constructed to not match the ' that begins a '( or '{ */ vnum1 [0-9]*?['']s?[bcodhBCODH][ \t\n]*[A-Fa-f0-9xXzZ_?]* vnum2 [0-9]*?['']s?[01xXzZ] vnum3 [0-9][_0-9]*[ \t\n]*['']s?[bcodhBCODH]?[ \t]*[A-Fa-f0-9xXzZ_?]+ vnum4 [0-9][_0-9]*[ \t\n]*['']s?[bcodhBCODH] vnum5 [0-9][_0-9]*[ \t\n]*['']s vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} %% .|\n {BEGIN STATE_VERILOG_RECENT; yyless(0); } /************************************************************************/ /* Verilator control files */ { {ws} { } /* otherwise ignore white-space */ {crnl} { NEXTLINE(); } /* Count line numbers */ "coverage_off" { FL; return yVLT_COVERAGE_OFF; } "coverage_on" { FL; return yVLT_COVERAGE_ON; } "lint_off" { FL; return yVLT_LINT_OFF; } "lint_on" { FL; return yVLT_LINT_ON; } "tracing_off" { FL; return yVLT_TRACING_OFF; } "tracing_on" { FL; return yVLT_TRACING_ON; } -?"-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; } "$sformatf" { FL; return yD_SFORMATF; } "$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; } "deassign" { FL; return yDEASSIGN; } "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; } "foreach" { FL; return yFOREACH; } "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 */ "event" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "force" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "fork" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "highz0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "highz1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "join" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "large" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "medium" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "pull0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "pull1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "release" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "small" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "strong0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "strong1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "triand" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "trior" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "trireg" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "wait" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "wand" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "weak0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "weak1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "wor" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } } /* Verilog 2001 */ { /* System Tasks */ "$signed" { FL; return yD_SIGNED; } "$unsigned" { FL; return yD_UNSIGNED; } /* Keywords */ "automatic" { FL; return yAUTOMATIC; } "endgenerate" { FL; return yENDGENERATE; } "generate" { FL; return yGENERATE; } "genvar" { FL; return yGENVAR; } "ifnone" { FL; return yaTIMINGSPEC; } "localparam" { FL; return yLOCALPARAM; } "noshowcancelled" { FL; return yaTIMINGSPEC; } "pulsestyle_ondetect" { FL; return yaTIMINGSPEC; } "pulsestyle_onevent" { FL; return yaTIMINGSPEC; } "showcancelled" { FL; return yaTIMINGSPEC; } "signed" { FL; return ySIGNED; } "unsigned" { FL; return yUNSIGNED; } /* Generic unsupported keywords */ "cell" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "config" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "design" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "endconfig" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "incdir" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "include" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented; probably you want `include instead: %s",yytext); } "instance" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "liblist" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "library" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "use" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } } /* Verilog 2005 */ { /* Keywords */ "uwire" { FL; return yWIRE; } } /* System Verilog 2005 */ { /* System Tasks */ "$bits" { FL; return yD_BITS; } "$clog2" { FL; return yD_CLOG2; } "$countones" { FL; return yD_COUNTONES; } "$dimensions" { FL; return yD_DIMENSIONS; } "$error" { FL; return yD_ERROR; } "$fatal" { FL; return yD_FATAL; } "$high" { FL; return yD_HIGH; } "$increment" { FL; return yD_INCREMENT; } "$info" { FL; return yD_INFO; } "$isunknown" { FL; return yD_ISUNKNOWN; } "$left" { FL; return yD_LEFT; } "$low" { FL; return yD_LOW; } "$onehot" { FL; return yD_ONEHOT; } "$onehot0" { FL; return yD_ONEHOT0; } "$right" { FL; return yD_RIGHT; } "$size" { FL; return yD_SIZE; } "$unpacked_dimensions" { FL; return yD_UNPACKED_DIMENSIONS; } "$warning" { FL; return yD_WARNING; } /* SV2005 Keywords */ "$unit" { FL; return yD_UNIT; } /* Yes, a keyword, not task */ "always_comb" { FL; return yALWAYS_COMB; } "always_ff" { FL; return yALWAYS_FF; } "always_latch" { FL; return yALWAYS_LATCH; } "assert" { FL; return yASSERT; } "bind" { FL; return yBIND; } "bit" { FL; return yBIT; } "break" { FL; return yBREAK; } "byte" { FL; return yBYTE; } "chandle" { FL; return yCHANDLE; } "clocking" { FL; return yCLOCKING; } "const" { FL; return yCONST__LEX; } "context" { FL; return yCONTEXT; } "continue" { FL; return yCONTINUE; } "cover" { FL; return yCOVER; } "do" { FL; return yDO; } "endclocking" { FL; return yENDCLOCKING; } "endinterface" { FL; return yENDINTERFACE; } "endpackage" { FL; return yENDPACKAGE; } "endprogram" { FL; return yENDPROGRAM; } "endproperty" { FL; return yENDPROPERTY; } "enum" { FL; return yENUM; } "export" { FL; return yEXPORT; } "final" { FL; return yFINAL; } "iff" { FL; return yIFF; } "import" { FL; return yIMPORT; } "inside" { FL; return yINSIDE; } "int" { FL; return yINT; } "interface" { FL; return yINTERFACE; } "logic" { FL; return yLOGIC; } "longint" { FL; return yLONGINT; } "modport" { FL; return yMODPORT; } "package" { FL; return yPACKAGE; } "packed" { FL; return yPACKED; } "priority" { FL; return yPRIORITY; } "program" { FL; return yPROGRAM; } "property" { FL; return yPROPERTY; } "pure" { FL; return yPURE; } "rand" { FL; return yRAND; } "randc" { FL; return yRANDC; } "return" { FL; return yRETURN; } "shortint" { FL; return ySHORTINT; } "static" { FL; return ySTATIC; } "string" { FL; return ySTRING; } "struct" { FL; return ySTRUCT; } "timeprecision" { FL; return yTIMEPRECISION; } "timeunit" { FL; return yTIMEUNIT; } "type" { FL; return yTYPE; } "typedef" { FL; return yTYPEDEF; } "union" { FL; return yUNION; } "unique" { FL; return yUNIQUE; } "var" { FL; return yVAR; } "void" { FL; return yVOID; } /* Generic unsupported warnings */ /* Note assert_strobe was in SystemVerilog 3.1, but removed for SystemVerilog 2005 */ "$root" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "alias" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "assume" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "before" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "binsof" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "class" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "constraint" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "covergroup" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "coverpoint" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "cross" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "dist" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "endclass" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "endgroup" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "endsequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "expect" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "extends" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "extern" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "first_match" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "forkjoin" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "ignore_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "illegal_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "intersect" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "join_any" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "join_none" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "local" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "matches" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "new" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "null" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "protected" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "randcase" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "randomize" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "randsequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "ref" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "sequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "shortreal" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "solve" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "super" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "tagged" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "this" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "throughout" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "virtual" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "wait_order" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "wildcard" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "with" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "within" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } } /* SystemVerilog 2009 */ { /* Keywords */ "global" { FL; return yGLOBAL__LEX; } "unique0" { FL; return yUNIQUE0; } /* Generic unsupported warnings */ "accept_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "checker" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "endchecker" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "eventually" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "implies" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "let" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "nexttime" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "reject_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "restrict" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_always" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_eventually" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_nexttime" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_until" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_until_with" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "strong" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "sync_accept_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "sync_reject_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "until" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "until_with" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "untyped" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "weak" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } } /* System Verilog 2012 */ { /* Keywords */ "implements" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); } "interconnect" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); } "nettype" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); } "soft" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); } } /* Default PLI rule */ { "$"[a-zA-Z_$][a-zA-Z0-9_$]* { string str (yytext,yyleng); yylval.strp = PARSEP->newString(AstNode::encodeName(str)); // Lookup unencoded name including the $, to avoid hitting normal signals if (SYMP->symCurrentp()->findIdFallback(str)) { FL; return yaD_DPI; } else { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported or unknown PLI call: %s",yytext); } } } /************************************************************************/ /* AMS */ { /* Generic unsupported warnings */ "above" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "abs" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "absdelay" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "abstol" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ac_stim" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "access" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "acos" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "acosh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "aliasparam" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "analog" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "analysis" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "asin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "asinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "assert" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "atan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "atan2" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "atanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "branch" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ceil" { FL; return yD_CEIL; } "connect" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "connectmodule" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "connectrules" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "continuous" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "cos" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "cosh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "cross" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ddt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ddt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ddx" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "discipline" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "discrete" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "domain" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "driver_update" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "endconnectrules" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "enddiscipline" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "endnature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "endparamset" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "exclude" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "exp" { FL; return yD_EXP; } "final_step" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "flicker_noise" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "floor" { FL; return yD_FLOOR; } "flow" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "from" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ground" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "hypot" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "idt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "idt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "idtmod" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "inf" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "initial_step" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "laplace_nd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "laplace_np" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "laplace_zd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "laplace_zp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "last_crossing" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "limexp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ln" { FL; return yD_LN; } "log" { FL; return yD_LOG10; } "max" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "merged" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "min" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "net_resolution" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "noise_table" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "paramset" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "potential" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "pow" { FL; return yD_POW; } "resolveto" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "sin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "sinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "slew" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "split" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "sqrt" { FL; return yD_SQRT; } "string" { FL; return ySTRING; } "tan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "tanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "timer" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "transition" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "units" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "white_noise" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "wreal" { FL; return yWREAL; } "zi_nd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "zi_np" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "zi_zd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "zi_zp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } } /************************************************************************/ /* Meta comments */ /* Converted from //{cmt}verilator ...{cmt} by preprocessor */ { "/*verilator"{ws}*"*/" {} /* Ignore empty comments, may be `endif // verilator */ "/*verilator clock_enable*/" { FL; return yVL_CLOCK_ENABLE; } "/*verilator coverage_block_off*/" { FL; return yVL_COVERAGE_BLOCK_OFF; } "/*verilator full_case*/" { FL; return yVL_FULL_CASE; } "/*verilator inline_module*/" { FL; return yVL_INLINE_MODULE; } "/*verilator isolate_assignments*/" { FL; return yVL_ISOLATE_ASSIGNMENTS; } "/*verilator no_inline_module*/" { FL; return yVL_NO_INLINE_MODULE; } "/*verilator no_inline_task*/" { FL; return yVL_NO_INLINE_TASK; } "/*verilator parallel_case*/" { FL; return yVL_PARALLEL_CASE; } "/*verilator public*/" { FL; return yVL_PUBLIC; } "/*verilator public_flat*/" { FL; return yVL_PUBLIC_FLAT; } "/*verilator public_flat_rd*/" { FL; return yVL_PUBLIC_FLAT_RD; } "/*verilator public_flat_rw*/" { FL; return yVL_PUBLIC_FLAT_RW; } // The @(edge) is converted by the preproc "/*verilator public_module*/" { FL; return yVL_PUBLIC_MODULE; } "/*verilator sc_clock*/" { FL; return yVL_CLOCK; } "/*verilator clocker*/" { FL; return yVL_CLOCKER; } "/*verilator no_clocker*/" { FL; return yVL_NO_CLOCKER; } "/*verilator sc_bv*/" { FL; return yVL_SC_BV; } "/*verilator sformat*/" { FL; return yVL_SFORMAT; } "/*verilator systemc_clock*/" { FL; return yVL_CLOCK; } "/*verilator tracing_off*/" {PARSEP->fileline()->tracingOn(false); } "/*verilator tracing_on*/" {PARSEP->fileline()->tracingOn(true); } "/*verilator coverage_off*/" {PARSEP->fileline()->coverageOn(false); } "/*verilator coverage_on*/" {PARSEP->fileline()->coverageOn(true); } "/*verilator lint_off"[^*]*"*/" {PARSEP->verilatorCmtLint(yytext, true); } "/*verilator lint_on"[^*]*"*/" {PARSEP->verilatorCmtLint(yytext, false); } "/*verilator lint_restore*/" {PARSEP->verilatorCmtLintRestore(); } "/*verilator lint_save*/" {PARSEP->verilatorCmtLintSave(); } "/*verilator tag"[^*]*"*/" {PARSEP->tag(yytext); } "/**/" { } "/*"[^*]+"*/" {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; } ":+" { FL; yyless(1); PARSEP->fileline()->v3warn(COLONPLUS, "Perhaps instead of ':+' the intent was '+:'?"); return ':'; } } /* SystemVerilog Operators */ { "'" { FL; return yP_TICK; } "'{" { FL; return yP_TICKBRA; } "==?" { FL; return yP_WILDEQUAL; } "!=?" { FL; return yP_WILDNOTEQUAL; } "++" { FL; return yP_PLUSPLUS; } "--" { FL; return yP_MINUSMINUS; } "+=" { FL; return yP_PLUSEQ; } "-=" { FL; return yP_MINUSEQ; } "*=" { FL; return yP_TIMESEQ; } "/=" { FL; return yP_DIVEQ; } "%=" { FL; return yP_MODEQ; } "&=" { FL; return yP_ANDEQ; } "|=" { FL; return yP_OREQ; } "^=" { FL; return yP_XOREQ; } "<<=" { FL; return yP_SLEFTEQ; } ">>=" { FL; return yP_SRIGHTEQ; } "<<<=" { FL; return yP_SLEFTEQ; } ">>>=" { FL; return yP_SSRIGHTEQ; } "->>" { FL; return yP_MINUSGTGT; } "##" { FL; return yP_POUNDPOUND; } "@@" { FL; return yP_ATAT; } "::" { FL; return yP_COLONCOLON; } ":=" { FL; return yP_COLONEQ; } ":/"[^\/\*] { FL; return yP_COLONDIV; } /* : then comment is not ":/" */ "|->" { FL; return yP_ORMINUSGT; } "|=>" { FL; return yP_OREQGT; } /* Some simulators allow whitespace here. Grr */ "["{ws}*"*" { FL; return yP_BRASTAR; } "["{ws}*"=" { FL; return yP_BRAEQ; } "["{ws}*"->" { FL; return yP_BRAMINUSGT; } } /* Identifiers and numbers */ { {escid} { FL; yylval.strp = PARSEP->newString (AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash return yaID__LEX; } {id} { FL; yylval.strp = PARSEP->newString(AstNode::encodeName(string(yytext))); return yaID__LEX; } \"[^\"\\]*\" { FL; yylval.strp = PARSEP->newString(yytext+1,yyleng-2); return yaSTRING; } \" { yy_push_state(STRING); yymore(); } {vnum} { /* "# 1'b0" is a delay value so must lex as "#" "1" "'b0" */ if (PARSEP->prevLexToken()=='#') { int shortlen = 0; while (isdigit(yytext[shortlen])) shortlen++; if (shortlen) { // Push rest for later parse PARSEP->unputString(yytext+shortlen, yyleng-shortlen); FL; LINECHECKS(yytext,shortlen); // Return is stuff before the tick yytext[shortlen] = '\0'; yylval.nump = PARSEP->newNumber(yylval.fl, (char*)yytext); return yaINTNUM; } } FL; LINECHECK(); yylval.nump = PARSEP->newNumber(yylval.fl,(char*)yytext); return yaINTNUM; } [0-9][_0-9]* { FL; yylval.nump = PARSEP->newNumber(yylval.fl,(char*)yytext); return yaINTNUM; } [0-9][_0-9]*(\.[_0-9]+)([eE][-+]?[_0-9]+)? { FL; yylval.cdouble = PARSEP->parseDouble(yytext, yyleng); return yaFLOATNUM; } [0-9][_0-9]*(\.[_0-9]+)?([eE][-+]?[_0-9]+) { FL; yylval.cdouble = PARSEP->parseDouble(yytext, yyleng); return yaFLOATNUM; } [0-9][_0-9]*(\.[_0-9]+)?(fs|ps|ns|us|ms|s|step) { FL; yylval.cdouble = 0; /* Only for times, not used yet */ return yaTIMENUM; } } /************************************************************************/ /* STRINGS */ <> { yyerrorf("EOF in unterminated string"); yyleng = 0; yy_pop_state(); } {crnl} { yyerrorf("Unterminated string"); NEXTLINE(); } \\{crnl} { yymore(); NEXTLINE(); } \\. { yymore(); } \" { yy_pop_state(); FL; yylval.strp = PARSEP->newString(yytext+1,yyleng-2); return yaSTRING; } {word} { yymore(); } . { yymore(); } /************************************************************************/ /* Attributes */ {crnl} { yymore(); NEXTLINE(); } "*)" { yy_pop_state(); } {word} { yymore(); } . { yymore(); } <> { yyerrorf("EOF in (*"); yyleng = 0; yy_pop_state(); } /************************************************************************/ /* Attributes */ /* Note simulators vary in support for "(* /_*something*_/ foo*)" where _ doesn't exist */ { "(*"({ws}|{crnl})*({id}|{escid}) { yymore(); yy_push_state(ATTRMODE); } /* Doesn't match (*), but (* attr_spec */ } /************************************************************************/ /* Tables */ \\{crnl} { yymore(); NEXTLINE(); }
{crnl} { NEXTLINE(); yymore(); }
";" { FL; yylval.strp = PARSEP->newString(yytext,yyleng); return yaTABLELINE; }
"endtable" { yy_pop_state(); FL; return yENDTABLE; }
. { yymore(); }
<> { yyerrorf("EOF in TABLE"); yyleng = 0; yy_pop_state(); } /************************************************************************/ /* Preprocessor */ /* Common for all SYSC header states */ /* OPTIMIZE: we return one per line, make it one for the entire block */ { "`accelerate" { } // Verilog-XL compatibility "`autoexpand_vectornets" { } // Verilog-XL compatibility "`celldefine" { PARSEP->inCellDefine(true); } "`default_decay_time"{ws}+[^\n\r]* { } // Verilog spec - delays only "`default_nettype"{ws}+"wire" { PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE,true); } "`default_nettype"{ws}+"none" { PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE,false); } "`default_nettype"{ws}+[a-zA-Z0-9]* { yyerrorf("Unsupported: `default_nettype of other than none or wire: %s",yytext); } "`default_trireg_strength"{ws}+[^\n\r]* { yyerrorf("Unsupported: Verilog optional directive not implemented: %s",yytext); } "`delay_mode_distributed" { } // Verilog spec - delays only "`delay_mode_path" { } // Verilog spec - delays only "`delay_mode_unit" { } // Verilog spec - delays only "`delay_mode_zero" { } // Verilog spec - delays only "`disable_portfaults" { } // Verilog-XL compatibility "`enable_portfaults" { } // Verilog-XL compatibility "`endcelldefine" { PARSEP->inCellDefine(false); } "`endprotect" { } "`expand_vectornets" { } // Verilog-XL compatibility "`inline" { } "`line"{ws}+[^\n\r]*{crnl} { PARSEP->ppline(yytext); } "`noaccelerate" { } // Verilog-XL compatibility "`noexpand_vectornets" { } // Verilog-XL compatibility "`noremove_gatenames" { } // Verilog-XL compatibility "`noremove_netnames" { } // Verilog-XL compatibility "`nosuppress_faults" { } // Verilog-XL compatibility "`nounconnected_drive" { } // Verilog-XL compatibility "`portcoerce" { } "`pragma"{ws}+[^\n\r]* { } // Verilog 2005 "`protect" { } "`remove_gatenames" { } // Verilog-XL compatibility "`remove_netnames" { } // Verilog-XL compatibility "`resetall" { PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE,true); } // Rest handled by preproc "`suppress_faults" { } // Verilog-XL compatibility "`timescale"{ws}+[^\n\r]* { } // Verilog spec - not supported /* See also setLanguage below */ "`begin_keywords"[ \t]*\"1364-1995\" { yy_push_state(V95); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1364-2001\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"VAMS[-0-9.]*\" { yy_push_state(VA5); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1800-2009\" { yy_push_state(S09); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1800-2012\" { yy_push_state(S12); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1800[+]VAMS\" { yy_push_state(SAX); PARSEP->pushBeginKeywords(YY_START); } /*Latest SV*/ "`end_keywords" { yy_pop_state(); if (!PARSEP->popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); } /* Verilator */ "`systemc_ctor" { BEGIN SYSCCTOR; } "`systemc_dtor" { BEGIN SYSCDTOR; } "`systemc_header" { BEGIN SYSCHDR; } "`systemc_imp_header" { BEGIN SYSCIMPH; } "`systemc_implementation" { BEGIN SYSCIMP; } "`systemc_interface" { BEGIN SYSCINT; } "`verilator_config" { BEGIN VLT; } "`verilog" { BEGIN PARSEP->lastVerilogState(); } } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCHDR; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCINT; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCIMP; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCIMPH; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCCTOR; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCDTOR; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { NEXTLINE(); } /* Pick up text-type data */ { {wsnr}* { yymore(); } {crnl} { NEXTLINE(); yymore(); } } /************************************************************************/ /* Default rules - leave last */ { "`"[a-zA-Z_0-9]+ { FL; yyerrorf("Define or directive not defined: %s",yytext); } "//"[^\n]* { } /* throw away single line comments */ . { FL; return yytext[0]; } /* return single char ops. */ } /* Catch all - absolutely last */ <*>.|\n { yyerrorf("Missing verilog.l rule: Default rule invoked in state %d: %s", YY_START, yytext); } %% int V3ParseImp::stateVerilogRecent() { return STATE_VERILOG_RECENT; } double V3ParseImp::parseDouble(const char* textp, size_t length, bool* successp) { char* strgp = new char[length+1]; char* dp=strgp; if (successp) *successp = true; for (const char* sp=textp; sp<(textp+length); ++sp) { if (*sp != '_') *dp++ = *sp; } *dp++ = '\0'; char* endp = strgp; double d = strtod(strgp, &endp); size_t parsed_len = endp-strgp; if (parsed_len != strlen(strgp)) { if (successp) *successp = false; else yyerrorf("Syntax error parsing real: %s",strgp); } delete[] strgp; return d; } void 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_aheadVal.token; 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) { VSymEnt* foundp; if (VSymEnt* look_underp = SYMP->nextId()) { UINFO(7," lexToken: next id lookup forced under "<findIdFallback(*(yylval.strp)); // "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); foundp = SYMP->symCurrentp()->findIdFallback(*(yylval.strp)); } if (foundp) { AstNode* scp = foundp->nodep(); yylval.scp = 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 yylval.scp = NULL; token = yaID__ETC; } } yylval.token = token; // effectively returns yylval } int V3ParseImp::lexToBison() { // Called as global since bison doesn't have our pointer lexToken(); // sets yylval m_prevBisonVal = m_curBisonVal; m_curBisonVal = yylval; //yylval.scp = NULL; // Symbol table not yet needed - no packages if (debugFlex()>=6 || debugBison()>=6) { cout<<" {"<filenameLetters()<lineno() <<"} lexToBison TOKEN="< #include #include #include #include using namespace std; //********************************************************************** //**** Configure-discovered library options // Define if struct stat has st_mtim.tv_nsec (from configure) #define HAVE_STAT_NSEC 1 //********************************************************************** //**** OS and compiler specifics #include "verilatedos.h" verilator-3.916/src/VlcTest.h0000664000177100017500000001030513205574202016043 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Test/coverage file container // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCTEST_H_ #define _VLCTEST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "VlcPoint.h" #include "VlcBucket.h" #include #include //******************************************************************** // VlcTest - a single testrun i.e. a file containing coverage data class VlcTest { private: // MEMBERS string m_name; //< Name of the test double m_computrons; //< Runtime for the test vluint64_t m_testrun; //< Test run number, for database use vluint64_t m_rank; //< Execution rank suggestion vluint64_t m_rankPoints; //< Ranked additional points vluint64_t m_user; //< User data for algorithms (not persisted in .dat file) VlcBuckets m_buckets; //< Coverage data for each coverage point public: // CONSTRUCTORS VlcTest(const string& name, vluint64_t testrun, double comp) { m_name = name; m_computrons = comp; m_testrun = testrun; m_rank = 0; m_rankPoints = 0; m_user = 0; } ~VlcTest() {} // ACCESSORS const string& name() const { return m_name; } double computrons() const { return m_computrons; } vluint64_t testrun() const { return m_testrun; } VlcBuckets& buckets() { return m_buckets; } vluint64_t bucketsCovered() const { return m_buckets.bucketsCovered(); } vluint64_t rank() const { return m_rank; } void rank(vluint64_t flag) { m_rank = flag; } vluint64_t rankPoints() const { return m_rankPoints; } void rankPoints(vluint64_t flag) { m_rankPoints = flag; } vluint64_t user() const { return m_user; } void user(vluint64_t flag) { m_user = flag; } // METHODS static void dumpHeader() { cout<<"Tests:\n"; //cout<<" Testrun, Computrons,"; // Currently not loaded cout<<" Covered, Rank, RankPts, Filename"< ByName; private: // MEMBERS ByName m_tests; //< List of all tests public: // ITERATORS typedef ByName::iterator iterator; ByName::iterator begin() { return m_tests.begin(); } ByName::iterator end() { return m_tests.end(); } public: // CONSTRUCTORS VlcTests() {} ~VlcTests() { for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) { delete *it; *it=NULL; } } // METHODS void dump(bool bucketsToo) { UINFO(2,"dumpTests...\n"); VlcTest::dumpHeader(); for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) { (*it)->dump(bucketsToo); } } VlcTest* newTest(const string& name, vluint64_t testrun, double comp) { VlcTest* testp = new VlcTest(name, testrun, comp); m_tests.push_back(testp); return testp; } void clearUser() { for (ByName::iterator it = m_tests.begin(); it != m_tests.end(); ++it) { (*it)->user(0); } } }; //###################################################################### #endif // Guard verilator-3.916/src/V3Hashed.h0000664000177100017500000000611713205574202016072 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-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/src/V3Task.h0000664000177100017500000000303613205574202015575 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Inlining of modules // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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.916/README0000664000177100017500000001627313206353157014416 0ustar wsnyderwsnyderNAME This is the Verilator package README file. DISTRIBUTION http://www.veripool.org/verilator This package is Copyright 2003-2017 by Wilson Snyder. (Report bugs to .) Verilator is free software; you can redistribute it and/or modify it under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. (See the documentation for more details.) This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. DESCRIPTION Verilator converts synthesizable (generally not behavioral) Verilog code into C++ or SystemC code. It is not a complete simulator, just a translator. Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage code. For C++ format, it outputs .cpp and .h files. For SystemC format, it outputs .cpp and .h files using the standard SystemC headers. The resulting files are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module. This is compiled in C++, and linked with the Verilated files. The resulting executable will perform the actual simulation. SUPPORTED SYSTEMS Verilator is developed and has primary testing on Ubuntu. Versions have also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It should run with minor porting on any Linix-ish platform. Verilator also works on Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated output (not Verilator itself) compiles under MSVC++ 2008 and newer. INSTALLATION For more details see . If you will be modifying Verilator, you should use the "git" method as it will let you track changes. * The latest version is available at . Download the latest package from that site, and decompress. tar xvzf verilator_version.tgz * If you will be using SystemC (vs straight C++ output), download SystemC from . Follow their installation instructions. You will need to set SYSTEMC_INCLUDE to point to the include directory with systemc.h in it, and SYSTEMC_LIBDIR to points to the directory with libsystemc.a in it. (Older installations may set SYSTEMC and SYSTEMC_ARCH instead.) * You will need the "flex" and "bison" packages installed. * "cd" to the Verilator directory containing this README. * You now have to decide how you're going to eventually install the kit. Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE, and SYSTEMC_LIBDIR as defaults into the executable, so try to have them correct before configuring. 1. Our personal favorite is to always run Verilator from the kit directory. This allows the easiest experimentation and upgrading. It's also how most EDA tools operate; to run you point to the tarball, no install is needed. export VERILATOR_ROOT=`pwd` # if your shell is bash setenv VERILATOR_ROOT `pwd` # if your shell is csh ./configure 2. To install globally onto a "cad" disk with multiple versions of every tool, and add it to path using Modules/modulecmd: unset VERILATOR_ROOT # if your shell is bash unsetenv VERILATOR_ROOT # if your shell is csh # For the tarball, use the version number instead of git describe ./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"` After installing you'll want a module file like the following: set install_root /CAD_DISK/verilator/{version-number-used-above} unsetenv VERILATOR_ROOT prepend-path PATH $install_root/bin prepend-path MANPATH $install_root/man prepend-path PKG_CONFIG_PATH $install_root/share/pkgconfig 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. You may now wish to consult the examples directory. Type "make" inside any example directory to run the example. 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 examples/hello_world_c => Example simple Verilog->C++ conversion examples/hello_world_sc => Example simple Verilog->SystemC conversion examples/tracing_c => Example Verilog->C++ with tracing examples/tracing_sc => Example Verilog->SystemC with tracing test_regress => Internal tests LIMITATIONS See verilator.txt (or execute "bin/verilator --help") for limitations. verilator-3.916/Makefile.in0000664000177100017500000004334713206346532015604 0ustar wsnyderwsnyder#***************************************************************************** # DESCRIPTION: Verilator top level: Makefile pre-configure version # # This file is part of Verilator. # # Code available from: http://www.veripool.org/verilator # #***************************************************************************** # # Copyright 2003-2017 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. # # Verilator is distributed in the hope that it will be useful, # but WITHOUT 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. #### 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 manpages. mandir = @mandir@ # Directory in which to install library files. datadir = @datadir@ # Directory in which to install documentation info files. infodir = @infodir@ # Directory in which to install package specific files # Generally ${prefix}/share/verilator pkgdatadir = @pkgdatadir@ # Directory in which to install pkgconfig file # Generall ${prefix}/share/pkgconfig pkgconfigdir = @pkgconfigdir@ # Directory in which to install data across multiple architectures datarootdir = @datarootdir@ # Compile options CFG_WITH_CCWARN = @CFG_WITH_CCWARN@ CFG_WITH_DEFENV = @CFG_WITH_DEFENV@ CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@ CFG_WITH_THREADED = @CFG_WITH_THREADED@ PACKAGE_VERSION = @PACKAGE_VERSION@ #### End of system configuration section. #### ###################################################################### .SUFFIXES: SHELL = /bin/sh SUBDIRS = src test_regress \ examples/hello_world_c examples/hello_world_sc \ examples/tracing_c examples/tracing_sc \ INFOS = README README.html README.pdf internals.txt internals.html \ internals.pdf verilator.txt verilator.html verilator.pdf \ $(VL_INST_MAN_FILES) # Files that can be generated, but should be up to date for a distribution. DISTDEP = info Makefile DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \ *.in *.ac \ Changes TODO \ MANIFEST.SKIP \ bin/verilator \ bin/verilator_coverage \ bin/verilator_difftree \ bin/verilator_includer \ bin/verilator_profcfunc \ doxygen-mainpage doxygen.config veripool-logo.png \ install-sh configure mkinstalldirs *.pod \ include/*.[chv]* \ include/*.in \ include/.*ignore \ include/vltstd/*.[chv]* \ .*attributes */.*attributes */*/.*attributes \ src/.*ignore src/*.in src/*.cpp src/*.[chly] \ src/astgen src/bisonpre src/*fix src/cppcheck_filtered \ src/vlcovgen \ src/.gdbinit \ src/*.pl src/*.pod \ examples/*/.*ignore examples/*/Makefile* \ examples/*/*.[chv]* examples/*/*.pl \ test_*/.*ignore test_*/Makefile* test_*/*.cpp \ test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \ test_regress/t/t*/*.sv* \ test_regress/t/t*/*.v* \ test_regress/t/t*/*/*.sv* \ test_regress/t/t*/*/*.v* \ test_regress/t/*.cpp \ test_regress/t/*.h \ test_regress/t/*.dat \ test_regress/t/*.mem \ test_regress/t/*.out \ test_regress/t/*.pl \ test_regress/t/*.pf \ test_regress/t/*.v* \ INST_PROJ_FILES = \ bin/verilator \ bin/verilator_coverage \ bin/verilator_includer \ bin/verilator_profcfunc \ include/verilated.mk \ include/*.[chv]* \ include/vltstd/*.[chv]* \ INST_PROJ_BIN_FILES = \ bin/verilator_bin \ bin/verilator_bin_dbg \ bin/verilator_coverage_bin_dbg \ DISTFILES := $(DISTFILES_INC) ifeq ($(OBJCACHE_JOBS),) ifneq ($(OBJCACHE_HOSTS),) export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)") endif endif default: all all: all_nomsg msg_test all_nomsg: verilator_exe $(VL_INST_MAN_FILES) .PHONY:verilator_exe .PHONY:verilator_bin .PHONY:verilator_bin_dbg .PHONY:verilator_coverage_bin_dbg verilator_exe verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg: @echo ------------------------------------------------------------ @echo "making verilator in src" ; \ (cd src && $(MAKE) $(OBJCACHE_JOBS) ) .PHONY:msg_test msg_test: all_nomsg @echo "Build complete!" @echo @echo "Now type 'make test' to test." @echo .PHONY: test ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users test: smoke-test examples test_regress else test: smoke-test examples endif @echo "Tests passed!" @echo @echo "Now type 'make install' to install." @echo "Or type 'make' inside an examples subdirectory." @echo smoke-test: all_nomsg test_regress/t/t_a_first_cc.pl test_regress/t/t_a_first_sc.pl test_regress: all_nomsg @(cd test_regress && $(MAKE)) examples: all_nomsg for p in examples/* ; do \ $(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \ done info: $(INFOS) # Use --no-split to avoid creating filenames > 14 chars. %.1: ${srcdir}/bin/% pod2man $< $@ verilator.txt: ${srcdir}/bin/verilator $(POD2TEXT) $< $@ verilator.html: ${srcdir}/bin/verilator pod2html $< >$@ # PDF needs DIST variables; but having configure.ac as dependency isn't detected verilator.pdf: ${srcdir}/bin/verilator Makefile pod2latex --full --out verilator.tex ${srcdir}/bin/verilator $(PERL) $(POD2LATEXFIX) "$(DISTTITLE)" "${DISTDATE}" < verilator.tex > verilator2.tex mv verilator2.tex verilator.tex pdflatex verilator.tex pdflatex verilator.tex -rm -f verilator.toc verilator.aux verilator.idx verilator.out README: README.pod -rm -f $@ $(POD2TEXT) --loose $< > $@ README.html: README.pod pod2html $< >$@ # PDF needs DIST variables; but having configure.ac as dependency isn't detected README.pdf: README.pod Makefile pod2latex --full --out README.tex README.pod $(PERL) $(POD2LATEXFIX) "$(DISTTITLE) README File" "${DISTDATE}" < README.tex > README2.tex mv README2.tex README.tex pdflatex README.tex pdflatex README.tex -rm -f README.toc README.aux README.idx README.out internals.txt: internals.pod -rm -f $@ $(POD2TEXT) --loose $< > $@ internals.html: internals.pod pod2html $< >$@ # PDF needs DIST variables; but having configure.ac as dependency isn't detected internals.pdf: internals.pod Makefile pod2latex --full --out internals.tex internals.pod $(PERL) $(POD2LATEXFIX) "$(DISTTITLE) Internals Manual" "${DISTDATE}" < internals.tex > internals2.tex mv internals2.tex internals.tex pdflatex internals.tex pdflatex internals.tex -rm -f internals.toc internals.aux internals.idx internals.out # See uninstall also - don't put wildcards in this variable, it might uninstall other stuff VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg \ verilator_coverage verilator_includer verilator_profcfunc # Some scripts go into both the search path and pkgdatadir, # so they can be found by the user, and under $VERILATOR_ROOT. # See uninstall also - don't put wildcards in this variable, it might uninstall other stuff VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_profcfunc.1 VL_INST_INC_BLDDIR_FILES = \ include/verilated_config.h \ 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 = \ examples/*/*.[chv]* examples/*/Makefile* \ installbin: $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator ) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage $(DESTDIR)$(bindir)/verilator_coverage ) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc ) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin ) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg ) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage_bin_dbg $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg ) $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer ) # Man files can either be part of the original kit, or built in current directory # So important we use $< so VPATH is searched installman: $(VL_INST_MAN_FILES) $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1 cd $(srcdir) \ ; for p in $(VL_INST_MAN_FILES) ; 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/hello_world_c $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/tracing_c $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/tracing_sc cd $(srcdir) \ ; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \ $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \ done $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgconfigdir) $(INSTALL_DATA) verilator.pc $(DESTDIR)$(pkgconfigdir) # We don't trust rm -rf, so rmdir instead as it will fail if user put in other files uninstall: -cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_BIN_FILES) -cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_BIN_FILES) -cd $(DESTDIR)$(mandir)/man1 && rm -f $(VL_INST_MAN_FILES) -cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_BLDDIR_FILES) -cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES) -cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_DATA_SRCDIR_FILES) -rm $(DESTDIR)$(pkgconfigdir)/verilator.pc -rmdir $(DESTDIR)$(pkgdatadir)/bin -rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd -rmdir $(DESTDIR)$(pkgdatadir)/include -rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_c -rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc -rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_c -rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_sc -rmdir $(DESTDIR)$(pkgdatadir)/examples -rmdir $(DESTDIR)$(pkgdatadir) -rmdir $(DESTDIR)$(pkgconfigdir) install: all_nomsg install-all install-all: installbin installman installdata install-msg install-here: installman ftp ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users DISTNAMEREV = $(shell sed -e '/DTVERSION/!d' -e 's/.*verilator_\([^"]*\).*/\1/' -e q ${srcdir}/src/config_rev.h) DIRPROJECT := $(shell project_dir --project) VERILATOR_CAD_DIR = $(CAD_DIR)/verilator/$(DISTNAMEREV)/$(DIRPROJECT_ARCH) INST_PROJ_CVS = cp_if_cvs_diff install-project: dist @echo "Install-project to $(DIRPROJECT)" strip bin/verilator_bin* strip bin/verilator_coverage_bin* $(MAKE) install-project-quick for p in $(VL_INST_MAN_FILES) ; do \ $(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \ done $(INST_PROJ_CVS) $(DISTNAME).tgz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz rm $(DISTNAME).tgz install-project-quick: ifeq ($(CFG_WITH_DEFENV),yes) @echo "%Error: Reconfigure with './configure --disable-defenv' to avoid hardcoded paths." false endif @echo "Install-project-quick (no strip) to $(DIRPROJECT)" for p in $(INST_PROJ_FILES) ; do \ $(INST_PROJ_CVS) $$p $(DIRPROJECT)/hw/utils/verilator/$$p; \ done for p in $(INST_PROJ_BIN_FILES) ; do \ $(INST_PROJ_CVS) $$p $(DIRPROJECT)/hw/utils/verilator/$$p-$(DIRPROJECT_ARCH); \ done install-cadtools: dist @echo "Install-project to $(CAD_DIR)" strip bin/verilator_bin* strip bin/verilator_coverage_bin* $(MAKE) install-cadtools-quick $(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/man/man1 for p in $(VL_INST_MAN_FILES) ; do \ $(INSTALL_DATA) $$p $(VERILATOR_CAD_DIR)/man/man1/$$p; \ done $(INST_PROJ_CVS) $(DISTNAME).tgz $(VERILATOR_CAD_DIR)/verilator.tgz rm $(DISTNAME).tgz install-cadtools-quick: ifeq ($(CFG_WITH_DEFENV),yes) @echo "%Error: Reconfigure with './configure --disable-defenv' to avoid hardcoded paths." false endif @echo "Install-cadtools-quick (no strip) to $(VERILATOR_CAD_DIR)" $(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/include/vltstd $(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/bin for p in $(INST_PROJ_FILES) ; do \ $(INST_PROJ_CVS) $$p $(VERILATOR_CAD_DIR)/$$p; \ done for p in $(INST_PROJ_BIN_FILES) ; do \ $(INST_PROJ_CVS) $$p $(VERILATOR_CAD_DIR)/$$p; \ done # VERILATOR_AUTHOR_SITE endif # Use --xml flag to see the cppcheck code to use for suppression CPPCHECK = src/cppcheck_filtered CPPCHECK_FLAGS = --enable=all --inline-suppr \ --suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList CPPCHECK_FLAGS += --xml CPPCHECK_CPP = $(wildcard $(srcdir)/include/*.cpp $(srcdir)/src/*.cpp) CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP)) CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src cppcheck: $(CPPCHECK_DEP) %.cppcheck: %.cpp $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $< analyzer-src: -rm -rf src/obj_dbg scan-build $(MAKE) -k verilator_coverage_bin_dbg verilator_bin_dbg analyzer-include: -rm -rf examples/*/obj* scan-build $(MAKE) -k examples ftp: info install-msg: @echo @echo "Installed binaries to $(DESTDIR)$(bindir)/verilator" @echo "Installed man to $(DESTDIR)$(mandir)/man1" @echo "Installed examples to $(DESTDIR)$(pkgdatadir)/examples" @echo @echo "For documentation see 'man verilator' or 'verilator --help'" @echo "For forums and to report bugs see http://www.veripool.org/verilator" @echo IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in # autoheader might not change config_build.h.in, so touch it ${srcdir}/config_build.h: ${srcdir}/config_build.h.in configure cd ${srcdir} && autoheader touch $@ Makefile: Makefile.in config.status $(IN_WILD) ./config.status src/Makefile: src/Makefile.in Makefile config.status: configure ./config.status --recheck configure: configure.ac ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users autoconf --warnings=all else autoconf endif maintainer-clean:: @echo "This command is intended for maintainers to use;" @echo "rebuilding the deleted files requires makeinfo." rm -f *.info* *.1 $(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 rm -rf test_*/obj_dir rm -rf examples/*/obj_dir examples/*/logs distclean maintainer-clean:: rm -f Makefile config.status config.cache config.log TAGS rm -f verilator_bin* verilator_coverage_bin* rm -f bin/verilator_bin* bin/verilator_coverage_bin* rm -f include/verilated.mk include/verilated_config.h TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \ ${srcdir}/*.in ${srcdir}/*.pod TAGS: $(TAGFILES) etags $(TAGFILES) .PHONY: doxygen doxygen: $(DOXYGEN) doxygen.config ###################################################################### # Test targets dist-file-list: @echo "begin-dist-file-list:"; # Scripts look for this @echo $(wildcard $(DISTFILES)) @echo "end-dist-file-list:"; # Scripts look for this print-cfg-with-threaded: @echo $(CFG_WITH_THREADED) ###################################################################### # 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.916/Changes0000664000177100017500000026144313206352627015033 0ustar wsnyderwsnyderRevision history for Verilator The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.916 2017-11-25 *** Support self-recursive modules, bug659. [Sean Moore, et al] *** Support $error/$warning in elaboration time blocks. *** Support $size/$bits/etc on type references. *** Add error when driving input-only modport, bug1110. [Trevor Elbourne] *** Add BSSPACE and COLONPLUS lint warnings. **** Detect MSB overflow when under VL_DEBUG, bug1238. [Junyi Xi] **** Add data types to --xml. [Rui Terra] **** Fix partial slicing with pattern assignments, bug991. [Johan Bjork] **** Fix false unused warning on interfaces, bug1241. [Laurens van Dam] **** Fix error on "unique case" with no cases. **** Fix MacOS portability, bug1232. [Jeff Bush] * Verilator 3.914 2017-10-14 ** Added new examples/ directory with appropriate examples. This replaces the old test_c and test_sc directories. *** Add --getenv option for simplifying Makefiles. *** Add --x-initial option for specifying initial value assignment behavior. *** Add --no-relative-cfuncs and related default optimization, bug1224. [John Coiner] *** Add /*verilator tag*/ for XML extraction applications. [Chris Randall] **** The internal test_verilated test directory is moved to be part of test_regress. **** The experimental VL_THREADED setting (only, not normal mode) now requires C++11. **** Fix over-aggressive inlining, bug1223. [John Coiner] **** Fix Ubuntu 17.10 issues, bug1223 partial. [John Coiner] **** Fix compiler warning when WIDTH warning ignored on large compare. **** Fix memory leak in VerilatedVcd dumps, bug1222 partial. [Shareef Jalloq] **** Fix unnecessary Vdly variables, bug1224 partial. [John Coiner] **** Fix conditional slices and add related optimizations. **** Fix `` expansion of `defines, bug1225, bug1227, bug1228. [Odd Magne Reitan] **** Fix -E duplicating output, bug1226. [Odd Magne Reitan] **** Fix float-conversion warning, bug1229. [Robert Henry] **** Fix MacOS portability, bug1230, bug1231. [Jeff Bush] * Verilator 3.912 2017-09-23 ** Verilated headers no longer "use namespace std;" User's code without "std::" prefixes may need "use namespace std;" to compile. *** Support or/and/xor array intrinsic methods, bug1210. [Mike Popoloski] *** Support package export, bug1217. [Usuario Eda] *** Fix ordering of arrayed cell wide connections, bug1202 partial. [Mike Popoloski] **** Support module port parameters without defaults, bug 1213. [Mike Popoloski] **** Add performance information to --stats file. **** Simplify VL_CONST_W macro generation for faster compiles. **** Fix LITENDIAN warning on arrayed cells, bug1202. [Mike Popoloski] **** Fix enum ranges without colons, bug1204. [Mike Popoloski] **** Fix GCC noreturn compile error, bug1209. [Mike Popoloski] **** Fix constant function default parameters, bug1211. [Mike Popoloski] **** Fix non-colon array of interface modports, bug1212. [Mike Popoloski] **** Fix .name connections on interfaces, bug1214. [Mike Popoloski] **** Fix wide array indices causing compile error. **** Better optimize Shift-And, and replication constructs. * Verilator 3.910 2017-09-07 *** SystemPerl mode (-sp-deprecated) has been removed. **** Update keyword warnings to include C++11 and others. * Verilator 3.908 2017-08-28 **** Support x in $readmem, bug1180. [Arthur Kahlich] **** Support packed struct DPI imports, bug1190. [Rob Stoddard] **** Fix GCC 6 warnings. **** Fix compile error on unused VL_VALUEPLUSARGS_IW, bug1181. [Thomas J Whatson] **** Fix undefined VL_POW_WWI. [Clifford Wolf] **** Fix internal error on unconnected inouts, bug1187. [Rob Stoddard] * Verilator 3.906 2017-06-22 *** Support set_time_unit/set_time_precision in C traces, msg2261. *** Fix extract of packed array with non-zero LSB, bug1172. [James Pallister] *** Fix shifts by more than 32-bit numbers, bug1174. [Clifford Wolf] *** Fix power operator on wide constants, bug761. [Clifford Wolf] *** Fix .* on interface pins, bug1176. [Maciej Piechotka] * Verilator 3.904 2017-05-30 *** Fix non-cutable ordering loops on clock arrays, bug1009. [Todd Strader] *** Support ports of array of reals, bug1154. [J Briquet] *** Support arrayed parameter overrides, bug1153. [John Stevenson] *** Support $value$plusargs with variables, bug1165. [Wesley Terpstra] **** Support modport access to un-modport objects, bug1161. [Todd Strader] **** Add stack trace when can't optimize function, bug1158. [Todd Strader] **** Add warning on mis-sized literal, bug1156. [Todd Strader] **** Fix interface functions returning wrong parameters, bug996. [Todd Strader] **** Fix non-arrayed cells with interface arrays, bug1153. [John Stevenson] **** Fix --assert with complex case statements, bug1164. [Enzo Chi] * Verilator 3.902 2017-04-02 ** Add -FI option to force includes,msg2146. [Amir Gonnen] ** Add --relative-includes. [Rob Stoddard] *** Add error on duplicate pattern assignments, bug1145. [Johan Bjork] **** Fix error on improperly widthed default function, bug984. [Todd Strader] **** Fix 2009 localparam syntax, msg2139. [Galen Seitz] **** Fix ugly interface-to-non-interface errors, bug1112. [Johan Bjork] **** Fix LDFLAGS and CFLAGS not preserving order, bug1130. [Olof Kindgren] **** Fix internal error on initializing parameter array, bug1131. [Jie Xu] **** Fix internal error on interface arrays, bug1135. [John Stevenson] **** Fix calling sformatf to display, and elab $displays, bug1139. [Johan Bjork] **** Fix realpath compile issue on MSVC++, bug1141. [Miodrag Milanovic] **** Fix missing error on interface size mismatch, bug1143. [Johan Bjork] **** Fix error on parameters with dotted references, bug1146. [Johan Bjork] **** Fix wreal not handling continuous assign, bug1150. [J Briquet] **** Fix nested structure parameter selects, bug1150. [J Briquet] * Verilator 3.900 2017-01-15 ** Internal code changes for improved compatibility and performance. *** Support old-style $display($time), bug467. [John Demme] **** With --bbox-unsup, suppress desassign and mixed edges, bug1120. [Galen Seitz] **** Fix parsing sensitivity with &&, bug934. [Luke Yang] **** Fix internal error on double-for loop unrolling, bug1044. [Jan Egil Ruud] **** Fix internal error on unique casez with --assert, bug1117. [Enzo Chi] **** Fix bad code when tracing array of structs, bug1122. [Andrew Bardsley] * Verilator 3.890 2016-11-25 *** Honor --output-split on coverage constructors, bug1098. [Johan Bjork] **** Fix various issues when making outside of the kit. **** Fix flex 2.6.2 bug, bug1103. [Sergey Kvachonok] **** Fix error on bad interface name, bug1097. [Todd Strader] **** Fix error on referencing variable in parent, bug1099. [Ian Thompson] **** Fix type parameters with low optimization, bug1101. [Stefan Wallentowitz] * Verilator 3.888 2016-10-14 ** Support foreach, bug1078. [Xuan Guo] *** Add --no-decoration to remove output comments, msg2015. [Frederic Requin] *** If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. [Frederic Requin] Set VM_DEFAULT_RULES=0 for old behavior. **** Add error on DPI functions > 32 bits, msg1995. [Elliot Mednick] **** Fix SystemC compiles with VPI, bug1081. [Arthur Kahlich] **** Fix error on wide numbers that represent shifts, msg1991, bug1088. [Mandy Xu] **** Improve Verilation performance on internal strings, msg1975. [Johan Bjork] **** Improve Verilation performance on trace duplicates, bug1090. [Johan Bjork] * Verilator 3.886 2016-07-30 **** Fix enum values of 11-16 bits wide using .next/.prev, bug1062. [Brian Flachs] **** Fix false warnings on non-power-2 enums using .next/.prev. **** Fix comparison of unpacked arrays, bug1071. [Andrew Bardsley] **** Fix compiler warning in GCC 6. [David Horton] * Verilator 3.884 2016-05-18 ** Support parameter type, bug376. [Alan Hunter, et al] ** Support command-line -G/+pvalue param overrides, bug1045. [Stefan Wallentowitz] *** The default l2 scope name is now the same as the top-level module, bug1050. Use "--l2-name v" for the historical behavior. *** Add --l2-name option for controlling "v" naming. **** Fix --output-split of constructors, bug1035. [Johan Bjork] **** Fix removal of empty packages, modules and cells, bug1034. [Johan Bjork] **** Fix core dump on Arch Linux/GCC 6.1.1, bug1058. [Jannis Harder] **** Fix $value$plusargs to string, msg1890. [Frederic Requin] * Verilator 3.882 2016-03-01 **** Internal Verilation-time performance enhancements, bug1021. [Johan Bjork] **** Support inlining interfaces, bug1018. [Johan Bjork] **** Support SV strings to readmemh, bug1040. [Stefan Wallentowitz] **** Fix unrolling complicated for-loop bounds, bug677. [Johan Bjork] **** Fix stats file containing multiple unroll entries, bug1020. [Johan Bjork] **** Fix using short parameter names on negative params, bug1022. [Duraid Madina] **** Fix read-after-free error, bug1031. [Johan Bjork] **** Fix elaboration-time display warnings, bug1032. [Johan Bjork] **** Fix crash on very deep function trees, bug1028. [Jonathan Kimmitt] **** Fix slicing mix of big and little-endian, bug1033. [Geoff Barrett] **** Fix pattern assignment width propagation, bug1037. [Johan Bjork] * Verilator 3.880 2015-12-19 *** Support display %u, %v, %p, %z, bug989. [Johan Bjork] **** Fix real parameters causing bad module names, bug992. [Johan Bjork] **** Fix size-changing cast on packed struct, bug993. [Johan Bjork] **** Fix function calls on arrayed interface, bug994. [Johan Bjork] **** Fix arrayed interfaces, bug879, bug1001. [Todd Strader] **** Fix constant function assigned to packed structs, bug997. [Johan Bjork] **** Fix interface inside generate, bug998. [Johan Bjork] **** Fix $signed casts under generates, bug999. [Clifford Wolf] **** Fix genvar constant propagation, bug1003. [Johan Bjork] **** Fix parameter constant propagation from package, bug1004. [Johan Bjork] **** Fix array slicing of non-const indexes, bug1006. [Johan Bjork] **** Fix dotted generated array error, bug1005. [Jeff Bush, Johan Bjork] **** Fix error instead of warning on large concat, msg1768. [Paul Rolfe] **** Fix $bitstoreal constant propagation, bug1012. [Jonathan Kimmitt] **** Fix model restore crash, bug1013. [Jason McMullan] **** Fix arrayed instances to unpacked of same size, bug1015. [Varun Koyyalagunta] **** Fix slices of unpacked arrays with non-zero LSBs. **** Fix ternary operation with unpacked array, bug1017. [Varun Koyyalagunta]. * Verilator 3.878 2015-11-01 ** Add --vpi flag, and fix VPI linkage, bug969. [Arthur Kahlich] ** Support genvar indexes into arrayed cells, bug517. [Todd Strader] ** Support $sformatf, bug977. [Johan Bjork] *** Support elaboration assertions, bug973. [Johan Bjork] *** Support $display with non-format arguments, bug467. [Jamey Hicks] **** Add VerilatedScopeNameMap for introspection, bug966. [Todd Strader] **** Ignore %l in $display, bug983. [Todd Strader] **** Fix very long module names, bug937. [Todd Strader] **** Fix internal error on dotted refs into generates, bug958. [Jie Xu] **** Fix structure parameter constant propagation, bug968. [Todd Strader] **** Fix enum constant propagation, bug970. [Todd Strader] **** Fix mis-optimizing public DPI functions, bug963. [Wei Song] **** Fix package:scope.scope variable references. **** Fix $fwrite to constant stderr/stdout, bug961. [Wei Song] **** Fix struct.enum.name method calls, bug855. [Jonathon Donaldson] **** Fix dot indexing into arrayed inferfaces, bug978. [Johan Bjork] **** Fix crash in commandArgsPlusMatch, bug987. [Jamie Iles] **** Fix error message on missing interface, bug985. [Todd Strader] * Verilator 3.876 2015-08-12 *** Add tracing_on, etc to vlt files, bug932. [Frederic Requin] **** Support extraction of enum bits, bug951. [Jonathon Donaldson] **** Fix MinGW compiler error, bug927, bug929. [Hans Tichelaar] **** Fix .c files to be treated as .cpp, bug930. [Jonathon Donaldson] **** Fix string-to-int space conversion, bug931. [Fabrizio Ferrandi] **** Fix dpi imports inside generates. [Michael Tresidder] **** Fix rounding in trace $timescale, bug946. [Frederic Requin] **** Fix $fopen with SV string, bug947. [Sven Stucki] **** Fix hashed error with typedef inside block, bug948. [Sven Stucki] **** Fix makefile with --coverage, bug953. [Eivind Liland] **** Fix coverage documentation, bug954. [Thomas J Whatson] **** Fix parameters with function parameter arguments, bug952. [Jie Xu] **** Fix size casts as second argument of cast item, bug950. [Jonathon Donaldson] * Verilator 3.874 2015-06-06 *** Add pkg-config .pc file, bug919. [Stefan Wallentowitz] **** Fix installing missing manpages, bug908. [Ahmed El-Mahmoudy] **** Fix sign extension in large localparams, bug910. [Mike Thyer] **** Fix core dump in sync-async warnings, bug911. [Sebastian Dressler] **** Fix truncation warning with -pins-bv, bug912. [Alfonso Martinez] **** Fix Cygwin uint32 compile, bug914. [Matthew Barr] **** Fix preprocessing stringified newline escapes, bug915. [Anton Rapp] **** Fix part-select in constant function, bug916. [Andrew Bardsley] **** Fix width extension on mis-width ports, bug918. [Patrick Maupin] **** Fix width propagation on sized casts, bug925. [Jonathon Donaldson] **** Fix MSVC++ compiler error, bug927. [Hans Tichelaar] * Verilator 3.872 2015-04-05 *** Add VerilatedVcdFile to allow real-time waveforms, bug890. [HyungKi Jeong] *** Add --clk and related optimizations, msg1533. [Jie Xu] *** Fix order of C style arrays. [Duraid Madina] **** Add --dump-treei-, bug894. [Jie Xu] **** Fix comma-instantiations with parameters, bug884. [Franck Jullien] **** Fix SystemC arrayed bit vectors, bug886. [David Poole] **** Fix compile error on MinGW, bug887. [HyungKi Jeong] * Verilator 3.870 2015-02-12 **** Suppress COMBDLY when inside always_latch, bug864. [Iztok Jeras] **** Support cast operator with expression size, bug865. [Iztok Jeras] **** Add warning on slice selection out of bounds, bug875. [Cong Van Nguyen]. **** Fix member select error broke in 3.868, bug867. [Iztok Jeras] **** Fix $sccanf from string, bug866. [David Pierce] **** Fix VM_PARALLEL_BUILDS broke in 3.868, bug870. [Hiroki Honda] **** Fix non-ANSI modport instantiations, bug868. [Kevin Thompson] **** Fix UNOPTFLAT change detect on multidim arrays, bug872. [Andrew Bardsley] **** Fix slice connections of arrays to ports, bug880. [Varun Koyyalagunta] **** Fix mis-optimizing gate assignments in unopt blocks, bug881. [Mike Thyer] **** Fix sign extension of pattern members, bug882. [Iztok Jeras] **** Fix clang compile warnings. * Verilator 3.868 2014-12-20 ** New verilator_coverage program added to replace SystemPerl's vcoverage. ** PSL support was removed, please use System Verilog assertions. ** SystemPerl mode is deprecated and now untested. *** Support enum.first/name and similar methods, bug460, bug848. *** Add 'string' printing and comparisons, bug746, bug747, etc. *** Inline C functions that are used only once, msg1525. [Jie Xu] *** Fix tracing SystemC signals with structures, bug858. [Eivind Liland] Note that SystemC traces will no longer show the signals in the wrapper, they can be seen one level further down. **** Add --stats-vars, bug851. [Jeremy Bennett] **** Fix bare generates in interfaces, bug789. [Bob Newgard] **** Fix underscores in real literals, bug863. [Jonathon Donaldson] * Verilator 3.866 2014-11-15 *** Fix +define+A+B to define A and B to match other simulators, bug847. [Adam Krolnik] *** Add optimization of wires from arrayed cells, msg1447. [Jie Xu] *** Add optimization of operators between concats, msg1447. [Jie Xu] *** Add public enums, bug833. [Jonathon Donaldson] *** Trace_off now operates on cells, bug826. [Lane Brooks] **** Fix public parameters in unused packages, bug804. [Jonathon Donaldson] **** Fix select when partially out-of-bound, bug823. [Cliffort Wolf] **** Fix generate unrolling with function call, bug830. [Steven Slatter] **** Fix cast-to-size context-determined sizing, bug828. [Geoff Barrett] **** Fix not tracing modules following primitives, bug837. [Jie Xu] **** Fix trace overflow on huge arrays, bug834. [Geoff Barrett] **** Fix quoted comment slashes in defines, bug845. [Adam Krolnik] * Verilator 3.864 2014-09-21 *** Support power operator with real, bug809. [Jonathon Donaldson] **** Improve verilator_profcfunc time attributions. [Jonathon Donaldson] **** Fix duplicate anonymous structures in $root, bug788. [Bob Newgard] **** Fix mis-optimization of bit-swap in wide signal, bug800. [Jie Xu] **** Fix error when tracing public parameters, bug722. [Jonathon Donaldson] **** Fix dpiGetContext in dotted scopes, bug740. [Geoff Barrett] **** Fix over-shift structure optimization error, bug803. [Jeff Bush] **** Fix optional parameter keyword in module #(), bug810. [Iztok Jeras] **** Fix $warning/$error multi-argument ordering, bug816. [Jonathon Donaldson] **** Fix clang warnings, bug818. [Iztok Jeras] **** Fix string formats under deep expressions, bug820. [Iztok Jeras] * Verilator 3.862 2014-06-10 *** Using command line -Wno-{WARNING} now overrides file-local lint_on. *** Add -P to suppress `line and blanks with preprocessing, bug781. [Derek Lockhart] *** Support SV 2012 package import before port list. **** Change SYMRSVDWORD to print as warning rather than error. **** Fix seg-fault with variable of parameterized interface, bug692. [Jie Xu] **** Fix false name conflict on cells in generate blocks, bug749. [Igor Lesik] **** Fix pattern assignment to basic types, bug767. [Jie Xu] **** Fix pattern assignment to conditionals, bug769. [Jie Xu] **** Fix shift corner-cases, bug765, bug766, bug768, bug772, bug774, bug776. [Clifford Wolf] **** Fix C compiler interpreting signing, bug773. [Clifford Wolf] **** Fix late constant division by zero giving X error, bug775. [Clifford Wolf] **** Fix gate primitives with arrays and non-arrayed pins. **** Fix DETECTARRAY error on packed arrays, bug770. [Jie Xu] **** Fix ENDLABEL warnings on escaped identifiers. **** Fix string corruption, bug780. [Derek Lockhart] * Verilator 3.860 2014-05-11 ** PSL is no longer supported, please use System Verilog assertions. ** Support '{} assignment pattern on arrays, bug355. ** Support streaming operators, bug649. [Glen Gibb] ** Fix expression problems with -Wno-WIDTH, bug729, bug736, bug737, bug759. Where WIDTH warnings were ignored this might result in different warning messages and results, though it should better match the spec. [Clifford Wolf] *** Add --no-trace-params. *** Add assertions on 'unique if', bug725. [Jeff Bush] *** Add PINCONNECTEMPTY warning. [Holger Waechtler] *** Support parameter arrays, bug683. [Jeremy Bennett] *** Fix begin_keywords "1800+VAMS", msg1211. **** Documentation fixes, bug723. [Glen Gibb] **** Support {} in always sensitivity lists, bug745. [Igor Lesik] **** Fix tracing of package variables and real arrays. **** Fix tracing of packed arrays without --trace-structs, bug742. [Jie Xu] **** Fix missing coverage line on else-if, bug727. [Sharad Bagri] **** Fix modport function import not-found error. **** Fix power operator calculation, bug730, bug735. [Clifford Wolf] **** Fix reporting struct members as reserved words, bug741. [Chris Randall] **** Fix change detection error on unions, bug758. [Jie Xu] **** Fix -Wno-UNOPTFLAT change detection with 64-bits, bug762. [Clifford Wolf] **** Fix shift-right optimization, bug763. [Clifford Wolf] **** Fix Mac OS-X test issues. [Holger Waechtler] **** Fix C++-2011 warnings. * Verilator 3.856 2014-03-11 *** Support case inside, bug708. [Jan Egil Ruud] *** Add parameters into trace files, bug706. [Alex Solomatnikov] **** Fix parsing "#0 'b0", bug256. **** Fix array bound checks on real variables. **** Fix --skip-identical mis-detecting on OS-X, bug707. **** Fix missing VL_SHIFTRS_IQI with WIDTH warning, bug714. [Fabrizio Ferrandi] **** Fix signed shift right optimization, bug715. [Fabrizio Ferrandi] **** Fix internal error on "input x =" syntax error, bug716. [Lane Brooks] **** Fix slice extraction from packed array, bug717. [Jan Egil Ruud] **** Fix inside statement EQWILD error, bug718. [Jan Egil Ruud] * Verilator 3.855 2014-01-18 *** Support modport import, bug696. [Jeremy Bennett] *** Add --trace-structs to show struct names, bug673. [Chris Randall] **** Fix tracing of packed structs, bug705. [Jie Xu] **** Fix --lint-only with MinGW, msg1283. [HyungKi Jeong] **** Fix some delayed assignments of typedefed unpacked arrays. **** Fix wire declarations with size and not range, bug466. [Alex Solomatnikov] **** Fix parameter pin vs. normal pin error, bug704. [Alex Solomatnikov] * Verilator 3.854 2013-11-26 *** Add UNPACKED warning to convert unpacked structs. [Jeremy Bennett] *** Add --compiler clang to work around compiler bug, bug694. [Stefan Ludwig] **** Support vpi_get of vpiSuppressVal, bug687. [Varun Koyyalagunta] **** Support vpi_get_time, bug688. [Varun Koyyalagunta] **** Fix evaluation of chained parameter functions, bug684. [Ted Campbell] **** Fix enum value extension of '1. **** Fix multiple VPI variable callbacks, bug679. [Rich Porter] **** Fix vpi_get of vpiSize, bug680. [Rich Porter] **** Fix vpi_remove_cb inside callback, bug689. [Varun Koyyalagunta] **** Fix crash with coverage of structures, bug691. [Eivind Liland] **** Fix array assignment from const var, bug693. [Jie Xu] * Verilator 3.853 2013-09-30 **** Add --no-order-clock-delay to work around bug613. [Charlie Brej] * Verilator 3.852 2013-09-29 *** Support named function and task arguments. [Chris Randall] *** Report SELRANGE warning for non-generate if, bug675. [Roland Kruse] **** Fix ordering of $fgetc, msg1229. [Frederic Requin] **** Fix --output-split-cfunc to count internal functions. [Chris Randall] **** Fix crash on 32-bit Ubuntu, bug670. [Mark Jackson Pulver] * Verilator 3.851 2013-08-15 *** Fix ordering of clock enables with delayed assigns, bug613. [Jeremy Bennett] *** Fix vpi_iterate on memory words, bug655. [Rich Porter] **** Fix final duplicate declarations when non-inlined, bug661. [Charlie Brej] **** Fix interface ports with comma lists, msg1058. [Ed Lander] **** Fix parameter real conversion from integer. **** Fix clang warnings, bug668. [Yutetsu Takatsukasa] * Verilator 3.850 2013-06-02 ** Support interfaces and modports, bug102. [Byron Bradley, Jeremy Bennett] *** Duplicate clock gate optimization on by default, bug621. **** Fix arrayed input compile error, bug645. [Krzysztof Jankowski] **** Fix GCC version runtime changes, bug651. [Jeremy Bennett] **** Fix packed array select internal error, bug652. [Krzysztof Jankowski] * Verilator 3.847 2013-05-11 *** Add ALWCOMBORDER warning. [KC Buckenmaier] *** Add --pins-sc-uint and --pins-sc-biguint, bug638. [Alex Hornung] **** Support "signal[vec]++". **** Fix simulation error when inputs and MULTIDRIVEN, bug634. [Ted Campbell] **** Fix module resolution with __, bug631. [Jason McMullan] **** Fix packed array non-zero right index select crash, bug642. [Krzysztof Jankowski] **** Fix nested union crash, bug643. [Krzysztof Jankowski] * Verilator 3.846 2013-03-09 ** IEEE 1800-2012 is now the default language. This adds 4 new keywords and updates the svdpi.h and vpi_user.h header files. *** Add --report-unoptflat, bug611. [Jeremy Bennett] *** Add duplicate clock gate optimization, msg980. [Varun Koyyalagunta] Disabled unless -OD or -O3 used, please try it as may get some significant speedups. *** Fix wrong dot resolution under inlining. [Art Stamness] **** Support pattern assignment features, bug616, bug617, bug618. [Ed Lander] **** Support bind in $unit, bug602. [Ed Lander] **** Support '() sized casts, bug628. [Ed Lander] **** Fix DETECTARRAY on packed structures, bug610. [Jeremy Bennett] **** Fix LITENDIAN on unpacked structures, bug614. [Wai Sum Mong] **** Fix 32-bit OS VPI scan issue, bug615. [Jeremy Bennett, Rich Porter] **** Fix opening a VerilatedVcdC file multiple times, msg1021. [Frederic Requin] **** Fix UNOPTFLAT circular array bounds crossing, bug630. [Jie Xu] * Verilator 3.845 2013/02/04 *** Fix nested packed arrays and struct, bug600. [Jeremy Bennett] Packed arrays are now represented as a single linear vector in Verilated models. This may affect packed arrays that are public or accessed via the VPI. *** Support wires with data types, bug608. [Ed Lander] *** Support bind, to module names only, bug602. [Ed Lander] *** Support VPI product info, warning calls, etc, bug588. [Rick Porter] *** Support $left, $right and related functions, bug448. [Iztok Jeras] *** Support inside expressions. *** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines. **** Fix pin width mismatch error, bug595. [Alex Solomatnikov] **** Fix implicit one bit parameter selection, bug603. [Jeremy Bennett] **** Fix signed/unsigned parameter misconversion, bug606. [Jeremy Bennett] **** Fix segfault on multidimensional dotted arrays, bug607. [Jie Xu] **** Fix per-bit array output connection error, bug414. [Jan Egil Ruud] **** Fix package logic var compile error. **** Fix enums with X values. * Verilator 3.844 2013/01/09 *** Support "unsigned int" DPI import functions, msg966. [Alex Lee] *** Fix package resolution of parameters, bug586. [Jeremy Bennett] **** Fix non-integer vpi_get_value, bug587. [Rich Porter] **** Fix task inlining under $display and case, bug589, bug598. [Holger Waechtler] **** Fix package import of non-localparam parameter, bug474, bug591. [Jeremy Bennett] **** Fix package import of package imports, partial bug592. [Jeremy Bennett] **** Fix package import preventing local var, bug599. [Jeremy Bennett] **** Fix array extraction of implicit vars, bug601. [Joe Eiler] * Verilator 3.843 2012/12/01 *** Add +1364-1995ext and similar language options, bug532. [Jeremy Bennett] **** Fix mis-optimized identical submodule subtract, bug581. [Charlie Brej] **** Fix crash on dotted references into dead modules, bug583. [Jeremy Bennett] **** Fix compile issues on MSVCC, bug571, bug577. [Amir Gonnen] **** Fix --debug overriding preceding --dump-treei, bug580. [Jeremy Bennett] * Verilator 3.842 2012/11/03 **** Add -x-initial-edge, bug570. [Jeremy Bennett] **** Fix parameter pins interspersed with cells broke in 3.840. [Bernard Deadman] **** Fix large shift error on large shift constants. [David Welch] **** Fix $display mangling on GCC 4.7 and speed up, msg927, bug373, bug574. [R Diez] **** Fix array of struct references giving false error, bug566. [Julius Baxter] **** Fix missing var access functions when no DPI, bug572. [Amir Gonnen] **** Fix name collision on unnamed blocks, bug567. [Chandan Egbert] **** Fix name collision on task inputs, bug569. [Chandan Egbert] * Verilator 3.841 2012/09/03 *** Add --savable to support model save/restore. [Jeremy Bennett] *** Support '{} assignment pattern on structures, part of bug355. **** Fix double-deep parameter cell WIDTHs, bug541. [Hiroki Honda] **** Fix imports under multiple instantiated cells, bug542. [Alex Solomatnikov] **** Fix defparam in generate broke in 3.840, bug543. [Alex Solomatnikov] **** Fix duplicate begin error broke in 3.840, bug548. [Alex Solomatnikov] **** Fix triangle symbol resolution error broke in 3.840, bug550. [Ted Campbell] * Verilator 3.840 2012/07/31 Beta ** Rewrote tristate handling; supports tri0, tri1, tristate bit selects, concatenates and pullup/pulldowns, bug395, bug56, bug54, bug51. [Alex Solomatnikov, Lane Brooks, et al] ** Support packed structures and unions, bug181. Note this was a major internal change that may lead to some instability. *** Support tri0 and tri1, bug462. [Alex Solomatnikov] *** Support nmos and pmos, bug488. [Alex Solomatnikov] *** Add INITIALDLY warning on initial assignments, bug478. [Alex Solomatnikov] *** Add PINMISSING and PINNOCONNECT lint checks. *** Add --converge-limit option. *** Fix generate operators not short circuiting, bug413. [by Jeremy Bennett] *** Fix parameters not supported in constant functions, bug474. [Alex Solomatnikov] **** Fix duplicate warnings/errors, bug516. [Alex Solomatnikov] **** Fix signed extending biops with WIDTH warning off, bug511. [Junji Hashimoto] **** Fix ITOD internal error on real conversions, bug491. [Alex Solomatnikov] **** Fix input and real loosing real data type, bug501. [Alex Solomatnikov] **** Fix imports causing symbol table error, bug490. [Alex Solomatnikov] **** Fix newlines in radix values, bug507. [Walter Lavino] **** Fix loop error message to report line, bug513. [Jeremy Bennett] **** Fix false UNUSED warning on file system calls. **** Fix GCC 4.7.0 compile warnings, bug530. [Jeremy Bennett] **** Fix svdpi.h compile error on Apple OS. **** Fix compile error under git submodules, bug534. [Aurelien Francillon] * Verilator 3.833 2012/04/15 *** Support += and -= in standard for loops, bug463. [Alex Solomatnikov] *** Fix processing unused parametrized modules, bug469, bug470. [Alex Solomatnikov] **** Add SELRANGE as warning instead of error, bug477. [Alex Solomatnikov] **** Add readme.pdf and internal.pdf and doxygen, bug483. [by Jeremy Bennett] **** Fix change detections on arrays, bug364. [John Stevenson, Alex Solomatnikov] **** Fix signed array warning, bug456. [Alex Solomatnikov] **** Fix genvar and begin under generate, bug461. [Alex Solomatnikov] **** Fix real constant parameter functions, bug475. [Alex Solomatnikov] **** Fix and document --gdb option, bug454. [Jeremy Bennett] **** Fix OpenSolaris compile error. [Sanjay Singh] * Verilator 3.832 2012/03/07 *** Fix memory delayed assignments from multiple clock domains. [Andrew Ling] *** Support arrayed SystemC I/O pins. [Christophe Joly] *** Report MULTIDRIVEN on memories set in multiple clock domains. *** Report ENDLABEL on mismatching end labels, bug450. [Iztok Jeras] **** Fix expansion of back-slashed escaped macros, bug441. [Alberto Del Rio] **** Fix inheriting real and signed type across untyped parameters. **** Fix core dump with over 100 deep UNOPTFLAT, bug432. [Joe Eiler] **** Fix false command not found warning in makefiles. [Ruben Diez] **** Fix hang when functions inside begin block. [David Welch] **** Fix hang on recursive substitution `defines, bug443. [Alex Solomatnikov] * Verilator 3.831 2012/01/20 ** Support SystemC 2.3.0 prerelease. This requires setting the new SYSTEMC_INCLUDE and SYSTEMC_LIBDIR variables in place of now deprecated SYSTEMC and SYSTEMC_ARCH. [Iztok Jeras] **** Suppress VARHIDDEN on dpi import arguments. [Ruben Diez] **** Support "generate for (genvar i=0; ...". [David Kravitz] **** Fix dpi exports with > 32 bit but < 64 bit args, bug423. [Chandan Egbert] **** Fix array of instantiations with sub-range output, bug414. [Jeremy Bennett] **** Fix BLKSEQ warnings on variables declared inside always. [Ruben Diez] * Verilator 3.830 2011/11/27 ** With "--language VAMS" support a touch of Verilog AMS. [Holger Waechtler] *** Add sc_bv attribute to force bit vectors, bug402. [by Stefan Wallentowitz] **** Search for user -y paths before default current directory. [Ruben Diez] **** Support constants in sensitivity lists, bug412. [Jeremy Bennett] **** Support $system. [Ruben Diez] **** Support $sscanf with %g. [Holger Waechtler] **** Indicate 'exiting due to errors' if errors, not warnings. [Ruben Diez] **** Fix bad result with if-else-return optimization, bug420. [Alex Solomatnikov] **** Fix reporting not found modules if generate-off, bug403. [Jeremy Bennett] **** Fix $display with %d following %g. [Holger Waechtler] * Verilator 3.824 2011/10/25 *** Fix "always @ (* )", bug403, bug404. [Walter Lavino] *** Add ASSIGNIN as suppressable error. [Jeremy Bennett] **** Fix 3.823 constructor core dump on Debian, bug401. [Ahmed El-Mahmoudy] * Verilator 3.823 2011/10/20 *** Support $ceil, $floor, etc. [Alex Solomatnikov] *** Add configure options for cc warnings and extended tests. [Ruben Diez] *** Add -Wall reporting ASSIGNDLY on assignment delays. [Ruben Diez] *** Fix UNDRIVEN warnings inside DPI import functions. [Ruben Diez] *** Fix --help output to go to stderr, not stdout, bug397. [Ruben Diez] **** Fix DPI import output of 64 bits, bug398. [Mike Denio] **** Fix DPI import false BLKSEQ warnings. [Alex Solomatnikov] **** Fix MSVC compile warning with trunc/round, bug394. [Amir Gonnen] **** Fix autoconf and Makefile warnings, bug396. [Ruben Diez] * Verilator 3.821 2011/09/14 **** Fix PowerPC runtime error, bug288. [Ahmed El-Mahmoudy] **** Fix internal error on integer casts, bug374. [Chandan Egbert] * Verilator 3.820 2011/07/28 ** Support 'real' numbers and related functions. *** Support 'const' variables in limited cases; similar to enums. [Alex Solomatnikov] *** Support disable for loop escapes. *** Support $fopen and I/O with integer instead of `verilator_file_descriptor. *** Support coverage in -cc and -sc output modes. [John Li] Note this requires SystemPerl 1.338 or newer. **** Fix vpi_register_cb using bad s_cb_data, bug370. [by Thomas Watts] **** Fix $display missing leading zeros in %0d, bug367. [Alex Solomatnikov] **** Use 'vluint64_t' for SystemC instead of (same sized) 'uint64' for MSVC++. * Verilator 3.813 2011/06/28 *** Support bit vectors > 64 bits wide in DPI import and exports. *** Fix out of memory on slice syntax error, bug354. [Alex Solomatnikov] **** Fix error on enum references to other packages, bug339. [Alex Solomatnikov] **** Fix DPI undeclared svBitVecVal compile error, bug346. [Chandan Egbert] **** Fix DPI bit vector compile errors, bug347, bug359. [Chandan Egbert] **** Fix CDCRSTLOGIC report showing endpoint flops without resets. **** Fix compiler warnings on SPARC, bug288. [Ahmed El-Mahmoudy] * Verilator 3.812 2011/04/06 *** Add --trace-max-width and --trace-max-array, bug319. [Alex Solomatnikov] *** Add --Wno-fatal to turn off abort on warnings. [by Stefan Wallentowitz] **** Support ${...} and $(...) env vars in .vc files. [by Stefan Wallentowitz] **** Support $bits(data_type), bug327. [Alex Solomatnikov] **** Support loop unrolling on width mismatches, bug333. [Joe Eiler] **** Support simple cast operators, bug335. [Alex Solomatnikov] **** Accelerate bit-selected inversions. **** Add error on circular parameter definitions, bug329. [Alex Solomatnikov] **** Fix concatenates and vectored bufif1, bug326. [Iztok Jeras] * Verilator 3.811 2011/02/14 **** Report errors on duplicated or empty pins, bug321. [Christian Leber] **** Report error on function call output tied to constant. [Bernard Deadman] **** Throw UNUSED/UNDRIVEN only once per net in a parametrized module. **** Fix internal error on functions called as SV tasks. [Bernard Deadman] **** Fix internal error on non-inlined inout pins. [Jeff Winston] **** Fix false BLKSEQ on non-unrolled for loop indexes. [Jeff Winston] **** Fix block comment not separating identifiers, bug311. [Gene Sullivan] **** Fix warnings to point to lowest net usage, not upper level ports. **** Fix error on constants connected to outputs, bug323. [Christian Leber] * Verilator 3.810 2011/01/03 ** Add limited support for VPI access to public signals, see docs. *** Add -F option to read relative option files, bug297. [Neil Hamilton] *** Support ++,--,+= etc as standalone statements. [Alex Solomatnikov] **** When running with VERILATOR_ROOT, optionally find binaries under bin. **** Suppress WIDTH warnings when adding/subtracting 1'b1. ** Add -Wall, -Wwarn-style, -Wno-style to enable code style warnings that have been added to this release, and disabled by default: *** With --Wall, add BLKSEQ warning on blocking assignments in seq blocks. *** With --Wall, add DECLFILENAME warning on modules not matching filename. *** With --Wall, add DEFPARAM warning on deprecated defparam statements. *** With --Wall, add IFDEPTH warning on deep if statements. *** With --Wall, add INCABSPATH warning on `include with absolute paths. *** With --Wall, add SYNCASYNCNET warning on mixed sync/async reset nets. *** With --Wall, add UNDRIVEN warning on undriven nets. *** With --Wall, add UNUSED warning on unused nets. *** The VARHIDDEN warning is now disabled by default, use -Wall to enable. * Verilator 3.805 2010/11/02 **** Add warning when directory contains spaces, msg378. [Salman Sheikh] **** Fix wrong filename on include file errors, bug289. [Brad Parker] **** Fix segfault on SystemVerilog "output wire foo=0", bug291. [Joshua Wise] **** Fix DPI export name not found, msg369. [Terry Chen] * Verilator 3.804 2010/09/20 *** Support tracing/coverage of underscore signals, bug280. [by Jason McMullan] **** Fix preprocessor `` of existing base define, bug283. [Usha Priyadharshini] **** Increase define recursions before error. [Paul Liu] **** On core dump, print debug suggestions. * Verilator 3.803 2010/07/10 *** Fix preprocessor preservation of newlines across macro substitutions. **** Fix preprocessor stringification of nested macros. **** Fix some constant parameter functions causing crash, bug253. [Nick Bowler] **** Fix do {...} while() not requiring final semicolon. * Verilator 3.802 2010/05/01 *** Support runtime access to public signal names. *** Add /*verilator public_flat_rw*/ for timing-specific public access. *** Fix word size to match uint64_t on -m64 systems, bug238. [Joe Eiler] **** Improve error handling on slices of arrays, bug226. [by Byron Bradley] **** Report errors when extra underscores used in meta-comments. **** Fix bit reductions on multi-packed dimensions, bug227. [by Byron Bradley] **** Fix removing $fscanf if assigned to unused var, bug248. [Ashutosh Das] **** Fix "make install" with configure outside srcdir. [Stefan Wallentowitz] **** Fix loop unroller out of memory; change --unroll-stmts. [Ashutosh Das] **** Fix trace files with empty modules crashing some viewers. **** Fix parsing single files > 2GB. [Jeffrey Short] **** Fix installing data files as non-executable, bug168. [by Ahmed El-Mahmoudy] * Verilator 3.801 2010/03/17 *** Support "break", "continue", "return". *** Support "`default_nettype none|wire". [Dominic Plunkett] **** Skip SystemC tests if not installed. [Iztok Jeras] **** Fix clock-gates with non-AND complex logic, bug220. [Ashutosh Das] **** Fix flushing VCD buffers on $stop. [Ashutosh Das] **** Fix Mac OS-X compile issues, bug217. [Joshua Wise, Trevor Williams] **** Fix make uninstall, bug216. [Iztok Jeras] **** Fix parametrized defines with empty arguments. * Verilator 3.800 2010/02/07 Application visible changes: ** SystemPerl is no longer required for tracing. Applications must use VerilatedVcdC class in place of SpTraceVcdC. ** SystemVerilog 1800-2009 is now the default language. Thus "global" etc are now keywords. See the --language option. New features: ** Support SystemVerilog types "byte", "chandle", "int", "longint", "shortint", "time", "var" and "void" in variables and functions. ** Support "program", "package", "import" and $unit. ** Support typedef and enum. [by Donal Casey] ** Support direct programming interface (DPI) "import" and "export". Includes an extension to map user $system PLI calls to the DPI. *** Support assignments of multidimensional slices, bug170. [by Byron Bradley] *** Support multidimensional inputs/outputs, bug171. [by Byron Bradley] *** Support "reg [1:0][1:0][1:0]" and "reg x [3][2]", bug176. [Byron Bradley] *** Support declarations in loop initializers, bug172. [by Byron Bradley] *** Support $test$plusargs and $value$plusargs, but see the docs! *** Support $sformat and $swrite. *** Support 1800-2009 define defaults and `undefineall. *** Add -CFLAGS, -LDFLAGS, .a, .o, and .so options. *** Speed compiles by avoiding including the STL iostream header. Application programs may need to include it themselves to avoid errors. *** Add experimental clock domain crossing checks. *** Add experimental --pipe-filter to filter all Verilog input. *** Add experimental config files to filter warnings outside of the source. *** Add VARHIDDEN warning when signal name hides module name. **** Support optional cell parenthesis, bug179. [by Byron Bradley] **** Support for loop i++, ++i, i--, --i, bug175. [by Byron Bradley] **** Support 1800-2009 /*comments*/ in define values. **** Add Makefile VM_GLOBAL_FAST, listing objects needed to link executables. **** Add --bbox-unsup option to black-box unsupported UDP tables. **** Add -Wno-MODDUP option to allow duplicate modules. Bug fixes: **** Fix implicit variable issues, bug196, bug201. [Byron Bradley] **** Fix 'for' variable typing, bug205. [by Byron Bradley] **** Fix tracing with --pins-bv 1, bug195. [Michael S] **** Fix MSVC++ 2008 compile issues, bug209. [Amir Gonnen] **** Fix MinGW compilation, bug184, bug214. [by Shankar Giri, Amir Gonnen] **** Fix Cygwin 1.7.x compiler error with uint32_t, bug204. [Ivan Djordjevic] **** Fix `define argument mis-replacing system task of same name, bug191. **** Fix Verilator core dump on wide integer divides, bug178. [Byron Bradley] **** Fix lint_off/lint_on meta comments on same line as warning. * Verilator 3.720 2009/10/26 ** Support little endian bit vectors ("reg [0:2] x;"). ** Support division and modulus of > 64 bit vectors. [Gary Thomas] *** Fix writing to out-of-bounds arrays writing element 0. **** Fix core dump with SystemVerilog var declarations under unnamed begins. **** Fix VCD files showing internal flattened hierarchy, broke in 3.714. **** Fix cell port connection to unsized integer causing false width warning. **** Fix erroring on strings with backslashed newlines, bug168. [Pete Nixon] * Verilator 3.714 2009/09/18 ** Add --bbox-sys option to blackbox $system calls. ** Support generate for var++, var--, ++var, --var. *** Improved warning when "do" used as identifier. **** Don't require SYSTEMPERL_INCLUDE if SYSTEMPERL/src exists. [Gary Thomas] **** Fix deep defines causing flex scanner overflows. [Brad Dobbie] **** Fix preprocessing commas in deep parameterized macros. [Brad Dobbie] **** Fix tracing escaped dotted identifiers, bug107. **** Fix $display with uppercase %M. **** Fix --error-limit option being ignored. * Verilator 3.713 2009/08/04 ** Support constant function calls for parameters. [many!] *** Support SystemVerilog "logic", bug101. [by Alex Duller] *** Name SYMRSVDWORD error, and allow disabling it, bug103. [Gary Thomas] **** Fix escaped preprocessor identifiers, bug106. [Nimrod Gileadi] * Verilator 3.712 2009/07/14 ** Patching SystemC is no longer required to trace sc_bvs. *** Support zero-width constants in concatenations. [Jeff Winston] *** Add verilator --pins-uint8 option to use sc_in. *** Add verilator -V option, to show verbose version. *** On WIDTH warnings, show variable name causing error. [Jeff Winston] **** Add BLKLOOPINIT error code, and describe --unroll-count. [Jeff Winston] * Verilator 3.711 2009/06/23 **** Support decimal constants of arbitrary widths. [Mark Marshall] **** Fix error on case statement with all duplicate items, bug99. [Gary Thomas] **** Fix segfault on unrolling for's with bad inits, bug90. [Andreas Olofsson] **** Fix tristates causing "Assigned pin is neither...". [by Lane Brooks] **** Fix compiler errors under Fedora release candidate 11. [Chitlesh Goorah] * Verilator 3.710 2009/05/19 ** Verilator is now licensed under LGPL v3 and/or Artistic v2.0. *** `__FILE__ now expands to a string, per draft SystemVerilog 2010(ish). **** The front end parser has been re-factored to enable more SV parsing. Code should parse the same, but minor parsing bugs may pop up. **** Verilator_includer is no longer installed twice, bug48. [Lane Brooks] **** Fix escaped identifiers with '.' causing conflicts, bug83. [J Baxter] **** Fix define formal arguments that contain newlines, bug84. [David A] * Verilator 3.703 2009/05/02 *** Fix $clog2 calculation error with powers-of-2, bug81. [Patricio Kaplan] **** Fix error with tasks that have output first, bug78. [Andrea Foletto] **** Fix "cloning" error with -y/--top-module, bug76. [Dimitris Nalbantis] **** Fix segfault with error on bad --top-module, bug79. [Dimitris Nalbantis] **** Fix "redefining I" error with complex includes. [Duraid Madina] **** Fix GCC 4.3.2 compile warnings. * Verilator 3.702 2009/03/28 *** Add --pins-bv option to use sc_bv for all ports. [Brian Small] *** Add SYSTEMPERL_INCLUDE envvar to assist RPM builds. [Chitlesh Goorah] **** Report errors when duplicate labels are used, bug72. [Vasu Kandadi] **** Fix the SC_MODULE name() to not include __PVT__. [Bob Fredieu] * Verilator 3.701 2009/02/26 ** Support repeat and forever statements. [Jeremy Bennett] *** Add --debugi- option, for internal debugging. [Dennis Muhlestein] **** Fix compile issues with GCC 4.3, bug47. [Lane Brooks] **** Fix VL_RANDom to better randomize bits. [Art Stamness] **** Fix error messages to consistently go to stderr. [Jeremy Bennett] **** Fix left associativity for ?: operators. * Verilator 3.700 2009/01/08 ** Add limited support for tristate inouts. Written by Lane Brooks, under support by Ubixum Inc. This allows common pad ring and tristate-mux structures to be Verilated. See the documentation for more information on supported constructs. ** Add --coverage_toggle for toggle coverage analysis. Running coverage now requires SystemPerl 1.301 or newer. *** Add /*verilator coverage_on/_off */ to bracket coverage regions. *** Optimize two-level shift and and/or trees, +23% on one test. *** Support posedge of bit-selected signals, bug45. [Rodney Sinclair] *** Line coverage now aggregates by hierarchy automatically. Previously this would be done inside SystemPerl, which was slower. **** Minor performance improvements of Verilator compiler runtime. **** Coverage of each parametarized module is counted separately. [Bob Fredieu] **** Fix creating parameterized modules when no parameter values are changed. **** Fix certain generate-if cells causing "clone" error. [Stephane Laurent] **** Fix line coverage of public functions. [Soon Koh] **** Fix SystemC 2.2 deprecated warnings about sensitive() and sc_start(). **** Fix arrayed variables under function not compiling, bug44. [Ralf Karge] **** Fix --output-split-cfuncs to also split trace code. [Niranjan Prabhu] **** Fix 'bad select range' warning missing some cases, bug43. [Lane Brooks] **** Fix internal signal names containing control characters (broke in 3.680). **** Fix compile error on Ubuntu 8.10. [Christopher Boumenot] **** Fix internal error on "output x; reg x = y;". **** Fix wrong result for read of delayed FSM signal, bug46. [Rodney Sinclair] * Verilator 3.681 2008/11/12 *** Add SystemVerilog unique and priority case. **** Include Verilog file's directory name in coverage reports. **** Fix 'for' under 'generate-for' causing error; bug38. [Rafael Shirakawa] **** Fix coverage hierarchy being backwards with inlining. [Vasu Arasanipalai] **** Fix GCC 4.3 compile error; bug35. [Lane Brooks] **** Fix MSVC compile error; bug42. [John Stroebel] * Verilator 3.680 2008/10/08 ** Support negative bit indexes. [Stephane Laurent] Tracing negative indexes requires latest Verilog-Perl and SystemPerl. *** Suppress width warnings between constant strings and wider vectors. [Rodney Sinclair] **** Ignore SystemVerilog timeunit and timeprecision. **** Expand environment variables in -f input files. [Lawrence Butcher] **** Report error if port declaration is missing; bug32. [Guy-Armand Kamendje] **** Fix genvars causing link error when using --public. [Chris Candler] * Verilator 3.671 2008/09/19 ** SystemC uint64_t pins are now the default instead of sc_bv<64>. Use --no-pins64 for backward compatibility. *** Support SystemVerilog "cover property" statements. *** When warnings are disabled on signals that are flattened out, disable the warnings on the signal(s) that replace it. *** Add by-design and by-module subtotals to verilator_profcfunc. *** Fix extra evaluation of pure combo blocks in SystemC output. **** Add IMPERFECTSCH warning, disabled by default. **** Support coverage under SystemPerl 1.285 and newer. **** Fix stack overflow on large ? : trees. [John Sanguinetti] **** Support arbitrary characters in identifiers. [Stephane Laurent] * Verilator 3.670 2008/07/23 ** Add --x-assign=fast option, and make it the default. This chooses performance over reset debugging. See the manual. ** Add --autoflush, for flushing streams after $display. [Steve Tong] ** Add CASEWITHX lint warning and if disabled fix handling of casez with Xs. *** Add $feof, $fgetc, $fgets, $fflush, $fscanf, $sscanf. [Holger Waechtler] *** Add $stime. [Holger Waechtler] *** Add $random. *** Add --Wfuture-, for improving forward compatibility. **** Fix verilator_includer not being installed properly. [Holger Waechtler] **** Fix IMPURE errors due to X-assignment temporary variables. [Steve Tong] **** Fix "lvalue" errors with public functions; bug25. [CY Wang] **** Add WIDTH warning to $fopen etc file descriptors. **** Internal changes to how $displays get compiled and executed. * Verilator 3.665 2008/06/25 **** Ignore "// verilator" comments alone on endif lines. [Rodney Sinclair] **** "Make install" now installs verilator_includer and verilator_profcfunc. **** Fix tracing missing changes on undriven public wires. [Rodney Sinclair] **** Fix syntax error when "`include `defname" is ifdefed. [John Dickol] **** Fix error when macro call has commas in concatenate. [John Dickol] **** Fix compile errors under Fedora 9, GCC 4.3.0. [by Jeremy Bennett] **** Fix Makefile to find headers/libraries under prefix. [by Holger Waechtler] * Verilator 3.664 2008/05/08 **** Fix missing file in kit. * Verilator 3.663 2008/05/07 **** Add DESTDIR to Makefiles to assist RPM construction. [Gunter Dannoritzer] **** Fix compiler warnings under GCC 4.2.1. **** Fix preprocessor `else after series of `elsif. [Mark Nodine] **** Fix parametrized defines calling define with comma. [Joshua Wise] **** Fix comma separated list of primitives. [by Bryan Brady] * Verilator 3.662 2008/04/25 *** Add Verilog 2005 $clog2() function. This is useful in calculating bus-widths from parameters. *** Support /**/ comments in -f option files. [Stefan Thiede] **** Add error message when modules have duplicate names. [Stefan Thiede] **** Support defines terminated in EOF, though against spec. [Stefan Thiede] **** Support optional argument to $finish and $stop. [by Stefan Thiede] **** Support ranges on gate primitive instantiations. [Stefan Thiede] **** Ignore old standard(ish) Verilog-XL defines. [by Stefan Thiede] **** Fix "always @ ((a) or (b))" syntax error. [by Niranjan Prabhu] **** Fix "output reg name=expr;" syntax error. [Martin Scharrer] **** Fix multiple .v files being read in random order. [Stefan Thiede] **** Fix internal error when params get non-constants. [Johan Wouters] **** Fix bug introduced in 3.661 with parametrized defines. * Verilator 3.661 2008/04/04 *** The --enable-defenv configure option added in 3.660 is now the default. This hard-codes a default for VERILATOR_ROOT etc in the executables. *** Add --language option for supporting older code. [Stefan Thiede] *** Add --top-module option to select between multiple tops. [Stefan Thiede] *** Unsized concatenates now give WIDTHCONCAT warnings. [Jonathan Kimmitt] Previously they threw fatal errors, which in most cases is correct according to spec, but can be incorrect in presence of parameter values. **** Support functions with "input integer". [Johan Wouters] **** Ignore delays attached to gate UDPs. [Stefan Thiede] **** Fix SystemVerilog parameterized defines with `` expansion, and fix extra whitespace inserted on substitution. [Vladimir Matveyenko] **** Fix no-module include files on command line. [Stefan Thiede] **** Fix dropping of backslash quoted-quote at end of $display. **** Fix task output pin connected to non-variables. [Jonathan Kimmitt] **** Fix missing test_v in install datadir. [Holger Waechtler] **** Fix internal error after MSB < LSB error reported to user. [Stefan Thiede] * Verilator 3.660 2008/03/23 *** Add support for hard-coding VERILATOR_ROOT etc in the executables, to enable easier use of Verilator RPMs. [Gunter Dannoritzer] *** Allow multiple .v files on command line. [Stefan Thiede] *** Convert re-defining macro error to warning. [Stefan Thiede] *** Add --error-limit option. [Stefan Thiede] *** Allow __ in cell names by quoting them in C. [Stefan Thiede] **** Fix genvar to be signed, so "< 0" works properly. [Niranjan Prabhu] **** Fix assignments to inputs inside functions/tasks. [Patricio Kaplan] **** Fix definitions in main file.v, referenced in library. [Stefan Thiede] **** Fix undefined assigns to be implicit warnings. [Stefan Thiede] * Verilator 3.658 2008/02/25 **** Fix unistd compile error in 3.657. [Patricio Kaplan, Jonathan Kimmitt] * Verilator 3.657 2008/02/20 **** Fix assignments of {a,b,c} = {c,b,a}. [Jonathan Kimmitt] **** Fix Perl warning with --lint-only. [by Ding Xiaoliang] **** Avoid creating obj_dir with --lint-only. [Ding Xiaoliang] **** Fix parsing of always @(*). [Patricio Kaplan] * Verilator 3.656 2008/01/18 **** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman] In such cases, a new {prefix}__Inlines.h file will be built and included. **** Fixed sign error when extracting from signed memory. [Peter Debacker] **** Fixed tracing of SystemC w/o SystemPerl. [Bernard Deadman, Johan Wouters] * Verilator 3.655 2007/11/27 *** Support "#delay ;" with associated STMTDLY warning. **** Fixed generate for loops with constant zero conditions. [Rodney Sinclair] **** Fixed divide-by-zero errors in constant propagator. [Rodney Sinclair] **** Fixed wrong result with obscure signed-shift underneath a "? :". **** Fixed many internal memory leaks, and added leak detector. * Verilator 3.654 2007/10/18 **** Don't exit early if many warnings but no errors are found. [Stan Mayer] **** Fixed parsing module #(parameter x,y) declarations. [Oleg Rodionov] **** Fixed parsing system functions with empty parens. [Oleg Rodionov] * Verilator 3.653 2007/8/1 **** Support SystemVerilog ==? and !=? operators. **** Fixed SC_LIBS missing from generated makefiles. [Ding Xiaoliang] * Verilator 3.652 2007/6/21 **** Report as many warning types as possible before exiting. **** Support V2K portlists with "input a,b,...". [Mark Nodine] **** Support V2K function/task argument lists. **** Optimize constant $display arguments. **** Fixed Preprocessor dropping some `line directives. [Mark Nodine] * Verilator 3.651 2007/5/22 *** Added verilator_profcfunc utility. [Gene Weber] *** Treat modules within `celldefine and `endcelldefine as if in library. *** Support functions which return integers. [Mark Nodine] **** Warn if flex is not installed. [Ralf Karge] **** Ignore `protect and `endprotect. **** Allow empty case/endcase blocks. * Verilator 3.650 2007/4/20 ** Add --compiler msvc option. This is now required when Verilated code is to be run through MSVC++. This also enables fixing MSVC++ error C1061, blocks nested too deeply. [Ralf Karge] ** Add --lint-only option, to lint without creating other output. *** Add /*verilator lint_save*/ and /*verilator lint_restore*/ to allow friendly control over re-enabling lint messages. [Gerald Williams] *** Support SystemVerilog .name and .* interconnect. *** Support while and do-while loops. *** Use $(LINK) instead of $(CXX) for Makefile link rules. [Gerald Williams] *** Add USER_CPPFLAGS and USER_LDFLAGS to Makefiles. [Gerald Williams] **** Fixed compile errors under Windows MINGW compiler. [Gerald Williams] **** Fixed dotted bit reference to local memory. [Eugene Weber] **** Fixed 3.640 `verilog forcing IEEE 1364-1995 only. [David Hewson] * Verilator 3.640 2007/3/12 *** Support Verilog 2005 `begin_keywords and `end_keywords. *** Updated list of SystemVerilog keywords to correspond to IEEE 1800-2005. *** Add /*verilator public_flat*/. [Eugene Weber] **** Try all +libext's in the exact order given. [Michael Shinkarovsky] **** Fixed elimination of public signals assigned to constants. [Eugene Weber] **** Fixed internal error when public for loop has empty body. [David Addison] **** Fixed "Loops detected" assertion when model exceeds 4GB. [David Hewson] **** Fixed display %m names inside named blocks. * Verilator 3.633 2007/2/7 *** Add --trace-depth option for minimizing VCD file size. [Emerson Suguimoto] *** With VL_DEBUG, show wires causing convergence errors. [Mike Shinkarovsky] **** Fixed isolate_assignments when many signals per always. [Mike Shinkarovsky] **** Fixed isolate_assignments across task/func temporaries. [Mike Shinkarovsky] **** Fixed $display's with array select followed by wide AND. [David Hewson] * Verilator 3.632 2007/1/17 *** Add /*verilator isolate_assignments*/ attribute. [Mike Shinkarovsky] * Verilator 3.631 2007/1/2 ** Support standard NAME[#] for cells created by arraying or generate for. This replaces the non-standard name__# syntax used in earlier versions. **** Fixed again dotted references into generate cells. [David Hewson] Verilator no longer accepts duplicated variables inside unique generate blocks as this is illegal according to the specification. **** Fixed $readmem* with filenames < 8 characters. [Emerson Suguimoto] * Verilator 3.630 2006/12/19 ** Support $readmemb and $readmemh. [Eugene Weber, Arthur Kahlich] *** Fixed configure and compiling under Solaris. [Bob Farrell] *** When dotted signal lookup fails, help the user by showing known scopes. *** Reduce depth of priority encoded case statements. [Eugene Weber] **** Fixed dotted references inside generated cells. [David Hewson] **** Fixed missed split optimization points underneath other re-split blocks. * Verilator 3.623 2006/12/05 *** Add --output-split-cfuncs for accelerating GCC compile. [Eugene Weber] **** Fixed $signed mis-extending when input has a WIDTH violation. [Eugene Weber] **** Add M32 make variable to support -m32 compiles. [Eugene Weber] * Verilator 3.622 2006/10/17 Stable **** Fixed --skip-identical without --debug, broken in 3.621. [Andy Meier] * Verilator 3.621 2006/10/11 Beta ** Add /*verilator no_inline_task*/ to prevent over-expansion. [Eugene Weber] *** Public functions now allow > 64 bit arguments. **** Remove .vpp intermediate files when not under --debug. **** Fixed link error when using --exe with --trace. [Eugene Weber] **** Fixed mis-optimization of wide concats with constants. **** Fixed core dump on printing error when not under --debug. [Allan Cochrane] * Verilator 3.620 2006/10/04 Stable *** Support simple inout task ports. [Eugene Weber] *** Allow overriding Perl, Flex and Bison versions. [by Robert Farrell] *** Optimize variables set to constants within basic blocks for ~3%. **** Default make no longer makes the docs; if you edit the documentation. sources, run "make info" to get them. **** Optimize additional boolean identities (a|a = a, etc.) **** Fixed coredump when dotted cross-ref inside task call. [Eugene Weber] **** Fixed dotted variables in always sensitivity lists. [Allan Cochrane] * Verilator 3.610 2006/09/20 Stable *** Verilator now works under DJGPP (Pentium GCC). [John Stroebel] **** Add default define for VL_PRINTF. [John Stroebel] **** Removed coverage request variable; see Coverage limitations in docs. **** Fixed DOS carriage returns in multiline defines. [Ralf Karge] **** Fixed printf format warnings on 64-bit linux. * Verilator 3.602 2006/09/11 Stable **** Fixed function references under top inlined module. [David Hewson] * Verilator 3.601 2006/09/06 Beta *** Added --inhibit-sim flag for environments using old __Vm_inhibitSim. *** Added `systemc_dtor for destructor extensions. [Allan Cochrane] *** Added -MP to make phony dependencies, ala GCC's. *** Changed how internal functions are invoked to reduce aliasing. Useful when using GCC's -O2 or -fstrict-aliasing, to gain another ~4%. **** Fixed memory leak when destroying modules. [John Stroebel] **** Fixed coredump when unused modules have unused cells. [David Hewson] **** Fixed 3.600 internal error with arrayed instances. [David Hewson] **** Fixed 3.600 internal error with non-unrolled function loops. [David Hewson] **** Fixed $display %m name not matching Verilog name inside SystemC modules. **** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate. * Verilator 3.600 2006/08/28 Beta ** Support dotted cross-hierarchy variable and task references. **** Lint for x's in generate case statements. **** Fixed line numbers being off by one when first file starts with newline. **** Fixed naming of generate for blocks to prevent non-inline name conflict. **** Fixed redundant statements remaining after table optimization. * Verilator 3.542 2006/08/11 Stable **** Fixed extraneous UNSIGNED warning when comparing genvars. [David Hewson] **** Fixed extra white space in $display %c. [by David Addison] **** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout. **** Add VL_CONST_W_24X macro. [Bernard Deadman] * Verilator 3.541 2006/07/05 Beta *** Fixed "// verilator lint_on" not re-enabling warnings. [David Hewson] *** Fixed 3.540's multiple memory assignments to same block. [David Hewson] **** Add warning on changeDetect to arrayed structures. [David Hewson] **** Fixed non-zero start number for arrayed instantiations. [Jae Hossell] **** Fixed GCC 4.0 header file warnings. * Verilator 3.540 2006/06/27 Beta **** Optimize combo assignments that are used only once, ~5-25% faster. **** Optimize delayed assignments to memories inside loops, ~0-5% faster. **** Fixed mis-width warning on bit selects of memories. [David Hewson] **** Fixed mis-width warning on dead generate-if branches. [Jae Hossell] * Verilator 3.533 2006/06/05 Stable *** Add PDF user manual, verilator.pdf. **** Fixed delayed bit-selected arrayed assignments. [David Hewson] **** Fixed execution path to Perl. [Shanshan Xu] **** Fixed Bison compile errors in verilog.y. [by Ben Jackson] * Verilator 3.531 2006/05/10 Stable *** Support $c routines which return 64 bit values. **** Fixed `include `DEFINE. **** Fixed Verilator core dump when have empty public function. [David.Hewson] * Verilator 3.530 2006/04/24 Stable ** $time is now 64 bits. The macro VL_TIME_I is now VL_TIME_Q, but calls the same sc_time_stamp() function to get the current time. * Verilator 3.523 2006/03/06 Stable **** Fixed error line numbers being off due to multi-line defines. [Mat Zeno] **** Fixed GCC sign extending (uint64_t)(a>>, $signed, $unsigned. [MANY!] ** Support multi-dimensional arrays. [Eugen Fekete] ** Add very limited support for the Property Specification Language (aka PSL or Sugar). The format and keywords are now very limited, but will grow with future releases. The --assert switch enables this feature. ** With --assert, generate assertions for synthesis parallel_case and full_case. **** Fixed generate if's with empty if/else blocks. [Mat Zeno] **** Fixed generate for cell instantiations with same name. [Mat Zeno] * Verilator 3.481 2005/10/12 Stable *** Add /*verilator tracing_on/off*/ for waveform control. **** Fixed split optimization reordering $display statements. * Verilator 3.480 2005/9/27 Beta ** Allow coverage of flattened modules, and multiple points per line. Coverage analysis requires SystemPerl 1.230 or newer. **** Add preprocessor changes to support meta-comments. **** Optimize sequential assignments of different bits of same bus; ~5% faster. **** Optimize away duplicate lookup tables. **** Optimize wide concatenates into individual words. [Ralf Karge] **** Optimize local variables from delayed array assignments. * Verilator 3.470 2005/9/6 Stable *** Optimize staging flops under reset blocks. *** Add '-Werror-...' to upgrade specific warnings to errors. **** Add GCC branch prediction hints on generated if statements. **** Fixed bad simulation when same function called twice in same expression. **** Fixed preprocessor substitution of quoted parameterized defines. * Verilator 3.464 2005/8/24 Stable *** Add `systemc_imp_header, for use when using --output-split. *** Add --stats option to dump design statistics. **** Fixed core dump with clock inversion optimizations. * Verilator 3.463 2005/8/5 Stable *** Fixed case defaults when not last statement in case list. [Wim Michiels] * Verilator 3.462 2005/8/3 Stable *** Fixed reordering of delayed assignments to same memory index. [Wim Michiels] **** Fixed compile error with Flex 2.5.1. [Jens Arm] **** Fixed multiply-instantiated public tasks generating non-compilable code. * Verilator 3.461 2005/7/28 Beta **** Fixed compile error with older versions of bison. [Jeff Dutton] * Verilator 3.460 2005/7/27 Beta ** Add -output-split option to enable faster parallel GCC compiles. To support --output-split, the makefiles now split VM_CLASSES into VM_CLASSES_FAST and VM_CLASSES_SLOW. This may require a change to local makefiles. ** Support -v argument to read library files. *** When issuing unoptimizable warning, show an example path. **** Fixed false warning when a clock is constant. **** Fixed X/Z in decimal numbers. [Wim Michiels] **** Fixed genvar statements in non-named generate blocks. **** Fixed core dump when missing newline in `define. [David van der bokke] **** Internal tree dumps now indicate edit number that changed the node. * Verilator 3.450 2005/7/12 ** $finish will no longer exit, but set Verilated::gotFinish(). This enables support for final statements, and for other cleanup code. If this is undesired, redefine the vl_user_finish routine. Top level loops should use Verilated::gotFinish() as a exit condition for their loop, and then call top->final(). To prevent a infinite loop, a double $finish will still exit; this may be removed in future releases. *** Add support for SystemVerilog keywords $bits, $countones, $isunknown, $onehot, $onehot0, always_comb, always_ff, always_latch, finish. **** Fixed "=== 1'bx" to always be false, instead of random. * Verilator 3.440 2005/6/28 Stable ** Add Verilog 2001 generate for/if/case statements. * Verilator 3.431 2005/6/24 Stable *** Fixed selection bugs introduced in 3.430 beta. * Verilator 3.430 2005/6/22 Beta ** Add Verilog 2001 variable part selects [n+:m] and [n-:m]. [Wim Michiels] * Verilator 3.422 2005/6/10 Stable *** Added Verilog 2001 power (**) operator. [Danny Ding] **** Fixed crash and added error message when assigning to inputs. [Ralf Karge] **** Fixed tracing of modules with public functions. * Verilator 3.421 2005/6/2 Beta **** Fixed error about reserved word on non-public signals. **** Fixed missing initialization compile errors in 3.420 beta. [Ralf Karge] * Verilator 3.420 2005/6/2 Beta *** Fixed case defaults when not last statement in case list. [Ralf Karge] **** Added error message when multiple defaults in case statement. **** Fixed crash when wire self-assigns x=x. ** Performance improvements worth ~20% ** Added -x-assign options; ~5% faster if use -x-assign=0. **** Optimize shifts out of conditionals and if statements. **** Optimize local 'short' wires. **** Fixed gate optimization with top-flattened modules. [Mahesh Kumashikar] * Verilator 3.411 2005/5/30 Stable **** Fixed compile error in GCC 2.96. [Jeff Dutton] * Verilator 3.410 2005/5/25 Beta ** Allow functions and tasks to be declared public. They will become public C++ functions, with appropriate C++ types. This allows users to make public accessor functions/tasks, instead of having to use public variables and `systemc_header hacks. *** Skip producing output files if all inputs are identical This uses timestamps, similar to make. Disable with --no-skip-identical. **** Improved compile performance with large case statements. **** Fixed internal error in V3Table. [Jeff Dutton] **** Fixed compile error in GCC 2.96, and with SystemC 1.2. [Jeff Dutton] * Verilator 3.400 2005/4/29 Beta ** Internal changes to support future clocking features. ** Verilog-Perl and SystemPerl are no longer required for C++ or SystemC output. If you want tracing or coverage analysis, they are still needed. *** Added --sc to create pure SystemC output not requiring SystemPerl. *** Added --pins64 to create 64 bit SystemC outputs instead of sc_bv<64>. *** The --exe flag is now required to produce executables inside the makefile. This was previously the case any time .cpp files were passed on the command line. *** Added -O3 and --inline-mult for performance tuning. [Ralf Karge] One experiment regained 5% performance, at a cost of 300% in compile time. *** Improved performance of large case/always statements with low fanin by converting to internal lookup tables (ROMs). *** Initialize SystemC port names. [S Shuba] **** Added Doxygen comments to Verilated includes. **** Fixed -cc pins 8 bits wide and less to be uint8_t instead of uint16_t. **** Fixed crash when Mdir has same name as .v file. [Gernot Koch] **** Fixed crash with size mismatches on case items. [Gernot Koch] * Verilator 3.340 2005/2/18 Stable *** Report misconnected pins across all modules, instead of just first error. **** Fixed over-active inlining, resulting in compile slowness. **** Improved large netlist compile times. **** Added additional internal assertions. * Verilator 3.332 2005/1/27 *** Added -E preprocess only flag, similar to GCC. *** Added CMPCONSTLR when comparison is constant due to > or < with all ones. **** Fixed loss of first -f file argument, introduced in 3.331. * Verilator 3.331 2005/1/18 ** The Verilog::Perl preprocessor is now C++ code inside of Verilator. This improves performance, makes compilation easier, and enables some future features. *** Support arrays of instantiations (non-primitives only). [Wim Michiels] **** Fixed unlinked error with defparam. [Shawn Wang] * Verilator 3.320 2004/12/10 ** NEWS is now renamed Changes, to support CPAN indexing. *** If Verilator is passed a C file, create a makefile link rule. This saves several user steps when compiling small projects. *** Added new COMBDLY warning in place of fatal error. [Shawn Wang] *** Fixed mis-simulation with wide-arrays under bit selects. [Ralf Karge] **** Added NC Verilog as alternative to VCS for reference tests. **** Support implicit wire declarations on input-only signals. (Dangerous, as leads to wires without drivers, but allowed by spec.) **** Fixed compile warnings on Suse 9.1 * Verilator 3.311 2004/11/29 ** Support implicit wire declarations (as a warning). [Shawn Wang] **** Fixed over-shift difference in Verilog vs C++. [Ralf Karge] * Verilator 3.310 2004/11/15 ** Support defparam. ** Support gate primitives: buf, not, and, nand, or, nor, xor, xnor. *** Ignore all specify blocks. * Verilator 3.302 2004/11/12 *** Support NAND and NOR operators. *** Better warnings when port widths don't match. **** Fixed internal error due to some port width mismatches. [Ralf Karge] **** Fixed WIDTH warnings on modules that are only used parameterized, not in 'default' state. **** Fixed selection of SystemC library on cygwin systems. [Shawn Wang] **** Fixed runtime bit-selection of parameter constants. * Verilator 3.301 2004/11/04 **** Fixed 64 bit [31:0] = {#{}} mis-simulation. [Ralf Karge] **** Fixed shifts greater then word width mis-simulation. [Ralf Karge] **** Work around GCC 2.96 negation bug. * Verilator 3.300 2004/10/21 ** New backend that eliminates most VL_ macros. Improves performance 20%-50%, depending on frequency of use of signals over 64 bits. GCC compile times with -O2 shrink by a factor of 10. **** Fixed "setting unsigned int from signed value" warning. * Verilator 3.271 2004/10/21 **** Fixed "loops detected" error with some negedge clocks. **** Cleaned up some output code spacing issues. * Verilator 3.270 2004/10/15 *** Support Verilog 2001 parameters in module headers. [Ralf Karge] **** Suppress numeric fault when dividing by zero. **** Faster code to support compilers not inlining all Verilated functions. * Verilator 3.260 2004/10/7 ** Support Verilog 2001 named parameter instantiation. [Ralf Karge] **** Return 1's when one bit wide extract indexes outside array bounds. **** Fixed compile warnings on 64-bit operating systems. **** Fixed incorrect dependency in .d file when setting VERILATOR_BIN. * Verilator 3.251 2004/9/9 **** Fixed parenthesis overflow in Microsoft Visual C++ [Renga Sundararajan] * Verilator 3.250 2004/8/30 ** Support Microsoft Visual C++ [Renga Sundararajan] *** SystemPerl 1.161+ is required. * Verilator 3.241 2004/8/17 ** Support ,'s to separate multiple assignments. [Paul Nitza] **** Fixed shift sign extension problem using non-GCC compilers. * Verilator 3.240 2004/8/13 ** Verilator now uses 64 bit math where appropriate. Inputs and outputs of 33-64 bits wide to the C++ Verilated model must now be uint64_t's; SystemC has not changed, they will remain sc_bv's. This increases performance by ~ 9% on x86 machines, varying with how frequently 33-64 bit signals occur. Signals 9-16 bits wide are now stored as 16 bit shorts instead of longs, this aids cache packing. **** Fixed SystemC compile error with feedthrus. [Paul Nitza] **** Fixed concat value error introduced in 3.230. * Verilator 3.230 2004/8/10 *** Added coverage output to test_sp example, SystemPerl 1.160+ is required. **** Fixed time 0 value of signals. [Hans Van Antwerpen] Earlier versions would not evaluate some combinatorial signals until posedge/negedge blocks had been activated. **** Fixed wide constant inputs to public submodules [Hans Van Antwerpen] **** Fixed wide signal width extension bug. Only applies when width mismatch warnings were overridden. * Verilator 3.220 2004/6/22 ** Many waveform tracing changes: *** Tracing is now supported on C++ standalone simulations. [John Brownlee] *** When tracing, SystemPerl 1.150 or newer is required. *** When tracing, Verilator must be called with the --trace switch. **** Added SystemPerl example to documentation. [John Brownlee] **** Various Cygwin compilation fixes. [John Brownlee] * Verilator 3.210 2004/4/1 ** Compiler optimization switches have changed See the BENCHMARKING section of the documentation. *** With Verilog-Perl 2.3 or newer, Verilator supports SystemVerilog preprocessor extensions. *** Added localparam. [Thomas Hawkins] *** Added warnings for SystemVerilog reserved words. * Verilator 3.203 2004/3/10 *** Notes and repairs for Solaris. [Fred Ma] * Verilator 3.202 2004/1/27 ** The beta version is now the primary release. See below for many changes. If you have many problems, you may wish to try release 3.125. *** Verilated::traceEverOn(true) must be called at time 0 if you will ever turn on tracing (waveform dumping) of signals. Future versions will need this switch to disable trace incompatible optimizations. **** Fixed several tracing bugs **** Added optimizations for common replication operations. * Verilator 3.201-beta 2003/12/10 ** BETA VERSION, USE 3.124 for stable release! ** Version 3.2XX includes a all new back-end. This includes automatic inlining, flattening of signals between hierarchy, and complete ordering of statements. This results in 60-300% execution speedups, though less pretty C++ output. Even better results are possible using GCC 3.2.2 (part of Redhat 9.1), as GCC has fixed some optimization problems which Verilator exposes. If you are using `systemc_ctor, beware pointers to submodules are now initialized after the constructor is called for a module, to avoid segfaults, move statements that reference subcells into initial statements. *** C++ Constructor that creates a verilog module may take a char* name. This name will be used to prefix any $display %m arguments, so users may distinguish between multiple Verilated modules in a single executable. * Verilator 3.125 2004/1/27 **** Optimization of bit replications * Verilator 3.124 2003/12/05 *** A optimized executable will be made by default, in addition to a debug executable. Invoking Verilator with --debug will pick the debug version. **** Many minor invisible changes to support the next version. * Verilator 3.123 2003/11/10 **** Wide bus performance enhancements. **** Fixed function call bug when width warning suppressed. [Leon Wildman] **** Fixed __DOT__ compile problem with funcs in last revision. [Leon Wildman] * Verilator 3.122 2003/10/29 *** Modules which are accessed from external code now must be marked with /*verilator public_module*/ unless they already contain public signals. To enforce this, private cell names now have a string prepended. **** Fixed replicated function calls in one statement. [Robert A. Clark] **** Fixed function call bug when width warning suppressed. [Leon Wildman] * Verilator 3.121 2003/09/29 *** Support multiplication over 32 bits. [Chris Boumenot] Also improved speed of addition and subtraction over 32 bits. *** Detect bit selection out of range errors. *** Detect integer width errors. **** Fixed width problems on function arguments. [Robert A. Clark] * Verilator 3.120 2003/09/24 *** $finish now exits the model (via vl_finish function). *** Support inputs/outputs in tasks. *** Support V2K "integer int = {INITIAL_VALUE};" *** Ignore floating point delay values. [Robert A. Clark] **** Ignore `celldefine, `endcelldefine, etc. [Robert A. Clark] **** New optimizations on reduction operators. **** Fixed converting "\ooo" into octal values. **** Fixed $display("%x"); * Verilator 3.112 2003/09/16 **** Fixed functions in continuous assignments. [Robert A. Clark] **** Fixed inlining of modules with 2-level deep outputs. * Verilator 3.111 2003/09/15 **** Fixed declaration of functions before using that module. [Robert A. Clark] **** Fixed module inlining bug with outputs. * Verilator 3.110 2003/09/12 ** Support Verilog 2001 style input/output declarations. [Robert A. Clark] *** Allow local vars in headers of function/tasks. [Leon Wildman] * Verilator 3.109 2003/08/28 ** Added support for local variables in named begin blocks. [Leon Wildman] * Verilator 3.108 2003/08/11 ** Added support for functions. *** Signals 8 bits and shorter are now stored as chars instead of uint32_t's. This improves Dcache packing and improves performance by ~7%. **** $display now usually results in a single VL_PRINT rather then many. **** Many optimizations involving conditionals (?:) * Verilator 3.107 2003/07/15 *** --private and --l2name are now the default, as this enables additional optimizations. Use --noprivate or --nol2name to get the older behavior. *** Now support $display of binary and wide format data. *** Added detection of incomplete case statements, and added related optimizations worth ~4%. **** Work around flex bug in Redhat 8.0. [Eugene Weber] **** Added some additional C++ reserved words. **** Additional constant optimizations, ~5% speed improvement. * Verilator 3.106 2003/06/17 ** $c can now take multiple expressions as arguments. For example $c("foo","bar(",32+1,");") will insert "foobar(33);" This makes it easier to pass the values of signals. ** Several changes to support future versions that may have signal-eliminating optimizations. Users should try to use these switch on designs, they will become the default in later versions. *** Added --private switch and /*verilator public*/ metacomment. This renames all signals so that compile errors will result if any signals referenced by C++ code are missing a /*verilator public*/ metacomment. *** With --l2name, the second level cell C++ cell is now named "v". Previously it was named based on the name of the verilog code. This means to get to signals, scope to "{topcell} ->v ->{mysignal}" instead of "{topcell} ->{verilogmod}. {mysignal}". This allows different modules to be substituted for the cell without requiring source changes. **** Several cleanups for Redhat 8.0. * Verilator 3.105 2003/05/08 **** Fixed more GCC 3.2 errors. [David Black] * Verilator 3.104 2003/04/30 *** Indicate direction of ports with VL_IN and VL_OUT. *** Allow $c32, etc, to specify width of the $c statement for VCS. **** Fixed false "indent underflow" error inside `systemc_ctor sections. **** Fixed missing ordering optimizations when outputs also used internally. *** Numerous performance improvements, worth about 25% **** Assign constant cell pins in initial blocks rather then every cycle. **** Promote subcell's combo logic to sequential evaluation when possible. **** Fixed GCC 3.2 compile errors. [Narayan Bhagavatula] * Verilator 3.103 2003/01/28 **** Fixed missing model evaluation when clock generated several levels of hierarchy across from where it is used as a clock. [Richard Myers] **** Fixed sign-extension bug introduced in 3.102. * Verilator 3.102 2003/01/24 **** Fixed sign-extension of X/Z's ("32'hx") * Verilator 3.101 2003/01/13 **** Fixed 'parameter FOO=#'bXXXX' [Richard Myers] **** Allow spaces inside numbers ("32'h 1234") [Sam Gladstone] * Verilator 3.100 2002/12/23 ** Support for simple tasks w/o vars or I/O. [Richard Myers] **** Ignore DOS carriage returns in Linux files. [Richard Myers] * Verilator 3.012 2002/12/18 **** Fixed parsing bug with casex statements containing case items with bit extracts of parameters. [Richard Myers] **** Fixed bug which could cause writes of non-power-of-2 sized arrays to corrupt memory beyond the size of the array. [Dan Lussier] **** Fixed bug which did not detect UNOPT problems caused by submodules. See the description in the verilator man page. [John Deroo] **** Fixed compile with threaded Perl. [Ami Keren] * Verilator 3.010 2002/11/3 *** Support SystemC 2.0.1. SystemPerl version 1.130 or newer is required. **** Fixed bug with inlined modules under other inlined modules. [Scott Bleiweiss] * Verilator 3.005 2002/10/21 **** Fixed X's in case (not casex/z) to constant propagate correctly. **** Fixed missing include. [Kurachi] * Verilator 3.004 2002/10/10 *** Added /* verilator module_inline */ and associated optimizations. *** Allow /* verilator coverage_block_off */ in place of `coverage_block_off. This prevents problems with Emacs AUTORESET. [Ray Strouble] **** Fixed `coverage_block_off also disabling subsequent blocks. **** Fixed unrolling of loops with multiple simple statements. **** Fixed compile warnings on newer GCC. [Kurachi] **** Additional concatenation optimizations. * Verilator 3.003 2002/09/13 *** Now compiles on Windows 2000 with Cygwin. **** Fixed bug with pin assignments to wide memories. **** Optimize wire assignments to constants. * Verilator 3.002 2002/08/19 ** First public release of version 3. * Verilator 3.000 2002/08/03 ** All new code base. Many changes too numerous to mention. *** Approximately 4 times faster then Verilator 2. *** Supports initial statements *** Supports correct blocking/nonblocking assignments *** Supports `defines across multiple modules *** Optimizes call ordering, constant propagation, and dead code elimination. * Verilator 2.1.8 2002/04/03 ** All applications must now link against include/verilated.cpp *** Paths specified to verilator_make should be absolute, or be formed to allow for execution in the object directory (prepend ../ to each path.) This allows relative filenames for makes which hash and cache dependencies. **** Added warning when parameter constants are too large. [John Deroo] **** Added warning when x/?'s used in non-casez statements. **** Added warning when blocking assignments used in posedge blocks. [Dan Lussier] **** Split evaluation function into clocked and non-clocked, 20% perf gain. * Verilator 2.1.5 2001/12/1 ** Added coverage analysis. In conjunction with SystemC provide line coverage reports, without SystemC, provide a hook to user written accumulation function. See --coverage option of verilator_make. *** Relaxed multiply range checking *** Support for constants up to 128 bits *** Randomize values used when assigning to X's. **** Added -guard option of internal testing. **** Changed indentation in emitted code to be automatically generated. **** Fixed corruption of assignments of signal over 32 bits with non-0 lsb. * Verilator 2.1.4 2001/11/16 ** Added $c("c_commands();"); for embedding arbitrary C code in Verilog. * Verilator 2.1.3 2001/11/03 ** Support for parameters. * Verilator 2.1.2 2001/10/25 ** Verilog Errors now reference the .v file rather then the .vpp file. *** Support strings in assignments: reg [31:0] foo = "STRG"; *** Support %m in format strings. Ripped out old $info support, use Verilog-Perl's vpm program instead. *** Convert $stop to call of v_stop() which user can define. **** Fixed bug where a==b==c would have wrong precedence rule. **** Fixed bug where XNOR on odd-bit-widths (~^ or ^~) had bad value. * Verilator 2.1.1 2001/5/17 ** New test_sp directory for System-Perl (SystemC) top level instantiation of the Verilated code, lower modules are still C++ code. (Experimental). ** New test_spp directory for Pure System-Perl (SystemC) where every module is true SystemC code. (Experimental) *** Input ports are now loaded by pointer reference into the sub-cell. This is faster on I-386 machines, as the stack must be used when there are a large number of parameters. Also, this simplifies debugging as the value of input ports exists for tracing. **** Many code cleanups towards standard C++ style conventions. * Verilator 2.1.0 2001/5/8 **** Many code cleanups towards standard C++ style conventions. * {Version history lost} * Verilator 1.8 1996/7/8 ** [Versions 0 to 1.8 were by Paul Wasson] **** Fixed single bit in concat from instance output incorrect offset bug. * Verilator 1.7 1996/5/20 **** Mask unused bits of DONTCAREs. * Verilator 1.6 1996/5/13 *** Added fasttrace script * Verilator 1.5 1996/1/9 *** Pass structure pointer into translated code, so multiple instances can use same functions. **** Fixed static value concat on casex items. * Verilator 1.1 1995/3/30 *** Bug fixes, added verimake_partial script, performance improvements. * Verilator 1.0c 1994/9/30 *** Initial release of Verilator * Verilator 0.0 1994/7/8 **** First code written. ---------------------------------------------------------------------- This uses outline mode in Emacs. See C-h m [M-x describe-mode]. Copyright 2001-2017 by Wilson Snyder. This program is free software; you can redistribute it and/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.916/README.pdf0000664000177100017500000026033513206353160015160 0ustar wsnyderwsnyder%PDF-1.5 %ÐÔÅØ 37 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ-±ŠÃ0 @÷|…Æx°É–lwëqéppK1]J‡BÛ»B %„Ëï_Œ»ˆ'ÞûÈMw  È$ò(EN Þ£ö ùçödBlïós¼.Ól¬#×:L¤Ãþó{¨|xŽwsÉ_›6&.ÚÍ&ª`}Ñûjý5Úeyíºn]Wü+ëy»ÁTçˆÓüS„à%°Îa UÀ=KdYÞI„IYK‘=FŠ`¥W¤ õƒÊa3äæX; endstream endobj 54 0 obj << /Length 391 /Filter /FlateDecode >> stream xÚuR[OÂ0~߯ècû@íéÙzy£˜¸v&„ø`Ш$þ};:¼ûÔ“ô»öt²‹)Är«¤"န<'Z*n,’pO6ôš¤Û—Ýþ–=²Ч8¼°bN‘[Pýˆ´uådáÒ<Ýí·ì&Ì.¦(¾¨#®$‘”«e\|Ì\Èž³þJøˆ„&w‡ls#È}¼šÁÑòv*ÍeœöÄgWÙ¸ï# œc®äg!e ÏQ¶O c•m<=¾¦ Ò~ *H¬ÁÍ@6²² Myª 4•=é 'nRûÐÖã.Ôˆ¤ò<xç«¶^á…Åð„ÎÚw«Õ²eVÑà&1N\Ž_ûà>’Áõ·W‘ØuãCÏ-çóò¤qÎhDŒóÛT%ZçK†’^ºd8YVÝ"nî¤ô)VYsþa¯ÏOÓº*¤øë!|h{é® ]奅ˆiG1Ib^/êïÆ}q-ëç‡6À¢P\+8/tøq endstream endobj 62 0 obj << /Length 1829 /Filter /FlateDecode >> stream xÚÛvÚFðÝ_Á[ű‘uC—ö ìÛá8>idi Û‰J«úõÙpH›Ó4³;;·Ûrµ8»¼¶‡½ÈŒ|Çï-^z¶ã˜^/p|3ŒÜÞ"ë}2>ôCו̓¾m¨þÀ6JªþÀu=Ã5#ÛGÐ5æ“Ñ›Û Á×2ýÏ‹w—×®ÕáéaÏ"Î0³,ˈf³ûy?ôŒ²Ÿ¼!&ñS¼˜ÜÆÈçl²8ûë̆ƒVÏÞ+éš¶ôÒõÙ§ÏV/ƒ­w=Ët£°·Õ„ëžë¦PÞ‹Ï~?»Bk°g{¦ëùÎÁ\? MÏ H)T­Œ»£M8rÕÝÌ ðˆz±’5iÛ~µ‡V‚h”ö*Ùc›$í;¡ñ¥?ôd)^ûÎ3þ°\/&É>V„{Ü «ê°ªo¦ñb>½zXLïïþ[åŠWjóëååv»5¿" *núJúÍͲZ^¶[¤=0FV^y×xÇq:F É(\l7Çå7w•\‚ì=„ËŽe¹DzBŸ5 Á2¯Ë‚à¸À3»LTfàYøghÍ«[1³çfÉÒTÉgw\àZ‘iÛAx«ŽùG¦ÚtÔÌ?áJˆ7Ó œ– ºØÚ1ÏöM;ŒŽüóã̱<Šø¾TBT—/ Eoñ'©Äo°l{àT®!š4)¨D&kUÉçFé《v’"»,YÈšî3“/;–ªˆ¸)À¡´¤V,_‰jÍJ•/íuÛ¶ }²GH å0¦SÜÜ=ðlufŠC¸…¨’œYóœË”Ée*Šš™pžÔo]×ú”¯¥Í($™ß¨Rà„×»šn¢åïŽia8yž§Xpª6q3r\Ú¬E¡ó%Q{Ý^H+¼[µäB%³‡x8•(®›ª\VÉ‘Ðh7™Ñ‚,ˆ€Õ ŒUI1ʨZ%ŠYPd!¸•yNÛÏ]Ú¦/M~A4 ƒ€ÇéâíýÂHFwO§œöØ·mÛÍ磻Å£ D­JdâD DA[û‡ˆ\or‰æèCÐURPús¢ÃÄ™æt;™ãêø-ˆÂ«]MßOOLTÑõt18¥çÝ$ŽÁ!P è$Ñg¦ùÍñw1?¼ñöìa>»'&aÃÖåP\#Œñ¬ƒ¶A ð!ˆy9ÉnÖ|%?QÚݶ´Oâñ|:û¹Êþãze$-u Å+ÐöhŒ@Û5êEùJÔòïä9tscI œïˆ²(íµAwŽŒÍ\–@ª“@ï*—´r=„J ˆ’°ñù9±~åG¾æxW+±“+÷Œ8‹§ªÛ…=V’–R(¾ˆZ®QÝF7¶ :ñgSQ¯µ¦0O¤ô¿Ôv›k»­íc——_t®d´iDÐ&rŠU|T#žÌJ;¾7ã1%oÄ»¢ÜÔ»ú>øA'Pl¦ýßJ$`dŸpkÍ•%•8xP _Ý,ì®Ý9Ù¦jB¥ÂuÏÂîCÊ VLÀ“,cÚ´d¯`%ç("ߨoA.ƒTiC  ‚[' ëDžéÖ€§µi´^€˜éfƒPÈŠáÒŠ¾4gA6†ß[‡P¤9pÃ…„§…¯…„$D7F›ZËS×°ï<µ&I•QTý .Å<Ùa°ðºC¸ðºÉ Ñ(IHR1+JA7H ×3Z ÈD|ŽWa;æÐK*&«¤Ú³¥O.ÛLPÚâ=—öD²áP;™Þ¤éÎxÐËVR”èÅëzEÇ›L´\\U+š5Á‰@Î])'´€šKä;^Û#®‘wìIßñ9 9g½è~QŠ,Ú„>a §ww 8Ô îòî!»×Ù½O$êÜ'¢â›HÅð¶éûB§¨0\†&(h©jh;*}ž?ÓŠ”Rá¿Z¼©GSEáwˆe…œ¤—…Bl©5Ra°Cž®NŽi{aûðçÿDþ§;•´ endstream endobj 67 0 obj << /Length 1938 /Filter /FlateDecode >> stream xÚ¥XÛrã6}÷W¨œ‡¡*E‚7q¶öÁãKEÉ̸bkS•JRJ„$¬)R!HÉNíÇo7º!Q6g“­<©¾œ>hèÃìl|ëGƒÔMcfË/„»“4ÌòÁ/ÎOÃIàÈZÙÐwšáÈw*êá(B'pS?F1pîo.¯?Ý|« 9ümöýø6ð:ÚE»‰˜ <Ò2Ïóœéç‡Ùp:—?^âa³éÝgÜ}v3;ûý̇åÞÀ?˜¸¾— ›³_~ó9|ú~à¹A:ìÍÂÍ ˆW€T Î~<û€>™~èa,ŽNÆ“‰ÉÑßš’ 2~­)¯Âä ÀM7IBÚ}‹VW5ù¾©jIR.›LšZÚˆøE©ç†ij²nšíûñx¿ß»;ˆøv8ˆöH$NU¸ÕFõj¼¸®þ-ï$&’ÓTfz¼WO0£ÆÓR7YQ¨rÕc¿}7ëù\— KÂõ“`0˜Vú4]‚ùB8/xxÕÒ`¯ 8£ ÁÜX‰. œ7£\-_ðd³à'Ì­$ë œ Q]Âê|G¯«¶Èiq«% ÍšUž¯TsNsÙ¬)¼:Óô«Z †±U…lN G!m¾ï¦QD¾5u¶À¯O”¡Ú´ÎʕԺ©Faê&WÃlÍÉo¤nHÞáNYkU•4¡8éªß £È dó‚÷fMü0tc?ùÿ°°“6÷0ìI´zn¯-&‘€c~䦂}mtìË¢Êr²²Yc±÷¸»µaC¿V¼`YW»/ã…Z5ò‚].sbŒ\.ªÍ¶–š‚ A]`z€¼,ŒÜÄP“AeE"ržw,I²n×háãŽBï6«?zB0²:ó‰a-‚¬q@èAé€i´Ú@ŇÝÈÍ ~õ"o§IÖ€%µZ£¶†f®¾ýà…¶Ù¶ ,ö!"N~é7jM ßÂãv;ðÐf÷Âb¢žïNÂN¹â$aÖ* 2gññ±êTM¢"Ƀj;S· œÐ¬ãg££¥ï?”J)s‚š=ú´ð*¬MäĆ„‡Ÿf7Ÿ®1S –ÏWÿu}CTas¨’ƒŒsö“^¹(Úœ¹ª#«ú…í"ÚœË[÷±‚ÂŽ@UƒÐ†nt´òãôÃõôžæŒÔSët÷£5Sß±æÙ" 5·Fe´4õ×@àÃ04à»+rÉ÷0' Bgò¥ivcøçÅ^@\•ì-áº<:wy{®¾c"CU ¼e²ÜE[³‚ÈøLà&a ˜dOµ'©O„…å²Ï½w•+‚-¢½où)ðÙaÍ\éªìÓ”ºaÙU¯XLÆ@ʼ€0…›D>;Ozy_Åawp¸× ‹Ž=UcÛ†.4ð2€ê¡(é"5Ûí½B½³9ŸÕµé$¥-p¬3T»ò•〘UÎskÓLðæÈw¶­YUlQxØ+I!¿…ø½œD“[ïŸÅÜx ²úsÕ åRËÐNÍ[Uäšd£ …E[×Ò‚xG±“-¯–¬ïæ~ʽåÝý£AøÝÝì‚öXäO‘uç×7}¥G•{oi ö©o¹\fmÑðHQ+‘ÿ Èg¹hlaâÄÑiiLöq)oy•-R²é³nQÕˆ 0__ËC' húÕ ÂU[Cê(ö©ëf°sÌ÷¬ÔA|×â qÜšn.×ªÌ šZrGƒˆ¨¦ g–ø‹f‡XNÅWã_4ÍÕmI‹¹5dUñYÔ>%kI;ž°«Ã™ciÀN²Þæ!q‚™)1ƶ— /“Ø‘™V¦ÁYùL¤ ¶lD|Ù`^‰Ü—ÓÖv»ª³Ü„oŠÔ™6ï§éŠÖÊ›J7}™º¹Æ£.¹øè=E]weÍ‚–ëÝ )ˆšä~ìõÍØ©ÌCÑA5‡¸\8áäÞ8éZ‘¶û жRÀ·~9A«º¡¶ŒÊlv‡NA™A‰ýóËvŸq”DÎ7´Jq÷RµÜØéµDÌGM¿óL÷ÞÎp‹Ér÷µãhþ«gâ»ãý?Î]ô뎡„– Höµ˜ðŒÃè$.‚«if¨¦hÃ`UTsfJUGª€QF?ç‹,ǧOÄ¢ôMrÓÒ·Û¨­yXÀ 1…é†5í÷ú’D&ij>ˆc ì.¾ZQ‡æ ˹{Wô@aÛÌØ7Êøñ?ÓÚBê±}Â`±Éßÿ5\µ¥iXºy¾7Ý>å9ðÁÝ¿¨¸sÎ+Há9æ¢0Gq„þL<ÿ–ØêÛŠwš5¡Dqd^Â'ßÍ;ÇZ’†ŸÚÍ\²&Ä—ÄG*ŽÊJqs©µšË?÷Y<mQy-—ê™fÆW—××Ó‡ì£ÓXR¿¼=ÀŒþÃq‘lϹ>¾VQóãx|þå`Ë1ñ—˦ëù7¬N¢þÎ{Ÿ•||F?› FòRY©PO¯Ã¹Ä·Ï û¾¯ƒ®*ˆñ†Ë&2-°ÿJý£É endstream endobj 74 0 obj << /Length 1835 /Filter /FlateDecode >> stream xÚåXYoÜ6~÷¯X *‘V©«}©ë#qÒØ®½ P¤Á]qwëØèð ÿ½3r[N‚¼öe5¼f†œß ÷ÏÉÞø„…£ÔK£ Mæ#žÅAä%)M²ÑGçÃ~ÂÕä…ÜgN·ï2§¡Ùw9÷R¡ÈËャwÇ$Ÿä…Úÿ4y3>áþ–ö `^,F>)†uÌ÷}çýÕÁ~8¯ÌÚ£óÃ÷ïŽÏ&hö&§`ï Ÿ¡Î½ãÉÞç=Zü[;Ì=æÇ£Y¹÷ñ“?Ê`èÍÈ÷xšŒîôÄrÄ£Ø @*FW{ïý‰;çÁöÎSßc‚¢$ñÉÅVÁ†Ã tòªídQ\7uŽè^áŒQ><8º>:½z;¾Õ‡ÔÕÍø öC³ÍëÊ­úrª·oUæb¿œÖ·ê+î¼qóÒ0$k}öTuK&?_žþu€+&ç—×—çç“¡5«F­T•¹+©C³$Ç.hÝkÒôbËûn<Í«WôN+:»8ÖUÊ]]Ñ7z‹Wׇçg'§¯®tâ¸ÖÛ.e£Æ«›Å¬®æù‚ ´T€Š‰ìÆžðM¸¸ Q“¥",Uê¾#©^u mÞR_WÓט7Ž&- @]=…þáKíÛ¼ZЄnm¤nJiV·m§J’a÷Ëö7s ¶¡6于ývà!èxx—3‘:¿,ÎéûP÷ IíR¡ûz°¥ïT¶ËŸÂ˜ËÂ8$SpR84'ùA_ýo˜œ [ôÆľQ?GaâxPtª©d—ß"A(ˆ„Ë¡û[uO™¬ŒPWÿú\h;ºCÒÀˆý÷Ôê–ˆI”6Q‡Æ]n¥Õ¾‹ÚW=\e…Q÷#G¶4VÖm§·È/’]п:{¿ª( ÌÚ~e”6ÝH4þ?ÂAÏsÝ•¾÷jžßSÏ.ë†MÝÇ8~yuz~6 ¡ãTl;‘h®/°`ÁF8H@©R*# ©ud­ Ç47ÎiÇžcUK1›löÚÓ]È…) qá…>3~£îB‹‚JèÅœÙZÊ›¡+/à‘d=˜Õå ³²nlr:ìÁø#Pžc©ôçýÑì]”Gž…’“à‰ghd©à;7æ Yn%¯%r·q3Ž<Æø®›‡;W_G³[¸ %@Zó®«*9-”[h$W tºð:…Â!X/›× Ù(kk ,àQ+S·¸¥ó‡9:³„,€5à7Á#L̲ܥ­±HxI>BlÝf—•Ôgu³†Ž\(Ã/¥ÔQ¢¬4ƒ`œúÜç Âç‘çtº­9_í‘·FîÖ™þƒÑ·¡‰M`cÌ$xˆ‹Õ4¨Y÷L‰èúަšÝ6Œ25§^"ì0ŸusÒ"œî˜ëxpÝÁIÅ"qŽ3<¶œ*PœLgL…( _gÞò¹[¢E\´”ÕBQ[Ã,tP÷êe‘s§‰¢¹l&$( ¦˜Œ¶'ýÑÊrõeX°l¾¨0Ø*kƒ\ŒÛNhÛ¿]$†×NAa â ua+K”"Úv"O„&rMŸ¸B:Nlé$T©¨môýÚ˜õY])Ä( ‹¦^4²li ]Ö}‘YuCÅŸvB@ÖTz;·ySW%É;?†Ø…S›oMµþrJö¾¢¦B ßNçÉV) J†?“íâZ­¡ÚR6<…Ò;îh4«é+˜“í&~ø”émõ”6#¨‘DjW šÂÄѯ:c§é+žœ/x¶Ô¤F#&_òÔ Cñ$š‹0ÞÕA]:Ù<œ Î`Ä4DúkŽÏ,ØNÒØABŸ°…ãkðƒ,‹FĘ́›š©]Ó +3üÒ£a‹j` ÙÍyëlöÙKârYe–îoèTLqٲ߽ó—xÁ©VÄGMkŸ*æuw÷;¬nÍúXÕØ¸³Õwº$¢)@§[½Ý©)æ©{‰©±¥îMÀ"JüïW1–Úâ{%OèùPK™I€É> stream xÚ•U]o›0}ϯàVá`¾™´JmšN™ÖUKh§©«*NAœ'iÿý®1&I—µÝKrë{Îýð¹çñ`x‰=-B‘oûZ¼Ð°m#W l…‘£Å™v§ß¡£V”‰un˜X§`0ÃtWwP„}a:út|vq5–öeQã>þ2¼t¬½èvè!ìš%#‡̲,ýëäj¡«Ÿ ¨xrým&Æñà÷ƒ·¥áž™ƒ°hi5¸»·´ >}Ñ,äD¡¶m+ÍñdƒUj³Á÷Á¹HÑ5ì"Çõí]Ž~"× $“˜ýb2âë©ÙúOHÅôY<5¬ßŒâ›éXætP1KƒŒQ¸2RœY‚¬`$唤‘/ŠZ–Œ+eÁ¥‘,8aÝ)bò„õc÷…y(é‚,hYRÃõmó±+°½_`Kô£e]ÿæE=ÜÈþAaðQÿtj˜žíé#Z­ ]L>ý`Éj¥ŠzC—âÉÄ Wµ¿µoÛ".'Ò=¥YÛuQŒQäy’AQ§å:#CÑn7 {d1%4yžpi59]—™´çDñÿÏtÝ13' R—Lä›UÂó×Hlˆð–´³(]­ ²ØzVŸK:.I)Ÿ]ó¢î‰Rù_õR‘Sïvôš¢ZÔúýLrÃtqtÈCqÈI’Ö¼;Ú@°š¤‚Íøz.­Œ,vÙ,(ëÓábêÞ P-_Ð…1ªh×§*YŠlËAH_†lX*†Áö¢ ?³¤nöf´-#4}c¸ÈSR­`ކy ×ãaKY™=¤/ú:GáÎ}“zûV 2}4OG'' ¯Þˆ™Âàyýrж1ö¡_‡=7mæ¤íÿ Ý^H–¤Ð;‘0ÜËè8êß n ¸(r¦Û4Û ï9LØq´™8òÜìòÚGý'"' `䑵#×@iBgO7&5èe­î†pn¤꼩ÔÐua›…»ƒû2&~úóº¸ÏH'Ý!ÁRû(Cü‰K•þey픜<‘tÍÉ‘†¹G؉ÔÜé³TW¥pfNÊÕN ¡È mu0±Ú ÝR. XÐUÁãÓ ¶Â¦"cÈÇõQ$zjËþÿÉ#Í endstream endobj 82 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0´TÐ5W02S0µPH1ä*ä2 (˜™Be’s¹œ<¹ôÃ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. (\®ž\\&Q# endstream endobj 83 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 84 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 85 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 86 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UеP0¶TÐ5RH1ä*ä26 (˜A$’s¹œ<¹ôÃŒ¹ô≠ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿÏÄÿа—«'W *› endstream endobj 87 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 88 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 89 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 90 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 91 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F †† )†\…\@Ú$l‘IÎåròäÒ pé{€IO_…’¢ÒT.}§g ßE!¨'–ËÓEAžÁ¾¡þÀÿ0XÀ¾AžËÕ“+ ‰;“ endstream endobj 92 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 93 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F Æf )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêüƒõìäðì:¸\=¹¹{-= endstream endobj 94 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V04S01T06QH1ä*ä26 (Z@d’s¹œ<¹ôÌ͹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿÿÿÄÿ °‘§\®ž\\ºâAŠ endstream endobj 95 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 96 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 97 0 obj << /Length 117 /Filter /FlateDecode >> stream xÚ31Ö3µT0P°T02W06U05RH1ä*ä22 ()°Lr.—“'—~8P€KßLzú*”•¦ré;8+ré»(D*Äryº(Ø0È1Ôá†úl¸ž;¬c°ÇŠí Èl ärõä äÇ\+ß endstream endobj 98 0 obj << /Length 168 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.cs ßÄI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.Ovþ;¢ù†: ÁPƒNØÿÿÿÿÿÿF0Ø1ü`€uŒ@¢†ñQÄf ñƒù„Àf2ØJÆìó~ ñ€¿‚ñ;—«'W ÇžsË endstream endobj 99 0 obj << /Length 251 /Filter /FlateDecode >> stream xÚ…±JA†'\!Ls­ÝÎ èÞ±žšÆ…Á+­,ÄJ--íÄ;ðÅy‘µ²4åB–[çO"h£ÍWì¿üßÌì¹Ýf,•4²s n,Í¡ÜÖüÀÎéc%ûÍ:¹¹çIËöRœc{ªÏlÛ3yz|¾c;9?–šíT®j©®¹ fDT„¿P&E—{åh+ç•9G2ËÏD~þ>/BG¯Eðô$E7è~ }§ø¬€ŸK…ÑvmV›:¶¼«$ê,HŠ@•%¡j»}¦W”}þa³ÂzHõ‘ ¦OØ#b£¼A=ðb2ñßãà~|Òò0Ž endstream endobj 100 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚmÉ=‚` à’.žÀ߉1‘ÁD'㤎]…Ä‹‘8p n #¡~ $(}úö­ëL<ŸL²å¸6y6í-<¡Óvf{¶ÝÃÅšÅ\¶(â]Î׊p9% ED‹Ì-Æ4 ð•Óžgö&ëÉ{ô¼øâ!1îå¥qƒú?µ\ÀÜ P˜ùCÁµ#ýA“dZz–4Àu ×,iºÔu8‹q…/ÂaoM endstream endobj 101 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚÏ1NÃ@й°4¹¬—QY AÂTˆ (‘A‹ÃÍrÁå 3AzšWÌJÿ_¤ãæ”kN|y¹9á‡H/”–v¬¹Iû—û'Zun8-)\Ø™BwÉo¯ïVWg)¬ù6r}GÝšÅ3J•~ ZýôªýT™Mè¥Øa.åˆÊ)¥œ- ™oö̤Å/½ó`t™œÝÿ˜þRôø27ÈäVÖ¯½ifðöƒíh·¾hãÛ`+-·Rû¡ÔÑÒìNç]Ódvg9 endstream endobj 102 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.c ßÄI$çr9yré‡+[pé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿþÿÿD|?€bØ0ÿ ÿAD}°ò€ÿÁ&> f0ñH0b!þO ¶ƒn%Ørv¸ƒÀî³?sóˆ?À>û æË `Ÿs¹zrríÇG endstream endobj 103 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿÿÿÿÄÿ Øæ Œ„ † ‚ƒ`|$€lthv›bˆ)ØŒ‡6 ¢Žä£ÿQ Ø.WO®@.ÌŒ‡r endstream endobj 104 0 obj << /Length 145 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.c ßÄI$çr9yré‡+[pé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿÿÿâÿHìó"ˆ Á€ƒø$`@±ØCLÁmQDýÿ ÿ!Ä( ,ÆåêÉÈæxô endstream endobj 105 0 obj << /Length 227 /Filter /FlateDecode >> stream xÚÐ=NÃ@à±\¬4๬¥PY AÂT(PR$‚ÖÞŽkÍ ¸7eŠU†ÙI"QÒ|Åìß{;—Ý5袥ùŒº½´¸Á°ÐaC]8®<¿ár@ÿHaþVÇè‡;zß~¼¢_Þ_S‹~EO-5kVE*#TòÉPËŽaa¥'\¦BÙƒ°û‰«oè¹Ò\Qéõ4÷pf<á¢`2éß”²Oà$‡Ì˜gãßëíµúD> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿþÿùÿŸñÿ?cÀÀ€êÄÿÿÿ±4± Nàô%—«'W žˆ‡ä endstream endobj 107 0 obj << /Length 108 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bc SC…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§g ßE!ÚPÁ –ËÓE¡þÿÿÿÿÿÿà >ÿ†Áޱ¹›ËÕ“+ H¨X~ endstream endobj 108 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚEÏ=nÂ@àE.,MÃvN€m M,ñ#ÅE¤P¥ˆR%)S€B‹9QPr„ø.]¬lÞÛÈ¢ØOš·ÒüLÒÑt¦±Žñ&c&ú•ÈFRf1K~|þÈ<—èMÓ™DÏH%Ê_ôw»û–hþºPÔK}O4þ|©…3EÓµ¦s|–Æ@F öÄAÖ¤ÃØÈHaÀž8pnÀ…\]Ï­GЈ-8¶j<ì\  8hP÷Ãýÿø­žHF¬é–=a…‹,oËÚ>“U.k¹9‰s endstream endobj 109 0 obj << /Length 123 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.cs ßÄI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿþÿÿ€L€Å˜ŒÁN|Œ?ˆ êÿÿÿÿã?*ûÀåêÉÈé f’ endstream endobj 110 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õøÿüÿÀ ÿBü`°ÿW$þð‰ü{ª1ˆy Ÿ‘‰ùŒ0¢Ÿñ1Œh†í͇ÄqÑ|¼F¼‡ï™aÄ Ñ𕨠‚l¢è·?`¿!°—«'W ±,ˆ endstream endobj 111 0 obj << /Length 194 /Filter /FlateDecode >> stream xÚUÏ-Â@à%ˆ&c¸Ì 迨¤”„ P‚$ޤu½Ö’[GEÓev›¶ æKÞ1Çî»hÑ8º&nL؃-;CF¹XïÀA_ í>¡ôpŠÇÃi º?!å—&+ŒRå"c¢(ɉ(§N+˜ÆµGÍSroˆ‰›‚W\¯Š‹"­àЬæüÏ ¦+éÕtI…–ðߣmÅ›h5|Ö ¸üˆ‹¢dXB]/†qsøº‰| endstream endobj 112 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚÅ1 Â@ERÓx„Ìt³Ž)R-Än!he!VÆÒBÑÖä¨9‚¥EØq™Š†Wüßü7sžæe”ÓÄ”Ϩ¶xAæƘ‡æxÆÒ£Ù3šUŒÑø5Ý®÷šr³ ‹¦¢½¥ì€¾"h é`,ò‚T¤'ÀuID ˆ§x¸/„ˆ¶Hÿ ¡øÙ÷®î9 ƒ›Zª¯šëpéq‹o¡lª endstream endobj 113 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bSC…C®B.cs ÌI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿ0üÿÿÿˆø"þ3Åþ70`øH؃þ@‚ýŒ`?€#^¬„ùŠ^°Q`Cƃ-YÉ ²œä fƒ€² Ô$êÿ700€ F"Àb\®ž\\æ„wN endstream endobj 114 0 obj << /Length 197 /Filter /FlateDecode >> stream xڕСÂ0à›jrfÐ{Ø::"#a‚‚ ‰€€îÞ e0‰XvtmC‚ùÄßöîOõh˜Ž)¦„Š´¦TÑ^á µ²aLiâOvGÌ ŒÖ¤FscT,èr¾0Ê–S²iNûf‹EN†`æÒY9†»Q‰¶3p‚qNÊNÙ3¼ÿ¶ßO0ïÉn‹ßè¶ ×ÄZ¿’J4½&}þ5tÊò›¦y+™A²ý ½-ؼ+Ô€³Wø2>z endstream endobj 115 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚu1NÄ@ E½Ú"’›a|˜„$ÕHË"‘ * D”H»$*â£å\!GØ2HQÌw€‰æÉãÿmÿ©«ãæT ©å¨”ºæDJÞsÕ ‰gõ­Ü?ñ¦åx#UÃñmŽí¥¼<¿>rÜ\IÉq+·¥wÜn…˜™åº2ûÐÌÌ4w„C0Mý€¤LúNÔéL”túAø ¨9ÁçÒ„Éa=tC¹6”8y€ÇF¢Ì›Ôa¥OÚ2éý/òaÁ<Ãô&ÄØùE>oùš¿åxv endstream endobj 116 0 obj << /Length 124 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿÿÿÿÄÿÿ¡êêð@†H0 zÂþÿ(Qÿÿ—ËÕ“+ +òT¬ endstream endobj 117 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚeÌ;‚@€á!$Ópæº,‚Š1q ­,Œ•ZZh´.FÇ5¸”\5šo’2ã¹s? ›šqòò98^Ñ}G›|ç»9^0ÈväÈV2#kºßgdÑfAYL{NöELi iÛwÐw?>Í,À¨Ì Ìʰ ]’ xB˜i ¿´LHäÊ›1VÞL0óJRþa”…¢Vèu¦èZ À¥À-¾òVi endstream endobj 118 0 obj << /Length 197 /Filter /FlateDecode >> stream xÚϯ ÂPð#†Á)>‚çt»ºËÂœà‚ É &5mÂ.øb_CY°N wíztøo,È¿ðNøìvÓéE‚‚ì69‚æWh .-rZùe¶D/@sL¶@³Ï5šÁ€6ëíMoØ%n}šðÏŸÂ :ƒš–ßæ}v%Ö$@ö—F•´T÷iX°zÒûÓ[õñ¬¿VÎÉ!zyMŽì-¹ß+_ªX=”Ey>JÍ3CN™.°àï{ŒK endstream endobj 119 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚmÌ= Â@à Óx„¸ ‰‚Õ‚?` A+ ±RK E[“›™£ä)S,;Îh%Xìûfæùh<¥” }å:exÅ\³T¿:8^pV¢ÝQ>E»’m¹¦ûíqF;ÛÌ)C» }FéËEÜ$ s­´àXBט^H”ȃ©ÁÃ@ž?|be¨®ŸàzY©E—ƒâÿðTZ_Õq×-`öRÅ!a~…ˆƒ„®K<.KÜâj/\ endstream endobj 120 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚŽ= Â@…g°¦ñ™˜„Ä"•#¸… •…X©¥…¢­ÉÑr”aË€!ãN;±˜æï½GÓY‡®âg!ŸBºR¤³@[]/”òw%ä¯Ü”|³æûíq&?Ý,ØõïÝåLƹ©¿+ðx•ƒ“À—´€"Ò¡@±y‰Rx Œ-¶0ª±éþ~Ð*ž?¢uîmÖ½rç!0±ƒe¥æ] ÔEÓ`ç%ÐÒЖÞ*Åsz endstream endobj 121 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚŽ1 Â@E¿¤¦Ik—9›°° Än!he!Vji¡h›äh%G°L2ΦÐÖ…}ðgÙ?of§óÇœêÅlS>'t#k5Ñ?œ®”;2{¶–ÌZ§d܆÷ç…L¾]rB¦àCÂñ‘\Á¤"iJzŒDˆÆ=á[5/”ÈjLAOåQ~Ñý‰ß¡@«B_ÕZ¯h4èÊJ—â5¡Î«µ^RMuZ9ÚѲuEJ endstream endobj 122 0 obj << /Length 193 /Filter /FlateDecode >> stream xڕα‚@ à’.<} L— &Þ`¢“ƒqRG®â›á£øŒ—;[pqÓᾤ½´ý 5)+ÊHñ+•9ís<¡’^&¥|ìŽXLפ*LçÜÅÔ,èr¾0­—S⺡MNÙMC±€Ä  ÿ$z1Ú1Þwxï!"Ëûâ>ô<æôZ™iá&³N°?â>cíH ãRa¸ÊÉHŽ'c Ë:ÇÑ´m™¸O,Î ®ð —ºYK endstream endobj 123 0 obj << /Length 201 /Filter /FlateDecode >> stream xÚmޱŠÂPEï’âÁ4ù„ÌìKˆ¬® ›BÐÊB¬Ôr‹mM>í}ÊûËâì}VÌ™;ܹ“ú³™i©“Ô¥ÖS=Tò'uÃù9&aÿ+óNüFëFü·â»¥žO—£øùêK+ñ ÝVZî¤[(²€ÂÐÛ f#2³;܃J>ÂPD´Cˆv@Z }•ˆ„‹÷c½C  ¤7¸¾Ð'Ð* 4u‘ö.æ7ú¹mp Ìb2ræcÀòÝÉZþI÷_þ endstream endobj 124 0 obj << /Length 154 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0asSC…C®B.cßÄ1’s¹œ<¹ôÃŒ¹ô=€¢\úž¾ %E¥©\úNÎ @¾‹B´¡‚A,—§‹ÿû@âÿÆÿÿ˜AûŸz ñHð?°*;&põÿÿÿš4A€Åðk£aÿÿÿ[~ `1.WO®@.òÅ^£ endstream endobj 125 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿ#E`š}!óšÄä”k.pž` A+ ±RK E»#›ÎÇðUò(y„”[,g‚²ìǰóÿÿÌÖÕÉzßòq¹áºâꜟJz¥º`;볟Öã íZÊï¸.(¿ÒwÊÛk~ûx¦|wsÁ%å{¾/¹x vÏ’€4¸ˆlnfxYé•DdöItÁ§S¶n\Å#7@efd=º`’El6X4jB*²`„éá¾fÀ}E_éh0‡íb•ôj“1SLÍ€,xÝ>v*‹Å!*:MÃö–Æ¢ó½:²?-y‰%Û§F‚Í@—-ÝÒ7ãè‚> endstream endobj 126 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcSC…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @¾‹B4Pe,—§‹Bý øÿ¬“Œ‘ò@dý ùóÿ? ùûÿ ùB~°o’äAdƒü ÉÀ$ÿÉ?Häz“õÿøÿÿÇÿÿIˆ8—«'W ƒzú endstream endobj 127 0 obj << /Length 132 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcKS#…C®B.cC ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ì ò ØþÃÄ@òx@ýÿ@ü€á?×C1;}pýÿÿþÿÿÿ†A|.WO®@.üØO) endstream endobj 128 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚÌ;‚@à%$Ópçò.¨H)L´²0Vji¡ÑV¸‰Wá(xŒ…[Æ_­Å~Éü³ó‡Á0ŠÑEŸ_ècäáÆƒ=’¹2Êb½ƒ4gA ΄Spò)§-8él„ôŒs˜ÃQ¹yÀ endstream endobj 129 0 obj << /Length 115 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b e¨bÈUÈel䃹 ‰ä\.'O.ýpc.} (—¾§¯BIQi*—¾S€³ï¢m¨`Ëåé¢PÿÿÃÿÿ‰zÁÀ<Œˆúÿÿÿ7ñÿ,ÆåêÉÈî{\W endstream endobj 130 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚ½Š= Â@…·[˜&GÈ\@7!Q°1#¸… •…X©¥…¢õ^,7ðæ[n±ì8šÎȃ÷WÃÑ3ä‚r„Å9œAl&’ø]ö'¨-˜\À,¤c—x½ÜŽ`êÕ s0 nå¹Û =œî=Cê¿bq䙣Ò1 S¥e¬”ö‰K•vI'ì’ö‡mrÿ/)Tžòì8R`ßû¾‡¹…5¼ízfÊ endstream endobj 131 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úòþÿ¨ÿ$þÿ$ÿÿÏÀPÿD2þÿ`ß$ȃÈù@’Hþ“Èô&ëÿ?:ñÿÿÿÿ7 “q.WO®@.‹£ll endstream endobj 132 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ}Ž=‚@…‡XLÃvNàBL¬H·0ÑÊÂX©¥…F[Ù£íQ8¥…a†‚Îb^2ï}¹™KJ)*%³ K†w4÷Ò‹ó +‹ú@¦@½á)j»¥çãuE]íV”¡®é˜QzB[Ä_P¥ ¢:˜…ðá9o’.êAµ@9(¡dq%Ÿ»7@â'a¸ý/=ßµÓGÃ.^¬ÄTyhÆ ‰”pÁ A!\\[Üã>P: endstream endobj 133 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚ¥= Â@…g°¦ñ™ èfI"¦üSZYˆ•ZZ(ښͣä[.(w“€–‚S|Åæ½7q4HRYs_8Ö ù éL‘WCNâvµ?Ñ$#µá(%µp:©lÉ×ËíHj²š²&5ã­æpGÙŒs” V,ÈS*7;(& A‰]ƒt,¾à -À•ÇýGTÎÀµ@Û8×=ÓF–>¼®á ¡¯†¾$Úñ¼Ë_È¥÷ªùF­Ñ<£5½Þ¯ì endstream endobj 134 0 obj << /Length 158 /Filter /FlateDecode >> stream xÚ­É1 Â@ПJø—ðŸÀÝu£Äj!Fp A+ ±RKAEëõh9J¼AÊÁqc!Ú[̃™Ií`4-ØԈËÞð™m»îjw쎜{Vk±«y\Yù…\/·«|9ê½e_Hx’+5ÐCôÑ8´äÂ#‚$ÒRC®¡¹šˆ\õ¡ì¸ÿBÿ"¨¿xo<ó¼âõõIw endstream endobj 135 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚMË1 Â@ЋÀ4!s7q5Æ@T0… •…X©¥EÁÊÍÑrr‹ñ,,Þ2³óÿÔŽg©D’€MÅ&rŽùÆv‚=ê×þpºr^°Ù‹°Yã—M±‘Çýya“o³YÊ!–èÈÅRÈùr¨êGB®ù7 }Kïÿ´D#"×eZS¨¡W¡ÿ!§ˆ("P÷B Ca÷£}­¢9ª6A«ª=> stream xÚ31Ö3µT0P0bc 3…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€Àž¢þÿÿÿ @ü¿A€ÅH2…‚ù`€hàÀ ß €AþAý~ [@óÿ Œÿ€LxÀÀåêÉÈþ:B„ endstream endobj 137 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úÌÿþÿ`ÿ…¬ÿÁ $0ð()DÚÉ? õþÜÆðêdƒ=˜”ÿH2ÿcÿÏÀåêÉÈÄ£d> endstream endobj 138 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ5Í= Â0ÀñW:oéúN`ú¥ÐÅB­`A'qRGE7©…^Ì­×è êØ¡4¾Ø”É? ‰Âé,&žQ@áœÎ>Þ0ÔÍÓ[}pºb*Qì)ŒQ¬¹¢zÜŸévI>ŠŒ>yG”½•¥:ÅôJ•^ý›]ƒS |Á-,ZHZX:È^<rœ[CÂ×Á准’qÊz¤b&Õg¤aì¦QŒ¥À½†¿À•Äþ$›Lã endstream endobj 139 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úÿ `Ôðÿ?ÃÙaCÄÙ00~ @2?ÀDv`²N2~¨+þߎ ¿#Èß``’ ?Ÿ‡“¿¿G#«¾g``¨?øA6 Hû†@Rž¡†ËÕ“+ Ém¢ endstream endobj 140 0 obj << /Length 202 /Filter /FlateDecode >> stream xÚEŒ; ÂPEoH!Lãœø£‚UÀ˜BÐÊB¬ÔÒBÑN!…Û²³t î@Ë!ãL@,ÞaæÌ»·µ{¸£¯Ûá¨ÏÛ™ lµÃfOÄܒ£¹©ZrÉŒOÇóŽÜp>âܘW!kJÆ‹/ŸLnRüQ;”H¡(Ô+€Øû­Üp{Íçh¼¯€/ O ¨.†êçê«oŸk> ¹¶´¬4¶ú…¥4Wè¬&F&ž”™äRŠ¢ª§ÚÑ$¡}¨xY& endstream endobj 141 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚEαjÃ@ àßdˆ‚ÁzöìØ)ÍCšB=Ò©CÉ”dÌÐÒnÆvÈÐ×jé‹:tÍ&É=Žûîî$%ñÍpÄ!ø:ºãdÀñ-¯"z¥X£!—Znh’‘yæxDæQâd²¿¿}¬ÉLæ÷‘™òKÄႲ)—Ö³µ[{²v§È­õöð+ïðOPy5À‘ Æ@®²äÌ©¤äUíð·-Gÿ[ùÙ;z¿Êßàµ[*ö‚l”ãŽBÉ;¥v\ɼHer”;åSú¾H‹R §Z88 ¾~íKôÑßÍa{ endstream endobj 142 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ}Ž1 ÂP †S2Y<‚9¯Å*B¡Vð ‚N⤎Š®­Gó(ï¤Ï¤c‡|?!?É'ãéœSžèä3>gt#Í”»Õ§+•žÜ^wrëŽ~ÃûóB®Ü.9#Wñ!ãôH¾â"Æ…ôPŒ‚¢x+š—"B I À/ >Š¡€i`˜¦$fà_£…$hŠ¡¨†¢Šj(ª¡D{£{-ÐÊÓŽ~æêb° endstream endobj 146 0 obj << /Length 85 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3s…C®B.ˆMÎåròäÒW0çÒ÷ž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ €ËÕ“+ hz¯ endstream endobj 147 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ô35R0P0UÐ52T06W03RH1ä*ä26Š(XC¥’s¹œ<¹ôÃŒ ¹ô=€â\úž¾ %E¥©\úNÎ @Q…h ¦X.O ¶CÂu@\Å€ø3‚ðfáÌ ˜„ X„ Øžrãih4…ƃqs¹zrræŠH endstream endobj 148 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3cs…C®B.ˆOÎåròäÒW0çÒ÷ ré{ú*”•¦ré;8+ré»(D*Äryº(üƒì*ËåêÉÈžã: endstream endobj 149 0 obj << /Length 88 /Filter /FlateDecode >> stream xÚ32Ö30W0PaC3S …C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ“ ¸\=¹¹¢9K% endstream endobj 150 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚuŒ± ÂP ES:²ÔÑAh~@_¯K§B­`A'qRGEçöÓü”úBcZÜD.gÉÍ=.¥“£©%—Kéhñ‚.¦>É·9œ1/ÑlÉÅh–zFS®èv½ŸÐäë9Y4í,Å{, ‚¨_B‘:yDÂvA;ÿ5R`Àãÿd¬V«‹£Îã¬ñ¸ªýé~ðY”ª¹j2ÎúͰ}s Oö:\”¸Á5y\, endstream endobj 151 0 obj << /Length 179 /Filter /FlateDecode >> stream xÚ36Ó³4T0P0VÐ5T06U0¶TH1ä*ä2 (˜@e’s¹œ<¹ôÃŒ ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæ òÿ0ÔÿÀðÿÿÆÿÿÿ0!û†þ ò8€˜Á¾‚븈ÿ‘õÀ̱?ÀÀ4— h‡û†:ö?Ìÿ˜ÿÿÿtà[>€ÝÄþ‡ËÕ“+ ßrDª endstream endobj 152 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚmŽ1‚@E?RL!G`. +¬šØH‚šHa¢•…±RK v8Gá”d×!R:Ékþäý=/BžpÄ£õŒõ‚¯!=HGNxÚo.wJRRGÖ©­Ä¤Ò¿žï©d¿âÔšORt¦tÍð 0@n ÇÚÒµ¶òZ¿ök·ñ+§ J´AO\ ‹e.d?:+°¦Ðaz²qw"–B…_c(/,]ã¹oÐé¹­¥¹„k@›”ô ÍUH endstream endobj 153 0 obj << /Length 234 /Filter /FlateDecode >> stream xÚ}±J1†ÿåŠÀ4y„Ì h6ç\·pžà‚Vr•ZZ(Úš> stream xÚ31Ò³T0P0bcs3…C®B.c4ƒH$çr9yré‡+pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ100Ð3þaøÇÿ¿áŸüÿÿêÿ?ø÷ÿÿ‡ÿ?äüÀþãÿæÿ˜ÿüo`üóŸÿÑs¹zrr¦…{ endstream endobj 155 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bCSs…C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þC¨'p¹zrr4ö+³ endstream endobj 156 0 obj << /Length 128 /Filter /FlateDecode >> stream xÚ32Ò34Q0PÐ5UÐ54W04S05WH1ä*ä22PAs˜\r.—“'—~¸‚‘—¾P‚KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÿvD `ÿ0HÿƒùêüÿD õÿäÿ10ÿ`àrõä ä­TTÀ endstream endobj 157 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ½Î;‚@à%$Ópæ.bK‚˜¸…‰VÆJ--4Z³GÛx:)ã?ÁMöÛ×ìÌäÉ|Á ë̱$|NéFY†ótÔ‡Ó•JGvÏYFv[²nÃûóB¶Ü.9%[ñ!åäH®âÑ`ü›ÙÂD=ˆ;P´ n€x3‚8„„=ˆ:· h@í`'Òþ@ˆ|,oå…¿â‘EŒæ3µRxE ÅJ¤u#í TfÚP ­Ú¤™¨'<­íè 'µwÕ endstream endobj 158 0 obj << /Length 89 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bC3…C®B.s ×ĉ'çr9yré‡+˜sé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þQ¸\=¹¹6VLÖ endstream endobj 159 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚÕL;‚@\BAòŽÀ; ! V$ˆ‰[˜hea¬ÐÒB£µ{´= GX;ÌŽ‹–žÀb2¿Ì”Åd>å”Ë)ç3>ft¡"÷þcÇ¢=S­Hî¸ÈI®|JR­ùv½ŸHÖ›g$ÞgœH5,‚—{ábèÂ%0´{ ŒžðªO[YtÑ`b BG:„ˆzè~¸rßï!Z*ÚÒK=Ù endstream endobj 160 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ31Ò³T0P0bcsc …C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.OÆ? ÿøÿ7ü“ÿà_ýÿÿþÿÿðÿ‡üÿØü?ÀüãóŸÿ Œþ3 ð?:`.WO®@.²dG endstream endobj 161 0 obj << /Length 190 /Filter /FlateDecode >> stream xÚ1‚PDÇPlÃØ èç †X‘ &R˜hea¬ÔÒB£­p4ŽÂ()Œëw-hm^1“™Mìd6刧<¶œDÏùdéJqêÄ諨s¼P^’Ùqœ’Y9™L¹æûíq&“olɼ·¨,Þ@ 5I ˆô‰¼œî¿‡ èPÕA‹¬„MV#hü¶rèOÀë\š×ÿ‹áV1$kQè*-×:H§éHTÒ¡4ÐhYÒ–>Yñ]] endstream endobj 162 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ­Î;‚@à!$Óp纋‹D+ÄD ­,Œ•ZZh´†£qŽ@IAvœ5cibóóü£ÉxNšb…1EšÌŒN!^Ñ©jšF}ëxÁ4Gµ#cP­¤Ž*_Óýö8£J7 Qe´I0ϼÀ,$\e®™à&i«@(0<+À vJ!ù…âû¿/Ë×7.ý®OÐ$KU»|²àìÐû­ÛË·øfswo endstream endobj 163 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ð36W0P0b#sc …C®B.#rAɹ\Nž\úá F\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O†Ø?üáÿðÇþßúþøûŸáï†ÿþ?`øŒþ3@Ñ?Š—«'W Ì“C¥ endstream endobj 164 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚMÍ; Â@à ir„Ìt³‰­"1‚)­,DÔÒBQ°r÷h{”!¥…dc¾æŸW¢£„"Š©¯)‰(ÓAããTˆ†]g¼Dµ¦8E5—U¹ ëåvD•/§¤Q´Ñm±,L¿Àg¶³ Eö)ðmž}À?Óɬ¨[¹† ½Ñ@€ÛP&ØÉ„ª/ÿg"vâk tìŒeÙ3²¶wžòÈÎJ\ánONØ endstream endobj 165 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0TÐ5T0²P01WH1ä*ä22 (˜X@d’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒˆÁÿÿÿÇÀÄê¥ÿch`üÇØÀðŸýÐR®ÿÏÀ`””ÀÀåêÉÈ|Q  endstream endobj 166 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚMÌ; Â@à?¤X˜&GØ=k ¢VÁ-­,ÄJ--m“ÜÄ›hŽ’#¤L¢³ ÂÂÌóŒæ£ÉBUÈÍlœCºQ4åºïØÁéJ‰!½WÑ”ôš»¤ÍF=îÏ éd»T!éTxóH&U_ ¨r@–ˆ‹’‘%rô2K7 j¯uð¿qðZ¿fD ´¢º>D”@ÞÃoËâÏ‹‘¸oKLjօV†vôg9Hã endstream endobj 167 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚEαNÃ0à‹> stream xÚUÎ1jÃ@ÐoT¦Ñ4pVkYÄ®¢"W.B*'e »t’ä*{’ #¨T!”Ì®¬Ãò`g˜?“¯îkÎXó\ßsîß»¦#å…T3.–×Öá“6%©=ç©'©“*Ÿù|º|Ú¼<°&µåWÍÙ•[þ’¦Rë1õˆ©R‹ ž¤´BÜ¢f=¢n¤CÔGfWZ`ˆ= ðå‘iT‰L ý©Kñ·ãw"ê'dÏ ­kxš‰Øc]T •ìXù™!à2Kr×KÚÑ?§êVv endstream endobj 172 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚ}бNÃ0€á‹ó[ñòŽ«í#•Ú[wж¾£¯Ïï7´«ûkÊÑ®é)§ìë5€Ú‚,ÝÇH‡Y˜1Fu˜EÃ1˜Û$Ì`„Ú³$ª] ½ciÕÝiÇ’˜¶MÓ6Òj T§Ä%˜0Òú©`t‰è)ßšô »µýÚ£Éî§ûì0„R7¡ ŒÇ’A¢«Ó\—þt‚‡dèC@ëf;„wÛ€75>à/G°ž% endstream endobj 173 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚÑ= Â0àJ‡Â[rß LK©¥S¡V0ƒ “ƒ8©£ƒ¢s{4Ò#tìP“ö¥qj |ä‡÷Ã[Æ‹$Dõ^†Åx àQ¢Î¾>ê‡ó 2ü€Q|£n‹->¯+ðl·ÂxŽÇýˆ¥^oÇémIiTEí¸²êud=X4ƒi;87v¶LNó7މoò™üTÏŒêd²T}Xö÷_õ§—QOË^Wþo5Q;ŽG2Ê7öOõ×Ò<êq.ÖœÔWX ØÃuRÖä endstream endobj 174 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚ½‘=NÄ@ …¥ÉÍ!¾L"±ËnC¤e‘H¢J ´$GóQr„-·­ñŒ7qF}#[ãŸ÷–«Óõ9Õ´ “†–g´XÑsƒo¨¬Sxm™§WÜtî5áZúúxÿ|Á°¹½¤Öª±Û´ (E¸TV";§‘èYäepšÒ{ðJý¥9†~P(eÔRÂé™XföìdH-Ø ÌXq*óKÏíÄ8§ãþ/÷ü§~ÖbyœoƃÑöq?´}Ý`ôƒéáÁô©ÀôºÓïëØ0fW Ø';´¬jœô÷#˜©†úcŠÍªþyÄ< ^ux‡ß³ = endstream endobj 175 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ37Ö32V0Pa3 Ss…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ@˜þ¥ÿÃè õ?ØÿÓp,ÿBóÿ‡ÐÌ@@4#P2Íðÿ„®ÿ€JÛÿ@£ÿ@hytúú?iBöÿAu?œ†ú«þª¿aá¥aá ?öÿ¨á[ÿþ°ø@‰Ÿ?P\®ž\\2oÉ™ endstream endobj 176 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ}б Â0à+Â-}½'0­Út µ‚ÄI‡‚¯ì˜¡Û¤…¦VÇÇår~>ÅS hR(Šéâ#^ô¦-Ç &ÙŽ"ŽlUÜ"“kºßgdÉfA!²”ö!”)isÞÀKT •¡oéY<py~# ³ˆ?@Iæz­S=©Z¿ˆ¿‹Ah1s–Ì!oâ9)ù–¹ÁÓʦ«:#Ç¥Ä-~·Ê endstream endobj 177 0 obj << /Length 262 /Filter /FlateDecode >> stream xڽѱNÃ0à«2Dº%à{p<¸-“¥R$2 ÁÄ€˜€‘súh~”> stream xÚ36Ó32T0P0aSs…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…h 1±\ž. ÿÿÿÿƒŒê0 uŒî'.WO®@.•õy9 endstream endobj 179 0 obj << /Length 138 /Filter /FlateDecode >> stream xÚ35×31V0PaScSs…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þVŠ¡þÃ0¤ØRüPŠ %BÙ£Põê?˜b„PÌŠÿ˜ªÿÝÿ8(.WO®@.‹† endstream endobj 180 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}Ò±jÃ0à·è ì{‚ʦIëBÀ¦P…vÊP:µ;´´ÒÁ~°~?‚Æ &×S !HÁßIËwWÅÙÅœ :—[U4¿¤—ß±šI_„6|<¿á²A·¦j†îV^Ñ5wôùñõŠnyM%º=–T> stream xÚeѽJÄ@ÀñYR¦É#džÀMü¸\·pž` A+ ±RK EA±ˆ¾™¾I|ƒ³Sˆgwv/'W,üfþÅn³¿ÓìQEþ4»tÐÐuw8›Ë\ùÑ/®nqÑ¢=§Ùí±Ü¢mOèáþñíâôj´Kº¨©ºÄvIÌ@ƼÚÀ˜À èøU´Á;€é=zÅ‹¬ž'|+ž|1 #G”R (¤ø¹¤2))€RT¸58BÒ )*¤¨¢BŠ ˜0Dtc„㈒ß(rþTd¾†À¿á±<\B¹…"!OÈL¬ÑmÁ%”‚Á£è!ü)ä Y‚Ùµx†n«Äº endstream endobj 182 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚµ‘1NÃ@EQ Mã#ì\Ì*Š •¥$\D‚*J(SAíÍGñ\º°2üñÈ "JË»Ïþ£ïÿÍã]>‘{™Êm”,—éƒ|DÞr!B~ôÊzó’Ó¥d‘ÓÈœ– ùþúùätöú$Pçòϊ˹‘vdW¢º3Vª-p¥uèÁµ›/ˆ «Æ—=›:Ô`Nzº¸wÏèʼn¬8røöØ,œÍVÃpÚž£¯Ý¥xèçóœðdnÿ¿&8둉ç°;æb9©•ßÞ³µ0ÔrEÓªõUXîЂyjóÖA‡^ªýŸó:œŸŸ'?—üÆ¿°ÛÈI endstream endobj 183 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚ33Õ3²P0P0b3Ss…C®B.S3 ÌI$çr9yré‡+˜šqé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ˜ú¡þA¨ÿ õ?øÿQŒÿ€( Ä Êþ2%ÿ…úO&…b ª Pk!Ž€: ì@ˆ'@Ôõ¬q%vŠËÕ“+ 0¾ª( endstream endobj 184 0 obj << /Length 233 /Filter /FlateDecode >> stream xڥѽ Â0ð‡Â->Bï4bÛ­àØAÐÉAAëækù(>BG‡Ð3͇‚uP=¤òAYý‡Ú¯K]¹k̵ÚpÍ&ŽËœÛÈ…MšÊgd ŸÎoç°Úk|x–¯pÿ +‡Â@Zä/0ƒ´d73(Mº\5|¢³3¿WU =e0ƒ>¬ß endstream endobj 185 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚeϱNÃ@ à?êÉyƒÆ/iJ"•¥‘J‘È€D'ÄŒ X{÷hy”^åc¡¯êŠ™D5‡=îþÙü:þé§“ÎÇ|ñ_.þ(Ø_’ IŸ˜4B±±ÌCjÑz8½–nZ:Ð7¡6 endstream endobj 186 0 obj << /Length 152 /Filter /FlateDecode >> stream xÚ33Ó31V0Pa3cS3…C®B.SK ßÄI$çr9yré‡+˜Zré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿƒANúÃÿÌÿêi†úõ Zþ@ˆæ‡Ó5`šNW€ifœôýà˜fÄI3€i0™4?(pÓ\®ž\\wG³æ endstream endobj 187 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚíÑ1‚P Ð’.^@?'ILtr0Nêè ÑÍGã(ÑP[ˆ‰““£Cû_Û´Ë‚Á0$êûy4Šhïã CmJ9î&»#&š5…!š¹´Ñd ºœ¯4ÉrJ>š”6>y[ÌRbæ\æò €[B§øãgpq ‰¸þD¬…b¢ ¤û7 ›%é¸ÇXzÂ’¯²+pîC‘7 M=$¿©¯¬qÓ˜«ŽÀY†+|œ¼T endstream endobj 188 0 obj << /Length 220 /Filter /FlateDecode >> stream xÚÕÑ=ÊÂ@€á )„i¦ž§u‚;ì{¹ÛU«-2tsê{tyE—ýÑaÜ L‡” Ñ"¡x‰Ùˆ˜ù sñÀOh_ΊV!xéË eA”Ëáü©ŽYæ'ý@V4Сn.— B)€Æ´`š²˜¬QCS;¤QãiùV¾¿ñ°”ĸ¨pnp©r^!z£Íðkˆä'~Ž3œá?jz”ó endstream endobj 189 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31×37U0P0bCS…C®B.cc ßÄI$çr9yré‡+sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€ÀDübvQ$þÿG%úAüȨÿÿÿÁåêÉÈB•\ endstream endobj 190 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚmÏÏJÄ0ð¯,Ì%ÐZ%c‹ã7¢â!¿02I†ñ|ÜøÖÛz¿ü¾“éGÆ­…Vx|–í,ÍïGi®˜•f¾ö‡×ã“4Û› ßI³ó÷odÞy¸A# ÕŒJõ—&E½8]&”ÃRj ©Ð¤ šÙõKXÿ™"9ãØß°öC¯ú"‚ãƒùÊÞáN¤¶¶šàžç‚ +–o¨q‘Ô ™€ï@æF2ŠÌÏh.ÊpFmLF IÿA.g¹•OÕ¬—´ endstream endobj 191 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿbaš> stream xڕϱ Â@ à– Yú6O`[¼Ò¥T¨¼AÐÉAœÔÑAQèP°ÖGé#tt«—ªtò $áB¢ÓyšpÄ :áDó%¦;騿‘¤Ò8ߨ0XÇnl•B³åçãu¥°Ø­ØVK>Ú/'2%;ŽãµÇÀ%|ÃAtG*èA0‡¬`/ºPu°½Fô19€9¬a{ÑíDíªb#úØj3XÃä5S¯øS… imhO_o`{ endstream endobj 193 0 obj << /Length 229 /Filter /FlateDecode >> stream xڅϱNÃ@ `G"yh_éüp’([+•"5:T #Ö^í%pcó»He``ùÛ÷û\·wm# iä¶”º’¦–ç’߸jQD¹ùéœ^yݱßKղߢ̾{”÷Ïöë§{)ÙoäPÊâÈÝFnˆ(ºžŠèF Ñ©j…Àd|ÉŒL@Àä6ììmБÜT /åˆõ¤sg`À|¸®Œ¿8c†Â¨Ò’5 MñÃÙâ—”i\Qn+ ¥yrŠevœEs¬á‡Žwü Ô4„s endstream endobj 194 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÏ=NÄ0à¥Mã#x.N´ŽV[YZ‰HPQ * ¤Aíp³%G0¢ÀE”a²» ÍgûYš¿<]6\±ç“š½çÆóCMÏ´XiXqÓì~îŸhÝ’»áÅŠÜ…ÆäÚK~}y{$·¾:ãšÜ†ok®î¨Ý0`2™€R¤Ó—é†r@ìŠI…ÀærBÈG£b¶dÅþ2lRÌ“V;äxFïò!#äSòÕI§gìµk4I±Yòžñ€;ý!þGøaÜbóžÝ¸óài^aÐeb_È»î+:‚¶‡ÑÚ(4¢ó–®é–•™ endstream endobj 195 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚϱ ‚`ðáÁ{2As‰3È!¨©!šª±¡(hˆôÑzÁñĺïŒt©¡~Ãÿ8îÎûa@ ¨ç‘R0¤‡Gô=9›Îö€qŠîŠ|ÝÇè¦s:Ÿ.{tãÅ„8MhÍ3L®±â“+ÿ"dL-V¢K±x{°pprm î%@%*­!š¥ÞiÉfúÈ£ú1ƒÖºÕh¬´fG«£Ý¨ZŸFéȶ> stream xÚEÐ;N1 `G)Fr“#Œ/³£Ñj«HË"1Tˆ ()@PgŽ–£ä)S„{Aló)Çù“iw¹›iC]Œ4M4Oô2â;n÷²¸¡yþÝy~ÃÂÃm÷8ÜÈ2Ë-}~|½âp¸»¢‡#=Ž´yÂåH`xpœv ú$¸ä"¸,t¹?“”¬¥JIÏRÜsTR/´°vÌ „ –å6£#`f€ÀÁ3G&û-Û]\\ò\´Eõ«åV>R®ô­tŠUÌ?p¦²"ÅFÏ ¶ø¿Ìò¢!ÚS‚S¯`% ^/x?}Ï“… endstream endobj 200 0 obj << /Length 327 /Filter /FlateDecode >> stream xÚ•Ó¿j„0Àq%C ‹`ž *½B]®W¨C¡:”NmÇ-ív¨–GÉ#dt—&æ—?RiDø¨ ~ýi]_\V´¤;½×WôzGß*òIê’šMš ¯dß‘â‰Ö%)îôYRt÷ôûëçû‡Z‘â@Ÿõm^Hw ‰YmVìaܶb«Nß4RbÕXM›Î”\u®N›n•ònbÁý |ä± –mˆœbçÞ©¶‹LEæ´]$â±±7æ!3äi»ÈlŒzçÚ.2Ob'Þzº>¸Ñƒtî!ò¸´—Æ9™7Ê ×˜CîÒ.Ík&) 7L³Èʬ ¦k–üÓùì“ËõÁóÇ Á͹!¾·!×Kk¹KÛøÌ!×#°€Ü¥m<æá“ÆÌþçÎFkó(­°¿4J@?û¯ÉmGÉ/ðc ¥ endstream endobj 201 0 obj << /Length 267 /Filter /FlateDecode >> stream xÚµ“=nƒ@…Ç¢@šfà9Al%"’C$SX²+V*;eŠDI£pJ ÄzÖ°òÚîÌŠÕ·üì›y^çOÏ‘=“Jftˆñ“ˆìॽ±ÿÂEŽzKI„zÉWQç+úýùûD½X¿QŒ:£]LÑæ™óÑ@G¦j…ÌQ¨P¦˜ÚϘº§‰iz‚ÿVÈ8Jy›Ž¦<_’â­oSÈr¡ûºãJ^CoC¿âÁàK(®¥vR“ਾB,á|.ÅÝÚWK¥uÅÉ¡Ë`DuO6®KNý™‡‘¯6‘_i JGãT+É­”´ ç¤KP±„û²¡J¨ðÿ~ ßsÜà uÍyë endstream endobj 202 0 obj << /Length 338 /Filter /FlateDecode >> stream xÚÍ“?N…@ÆgC±É6½€QãÚ¸Éó™Ha¢•…±RK vF8Þä%^€’‚0Îì ‘¼Z ø-;;3|óqvrX”ºÐ§ú ÔÆhs¤ŸJõªL¡ù6Ç~çñEm*•ßiS¨üŠ^«¼ºÖïoÏ*ßÜ\èRå[}O‰TµÕ@W‚€dªR‰ˆ;Ȉ,Q–ˆG¨9ÛCi ì7rXKËä0—Aà@$ˆs;’²º:ñ>GOÔ11PV¨GG’ª à{ ré(µëÜ‘  J}1*7S(»$;SheIÙLõ>âoúCø¨^¥f­i0Ó¤ÚÙIñ™Î§ÉÌô¬ð§ Cœ4ôqú¢ŽHºèG®¹‹nJÛè°¬‰®³œcÔC +{ç7ZÛÎÛ¶>»ƒ Úà¿¢‹*E!¼Õe¥nÕ/ÙÏíã endstream endobj 203 0 obj << /Length 258 /Filter /FlateDecode >> stream xÚÕÓ1nƒ0`£ ‘ÞÂx'¨¡b€ ‰¦R"5S†ªSÛ±C¢d†£õ(9BF†ˆcWæGµR¦Z}lÀþ_ÇYÂ1§æÈSÎù#¡=e¹éÇ}·¿ñþEeEzÇYNzm®’®6|<œ>I—/Oœ^ñ«™æª‹kªo?nÁ‚>ƒíCK¹(Iç¸ÖªoïÐv^سs`'rVr\wƒ Iã‚—ý˼ÏÞ‹‘/ÞÁÈí¤íýênp=g¹ÇÍ?ôÿ;³†¸ÎØ—¹=Å  13èr…Ù‹ “E7™ÛòŒ™ÇZ€1µÓŒk kmªgjÖ.=W´¥€Ms³ endstream endobj 204 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚ•Ò= ð×t y G('«Æv3ñ#±ƒ‰NÆI4:—£õ(ÁÑIÓ¾ú¤H~…þi¿ÕE[ôLK;¶nc<`’˜ïgØìq˜¡\Š$A95½(³™8Ï;”ÃùHÄ(Çbe–Yc6º,wh*àúÀ´.9)"1RH HP+wh ¾yÅ›(¸/*±†øPè#qRDÒ¥LùSõÜ×õ¸c_ÿÿ½Ÿè擽®²éPèÒå[Ì+^« —& ÊIº ¬)J¢¢t*Jl)sŪJ¶SàN2\àîÀU\ endstream endobj 205 0 obj << /Length 349 /Filter /FlateDecode >> stream xÚÕ“±NÄ0 †]u¨”¥P¿´U‘®"‡D$˜02€`ny³ãMNâ¸ñ†ªÆIÜ»´EÀJ÷“ã8vâ?ÏŠã¢Â x”cµÀ²Àû\=©Ò83,OÜÊÝ£ZÖ*½Æ²Ré9»UZ_àËóëƒJ——§˜«t…79f·ª^!ðÒ û5D±Åˆˆ6XÖÌ;Ж©‡Æí¤uH@†cýN.|ÍŽrá.m@µÎ³Û¯F|Ž=›Mb¶š Ö´`]ƒÃœb{)Ð$èÀU2¤ئç¿ô' ÄcW˜¾|–rƬÇ,eŽ9sóýÃôOx^cf¥u=þÌzÆ.‡–{6œü‡·›òðÖS–1´Œ¸;ôAýe&oVýögÛ›ù`¦_#œˆ7ÄŸ¢)ÒNG¼¼ èöÝYmv¢M£Ù­è×Üf !ˆ&\oê¬VWê ?¦! endstream endobj 206 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bS #…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿA ÉÀþÿÃ(9THü±ÉåêÉÈ’:Õ° endstream endobj 207 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ3·Ô30T0P0bs #…C®B.3K ßÄI$çr9yré‡+˜Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü Ä0ø!Ô(c2~f0ÂH`0ãf°c0øáŒP†<Ãƨ‡1þCŒ0;ŒÁcÔCÌÀ¤ø Ãàrõä ä6n6 endstream endobj 208 0 obj << /Length 311 /Filter /FlateDecode >> stream xÚÔ±N„0Àñ’oé#´O ”\<'HÎ3‘ÁD'㤎ÝHàÉ ÆÁÑGð‘áBýú•Iû%)ð+,ÿ¦`ÊÕÑz­ ½ÂaJ£OJ}oà Œ9Æ™ÂÙ=º{„MùµÆyÈÏqòæB¿<¿>@¾¹<Õò­¾1º¸…f«­µ£ #q·8&ÏtáÞ3ûŸxž=%Ýüæ·õT]ˆ_¶'V1ü´± òÃîˆSï>8ƒ|º‹bGýx ²¦~Ù‡©¨_‰(Jê¯fÔß2L©Šcâ–# ןî8º~w‰¢[ÙstýJptýU,Ýr´,]ÿÄû±ž#öc},»=Ö3Ö³Tëc)íÛfôÑrLi‡G’vKA;+DEï ñß1¥]þ*Y÷‡¨ÄB8kà ~oˆ§L endstream endobj 209 0 obj << /Length 316 /Filter /FlateDecode >> stream xÚuÓ1NÃ0ÆqG"yÉâ¤êÐL–J‘È€bFÌé ¸Rc@n@G†*Æï9~ýÈðäßóò,×Õâdµ4•¡i³Z˜ûZ?é†öŠVÂÝ£^·º¼6ÍR—çþV—í…yy~}ÐåúòÔԺܘ›ÚT·ºÝçÜR*ñç<‚ÝV™s[¿(;(rOηì¼wþäpô(þàXð;¸áàŽÃуØr,¸çÎ8=ŠSpÂá`ÅáÉb æðdOæ°x§`Oæp4…ÄLáh }S8:S8šÂà^ìÃb öa±ƒb§`ûØx'îÜ·Ø‚ ~›à|Æ8'`5çlÁ8ŸqNÁ X‘‹½xúƒ> ¶àœÿµ>kõ•þJÔ@ endstream endobj 210 0 obj << /Length 325 /Filter /FlateDecode >> stream xÚÍ“±NÄ0 @ÝPÉK?¡þh H×›*‡D$˜02€`¾û´~J?¡c†ª&±ãrœNldH^âØŽ{U.+,p‰'%®Î°:ÇçÞ ºð‡ú…%O¯°n ¿÷_óÜÜàÇûç äëÛK,!ßàC‰Å#44~d´32DCÄšˆZAOÔ3%ä,F•¢b= _&gŒåË2‡½·dõÀ‚FL¤dtæ½Èêˆ^c;È“ºh†MZE=°p¡8È}ÃÚ‰âèÝ´1ª˜M¸Ótøµž°=Š[’l¥ÔýiÂþÿâìéñq<”3Mu;Ëúo˜ê†Ïš0Ñï÷q¯fUËȱ„±çšà:ëØ „Æåq’ñÌ×Ä·€•ZwÑ»¾$D#ÌB·HÜIè!iÐýh²Dåß W ÜÁxkD— endstream endobj 211 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ³°Ô³0U0P0b c #…C®B.s ßÄI$çr9yré‡+˜[pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÁëÿ8ëœõ¿ÎJóƒûÿ ,fn0‹¤ªÿcÙ5CXòÿ@Y ÂbGb}ÀÂúe1ceý¡ Ÿ½ìH,ln~÷å Ÿ#BBðPŒº`pÎb€±~ÀY 0SFYä± I—«'W TÛ4# endstream endobj 212 0 obj << /Length 290 /Filter /FlateDecode >> stream xÚµÓ±NÄ `H‡&ÿÒGèÿJk×NMÎ3±ƒ‰NÆIMÔèÜ{4¥ÀØá"R ÜßÈ%)ù ~ø¡Ùœo®°ÀK<+±©±¾À×>¡©Lcuåz^ÞaÛxĦqkšAtwøýõób{%ˆ>•X> stream xÚ}ѱJÄ@à?¤l“v_@“pÞ] !pž` A+ ±RK E;!÷hñMÎ7H¹à’qfwO ¦ù`vv23»œ•µ)ÍÒVf±0õÌÜWêIÍ%Xšú8œÜ=ªU«Šk3¯UqÎaU´æåùõA«ËSS©bmn*SÞªvm€| 82"‡7@бï, }8$´þtHIR2>JØÜJ =°MT;4[6ÿ±ùR׳éÄÄ~“û íD©Ï}~k£.:Âíì£6ʃH«¬Ï±¥DÎJ†wðkñ©8ÊÌ1ÁÛ‡=Iszÿ‚‰6üÑWÎBðJIľ7ìl¢:šÇa²hJ½Ý7ùCÞ¦ûßÍ8‘ÂýðˆþÝÆðâÞ5,φýkV›Ôqœ<ò Òöè÷Ã/™„µXY×dã|…ËvRJµêJ}áI± endstream endobj 214 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ³4Ô31W0P0b 3 C…C®B. rAɹ\Nž\úá \ú@Q.}O_…’¢ÒT.}§g ßE!ÚPÁ –ËÓEÁþ?ü!žu€¡þ?3õ‡Äb°ÿSÿÂâÿWÿÂbÿWÂbþWßa1þ«g€°Xu0V6V ŒeG,ëŒeÿÆ’'Åc1Œ²†%‹’œÍârõä äãCì< endstream endobj 215 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚ퓱 Â@ †S:Y|„æô]ª‚ÄIÝÄöÑú(>BGñLÓZD''—|ü¹ÿr7œÑ¦©;¤©M CA‡º>­ î0ðYÔÔmÕÃ՜՘eTÑ„ûãU8A5¤…!½ÄhH–ãàpɾe¨Û ä§P±þóï¸Vrÿ…{ÂÙŸy¹%ŸÞرWáÛ K¶¹Žp,ìŠ+¾ç¹&ûÂuaÏJNE±IÞM ºœ4y0犉%®Þ­àØ^žÃù ŽâAlæH 4È—¬6eOæ†E8Ã`ò| endstream endobj 216 0 obj << /Length 285 /Filter /FlateDecode >> stream xÚíÓ±NÃ0€a£ ‘nÉ#ÔO€›R iõ\/ÂfOõÙB?´ð vÎçñ4ÞØ<Áªs«íÌe¸ ¦»Ò¯/o`V×纳Öwa™{èÖÕR³pø©Ãn¯âpáЈ¯TMS¤]ôar%va;B,½‹~;1­°E_¸Sé)Ž\ ´0…ãíº§rC pPòArRSlœÌA”#Ac²Ÿã8‡ƒ²Éá8Îá ìQr8Žs8(%‡ß–äPPa?&oñcŸìð³ð×<+Ü ö…}r]¸’Ï‘ßPš†|Öÿ¹›ø¿õ¿0\tpß4­ endstream endobj 217 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚ…¿J1‡gÙ"0M!óº·`D«Ày‚[ZYˆ•ZZ(Úºy´}”<•aÇ™¹ãôP1|ðå—?üâéáIO :¢ƒžâ1ÅH=>cT¹Pc;÷O¸°»¡Øcw!»á’^_Þ±[^‘ØÝÊ™;Và8ƒŒ‘?dm˜gPÇj·\R…q :“dÄ„*Á |…Vbn¶;ƒg³Eó çd˜ö1Öo( Ø÷aãhDBÿcü³!ýD[Áo˜¬1¿En¥ ¹±¦ä%iêÝînª6N:ó\ÒZÛ` æ]H›_ÙI<ð?yë­œ endstream endobj 218 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚíѱ‚@ à& &]xúÞÜHLtr0Nêè ÑUy´{ጃ „zwÀ¡Í×6ÿÔd4”’™JBG´ñ„qlfiG{Ø1+P¬)ŽQÌÍE± Ëùz@‘-§¢Èi’Üb‘¤‚˜µ©ÒÁc®|æÚ!P÷Æái à±®!`{èø.ÿT¼ÊV6ß¡ýAÓõ_°yÍÀ4Õ8+p…o âøš endstream endobj 219 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚµ‘±‚0†kHná¼Ђ±0’ &2˜èä`œÔÑA£3<šÂ#02Î^KL%!_sý{½þ¬æI‚!.qa¼@¥ðÁCT±Ý9ß +@P% 7º ²Øâóñº‚Ìv+Œ@æxŒ0> stream xÚ]Ð1NÃ@Ð¥°4¾;ÛŠBƒ¥$\ ‘ŠQ%Ú¬æ£ì\¦°v˜Y)¢yÒî·çÝT—ëk.¹æ‹Šë57 ¿UôIõJ/Kn®æäõƒ6O\¯¨¸×k*ºþþúy§bóxË[~®¸|¡nËXÊp8™ÎÙë…HDÑFä#ò°Ô々Ú~Àþ¨¨7ö'ÉQÈ”´^;LKZ+45qj@.dêtÜÇv“ù!¤¸Ç"iíÐÄÌôehÖ”ôÁjÛ]ˆÿdVçµ³½ÍSuž‡è ±ýõ?h©›ÓêgåcfKxýºëhG¿Á•¡Z endstream endobj 221 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ35Ô34S0P0RÐ5T01Q07SH1ä*ä21 (˜›Cd’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.O†ÀOþÁN2bÌH$;É&åÁ¤=˜¬“ÿA$3˜äÿÿÿÿ?†ÿ8H¨úANò7PJÊÃç‚”ÿÇ`$ÿƒHþÿ ÀØ`ÿð(Èþßÿ ýß E` q¹zrr:é“p endstream endobj 222 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ33Õ37W0P04¦æ æ )†\…\&f  ,“œËåäÉ¥®`bÆ¥ïæÒ÷ôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQ```c;0ùD0ƒI~0Y"ÙÿIæÿ ò?&ù¤æDå(I²ôÿÿà"¹\=¹¹VI¢” endstream endobj 223 0 obj << /Length 301 /Filter /FlateDecode >> stream xÚ}ÑMJÅ0à)Y²é’Ø–G_]x>Á.]¹WêÒ…¢ëôh=JŽe¥ãüˆ? Ú¯if¦“tߟ ChÞ¯6 §á±s/®ßÑ\¦¼ððì£knC¿sÍ%½uÍxÞ^ߟ\s¸>kŽá® í½Ào@£B,D¸'€DdZš"-š,-ÚB/6¨3"x‰š¢äç”™œ®—ÓÊ®k‰í ƒËpÞ7q|Ì$pãFúæš¿È »ùdíL™@ÚAvüZ´H¥ÙFÓ¬¦YM«5Þk|,ZdÖìI³eb4Ðj`Môä³g!@Tt¶«`[ÈBÍ».àA8ã²EþõËwÌ•b«ÔŠW¢’üÉü'îbt7î}tû” endstream endobj 224 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚ‘½N„@LJlA² À¼€ÅgErž‰&ZY+µ´ÐhÍ=Ú> @IA烋 á·ì|ýgf.ëK xQá®Âz¯•ÿð!ðe‰õ•Y^Þý¡õÅ#†à‹[¾öE{‡_Ÿßo¾8Ü_cå‹#>UX>ûöˆ)Eà§£‰¿ŽˆN£ÈGG#›"ˆqhfHøÔ8¾ÏéäfEÊAEIÅÈ=¿ÿ„Å-ˆÎ’%$©#쵂H\ÀÕWèfä¹  Íhg™…™cgݺi†¹8iZþG«`©s+´¤É,25×ô\iÜ`2[Ì[¸¨ÈE3)Dä/ˆþbZÁ1.8Gƒ ƒ•I¬³éUuužR¯áÍ:îXÔ&¼oÝ´í]Ö¯"MºÎÝß´þÁÿéýëo endstream endobj 225 0 obj << /Length 225 /Filter /FlateDecode >> stream xڽнjÃ0ð ‚[ôº'ˆìPÛt±!têP2µ;´4›qüh~?‚G‚$ÎýÅC»õ@ú¡Bw—&ó,㈮+]pöÈo1}R2æ¢ñ8^¼~в$ÿÌIF~{Í’/wüýu|'¿Ü¯8&¿æ—˜£•kžnûLMÔÐ@;ÑÁž&žEõD-twñ>‡5 pU/jh:ØŠ¶,PW+D5À^Ôh ma#:ôYÀVpÔ=ìDÓŠºb~9¬a€g‰æ/ÌÿŸuøÿwiSÒ]]Óq endstream endobj 226 0 obj << /Length 285 /Filter /FlateDecode >> stream xڭѽJÄ@ðY l“Gȼ€&áH¢ ç ¦´²+µ´P´N-²°`“b¹u>r‡"X?²ÙLæ¿Ó6']‡¶x\c[awŠOµ}µÍšéñLß<¾ØMoË;lÖ¶¼¢e[ö×øþöñlËÍÍÖ¶Üâ}Õƒí·hF8ˆs0;àÛ¤Ž¡+*³¯Lʨ€•Yñ ‘ iþŸŒk›àäï!%Nó¹4tíaà(.JÚ‚bÒî> stream xÚ’=NÄ0…'ÚÂ’›!sHRd ‘–E"Tˆ ()@ Qa-GÙ#¤Lyxcó´‘•Oòóx~ž×ÍaÛrÅ Ô¼®¹=âûÚ>Ù¦ÁfÅíqRîí¦·å57-ϱmËþ‚_ž_l¹¹<åÚ–[¾©¹ºµý–‰ÈÒOdÀ%2…È ¸9SQväTòÔy2ÙSÁ Tà» 2NXFvY òŒø_ȹèíC!š‹"Þˆº%R­î/ºQ‘‰(Œ¶"!×V$ÞMÀ x#$“0"»W ­ ÎˆPrÂ(¨ì$Ó7´Ày?â Âîßèö"^Ò\æ%òˆI‘Éd¾«^EÀ€AíÈRɯiP7ë@tÊê4F¦¾Ã}œÒ·  CÔGƒÉžõöÊ~†\ö endstream endobj 228 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­Ò±jÃ0`™[ü¾he…ÚÎTAš@=š)Cé”dÌÐnÁò£ùQü5˜8²þ@mp CoÐ'¸ÓJ“§,ã˜3~Tœ>óLñVÑ’Ô%cžMq³ÙÓ<'¹æ$%ùæÒ$ówþ>þìHÎ?^Y‘\ð§âø‹òGÂGT‚ ´%ð1Šîs °à< (G˜®Ï‹(ºnhÄÉõ<œA홀°OîÐÂS€ÆiüX+ÒÃé"¬]ö1¨Õö n\PrÀ䚇cDôÆÞ§ý+Á"ZlÎ`eºúý1´ÌiEWÂÁL endstream endobj 229 0 obj << /Length 339 /Filter /FlateDecode >> stream xÚU‘1NÄ0E'JÉMŽ`_²)²ÊÒ²H¤@‚ŠQ-” ¨£…›øéHayøcARäIñÿù?ûî¼ïÍÎtæ¬5ûÖôæ¹UoªëðqgúË|rzU‡A5¦ëTsƒÏªnÍÇûç‹jwW¦UÍÑ<¶f÷¤†£!*y"<–Þ3Dà‰ê@¼àȓơ©ŠD,#DQÄc!C<– S 1¹©úŸ`}½EØ fðŠQæjÙÀM5ÏA°˜øcÁ²¦Ç.%ó‚Í€€ %‚Æ ç œ9æd’QÿÅœrè™’t‘pI#xÙï$u_"E`—-5KˆfXÊz‘ qv, /&Áy¹6:)z…‹©veÒuFµA¹EøÅ”àVxXVˆ;Õ³]äß‘^KFƒùa9 ÔjcªG²ëÜY•ëAEJ˜¨ëAÝ«D© endstream endobj 233 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÐÁjÂ@à ƒ4׊ÁSµ`B{êAA{,ØÒž“GË£ôrô ngvÜ]vù˜]Øaþb:™Î•QOt ·O9~ᬠڕüpüÄe‰ú]Í ÔºE]nÕÏ÷ïêåëJå¨×j—+³Çr­€Ö€Ç(àYXU€õ‰zj&®|’€aOÃd pèùcš1uÔŽ¸Æ-1H[7c(< ¤bÆgá Xk;®>É÷èN`$ŸŽ³„Ö:¢‹ -åomc)¾ŠZ¶ç†/%¾á?OFi° endstream endobj 234 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚÐÁJÃ@àYh`Í ”f^@“[ …ZÁ zò ‚ …* =É£åQò9î!tÝ™¤‡âAO;»³Ìü¶8-Î)£‚NÎhaÉô’›wcm(f´È‡›ç7³*MzOÖšô&”MZnèóãëÕ¤«Û+ ç5=ä”=šrM¢“@åë) ¼oç\SÝ%´Ø}‡«³ØqÝKK䄸´ã‡PËFïF왎»m4â„øˆ¤cž´ÂRÀ1Uó'~¤þú@õ›h`"[bzÄ ÉOv˜ÙJ:Y³åœ ¨°»®‡8!áÎy¥»@ì4÷h? î%<$ü¹.ÍùD‰pj endstream endobj 235 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚѽnƒ0àC"ÝÂ#pOƒ(TLH ‘ÂP©:D™ÚŒZ53<Â#02 ßÙ$i¤(Aœ>l#ÝÓxñSHiLÉ+}GøƒIfÖ!/ùàë€ËÕ'%ªÙEU¾Ñßïqjù¾¢UAۈ–A¥µîÄÑ©kó¡~ÍF AkóæpÖ³Þ`…Ñ9EåÌkð&Çkkpk ³Éá9ç“\SþX¿·ù}iúžõÙÀõ,3ÐðO®ùZ®)g{I!9ÅÎê·VÓ®ÈQ5’Fb´)e¬<îþR‚gJàëàÛ‘)›gpò-áºÄ<[?—Ò endstream endobj 236 0 obj << /Length 230 /Filter /FlateDecode >> stream xÚmпJÄ@ð „´bæ ÜD؈ œ'˜B8+ µT´5y´> stream xÚ…Ð?JÄPð/¤ b.°ìÎ4‰°‚XW0Å‚Vb¥–ŠÂ²ÉÑr”=BÊ!Ï™I\ˆ ¾æG&óþÌ—¥§IÆ1/ù䌳”Ós~NèR-Æœ%ß§WZÝsšQt#eŠŠ ¼¾P´º½bù^óCÂñ#kôð…ÜUà9·µæµs`Ñàâ(+Ìw€z;#h¿GØÈž‹½œÐ!¯ éW¤øñze«»e0Òá¹TV<%× ä‘Êú_ÜHõ'Ëèo@Ûííeõ7®²)Àˆ%pÀb9 czCr™&!j.Ç; w¶³‘¶uØùÍLÚœ«ô$ – ]tGßPÄ< endstream endobj 238 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0bc Ss…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿÿ!êAC=3Ø€õ`¢ñL0`'ÁÄ?3˜øƒƒ`?pü`âBL<ÀAØ£úA€=ÿÿÿñDp¹zrr¾aZ¡ endstream endobj 239 0 obj << /Length 196 /Filter /FlateDecode >> stream xڅн Â0Àñ ‚…Côï LC[T?À ‚N⤎Š‚›>šÒGèØAŒEl ù‘Ëø'ªÙ¡"ÞIDI‹Ö wÛYh¯öaµÅ¾F9§¸ƒrÌS”zB‡ýqƒ²?B9¤…¢p‰zHp6&øÌÕžp¾|b¿-j8 endstream endobj 240 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚmÑ¿KÃ@ðxT³r¹X4íT¨Ì èä B :Š?Ð9'þ[·uô_ˆ®f’Áó½k›Úá¾|ÞÝÁ»Éá^¼/•ìÓôåA"¯c|ÀdHµâ’¦·8N1ºÉ£šÅ(=•OÏ7ÏŽdŒÑD^ÆR]a:‘[ Âþ’LK> "@ÎÚª(î ŠÖw­wVÞÒ¬¤˜nÐŒä5z+WñJ¥ð×ÕiÄ µì:yNÅR½ RN@WP!Ége¬Ë„¦­<½.#Òv­.©#ÍéFÝZ½ÊI»åÔ[Ê6È,,iÁ‡vR|Ÿ¶­¯•üŸZx¬ûZøsà!‰¥J¥“G*œh;‰¿ÜÚBamÅòi'> stream xÚeÑAK„@Àñ' Èk‡Àù©Úv¶ ò°P§KTÇ`‹:;}³‰û ó òèÁvzÏ]Å=èüFaü;“ON&S™ÈSºòs™ÉÇ_0Ïhžð”_<<ã¬ÄøVæÆWôãr!ß^ߟ0ž]_Èã¹\¦2¹Ãr.¡²„µjÀÊ5ƒn¡rh„߯á‡à3¾Û1¾ÖÒè}Z‡ÂCÑG¨tc‚P…ÙG¢zŒ°é1Ž Ú>#é ÖcxÖ,¬ ‹³ŠA•ºwÐÅÆ!2´EÕ *kíÐ8;´âAqÂ2¨À³jØGÅXmÁ Á'ñÎmA?N¼i¿ƒÞ/K¼Á¨‡xƒ endstream endobj 242 0 obj << /Length 262 /Filter /FlateDecode >> stream xÚ…‘1NÅ0 †]e¨ä%Gˆ/m©xS¤ÇC¢L ˆ ßð¬´GëQz„ŒªÛdè"Jò)ËþÓ^žû+ªiGgÔzò;zmð„Þ³XSÛüܼqßaõHÞcuË2VÝ}¼¾aµ¿¿&>è©¡ú»€]@ƺ¼›ÙN¢ff¹üÒYÌ*˜à('‰’ ü‚Q‚ BФùŠ Id“!Ù‹¥T$·pÓa“¨èÿ‡6U.ÃοÀÅ~‹I2FE?h+(¸QÊ©š[/¹UöB–€éÃÄ oÄ\öLrƒD’Š5éßÑð¦ÃüÖ¼ˆ„ endstream endobj 243 0 obj << /Length 207 /Filter /FlateDecode >> stream xڅϱ‚0à# $·ðÜX0)ÆÉD1‘ÁD'㤎áÑxÑP¯GIt0 Í—»¶×¿:è„bšòÒsÒ3º$xGrÛÒnœo¸ÌQH§¨6ÜE•oéùx]Q-w+JPetä1'Ì3‚ÂÓ€Ðõ˜ÀTPÔ\–6Bðæf ~ËxŽî3à9º:ð^vì@+ð{B#pˆ€‰*ɱpqä”íý‚>{È{ wƈõ( G5Já(ÿâ9Ò‡ýÂ6qã?¾}O endstream endobj 244 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚнNÃ0`G,Ý@¡÷à8UÚ2E*E"L ¨tìPsüh~”> stream xÚuнNÃ0ðä¡Ò-YÙz/IÀTt!R)`b@LÀˆ&PãGó£øÌV¤¨æÎa¨øÈðS|gûîlg{Í×lywŸíœç|×ÐY+Ášg͘¹} EGÕ[KÕ™„©êÎùåùõžªÅÅ ËzÉ× ×7Ô-0j`šÜ#ЧQ æ#ÀD¼LÚ€Òc0u(e ‹+9í1ü´ _¬E—ÿÿrùŠ4ê²A)'RòÐvd/Ú”F½¶™¢”NI/ÏJB7™,ú|z’5[%°m_‰«¾}תŒ¦£G9Ð;}ŒÞ£tøŒúBq)[m0”:˜Ï}ÐiG—ôy?x endstream endobj 246 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ…ÐÍ ‚@àÂyõ 5OÐ*h&‚ä!¨S‡‚êØ¡¨³>šâ#tô°d»µDFäÀð1?00~8r(9ôÈhïâ }OÔŽ,å`wÄ8E¶"ßC6]déœ.çëY¼˜‹,¡µKÎÓ„ŒZÿ¢‚¬Ô¹Y@T7sɸ z‚l»õbô¤ãÔ x³ýÄR I´;Èø‡®à­ŠªSqk¥¯([‰Å²µ\ÑŧÅy£NS\âwpmõ endstream endobj 247 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚ}ÐÁJÃ@à ¸0HsõPè¼€nHLO…ZÁ=yBA= * ÞÌ£åQò9öP:Îvô 9}à 3Uœ5gœ|Zp5çòœsz¥²ÒnÆå<ŽžiÙ»ã²"w¥}rÍ5¿¿}<‘[Þ\pNnÅ÷9gkjV,"­ùVöFZે˜áÀ&²WŽG˜"‰ì”“jØÈVÉFxA”Í=f‘^éþÇtXD:¥ýƒ$‚ߨÀQ`¢uþõÓ@ ¤ºú3 çØF«d@âma5_³óÙjέ ñ"btÙÐ-}”^p endstream endobj 248 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚÎÍJÃ@ð ƒØko™'p7…Øô¨ÌAГ ­GAEÏÙGÛGYñ ‚ôP2îÇH=沿ÝÿÎ s1;Ÿ5¤©Òþ˜kªç´­ðë…Ä?ãÏæ—ª{ª¨®}Œª»¡÷·'TËÛKªP­è¡"ýˆÝŠ˜ dwthÙåì g ïDŸõAs´ u<ñ–¾öTœŠw²ÐâÚ[l2 æd&™Cã8ÈÎÄ0Ö/b¦bí틸N:m?Å/-¿!ù“œ âAÜ'‹?w’ÕÉü±¦õ )§¾žÙŠæŸxÕáþZmà endstream endobj 249 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚeνŠÂ@à Ñ6…ûN²1’NðL!hµÅ"v·\6ŠÖæM|ßDÁÒBϱÐÂóÁ{¦—t³µÇ¤šõõ'‘•¤9æ˜#ß2,Ä~jš‹âVl1ÓÍzû+v8i"v¬_‰ÆK)Æjpª'gÄ#> N ý$"òOÜÝ#ð÷$ Ò$á 6&')Éx5ðÍ“éĤ47tGü4HÓxWtAN*²sÎ] î‚¿\ÌÁ‹ó;mçN/dRÈB\ endstream endobj 250 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚuϱJAà± ¢­•7/ {›Üy¸Dð A+ „ÄRPQ°òÖ7[ð|ûW¦8¼Ì$Ml¾…ÙÝf w\9ç>rQpYòÜÑ3*)æ\V››Ù#k²7<ªÈ^H™l}ɯ/odÇWvd§|ë8¿£zÊØKdiÐ"ëû¤D%(€ï;¥œ”Û<)÷ÿ‘”Ø_ŒïOIY Ó~0-Î`> stream xÚ]Ð1NÄ0Ð¥ˆ4à¹$Ù]C*,-‹D $¨¶@T@I‚aÍ7 ¥ â)]D˜I²H@᧑ǶþxUï›W|À{ ^6†ojº§e#››Ã¹s}Gë–Ê-/*Oe›ÊöŒžn©\ŸsMå†/k®®¨Ý0€$«HЩ"² òŠNjòÚ ‚Cñ52 ûëEÿƒšèÝYý‘:èÏa_ñ ûŽ#Ø7yÑFyÛö‚“APÁ¹9ãgô/þc'‚ûË‹Lã'Ü8—…¤Þ‘ME(/YUPA2KÈ,Ÿ‘†)4@'-]Ð70¥oÈ endstream endobj 252 0 obj << /Length 260 /Filter /FlateDecode >> stream xÚm±JÄ@†ÿ°E`š}ƒd^@s¹\ˆ…8O0…àUb¥–Š‚ÅAòhû(û[¦7Î(‚,|Åìÿ;ì¦>m×¼â–OÖ¼i¸mù©¦Wj:ê¸û¹y|¡í@Õ7U×:¦j¸á÷·gª¶·—\SµãûšW4ìÈ€þ¨™à’ȃ‹ðÈ á˜q|êùEú‹Ù"³…«‘EȤ y€D?aœK`\TÖ‹&K‰€—  ˆ*2›yY€b5–2eɛ™"“  ‰ªèã…¶£z|.Îóü¾¡‘|2@kÞP@U”ú”Ê|„³/€Øg”Ú¡«öôé8p endstream endobj 256 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ1 Â@E°L¡70sÝì ’@°ˆÜBÐÊB„€ZZ( 9ZŽ’#XZ:IV›t«þ 3ïOÌØÄrÄ#²‰xjø¨éBºN%7nt8SjImYǤ–’“²+¾]ï'RézΚTÆ;ÍážlÆ@TðJô ø@ ðhxÁ«jze/¨ š]aöåÙáýÝ;¿íÇÎAdDÉ/ak+ÚÎ?i¶¥”T“‚RSÊ"§…¥ }G«@ endstream endobj 257 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ1 Â@E¿¤L/ :ÐÍ®A"ˆEŒà‚Vb¥–‚Š‚…EŽ–£äÁÍ$±ÐNxÕÌgæý¡˜1‡qß„l">hº.§!Ǧ^íO”XRÖcR 7'e—|»Þ¤’ÕŒ5©”·šÃÙ”s Î@ t€h~//i¹ÝKxO`L®Ð“tIVãçßxÅ?üÞù¼¨>ö‡©(=C±uÚ•¿/ñ@ªÅRÓr•iniMoEËBs endstream endobj 258 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Œ?øØ¾á„ËüýóƒðÚcyn€8£žáÐ@§Ô­ÿÏ¡A|8X¤¤^þ}ÜÇÿ& ð…(¼À…ã.WO®@.QåXÙ endstream endobj 259 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. þ```ÿÀÀÀâÔ±=700ȃ0P’ŸøÐ aþäy û]ɃÔÔƒôÑÃ} p…(\ìàN9~ ×r¹zrr°Wß endstream endobj 260 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 261 0 obj << /Length 130 /Filter /FlateDecode >> stream xÚ-ɱ Â0…á gð 2œ'0¹-¥™k3:9ˆ TGAEçæÑòfÚ¢|Ûÿ—ÕÒ7ôlXUÔÀ:ð¢x@='eý;ý m„;P=ÜfÌpqË×ó}…kw+*\Ç£ÒŸ;Zä“Fy2d›åÏd“L*R!s™ÉB¬¹ËY°ŽØã ,P#Œ endstream endobj 262 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 263 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ-É1 Â@EÑ?^á ¦xЙ‰‰mŒà‚V"ÑRPÑ:³´Ù™&Nwo¾\ø’ž%红V\ó¦xA=y1žö:À¨n×w¸°ççý½ÃÕ‡ ®áYé/ ­tò‹½4è’M22ÉD³˜ÉT&2+•<å*ØñBÛ#´ endstream endobj 264 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsK…C®B.K Ïȉ&çr9yré‡+Xré{€O_…’¢ÒT.}§gC.}…hCƒX.O†z†ÿ 0XÏ ÃÀåêÉÈ[\w endstream endobj 265 0 obj << /Length 153 /Filter /FlateDecode >> stream xڅ̽AÅñ ɉ¨ŠóÌ—eëµSH¨"‘ ” ôÍ£xw³ÓN¦ø5çæþgvZ8œ8K¿àÜñbñ€·²–>žÎ7TzOo¡×²C‡ _Ï÷ºÚ.)k̓<j*¥zÑP ¢±‰R˜è.NÑO|[ƧÕmÈÜÏdSéL6•Îeé\6•NdV;üxÔ*Æ endstream endobj 266 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsc3…C®B.K ×ĉ'çr9yré‡+Xré{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]dêþ7À`=ƒ 1S—«'W fp"¸ endstream endobj 267 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ54S0´P06SH1ä*ä24PAS#¨Tr.—“'—~¸‚¡—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEA†¡žá Ö3È0຀`ý™ PÈx€±±¹™¨Ò‚¡€!ËÕ“+ &,• endstream endobj 268 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 269 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31Ô35R0P°T0²T06V0µTH1ä*ä22 (Ce’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. 5 5ÿþýg„" Õ1ü*Êl*,,0‘ƒ—«'W /¨67 endstream endobj 270 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚUÏAJÃPà‘Y13Ð4i»j³tåBA] * ]”vB.{b yÐ ÜdÞsJDìâÛüÃ{ÿÌqt”ô¹Ç &yÐ燈^(Ž4ìñ`ØMîŸhœSxÍqDá¹ÆæüöúþHáøò”5ð¾¹¥|€ü`aaÇ9Áïeå­ ã—R(£L¥(û3”]µ7EÉÛ`±¥EiÕÔêN-6Vj-pâW©|gÁÓíªÀ9£Ãpã«\ª²,~‰UsퟻNöŸívI ÊìN=k¿jF(uŠE}€¥ññ£òÖŸÚg\ غ]ÑYNWô_Z endstream endobj 271 0 obj << /Length 295 /Filter /FlateDecode >> stream xÚ¥Q±JÄ@}a‹ÀîÚÁìh6± œ'˜B8+ j)DQlDîÓ⟠ø)-qf·ÑÚdáM^&/oÞlª“º±ÎÖö¸´ÁS{_ÒÕ•Î3úæî‘¶×¶®¨¸šŠîÒ¾<¿>P±ÝŸÙ’н)­»¥ng³@¯|a…Yn b Ä=Z F˜Á-µ;C4 ¬`Ú £ FŠhj…x‘†¹1føo8ý}}‹Èà¢IDœ3Ö솘sÓ{Hûõø ØC6æb‰“BKú¿à›i°”ªÁœSµÛr£æßØé(_Ó ƒ}NìÇ\F?t"@!„°Bzéï>a3û„óÉ'¼tíìס²¡é¼£+ú®E}d endstream endobj 272 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bSK…C®B.# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ø0Aý? Áøƒ½ýãù† ö@CÿùA2þ€’@5@’±D‚!™dþÀðPI¸ùÌCdþÃÀþƒ¡þÿƒÿÿ “\®ž\\^åˆÓ endstream endobj 273 0 obj << /Length 154 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bSK…C®B.# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]øÿ0AýÿÆÌذIù~ iÏ"ëÈ?P¨†ñ3õÈÿ@€JR×|Z“ÌÀ0ù Çÿÿ@&¹\=¹¹)“ endstream endobj 274 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚmÐÁj1à é^=;OÐd-‘õ$¨…îAhO=”‚ÐöX¨ÒÞ„Í£í£ø{ô°˜N"¸Q6>fB&?™Nî'izàmf4Õô™ãáZûÒ||ã¢DõJÆ zâ.ªrM¿»¿/T‹ç%å¨Vô–“~ÇrEP@X×ìû8õ \²²IU{ó˜»ùÁ3ÌbÆYã¥1Ezôè$æ'i=SË©†LÂB„p6Pu Ž–8ç:R†£ ²Ž÷›[4ß9Þ²áéí…ÃŽ&ÎÈ&üZÚú'­ãXήÁÇ_ð%°m¼ endstream endobj 275 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ•±‚0†0Üâ#pO`Amd3ALd0ÑÉÁ8©£ƒFgúh< ÀÈ@¨…«Ú´_®íÝýýe4fÐÜ,¹ ¹¤kˆ”µÓ„íÅåŽqŠâH2@±5§(Ò½žïŠx¿¦EB§‚3¦ i3 €5C8ZA–›À/:LÊ^ÕÁ­ûpšôXpžÛôkÚF¶­±bIF°Ü2ÕéqžËUœNÐC¨™E>ª_…ñ÷c‹ð+v·d¯ó¯åínÔâ&Å~VŸP endstream endobj 276 0 obj << /Length 260 /Filter /FlateDecode >> stream xڭѱJÄ@à? LaZ áæ4‰Üª[-œ'˜BÐÊB¬ÔRPÑÖÌ›ø*¾‰yË+Äuv²g!–Bà#“ÍÌî¿ÎïúnÙñÎ;ÇÎóMG4÷Zly¿›¾\ßÑ¢§æ‚çžš-SÓŸòÓãó-5‹³#Ö÷%_vÜ^Q¿d ˆRPDZT†¸R´öR ÊOÔµ þ@ù*˜(ÞAWEÁ],øR‚º˜IµRê5ú7P­Ñ&?”2oÆ(~#FLØàgÈü5=dF#ïzv¢L;mf–Ä&,—mXJ[°Ìa Þ#å }Rº:%e-vÁvS½•Ô=U:î霾šes– endstream endobj 277 0 obj << /Length 194 /Filter /FlateDecode >> stream xÚ33Ö31V0PaS Ss…C®B.S ßÄI$çr9yré‡+˜špé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÁõBýc``üßD@.ƒý0ÅÿL1ÿSŒÀÃ?UBÙ7@¨`JJ=SüPêŠýê (<ö¡9ÅñP¯@=ómrüC%h˜ACž  !@ y`> stream xÚuб Â0Ð  ·ô¼/0­ µ‚Dª£ƒ¢³ý4?Å/iLsqˆð’»INÍÆª œ&vª)©9 ¼¢‹åý¶O4¬4Ê©åÊFQê5Ýo3Êj³ ­ioK¨k2ýè D˜ÒÀ€§dFLƤ1’(­C8^Qˆ€„ÉÆDð¹ïɰ|pÃ1ÆÛ½Ó.þ"bøÿyÒ€Œ)™gëºk¸×¿àRã?UŸ’~ endstream endobj 279 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚ35Ñ3R0P0bSCSs…C®B.s ßÄI$çr9yré‡+˜˜sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÀd’ñƒü†ÿ Œ`’ᘬ“6`R‰äÁAòI68ÉØ€L2`%™‘Hv0)"ÿÿG'!âP5Ⱥ‰ A€J$ãÿ `G@%¹\=¹¹Mÿx× endstream endobj 280 0 obj << /Length 254 /Filter /FlateDecode >> stream xڭѱJÄ@à?l˜&yM"&`µpž` A+ ±:--­7`ákMgé+ä ¼òŠãÖÙÍ& XšæKf’Íì¿]{Üt\ó)p×p{Æ =SŠu¨ÄÎæ‰V=U·ÜvT]j™ªþŠ__Þ©Z]Ÿ³>¯ù®áúžú5ð(ü6S¬ßü`À쑊-Ì— oÕ¶¸áÖë¥d‡ˆ¾¯ I¾Sòý03a‘™LlB".€¿Ñ!1ÍúOx½&ÂpcÄJÂ&ÆHù‹¸£…¸Û…˜„rI)¥ÌÜ” _ò,v0Ÿšõù{lØtéT–‰é¢§úî”Û endstream endobj 281 0 obj << /Length 125 /Filter /FlateDecode >> stream xÚ33Ò3²P0P0bSKSs…C®B.SS ßÄI$çr9yré‡+˜šré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÏøÿÿ?TŠñó bü78) À¤¯s‘)hèb y.WO®@.!»¥7 endstream endobj 282 0 obj << /Length 106 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0aKSs…C®B.#3 ßÄI$çr9yré‡+™qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿ†€ˆ¡¾aècWüÅåêÉÈ3v\‚ endstream endobj 283 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ35Ô³T0P0bKSs…C®B.S ßÄI$çr9yré‡+˜˜ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÿ€™dü€þ3 eR/i& 0È ò‚d“Ì`’LÊ?`üßÀðÿÁ@!¹\=¹¹Afl÷ endstream endobj 284 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚuÑ?kÂPð{<0p² Þ'ð%œÿ€ ur(Ávt°ÔÙ€«ê•]ÝÌGÈè|½¨X#yîøÝ=8. [~›< 8¢€:½û¸Ä°ËµW”ÅÇ|ýÕ”Â.ª1wQÅÏôõ¹ú@ÕjH¯>yoÉà瘣1 ýƒ¸ 8hFãx‡]Ê*ñ›1æ•øá8§¾yºØTBŸ¤,a P³ —À“M õ2Ü< œ fepÒˆ\$ÀIÂÖ5+zÛG4÷V¸Y5D NZ@fWðí¤'c´ÔÒÇýoÊÀQŒü¦Â! endstream endobj 285 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚUпJÄ@ð/.0…ûfŸÀMNÖ?óSge!Vji¡hkRù\AKÁTÖ©$EØuwöŠM1üøf`Šï`¹·<’…Üw£¥>”w%=’Ö.>úÃí­jRWRkRçnKª¾ÏO/÷¤V›SY’ZËëR7T¯¥µ@fµm óÀ¦‡í¼ÅÏ0 à{d¾¦˜üۘÎ=õ4]LÕ3ùȦ€aÒ@b·´liº@ÏT|`Ä“MLjbËÀ¾Å4ŸLõ“ÿ1ÂÄdtFÀœW$®Gœ á*Ã.|ר™±ÕtIÿ6D†c endstream endobj 286 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­‘±‚0†Ï8˜ÜÂ#ô^@D'ÔDŒ“::htGáxWÚœmš~éÝßöú_LÂyÒxJsNgoô(ò»ÌéŠIŠîžÂÝ5‡ÑM7ô¸?/è&Ûñ~IŸ¼#¦K¶ Cµ¥ Ô¼*x1F%¨À)dBœÃè ñ‘Š…¬ªA«ÑŸ8çEÅjGîU…Ò(ßNk¼ûÈ4ª,— ~ÐjÔ…}Á<ÛC¿2[|Žþfa?­-ÈÖžÆ3ë ñ“­oŒ×œÈ¾}°]Ñ=ÂUŠ;ü”K‰É endstream endobj 287 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ35Ó35T0P0bS#Ss…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü‚ ê„úÏÀÀø¿,ÊÀ ÿLñSÌ? Ô0Åø™adªT Y;ªÑPû ¶CÝuP7ÈÙÿÀÔˆ ƒ™….ĵ˜—«'W ŽK€¿ endstream endobj 288 0 obj << /Length 221 /Filter /FlateDecode >> stream xڕѽ Â0ð–‚ì#x/ i*Uœ ~€ÄIí£ù(}„ŽJãÙK Í"&…äHrÿt¢F*ÄÇ8 q¢0šâYÁ È€f4ãÊé óäžê ×´ 2Ùàãþ¼€œo¨@.ñ 08B²D­uåÐ uf,HW§‚ ô¥lüfëç¬(ºz¥eõ§Ö~ûüæÞ¦Øô§¹_Qš@™ñÍëõ6Ò+L®6ŸñeålóZ¹šÿ«›v,X¿ÕKéP~ï‡ÞEÔºe¯Ö©úN=â’¹«vð™<›Â endstream endobj 289 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚUϱNÄ0 à¿Ê)K¡~h{=îÄB¤ãè€Ó ˆ @°!ZÞ̉èF%Psw ²|Jì8¶ç‹Ãª¦’æt0£ùŒŽŽé®r®^j°¤EµËÜ>¸U㊠ÕKWœkØÍ=?½Ü»buyJz_ÓuEåkÖ?€ÆŒ!òÎf°l#>Ù3ZÎ;@Î'€ç7Àîx ïÉ&Œ&È–Nm9ƒR0—!¡G/aEïFD+E$½ÑŒµ²MX‰¿„^É>a‡-úÆü‘Mˆÿèû=¦×:upÇ´–¤-µiÞ}õèGŒˆA§Š^{s¦ywÖ¸+÷=Ÿ†# endstream endobj 290 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ3µÔ³4W0P0bSsJ1ä*ä2ñÁ" Fr.—“'—~¸‚©1—¾P”KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÁþ?<@£0ÿg`ÇÀøùA ˆbüP¢>€©T*L`¥€)‹`J+ŦF Åþ¿Hʃ‚ârõä äWÎr° endstream endobj 291 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚåÐ= Â@àÑÖBÈ\@7‰¬ÆJðL!he!Vj)¨h«9šGÉ,SˆëlÅ3X,ßòf˜âu¢VsÀmnFlzlº¼ é@ÆH¸¤˜¬w4HH/ØÒ‰I'S>Ï[ÒƒÙCÒ#^†¬(±µÊ>ñl \3X~ZPCAù©J'BEH?4€þ—ºôuâ7{©-'¿ROrï%ËxºVÝ™‹Ã·¹CÙ ï qBszØxaº endstream endobj 292 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚmÐ1jÃ0Æñg1> stream xÚuÑ1KÄ0àW „ãºv8ÈûÚôÎb ç vtrá@ÿ…?'â)ΤC¹ø’£âMHøH^ÂK^Yì/Pá÷æX.°8ÄÛ\<ˆR¡ëÅÑvçæ^,k‘]b©DvJË"«ÏðéñùNdËócÌE¶Â«Õµ¨WhíÀ­í"kÿ·ä@öŒæ¤àmDâ$f~¤#; Hl ¿¥½8@£ÁŠwdFUšì¨%[pù¤^q(é`J7)¯Iˆ’›ÑMk¯T¢äRÙñRI JN%}¤½Ö<=“Dt2l¥IÜ©yÑÑ&ôFš:Uï; ôAš9ÉOŠ} ô5*¡¿­ºÿÄÿ‰°­ ÄœŒE'"'íEÑ<´¾¦®_g'µ¸ßÑÆ©Ñ endstream endobj 294 0 obj << /Length 279 /Filter /FlateDecode >> stream xÚ]ÑAJÄ0àC»…МÀ¦Ç.„Â8‚]ãÊ…êÒ…¢ëöÁ«ô&æuW°ôù’<3‹ôãÑ¿ù».OËÊXSÒZ[svnž ýªIkÂè_<¾èM£ó;šu~žÍyûxÖùfwi oÍ}aìƒn¶¦E„'8p…@ë@Òµ1Ù±=™Ž h¨ $«3,ØÄ+N¼€ÝŠ­‚moƒµÛ³.˜ }0ý颿Q…£’x(`ÜO‡b<¾£âkˆç|ŽÑ4ºPS0á€%»â€ ¢–ƒöàØÞW¾œÌÈCeàË  »ä›PIÂ{Á7™½]øоiՈݱúªÑ·úR}Ý endstream endobj 295 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚÍαJAàYÈÁL›"y÷.p1©b¯L•BAS¦P´Î=’p²2EÈ8»n@ô,†ofgÙ§“ËÉŒK®´¦×WüRÑ+ÕsË8ÆÅó– ¹5×sr·zJ®¹ã÷· ¹Åý5Wä–ü 7©Y²È ð~k%…öÒvìT²Z^{ÓcÝÙ³ ÷ÃâôU«o²CÕ0Ë–*¤ÅSTB¶‹ú`ζÑñÞ&‡í%‹ãE¶Ÿ´§QÒÈ0›b4è3¾Ýe}÷¿Íÿô"Ý_馡}Èl® endstream endobj 296 0 obj << /Length 204 /Filter /FlateDecode >> stream xÚmÌ; Â@à . ´Vf. ›´1àL!he!Vji¡(X›£å({„”Á8ë£—åø‡ùÝéÅQ—Úš’˜º}Úi<"ÏÈŃ÷f{ÀQ†jÅ{T3ŽQes:Ÿ.{T£Å˜4ª ­5EÌ&¡€º6äü¥…°%/_x÷/PAP02gøýÁ0Ò¦–yp&îî¬dBw›:Œ+0ðÁüâ}¨AT¾yóMÞ6Ó¢5lö–¢.Ë5²Ài†K|¤øT£ endstream endobj 297 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01V0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃT‚D0S$ê00|`ÇÀü¹A¾ù;ÿæ ì˜ÿå˜00þ* àÄ?8Q"êI&êPMÊøbÛ½`Ëßœq ä ã ò Ìê˜þÿ:]þ—«'W ÈckA endstream endobj 298 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚÎA ‚`à'?( ‘œ ”ýüºÌ A­ZD«jXÔ.Ì£yàÒ…Tcu€ßæ 7f: 5ÙðP³™° ø éL¦ %¿—ý‰â”ü MþBbòÓ%_/·#ùñjÆ’&¼•ÎŽÒ„¡ZÀ{ÈUe5ÈTÆ©¬Ö-Õ‡W¨6êÀj@-ÐÉÅóOù¯Ó‰;*`{ú^‰ž[bàTd7“ý w§”§ÍSZÓ»= endstream endobj 299 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0VÐ5T01Q0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÿó‚ÁþT‚zó !ÿHÔ±÷`øÁøþó†ú쀶¤ „|P±=˜i«‡u âÉDª)öph‘<„ÚkrF=ÈAï?0þ`<ÿŸ¡†½ÿ?ƒü?þÿ ì@‡s¹zrroXhI endstream endobj 300 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ]Î1 Â@Ð\˜B/ 8ÐM²(ÚЦ´²+µT´“èÑr”!åbI qáÁ23ü;èö9änÀ¶ÏvÈû€ÎdC)úlGUgw¤IBfÍ6$3—2™dÁ×Ëí@f²œr@&æm)‰Ú¸·2Ï©\^¡sϵ2¸Î÷¯HÅøQ‰RñþQÖOþø—Ö5ÉQÑJrµìhè M£íÂá„TårL¼@³„Vô½£@ endstream endobj 301 0 obj << /Length 141 /Filter /FlateDecode >> stream xÚ32Õ36W0P0bcSK…C®B.# ÌI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ê˜ÿ70ð|À ßþ€ÁžÿCÿ`ÆÌ00ŠÿÿÿÇäè§3ÿa`¨ÿÿ޹\=¹¹¢&[ endstream endobj 302 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ¿J1Æ¿00…ñ v^@³9ïäŠÃ…ó·´²+µT´[¸}´> stream xÚ31Ó34V0P0bS …C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ì€à?É&™iN‚ìaþ`ÿD~°’È700nà?ÀÀüDþ“ØÀÈä‡$Ù€‚ëÿÿƒÿÿ7 “\®ž\\y endstream endobj 304 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS3…C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜ø0È@A@ 8~Àüá? ±q©ŽØ0üÿ‚¸\=¹¹(CE` endstream endobj 305 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ32Õ36W0PÐ5QÐ54W0´P05SH1ä*ä22 (˜Ãä’s¹œ<¹ôÃŒ ¹ô=€\úž¾ %E¥©\úNÎ @Q…h ®X.OÆ ìø   P?`üÁð†Ø€¸ôE6Œ?êügüðŸ‚üc?PÃ~À†Ÿÿó.WO®@.ÿ§Wõ endstream endobj 306 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚµÍ1 Â@Еir3'p.#˜BÐÊB¬ÔRPQ°ÍÑr±0EÈ:? êdÙ³3ó7èuÂ.{Œô¸òʧãH‰ÆrCqJzÆGz$¯¤Ó1öÇ5éx2`ŸtÂsŸ½¥ […RÊüâë?´LõºæÝ3Ø‚ærÁÊkm‚¨„;xÔÂ3êH†Kv¤Ø@%¯â.êýoÔ nn—**ŒÉù@Ô¦ôDr endstream endobj 307 0 obj << /Length 108 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS …C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?0ü‡!þ ̃±ÿ`øÿÿq¹zrrÆ‚Q. endstream endobj 308 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ3³Ô3R0Pa3scs…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?ð`Àðÿƒý†ú@úƒ=ãƒ:†ÿÈ77Ø3ðnà?Î ßÀüÿˆþÇÀDÿa`ÿÁÀNÿ``ÿ€þÀÀþ`Ð O€âÿÿƒÿÿ7ÿÿNs¹zrr#߈ endstream endobj 309 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bcs…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ìø?00üÿ`ÿD~°’È70ðnà?ÀÀüDþ“ØÀÈä‡$Ù0½ñÿÿÁÿÿI.WO®@.‡e% endstream endobj 310 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚŽ1‚@E¿¡ ™†#0Ðeƒ6 &na¢•…±RK v9Gá”Tâd)H¬ÌN^fþîþù‘žÌ¦ð”Çš£€Ã9Ÿ5Ý(ŒE”qÑßœ®”R{cRk‘I™ ?îÏ ©l»dM*çƒæàH&g8^W‰S­œQƒdHàVðá•R¾ ò!J*¨- Ài~ nNû/†ooñkg»Íîõ$AéÖHåŠ> éáwlzZÚÑIKÚ endstream endobj 311 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚα Â@ àH†B¡y½ž­uj;:9ˆ“::(ºÚ>Z¥p"ØŠç]qÐQ |CB’?Šû2ä€Ü“1G!‡#ÞI:R°«aøm”d$V$f¶O"›óùtÙ“H–$R^K6”¥ŒÊ¯À¨\ƒ¹UW0÷Â/¼º%>Á«°T¨5*è´4hy~“ÿÌ÷ö²¥ý¦Ýß> stream xÚ31Ö³0R0P0VÐ54S01Q06WH1ä*ä21PASc¨Tr.—“'—~¸‚‰—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃùŒêØ0üa<|€ùÃãìÊð?`0?À€Áþ€> stream xÚ36Ò35R0PacCcs…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ØÈ3üPàÿÃÇþ?nÿÀÿœýó3 ~Äo˜0ÿah`þÁÀ€‚?P³Íüÿÿs¹zrrjÙF„ endstream endobj 314 0 obj << /Length 195 /Filter /FlateDecode >> stream xÚ=αJÄ@à¶X˜fßÀÌ x{›`TñSwÕ‡•Z * Wî£í£ÄÊ6`“"8Î%GŠ™ùÿfŠ|q~ÆK.ø4p¡ó‚½R^j¨çåÔ<> stream xÚ36Ò3²T0P0TÐ5T0²P05TH1ä*ä22 (˜Ad’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  Ø W á Œ@Ì Äì@,ÿÿ?Ã(f„ÊQ „þ0‚pC sC3ƒ=;ÿ?°f.WO®@.uH– endstream endobj 316 0 obj << /Length 153 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01Q06WH1ä*ä21 ([@d’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæ ìþ`üJò`À‘p’ƒºBþ`°ÀÀðƒ¡üÆçÿì™Iùÿí@’ùÐ.WO®@.1c endstream endobj 317 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚU̱ ‚PÆñ#‘k[çêªWJ'Á rjjˆ ¨Æ†¢¶ˆûh>Š`›Ph—º—jù ÿ¾@ BŸ\ò©ïQà“ÒÎÃ#ŠHE—Äè³l˜dÈ—$"äS•‘g3:Ÿ.{äÉ|Lò”V¹kÌRj×_œ œÒ.Á.X ,g0i)à <¡¥©¡pƒ¶&†®A†=éjœ|c(v‘kØ]þb=ÀÐ(Ô¿áúO¨ÁI† |F£?ê endstream endobj 318 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÎ=KÃPÅñs Xx³v(æùzËíËb ­`A' ÖQ|A7©‘|±€Ð~Lïx‡`¼7UÓN?8gù«áá°Ï!ñAÄjÀÝÏ"z$¥ìr·¿~nîh”¼d¥HžÚ™drÆÏO/·$GçcŽHNø*âðš’ WUPñ÷6¾Aß´4æðŠ5¹§q ‘þ" bxØ%âtÇq¿Á_ù®cùGˆÅ²h;²š÷L€ Ëtè5Â<þfúOk…2·|âµÁ+ñ–ZlECÝdÑ ±ï(°ç˜ÂÑIBô¥Y_™ endstream endobj 319 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚMν Â@ ð)(¡«ƒÐ> stream xÚUÎÁjÂ@àYi® Î èn²Zõ$¨sÚSE¨GÁ½‰æÑöQ|„x ‰³²Iéå;üÃüü=ÝF¤(¢N8 ^DúÖ!þ qª¨¯ÝiµÅIŒò‹ôåœs”ñ‚ö¿‡ ÊÉÇ”B”3úI-1žQY¦ãâàAægà//7ˆœŽ4gËZŽvª*Ì 0‰Ã¿˜Š+ã]S‡¸CEÉ@QsüϰFÕì,IqSn/¼'¶’gCþbŸ^m‘mjg`ç1øã'>ÚŸKø endstream endobj 321 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ%Î1 Â@„á‘@„‡$|'0‰+AA¢‚)­,D¨¥ ¢æQ<‚eŠ`œÅ_ìì·°&î# µÇL_M¬‡H.bìÚ£½ØŸ$I%ب‰$Xp• ]êíz?J¬¦Êu¦[>ÙI:ÓIU•uO§Ã)Fh~ðß!;£ó:còÌÛዬQÖ‘‚ôŸÿ)HÿåpIëH]R·YÀ#õH[¤mé(œ²âl2Oe-?uàC endstream endobj 322 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚµ1 Â@EH!L“#d. ›ÍºˆBŒ` A+ ±RK EÁBb޶GÉR¦R×l´6¯˜˜ÿþPtÌ+îǬƬ5$Ii;ŒXÜf¢$#±a¥I,ì˜D¶äëåv$‘¬f,I¤¼•í(K~ |[äj¿„W¢‚opGÏà ÀÄ!´—S‹¢E¦ /‹òèzù´ÌO¾6x+Ó¸YÛ~åÕÎÜuдñí…æ­éÂÕ`ú endstream endobj 323 0 obj << /Length 121 /Filter /FlateDecode >> stream xÚ31Ô35R0P0bc3SS…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]0001;Ëñÿ ÿaX*6T°ý†úÿÿ?À0—«'W ¾NÚ endstream endobj 324 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚmαJÄ@ÆñoÙ"0M^ป'p÷WóSZYˆ ¨¥ ¢`eòh>JáÊ+ŽŒóé5‚E~°;ÿY²¬šc­té_^iÓèC-/’³Ÿ+9¸’u'éZs–tî·’º }{}”´¾<ÕZÒFoj­n¥Û(Ê-€~‚Ù€8¶#J^ÎQì0CÜc…0áùîÈDÌ_úŸžÓÁïø:ßsöNüaçü™r$_΂[-> ³À,°ˆ, %‡s„'äƒlÏ"³ÈÌñ¥™aAZÒ›M°¿ÈY'Wò TŸc| endstream endobj 325 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÐ1NÄ0ЉRXšß`3', ZiY$R AE¨€ ´ØGóQr„”[¬0¼„‰"OÊŒóÇ“ãîÈ/¥•^—ÒŸ‰÷òØñ+÷ÅVüɾóðÌëÝ­ôžÝ%Êì†+yûxb·¾>—ŽÝFî:iïyØ™-­2È9QµµÕ EëPõE6‚f¤LÍôV»&‘ÆàðÌÔb&e6‚€§Ñf“õÕŽó‘òY (yâ/ifU ý°Å_ cBüÔ¨M>Õ‹ý‚¸Ÿ™°y¥ÿ€‚޵¸2_ |ÃßÇ›jh endstream endobj 326 0 obj << /Length 188 /Filter /FlateDecode >> stream xڕν Â@ ð+ At-(˜'ð®¶µkotr¡P?ÁQðÅ_ÄÇè èý‹­³ù‘äIàõÃ+FŠÃ!¯=Ú“™º,ñ‘o)Ñ$ìG$'¦KROùt8oH&³{$S^z¬V¤SBĢ⊠ØÀ©iƒèA«äf°1ë€h‚.p;»Áö`¯Z  \2ðoóŠß›ÿÂy™³54Ö4§òý`ö endstream endobj 327 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚ•Ï¿jAðïnaÜ ˆÎ ˜½s=b!j W¦J!‚`R ìnÍG¹G°´8ÜÌœEH:›_1;ödÏyŸSp¯ÏnÈyΟíÉ9)¦œ¿Ü_6[šd?Ø9²oR&[Ìùð}ü";YL9#;ãeÆéŠŠÇÀŒÇæÒºÂ„ÐpQ*Å+j .+xsº7á”xÄ•‘Íç–Üð‘\ƒ }µrÓþ† ”¿ø´•R þ/:tK­¬uéîNTc¨'Û¼‰Ä'ò¡jìiT”2ƒ®D¥×‚Þé+XÑ endstream endobj 328 0 obj << /Length 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 330 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 331 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 335 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 336 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 337 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 338 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 339 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 340 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ¿NÃ0Æ?+C$/~„Ü @pK§V*E"L02€`«÷ÉÈ£Dâ`ž”7Ѭ$7ëãî¨d¸¬*¦ ¯:}§¿$ X endstream endobj 341 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 342 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 343 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 344 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 345 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 346 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 347 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 348 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 350 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 351 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 352 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 353 0 obj << /Length 238 /Filter /FlateDecode >> stream xڭбJÄ@à?ìÂ4y1󺉗‹[8O0… •…‚Z *Úš<Ú>Ê=BÊKÖD¸Òæ+f™™¶ö‡Ç+.yÅG\×Ü4üPÑ -½Knü÷Ëý­;r×¼ôäÎ¥L®»à·×÷GrëËS®Èmø¦âò–º ÁØ`#úÁ¦” ÌJT&e« 0m´ã?H‚M¦ÈF3âC‚ …P J°@¤#ßJ“ÿ2 ‹_â.N”^‘v2%5+w:ù‹gY9–º×Cbì)û@;ä@¯ùf,B‘M¥—B‘~2ÑYGWô îøeß endstream endobj 354 0 obj << /Length 219 /Filter /FlateDecode >> stream xÚ¥ÏÍJÃ@ð Ci®Š°» ùX/b Í¡ §ŠPB,íM$–Gé#xôPÔÝ .ÔC¡3ð;ÌÌîÎ&z’§¬8åë˜ÍYÎϽQ›¢âì¦ë<½RQ’\q“\˜2ÉrÉÛÍî…dqÇɯ#VTÎx$ltŽøc¢uZGaýÚL„ÂùÚ¨EeT°†{Øšôk€ç.àÐYàjXà î-æ‚^› Çð Þ:~ÀwÇßޑþ×ÿ'žaðÙ”æ%=Ð//ó]ã endstream endobj 358 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×31R0P0F¦ :Å« Ì ƒYɹ\Nž\úá@—¾˜ôôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàg°?Pÿàÿ¬`€ŸËÕ“+ è±"g endstream endobj 359 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 361 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 362 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 363 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 365 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 366 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 368 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 370 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 371 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 372 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 373 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ33×3Q0P04¦æ –& )†\…\& ¾ˆ –IÎåròäÒW01æÒ÷ sé{ú*”•¦ré;8+ré»(D*Äryº(000`f0É&ùÁ¤=˜¬‘ŒÿA$?˜ü"ÿCÈ ÙÿÀ$Då(9„Éÿà$ûÿ?àXþÿÿ&ÉåêÉÈie£\ endstream endobj 374 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 375 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 376 0 obj << /Length 339 /Filter /FlateDecode >> stream xÚÒMJÄ0àWº(d“˜\@ÛÊLe@ˆŒ#Ø… +âJ]ºPtÞÀ+õ^¡7˜.»}¾÷R¡ÝŒ–Ò¯$!Éû©ÎNV¶°•=>µUi7+û\ª7µæÁÂnª8óôª¶µÊïíz¥òkVy}c?Þ?_T¾½½´¥Êwö¡´Å£ªw EàÇ`Çxè› ŽD6&<©{p-­èø×ðxš&hY:@B$Òü›ñ(‹iµš LJ¹v‰:ßòu–ôø'ƒ ÿO˜c‚?€\pÂýb&$¢ gìƒÄ¾”H¾C"œ¬¯À9Ëtà j‚òyDÐnçåtÐ;ÆŒÀÀ…«5Ñ@ê nI;ÇO4sPêÊ…‹e4±¨BÒÅ(ôΗ¢S9¦ÝÄ^Ø+4IÖI“¤½ìNÝ%5÷(5p(­˜a NÆÔU­îÔÃâÛE endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 809 /Length 4156 /Filter /FlateDecode >> stream xÚÝ[Yo¹~Ÿ_ÁGûa{È*ž€±€|m„ø‚%#Ù~Plí®]i!ƒÍ¿ÏWdó˜Cã‘äE€@îž>x‹¬¯¾*¶ÒÊ)ÖÊ+N*)Ÿ”Ñ*zeXƒ‹+R&(ãññÏ*2øgDŠ—NÞ‘W„z”£4Zdk³â@¸T£b§,áETÎôçœ]°W.YåXy”´VEôgJÞ+ tJÊ¢{B#ý3D´ÒiTÒËb¿pN™„¦Ê'‡÷9%§<¤Ô¿ Á¤SD&©€‡¦ð–5šÀ@ØBßè€l@­ˆ1ziƒÔ¨†÷"ÔóÉ(z# h6bŒ¨B‰‚ ¢ H+jcehˆ$ ÑrUAz")Œrx€‡øuQ\Z­eNØ& ÕfmbF %kœ[èÉzté1VkEPª(!]’ „”ž0: Ô;ˆ`R€¦¡“"šf—Œ:’>m"ª!´Ì+D 3G˜“HÕy,h’0_QÚ'´”4z$(?±Æ¤‘JNƈ:)âC7FãÕ‚1‡FG¬¬ c"æžeÎHËѶÉÁ2äÐ « A‰ZC… ‹€±0 ÄrÀ¡Ãè|ÁQÔ¤54Gr!SƒâÖ@kYq-”!Ìj^ßœûâ,emd%E¦Š17Æz©å‰Zþpuz¥–OÕƒÏçWW—=Tß¿x`Ô«£—ÏÞXŒK1ROONß?~wzüúÕÍÅm)Îê鳓'oßì/íJi«NÞ½yóúíé³§êäÇ“Óg/On®ãK§Ž_œ½xq´¿ cJy¯ÞýðL=}ýäÝËg¯N¿VmVOÀ¸ß>{rúúí ã÷äôÝÛ=Ú2³º¢zqüò¸t²=–÷XøZ½UËç«RþÑ£Åòô?¿Ÿ«å›³ŸÏË'W—«óËÕg¬)¸X¾=ÿ|õåúã9žøòäåù§‹³ÇW¨÷<–@Hôa®QS–›ÛºüûÿÀª1¬˜ý$øwùå×_?ÜX’PÒ§ˆóZ¹çPɰžc-Z=§ØÇ|-˜™¯QeùæúêãÉùJ½ÇŸ>WËÓó?Vªµ¶sì°Ï±;ºÍØ—G——Whç½`³ÈaËÀ¬/?¡üÄò“ò+#qeòåöË“/ÿ\åû—ÿZ,_]:¿Î’˜Ë¿,—Oæý#†œÕ Ð÷Ž'ˆ`'PóÐ-G;RûôÛJaÒ”ýd„“óû…ào/ rŠð¸pf“x8Òɧ°W û'ˆáÌ”œxÇ0y¸ ç5ÄÚ/†ûÄ0qÒâ¬0)«Ô‘‡X~¯þÛ‹a£nœbœ< YaˆåöŠ1Ãë·•Ãé‰až„EoŠû¹¾"ÇŸ`)ÖøÉÂ}£ï ôpæ —Ý/Çš±MŠ»ë%wƒö<ÀMÀÛvù¼Çùù¼ÁÅz„>Ý„=m‚°×ws@Þªˆõ’78 Ýå8LÁ„JZJ˜[@IÒ«Áßg@F½½×,lÑïî8 þàYðÎÂV9гpHI“hŠ!|Ýâš$万žÃåt7=‡ƒÍ>ðö*¶“Ñö€’.‘âõNþöŠî •~GåF½¥ÜxG妃•›[ÄÛål I î³4o½¥ýÁaÉC^,_ývž›+¼<[]_ˆ®&øSV,þúõ‡RêqÖ§úÎà_ê ±>ŒÊ—alÊtü¦ì±Ê1 ‚“ëÏ«'¿œ]#ˆ_,_œÍ7ðÈ‹åß.>­~ùœû<ƒÏ.?^}º¸ü9Gøù‰”•楫ó÷Þ‚Cšá,Òo^í?ë»[ßÒòmÊê¯>Û%á}Îú–:äüaX˜u~a,?ýt³”%ôžíò,‡d8–(×§óŸ'7YŒôÞdÉ9Ò& I´ÉB’-m²@'±u•Äþúw#ç8Ä;›»xg§¾ƒˆ©°êïê­_óΦ{gŸ6½sÐ[Þ9˜æ ñ¾dð¦œhÛþ+ïõž¿¯—Øþã4‰œ`p'êoÃ^š4Éæ MX0VO~~àÝ‹È%†Â"JÔÌf‚í!ÌË(Æq’XØO™â—»\vP8©À›N&»ÀÝà R±S­È7³Â5ô‡¼á&ääïåi†×±» ‘þ¦8 Ó½ƒldYßáÛØÐñÛØ8 ©ML¹™œ±Èш>ŽGôqvDב b8?b‘ #¹8b‘K#y=b‘7#y±ÈóˆEÞŽXä݈>ÞèãÈ7>Þ:(Ý:H¨}Œ÷¡õ6 ÀSÇÊ:nTV0àÆL2«<èáçM@¨r&ðŦO@gOÅZäfç,1žÉ\˜@= ÀÁæ&±<#g BöQ¸ÃÌ:€‘PD)‹ó2nÝbü029ìÌÁ0H”ƒY:–ƒ]aAº°ÁHqø‘‡ªÐ­+³Qƒî÷ÀF椷à¥8„,ô·R> ö‹åÙ(šì:7Ž&[ϘåýæÆÌd¯µšBÞo­–·©«!È®gcyÂÔBãc²{Ëm v mÁ ´-ø©…0ÀIùXùXùXùXùXùXùXùXcZxjËÒÚ­ 9n²Žì«!×ë†,Àa¾‰%®š)S¥eÍ”©R³nÊ4ó31eXT|øyÓ”SšÐAB Ú:eϦ'ÌQôSî˜?e²fãd Ä…”Ë‘•öàŵ§8ar#ܼLUjx1aÀ@2“Í@'¥ÏÝäÂ¥)n¿+M#p` IÎÀúÿkhj~…~Z¡giÆ7®3Š5ˆ¡mb¨€j± †Z¨áäCß!†Z ˆ¡g@Ô ù$¢ƒò5„éC=Œ¸á14ƒÔƒAHЃAi-tˆ¡ Jk©C µ`ª§ b¨ƒò±wˆ¡ :ÙLêCÆ̈Lx ™8ð2ià&Dzà&Dæ¶ÁоãÈ¡9øÔ]qÊÑnÆAn3Hn+HnÈ#¾?œõ q HD^Nù~ˆ… È”'  `—~Â\–ŠÞNÂôk#o,Þsmpn¾wuzd´hˆ¡\O-9¿;nNtý¯ †˜ucþbÖù‹Y7æ/–܈¿X2ü€xàÄ? øñÀˆ~@<ð²? ;ð²? ;ð²? ;ð²? ;ð²·åÆÝ%G`sŽ@ ïî9a&;3ø\s3Íò¸ÎL·<žç'[^^üåÜrÛ[XòLf—³žM©¼¡0ùz½mË·=Ïm®åJoÅ$]œ0ÇÛà¬ÄJÁ{A9GùN`í‰Þ«¥7r %å1^Ë—a­Ì<Æòœe<å‰OS-2/E z—ÏàÜeÆ·Eðr=—/‚¬MçxFÀ‘|`²;•ÍÅÝØïÞ&‡Ý€¥ÚŽ\y›`k«GüóÂ$=#ÁYuÜD‰|l1±½›wÀ˺=€#nr®²M ’ßȶap@&HN|û­!àCÈmìˆq´øN>Üjñ¦˜|ê›TsŒ²k@-ÝP¦–Á±²ÂCßD –‡±Ò÷mò±ï#PKÉÈ×A-#cå£ÙÖ€w6Ê€Ê×Ê®³Qî”å;æî¶¸P±›Ô}·4·Ëß<÷\µ”Pùž¬ú0Œ'˜ÁïõPXTå'ØBaAÆ ‹ì¡0”ØCa#_Zô½ ê¡°|ÏMƒ{l¡°¸Ç ‹{l¡°¸Ç K5 î±íøˆ{lùq-Ÿ î±åò÷ôÔ÷6¨åä3·–O/Úw7d¶uÏ!RK.$©zB‘R¶:(¥Ds d«ƒµ’¬iH6²æ!ÙÈÚÉFÖnH6²öC²‘u’¬ã@ÚY§´³ÑC²‘MO=B3¦ÙŒ©G6cê‘¶A¸‡ ù‹û0$"¹‡ ò¿zÈ@²ôõ° Â}³ˆ„³Åaëƒ\º-¯ Û¼F¼Fïâ5´&ÿÁón-ïÑ ®©ãNk*ø ´f† ¡5â)…•`6m̙ʭ³.Y‹|ÕŸ”:úOøƒKÎT¬ô®bÂÐ[¿ßcÖÔ ¯þ‚È9ƒžìa9Ow“»EK=Lá š®{ŒìzåÚ=›$îvllŠÇ9ů‡†Š«Û³ó‘sý¡ÿÊ&ÈÌ€õñàr¸E#Vß.§:ârz Õ»!“ÊmƒC|IÛ߀f¸oh nõ-LAª¾…)HÕ·0©ú¦ ‘åq¬Ǻc¬QÅŽÛ©lÇíT¶·F¿ùô)´Ìç|½#¡·Z0þo³û9¤>9lîbpØÚÅàÐw1`1¶D/Wýg×EÿË™H?_Ò$Ûõf‚7ް¿u\ÒNÎŽ™R¢íF¶ò½KW6Ju±îYÖ-©Qަ¼`ÊïÁ»œÊvë(ùMå:oÍ\!S·Ü̸׳!ó"÷e/âȺ%eјvÈü$Ä fÐwãÓ(wÏ>ë 0ãn .©Ï=¸²¶[ÊÍ— ,„!Êú ÅlÔOˆd¶Q¸í^Â7r#DòÿÌ™²FÓ±rÜX24Å~øx„ý˜nä¾m)¨âÇ;دñ˜ G fÄ‘@ÛX!_~~–O?¿\®Lò¯Ÿ>·ÿX4ç>i=<²ZÌqã«È×_V¿^\JƒÙìÕ<<±zUÓ¥«Ø*^¬~=W5“q¤*mŸ¿(åÊ›ß\Ÿÿ[Ñz'W­¤ÿHÕ(awÕY–Wò1'ÓŽv\k‡öµ£‡vvÊcj;•ãíl§’ÃÒŽÝn§òÅ#U9æîvhlGïh§©ÖìSmš™e[k¦iyŸ’G›:n*6»É×t*^ òÁӫ߬ήWUq¿êÁñêü·É自¸ùAx¨Š Ì÷ñ¡*V0ß§‡ªØ°zð;ÖþdªÂ"àÖ^\üv±Úè­–Ê+ý¿Æí¾¦ endstream endobj 389 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.16)/Keywords() /CreationDate (D:20171125154536-05'00') /ModDate (D:20171125154536-05'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/Debian) kpathsea version 6.2.1) >> endobj 383 0 obj << /Type /ObjStm /N 6 /First 46 /Length 310 /Filter /FlateDecode >> stream xÚuRËjÃ0¼û+öXjY–äC©oM“’´§àƒšˆ`ð‹J9ôﻲã"›æ´šÕììhW, –r <Á(€Ñc ,Ë0&ÀSaèå¹G¶²UŽƒ¼¨ òAØÃ„™1s0Gœ:Xø¸ü؇”NX«“©ûî1 ¨™Ø\å‘MÝÖÆíæÒ*¯(–nwE‰ˆ-dŠÅQ²Ê¡]¶lo{¬*‘´ªÃWQºvè6w˜wMâ(¨Xêâ4hvOWø.ñOöµ>#‹Ý¦ÈÆuîÇ…NQ¬õÊþôt0òÛü¯W*4û°nN~ü È‹4²é/yÇehàãœ<²»š¦î”- §ÌôTûyFhéoýY‘O­fò˜ÜÈ/Õè<'Ûk«!¤, :*lOvƒêžG›ÀølêbQ¹ endstream endobj 390 0 obj << /Type /XRef /Index [0 391] /Size 391 /W [1 3 1] /Root 388 0 R /Info 389 0 R /ID [ ] /Length 1103 /Filter /FlateDecode >> stream xÚÕ{tÏuÇñÏû·1f3æ2l3›]ÌÆÌ6›Íìbî×1ìâ.–è(‡·R)¥£P‰è ”R9¢p”,Ýœ9*¹T†jTDÖëùýçq~ç÷ùü>Ÿ÷çý~>?眫÷9çsfýï8>u„)`àƒX˜ ~àq0 @Cˆ‡‰ 3L€ÆÝa<4 èã šB&T@4ƒæÐÒœ ñ …0Ša(”Akƒ6ÐÚA8D@$t€Væ,Ü[´= „(è Ñæ|u޼ȅ.ÐÉ\`¥7=! ’! ºš èMIn Yn®í§Þh†¹È©Î\û"ªèàõ"z¿ˆyEt\/bËE\w¸,âψ„5¢Ó`‘˜ Eç"é5‘\+ºÜ)Q¢[‚Hm×EZ4\éÛEëõØ,2ùmÖ^Ñóm‘½[ä¹N‰ÞçDÞŸ¢@Ét…Á¢OKQ/úæ‹~I¢ÿ1`¦ÈwƒÆŠÁábH˜ê'†ÐðX1‚GŠ‘á†uG”Üc[ìe-r —¹Ò‘(eJÙyQ¾ZT¤‹q½ÄxöÀ”‰äjÒ,19ÈÁTìlÓ‰é,P¹A<8[Ì໇X`f™˜µÞ‹ 7äA¾¹‡IÎlŽÿH†x”æ°ÞÜ¢Š=ªˆyëÄü bA¦X¸L<>_,zW,æÐ‹ëÄÒ±Œ#,£ž`ò“UbÅrñK=MUW{±B(2·Š.YÍ*k†‰g©ÑÚ"ñ<¥XG ¬#‚N‹õÔã¥KbÃBñòF±1Dl:(6(^ýK¼N‹n¡¯Þ Ò­¿‰7sÅöbGŒx‹¦Ùɧ]%b÷ñÎP±gd?è̽—ª½´ÅûÇľFbž8@ÿ}°VÜ&>"Ü_‡®‰ÃAâ“1âa=!>#kdžˆãsʼn}â¤ÏÛr †!æ>ç¨_L§æˆ/§ùE5}Z}_|EbÏ<#¾ÎßÄþ-ßUŠï¹~gW‰ªZCyÎq…ÎÓ÷?7‰Ÿöˆ Äò3·çâ=q餸¼B\™"~áÒýÊ ½Jµŵbqι±RüNþQ#ê&ˆ›äê‘þÍú‡Xn÷wFˆ™r—–¿G-ÿ›.î“çú6zô]P¤fʤùª…Ÿ®‹ù«U¬a00 å­Ñј)gEP¨Vg[ÓÉ"d†h6O4×ݲP5¦µP=¬å!ÑJ gaLn£gÉÚnóJ1 †Ã³vz¥,\wÁ"”I‹,‚›"ªµè è-Z5²–QŠ-VO•Å©ÈÏ9Ú‹N:¹%.Õz–¤‚Z²:ºx[Ž„QPb–’¦5º¥ª¯,Mo‰¥«#,ƒz°G–2nÙʤå¹pWô>.ò›‹¥Ý U-ë£KbEºÖo´·Û ¥P<.K4¥¬–ÿÝ%>ðh`VºUS*žsÿeûJ endstream endobj startxref 88975 %%EOF verilator-3.916/configure.ac0000664000177100017500000002400613206352634016014 0ustar wsnyderwsnyder# DESCRIPTION: Process this file with autoconf to produce a configure script. # # Copyright 2003-2017 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.916 2017-11-25]) # When releasing, also update header of Changes file # and commit using "devel release" or "Version bump" message AC_CONFIG_HEADER(src/config_build.h) AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc) AC_MSG_RESULT([configuring for $PACKAGE_STRING]) # Special Substitutions - CFG_WITH_DEFENV AC_MSG_CHECKING(whether to use 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_LINK_IFELSE( [AC_LANG_PROGRAM([#include ], [[int* a=new int; delete a; ]])], [], [AC_MSG_ERROR([$CXX does not seem to successfully compile a simple C++ program])]) AC_DEFUN([_MY_CXX_CHECK_FLAG], [# _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS $1 -Werror" AC_MSG_CHECKING([whether $CXX accepts $1]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include ], [[int* a=new int; delete a; ]])], [_my_result=yes if test -s conftest.err; then if grep -e "$1" conftest.err >/dev/null; then _my_result=no fi fi], [_my_result=no]) # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[an_error "intentional-error-for-test.h" ]],[])], [], # Ignore ok exit [if test -s conftest.err; then if grep -e "$1" conftest.err >/dev/null; then _my_result=no fi fi]) AC_MSG_RESULT($_my_result) CXXFLAGS="$ACO_SAVE_CXXFLAGS" ]) AC_DEFUN([_MY_CXX_CHECK_SET], [# _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$$1" = ""; then _MY_CXX_CHECK_FLAG($2) if test "$_my_result" = "yes" ; then $1="$2" fi fi ]) AC_DEFUN([_MY_CXX_CHECK_OPT], [# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable _MY_CXX_CHECK_FLAG($2) if test "$_my_result" = "yes" ; then $1="$$1 $2" fi ]) # Flag to select newest language standard supported # Macros work such that first option that passes is the one we take # gnu++14 is the newest that Verilator supports # std++03 is the oldest that Verilator supports _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++14) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++11) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++03) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++14) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++11) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++03) AC_SUBST(CFG_CXXFLAGS_STD_NEWEST) # And likewise oldest standard (same list above, backwards) # This is used for internal testing _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++03) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++11) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++14) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++03) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++11) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++14) _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++17) AC_SUBST(CFG_CXXFLAGS_STD_OLDEST) # Flags for compiling Verilator internals including parser, and Verilated files # These turn on extra warnings and are only used with 'configure --enable-ccwarn' _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wextra) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wfloat-conversion) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wlogical-op) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wthread-safety) AC_SUBST(CFG_CXXFLAGS_WEXTRA) # Flags for compiling Verilator internals including parser always _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-faligned-new) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-delete-null-pointer-checks) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-shadow) AC_SUBST(CFG_CXXFLAGS_SRC) # Flags for compiling Verilator parser always (in addition to above CFG_CXXFLAGS_SRC) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-char-subscripts) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-null-conversion) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused) AC_SUBST(CFG_CXXFLAGS_PARSER) # Flags for Verilated makefile # For example, -Wno-div-by-zero isn't in 4.1.2 # Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn # without this flag, even though there's a conditional to prevent the divide. # We still don't add no-div-by-zero as it throws message to stdout, though doesn't die. #_MY_CXX_CHECK_OPT(-Wno-div-by-zero) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow) AC_SUBST(CFG_CXXFLAGS_NO_UNUSED) # Set CFG_WITH_THREADED if can support threading AC_MSG_CHECKING(whether $CXX supports Verilated threads) ACO_SAVE_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $CFG_CXXFLAGS_STD_NEWEST $CFG_CXXFLAGS_NO_UNUSED" AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include ], [[ ]])], [_my_result=yes if test -s conftest.err; then if grep -e "$1" conftest.err >/dev/null; then _my_result=no fi fi], [_my_result=no]) CFG_WITH_THREADED=$_my_result AC_SUBST(CFG_WITH_THREADED) AC_MSG_RESULT($CFG_WITH_THREADED) # Checks for library functions. AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec], [AC_DEFINE([HAVE_STAT_NSEC],[1],[Defined if struct stat has st_mtim.tv_nsec])], [], [#include ]) # Checks for system services # Other install directories pkgdatadir=${datadir}/verilator AC_SUBST(pkgdatadir) pkgconfigdir=${datadir}/pkgconfig AC_SUBST(pkgconfigdir) AC_OUTPUT AC_MSG_RESULT([]) AC_MSG_RESULT([Now type 'make' (or sometimes 'gmake') to build Verilator.]) AC_MSG_RESULT([]) verilator-3.916/mkinstalldirs0000664000177100017500000000123412111011551016307 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.916/Artistic0000664000177100017500000002156112111011551015216 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.916/install-sh0000664000177100017500000001271113205574202015523 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.916/verilator.html0000664000177100017500000054434413206353161016433 0ustar wsnyderwsnyder

NAME

Verilator - Convert Verilog code to C++/SystemC

SYNOPSIS

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

DESCRIPTION

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

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

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

The resulting executable will perform the actual simulation.

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

ARGUMENT SUMMARY

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

    {file.v}                    Verilog package, module and top module filenames
    {file.c/cc/cpp}             Optional C++ files to compile in
    {file.a/o/so}               Optional C++ files to link in

     +1364-1995ext+<ext>        Use Verilog 1995 with file extension <ext>
     +1364-2001ext+<ext>        Use Verilog 2001 with file extension <ext>
     +1364-2005ext+<ext>        Use Verilog 2005 with file extension <ext>
     +1800-2005ext+<ext>        Use SystemVerilog 2005 with file extension <ext>
     +1800-2009ext+<ext>        Use SystemVerilog 2009 with file extension <ext>
     +1800-2012ext+<ext>        Use SystemVerilog 2012 with file extension <ext>
    --assert                    Enable all assertions
    --autoflush                 Flush streams after all $displays
    --bbox-sys                  Blackbox unknown $system calls
    --bbox-unsup                Blackbox unsupported language features
    --bin <filename>            Override Verilator binary
     -CFLAGS <flags>            C++ Compiler flags for makefile
    --cc                        Create C++ output
    --cdc                       Clock domain crossing analysis
    --clk <signal-name>         Mark specified signal as clock
    --compiler <compiler-name>  Tune for specified C++ compiler
    --converge-limit <loops>    Tune convergence settle time
    --coverage                  Enable all coverage
    --coverage-line             Enable line coverage
    --coverage-toggle           Enable toggle coverage
    --coverage-user             Enable SVL user coverage
    --coverage-underscore       Enable coverage of _signals
     -D<var>[=<value>]          Set preprocessor define
    --debug                     Enable debugging
    --debug-check               Enable debugging assertions
    --debugi <level>            Enable debugging at a specified level
    --debugi-<srcfile> <level>  Enable debugging a source file at a level
    --default-language <lang>   Default language to parse
     +define+<var>=<value>      Set preprocessor define
    --dump-tree                 Enable dumping .tree files
    --dump-treei <level>        Enable dumping .tree files at a level
    --dump-treei-<srcfile> <level>  Enable dumping .tree file at a source file at a level
     -E                         Preprocess, but do not compile
    --error-limit <value>       Abort after this number of errors
    --exe                       Link to create executable
     -F <file>                  Parse options from a file, relatively
     -f <file>                  Parse options from a file
     -FI <file>                 Force include of a file
     -G<name>=<value>           Overwrite toplevel parameter
    --gdb                       Run Verilator under GDB interactively
    --gdbbt                     Run Verilator under GDB for backtrace
    --getenv <var>              Get environment variable with defaults
    --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
    --l2-name <value>           Verilog scope name of the top module
    --language <lang>           Default language standard to parse
     +libext+<ext>+[ext]...     Extensions for finding modules
    --lint-only                 Lint, but do not make output
    --MMD                       Create .d dependency files
    --MP                        Create phony dependency targets
    --Mdir <directory>          Name of output object directory
    --mod-prefix <topname>      Name to prepend to lower classes
    --no-clk <signal-name>      Prevent marking specified signal as clock
    --no-decoration             Disable comments and symbol decorations
    --no-pins64                 Don't use vluint64_t's for 33-64 bit sigs
    --no-skip-identical         Disable skipping identical output
     +notimingchecks            Ignored
     -O0                        Disable optimizations
     -O3                        High performance optimizations
     -O<optimization-letter>    Selectable optimizations
     -o <executable>            Name of final executable
    --no-order-clock-delay      Disable ordering clock enable assignments
    --output-split <bytes>      Split .cpp files into pieces
    --output-split-cfuncs <statements>   Split .cpp functions
    --output-split-ctrace <statements>   Split tracing functions
     -P                         Disable line numbers and blanks with -E
    --pins-bv <bits>            Specify types for top level ports
    --pins-sc-uint              Specify types for top level ports
    --pins-sc-biguint           Specify types for top level ports
    --pins-uint8                Specify types for top level ports
    --pipe-filter <command>     Filter all input through a script
    --prefix <topname>          Name of top level class
    --profile-cfuncs            Name functions for profiling
    --private                   Debugging; see docs
    --public                    Debugging; see docs
     -pvalue+<name>=<value>     Overwrite toplevel parameter
    --relative-includes         Resolve includes relative to current file
    --no-relative-cfuncs        Disallow 'this->' in generated functions
    --report-unoptflat          Extra diagnostics for UNOPTFLAT
    --savable                   Enable model save-restore
    --sc                        Create SystemC output
    --stats                     Create statistics file
    --stats-vars                Provide statistics on variables
     -sv                        Enable SystemVerilog parsing
     +systemverilogext+<ext>    Synonym for +1800-2012ext+<ext>
    --top-module <topname>      Name of top level input module
    --trace                     Enable waveform creation
    --trace-depth <levels>      Depth of tracing
    --trace-max-array <depth>   Maximum bit width for tracing
    --trace-max-width <width>   Maximum array depth for tracing
    --trace-params              Enable tracing parameters
    --trace-structs             Enable tracing structure names
    --trace-underscore          Enable tracing of _signals
     -U<var>                    Undefine preprocessor define
    --unroll-count <loops>      Tune maximum loop iterations
    --unroll-stmts <stmts>      Tune maximum loop body size
    --unused-regexp <regexp>    Tune UNUSED lint signals
     -V                         Verbose version and config
     -v <filename>              Verilog library
     +verilog1995ext+<ext>      Synonym for +1364-1995ext+<ext>
     +verilog2001ext+<ext>      Synonym for +1364-2001ext+<ext>
    --vpi                       Enable VPI compiles
     -Wall                      Enable all style warnings
     -Werror-<message>          Convert warnings to errors
     -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>           Assign non-initial Xs to this value
    --x-initial <mode>          Assign initial 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.

--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, the cmos and tran gate primitives, deassign statements, and mixed edge errors. This may enable linting the rest of the design even when unsupported constructs are present.

--bin filename

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

-CFLAGS flags

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

--cc

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

--cdc

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

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

--clk signal-name

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

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

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

If clock signals are assigned to vectors and then later used individually, Verilator will attempt to decompose the vector and connect the single-bit clock signals directly. This should be transparent to the user.

--compiler compiler-name

Enables tunings and workarounds 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.dat.

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

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

--coverage-toggle

Specifies signal toggle coverage analysis code should be inserted.

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

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

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

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

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

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

--coverage-underscore

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

--coverage-user

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

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

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

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

--debug

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

--debug-check

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

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

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

--default-language value

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

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

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

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

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

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

--dump-tree

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

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

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

-E

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

--error-limit <value>

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

--exe

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

-F file

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

-f file

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

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

-FI <file>

Force include of the specified C++ header file. All generated C++ files will insert a #include of the specified file before any other includes. The specified file might be used to contain define prototypes of custom VL_VPRINTF functions, and may need to include verilatedos.h as this file is included before any other standard includes.

-Gname=value

Overwrites the given parameter of the toplevel module. The value is limited to basic data literals:

Verilog integer literals

The standard verilog integer literals are supported, so values like 32'h8, 2'b00, 4 etc. are allowed. Care must be taken that the single quote (I') is properly escaped in an interactive shell, e.g., as -GWIDTH=8\'hx.

C integer literals

It is also possible to use C integer notation, including hexadecimal (0x..), octal (0..) or binary (0b..) notation.

Double literals

Double literals must contain a dot (.) and/or an exponent (e).

Strings

String must in double quotes ("). On the command line it is required to escape them properly, e.g. as -GSTR="\"My String\"" or -GSTR='"My String"'.

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

--getenv variable

If the variable is declared in the environment, print it and exit immediately. Otherwise, if it's built into Verilator (e.g. VERILATOR_ROOT), print that and exit immediately. Otherwise, print a newline and exit immediately. This can be useful in makefiles. See also -V, and the various *.mk files.

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

--l2-name value

Instead of using the module name when showing Verilog scope, use the name provided. This allows simplifying some Verilator-embedded modeling methodologies. Default is an l2-name matching the top module. The default before 3.884 was "--l2-name v"

For example, the program "module t; initial $display("%m"); endmodule" will show by default "t". With "--l2-name v" it will print "v".

--language value

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

+libext+ext+ext...

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

--lint-only

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

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

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

--MMD

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

--MP

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

--Mdir directory

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

--mod-prefix topname

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

--no-clk <signal-name>

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

--no-decoration

When creating output Verilated code, minimize comments, whitespace, symbol names and other decorative items, at the cost of greatly reduced readability. This may assist C++ compile times. This will not typically change the ultimate model's performance, but may in some cases.

--no-pins64

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

--no-relative-cfuncs

Disable 'this->' references in generated functions, and instead Verilator will generate absolute references starting from 'vlTOPp->'. This prevents V3Combine from merging functions from multiple instances of the same module, so it can grow the instruction stream.

This is a work around for old compilers. Don't set this if your C++ compiler supports __restrict__ properly, as GCC 4.5.x and newer do. For older compilers, test if this switch gives you better performance or not.

Compilers which don't honor __restrict__ will suspect that 'this->' references and 'vlTOPp->' references may alias, and may write slow code with extra loads and stores to handle the (imaginary) aliasing. Using only 'vlTOPp->' references allows these old compilers to produce tight code.

--no-skip-identical

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

+notimingchecks

Ignored for compatibility with other simulators.

-O0

Disables optimization of the model.

-O3

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

-Ooptimization-letter

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

-o <executable>

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

--no-order-clock-delay

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

--output-split bytes

Enables splitting the output .cpp 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 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 files into multiple functions. Defaults to same setting as --output-split-cfuncs.

-P

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

--pins64

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

--pins-bv width

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

--pins-sc-uint

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

--pins-sc-biguint

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

--pins-uint8

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

--pipe-filter command

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

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

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

--prefix topname

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

--profile-cfuncs

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

--private

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

--public

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

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

-pvalue+name=value

Overwrites the given parameter(s) of the toplevel module. See -G for a detailed description.

--relative-includes

When a file references an include file, resolve the filename relative to the path of the referencing file, instead of relative to the current directory.

--report-unoptflat

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

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

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

    dot -Tpdf -O Vt_unoptflat_simple_2_35_unoptflat.dot

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

--savable

Enable including save and restore functions in the generated model.

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

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

Specifies SystemC output mode; see also --cc.

--stats

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

--stats-vars

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

-sv

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

+systemverilogext+ext

A synonym for +1800-2012ext+ext.

--top-module topname

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

--trace

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

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

--trace-depth levels

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

--trace-max-array depth

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

--trace-max-width width

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

--no-trace-params

Disable tracing of parameters.

--trace-structs

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

--trace-underscore

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

-Uvar

Undefines the given preprocessor symbol.

--unroll-count loops

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

--unroll-stmts statements

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

--unused-regexp regexp

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

-V

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

-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

--vpi

Enable use of VPI and linking against the verilated_vpi.cpp files.

-Wall

Enable all code style warnings, including code style warnings that are normally disabled by default. Equivelent to "-Wwarn-lint -Wwarn-style". Excludes some specialty warnings, i.e. IMPERFECTSCH.

-Werror-message

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

-Wfuture-message

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

-Wno-message

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

-Wno-lint

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

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

-Wno-style

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

-Wno-fatal

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

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

-Wwarn-message

Enables the specified warning message.

-Wwarn-lint

Enable all lint related warning messages (note by default they are already enabled), but do not affect style messages. This is equivalent to "-Wwarn-ALWCOMBORDER -Wwarn-BSSPACE -Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX -Wwarn-CMPCONST -Wwarn-COLONPLUS -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 controlled with --x-initial.

--x-initial 0
--x-initial fast
--x-initial unique (default)

Controls the two-state value that is used to initialize variables that are not otherwise initialized.

--x-initial=0, initializes all otherwise uninitialized variables to zero.

--x-initial=unique, the default, initializes variables using a function, which determines the value to use each initialization. This gives greatest flexibility and allows finding reset bugs. See "Unknown states"

--x-initial=fast, is best for performance, and initializes all variables to a state Verilator determines is optimal. This may allow further code optimizations, but will likely hide any code bugs relating to missing resets.

Note. This option applies only to initial values of variables. Initial values of clocks are set to 0 unless --x-initial-edge is specified.

--x-initial-edge

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

    reg  res_n = 1'b0;

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

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

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

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

-y dir

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

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

EXAMPLE C++ EXECUTION

We'll compile this example into C++.

    mkdir test_our
    cd test_our

    cat <<EOF >our.v
      module our;
         initial begin $display("Hello World"); $finish; end
      endmodule
    EOF

    cat <<EOF >sim_main.cpp
      #include "Vour.h"
      #include "verilated.h"
      int main(int argc, char** argv, char** env) {
          Verilated::commandArgs(argc, argv);
          Vour* top = new Vour;
          while (!Verilated::gotFinish()) { top->eval(); }
          delete top;
          exit(0);
      }
    EOF

See the README in the source kit for various ways to install or point to Verilator binaries. In brief, if you are running Verilator that came from your operating system (as an RPM), or did a "make install" to place Verilator into your default path, you do not need anything special in your environment, and should not have VERILATOR_ROOT set. However, if you installed Verilator from sources and want to run Verilator out of where you compiled Verilator, you need to point to the kit:

    # See above; don't do this if using an OS-distributed Verilator
    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

    make -j -C obj_dir -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

    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; to aid this Verilator can create a makefile dependency file. See the examples directory in the distribution.

EXAMPLE SYSTEMC EXECUTION

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

    mkdir test_our_sc
    cd test_our_sc

    cat <<EOF >our.v
      module our (clk);
         input clk;  // Clock is required to get initial activation
         always @ (posedge clk)
            begin $display("Hello World"); $finish; end
      endmodule
    EOF

    cat <<EOF >sc_main.cpp
      #include "Vour.h"
      int sc_main(int argc, char **argv) {
          Verilated::commandArgs(argc, argv);
          sc_clock clk ("clk",10, 0.5, 3, true);
          Vour* top;
          top = new Vour("top");
          top->clk(clk);
          while (!Verilated::gotFinish()) { sc_start(1, SC_NS); }
          delete top;
          exit(0);
      }
    EOF

See the README in the source kit for various ways to install or point to Verilator binaries. In brief, if you are running Verilator that came from your operating system (as an RPM), or did a "make install" to place Verilator into your default path, you do not need anything special in your environment, and should not have VERILATOR_ROOT set. However, if you installed Verilator from sources and want to run Verilator out of where you compiled Verilator, you need to point to the kit:

    # See above; don't do this if using an OS-distributed Verilator
    export VERILATOR_ROOT=/path/to/where/verilator/was/installed
    export PATH=$VERILATOR_ROOT/bin:$PATH

Now we run Verilator on our little example.

    verilator -Wall --sc our.v

We then can compile it

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

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

    export SYSTEMC_LIBDIR=/path/to/where/libsystemc.a/exists
    export LD_LIBRARY_PATH=$SYSTEMC_LIBDIR:$LD_LIBRARY_PATH
    # Might be needed if SystemC 2.3.0
    export SYSTEMC_CXX_FLAGS=-pthread

    g++ -L$SYSTEMC_LIBDIR ../sc_main.o Vour__ALL*.o verilated.o \
              -o Vour -lsystemc

And now we run it

    cd ..
    obj_dir/Vour

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

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

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

BENCHMARKING & OPTIMIZATION

For best performance, run Verilator with the "-O3 --x-assign=fast --x-initial=fast --noassert" flags. The -O3 flag will require longer compile times, and --x-assign=fast --x-initial=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 -fno-stack-protector" -f Vour.mk Vour__ALL.a

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

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

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

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

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

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

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

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

FILES

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

Verilator creates the following files in the output directory:

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

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

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

In certain optimization modes, it also creates:

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

It also creates internal files that can be mostly ignored:

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

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

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

ENVIRONMENT

LD_LIBRARY_PATH

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

OBJCACHE

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

SYSTEMC

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

SYSTEMC_ARCH

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

SYSTEMC_CXX_FLAGS

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

SYSTEMC_INCLUDE

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

SYSTEMC_LIBDIR

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

VCS_HOME

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

VERILATOR_BIN

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

VERILATOR_GDB

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

VERILATOR_ROOT

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

CONNECTING TO C++

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

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 <iostream>             // Need std::cout
        #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.

VPI is enabled with the verilator --vpi switch.

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 (i.e. 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 its 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.

For signal callbacks to work the main loop of the program must call VerilatedVpi::callValueCbs().

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.

    cat <<EOF >our.v
      module our (input clk);
         reg readme   /*verilator public_flat_rd*/;
         reg writeme  /*verilator public_flat_rw @(posedge clk) */;
         initial $finish;
      endmodule
    EOF

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

    cat <<EOF >sim_main.cpp
      #include "Vour.h"
      #include "verilated.h"
      #include "verilated_vpi.h"  // Required to get definitions

      vluint64_t main_time = 0;   // See comments in first example
      double sc_time_stamp () { return main_time; }

      void read_and_check() {
          vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"TOP.our.readme", NULL);
          if (!vh1) { vl_fatal(__FILE__, __LINE__, "sim_main", "No handle found"); }
          const char* name = vpi_get_str(vpiName, vh1);
          printf("Module name: %s\n", name);  // 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"
      }

      int main(int argc, char** argv, char** env) {
          Verilated::commandArgs(argc, argv);
          Vour* top = new Vour;
          Verilated::internalsDump();  // See scopes to help debug
          while (!Verilated::gotFinish()) {
              top->eval();
              VerilatedVpi::callValueCbs();  // For signal callbacks
              read_and_check();
          }
          delete top;
          exit(0);
      }
    EOF

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_on [-file "<filename>" [-lines <line> [ - <line> ]]]
coverage_off [-file "<filename>" [-lines <line> [ - <line> ]]]

Enable/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_on [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
lint_off [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]

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

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

If the -msg is omitted, all lint warnings (see list in -Wno-lint) are enabled/disabled. This will override all later lint warning enables for the specified region.

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

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

For tracing_off, cells below any module in the files/ranges specified will also not be traced.

LANGUAGE STANDARD SUPPORT

Verilog 2001 (IEEE 1364-2001) Support

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

Verilog 2005 (IEEE 1364-2005) Support

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

SystemVerilog 2005 (IEEE 1800-2005) Support

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

It also supports .name and .* interconnection.

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

SystemVerilog 2012 (IEEE 1800-2012) Support

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

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

Verilog AMS Support

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

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

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

Synthesis Directive Assertion Support

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

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

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

LANGUAGE EXTENSIONS

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

`__FILE__

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

`__LINE__

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

`error string

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

$c(string, ...);

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

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

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

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

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

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

`coverage_block_off

Specifies the entire begin/end block should be ignored for coverage analysis. Must be inside a basic block, e.g. within a begin/end pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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. Must be placed as a module item, e.g. directly inside a module/endmodule pair. 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 was specified.

/*verilator clock_enable*/

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

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

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

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

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

/*verilator coverage_block_off*/

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

/*verilator coverage_off*/

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

/*verilator coverage_on*/

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

/*verilator inline_module*/

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

/*verilator isolate_assignments*/

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

IE, with the following

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

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

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

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

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

/*verilator lint_on msg*/

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

/*verilator lint_restore*/

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

/*verilator lint_save*/

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

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

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

/*verilator no_inline_module*/

Specifies the module the comment appears in should not be inlined into any modules that use this module. This is useful especially at the top level module to reduce the size of the interface class, to aid compile time at a small performance loss.

/*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*/ (parameter)

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

    parameter [2:0] PARAM /*verilator public*/ = 2'b0;
/*verilator public*/ (typedef enum)

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

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

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

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

/*verilator public*/ (task/function)

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

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

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

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

/*verilator public_flat*/ (variable)

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

/*verilator public_flat_rd*/ (variable)

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

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

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

/*verilator public_module*/

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

/*verilator sc_clock*/

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

/*verilator sc_bv*/

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

/*verilator sformat*/

Attached to the final input of a function or task "input string" to indicate the function or task should pass all remaining arguments through $sformatf. This allows creation of DPI functions with $display like behavior. See the test_regress/t/t_dpi_display.v file for an example.

/*verilator tag <text...>*/

Attached after a variable or structure member to indicate opaque (to Verilator) text that should be passed through to the XML output as a tag, for use by downstream applications.

/*verilator tracing_off*/

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

/*verilator tracing_on*/

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

LANGUAGE LIMITATIONS

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

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

Synthesis Subset

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

        always @ (x)   y = x & z;

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

Signal Naming

To avoid conflicts with C symbol naming, any character in a signal name that is not alphanumeric nor a single underscore will be replaced by __0hh where hh is the hex code of the character. To avoid conflicts with Verilator's internal symbols, any double underscore are replaced with ___05F (5F is the hex code of an underscore.)

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, depending on --x-initial setting, are typically 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 (since typically control signals are active-high).

--x-assign applies to variables explicitly initialized or assigned to X. Uninitialized clocks are initialized to zero, while all other state holding variables are initialized to a random value. Event driven simulators will generally trigger an edge on a transition from X to 1 (posedge) or X to 0 (negedge). However, by default, since clocks are initialized to zero, Verilator will not trigger an initial negedge. Some code (particularly for reset) may rely on X->0 triggering an edge. The --x-initial-edge switch enables 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 buses [0:15] are not supported as they aren't easily made compatible with C++.

Gate Primitives

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

Specify blocks

All specify blocks and timing checks are ignored.

Array Initialization

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

Array Out of Bounds

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

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

Assertions

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

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

Language Keyword Limitations

This section describes specific limitations for each language keyword.

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

Fully supported.

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

Generally supported.

++, -- operators

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

'{} operator

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

cast operator

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

chandle

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

disable

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

inside

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

interface

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

priority if, unique if

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

specify specparam

All specify blocks and timing checks are ignored.

string

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

timeunit, timeprecision

All timing control statements are ignored.

uwire

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

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

Generally supported.

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

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

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

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

$finish, $stop

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

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

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

$fscanf, $sscanf

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

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

All specify blocks and timing checks are ignored.

$random

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

$readmemb, $readmemh

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

$test$plusargs, $value$plusargs

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

    Verilated::commandArgs(argc, argv);

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

$timeformat

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

ERRORS AND WARNINGS

Warnings may be disabled in three 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

Second, warnings may be disabled using a configuration file with a lint_off command. This is useful when a script is suppressing warnings and the Verilog source should not be changed.

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

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

This is not illegal in SystemVerilog, but a violation of good coding practice. Verilator reports this as an error, because 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.

BSSPACE

Warns that a backslash is followed by a space then a newline. Likely the intent was to have a backslash directly followed by a newline (e.g. when making a `define) and there's accidentally whitespace at the end of the line. If the space is not accidental, suggest removing the backslash in the code as it serves no function.

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

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.

COLONPLUS

Warns that a :+ is seen. Likely the intent was to use +: to select a range of bits. If the intent was a range that is explicitly positive, suggest adding a space, e.g. use ": +".

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

CDCRSTLOGIC

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

CLKDATA

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

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

CMPCONST

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

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

COMBDLY

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

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

DECLFILENAME

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

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

DEFPARAM

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

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

DETECTARRAY

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

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

ENDLABEL

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

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

GENCLK

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

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

IFDEPTH

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

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

IMPERFECTSCH

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

IMPLICIT

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

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

IMPURE

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

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

INCABSPATH

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

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

INITIALDLY

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

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

LITENDIAN

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

Also warns that a cell is declared with little endian range (i.e. [0:7] or [7]) and is connected to a N-wide signal. Based on IEEE the bits will likely be backwards from what you expect (i.e. cell [0] will connect to signal bit [N-1] not bit [0]).

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

MODDUP

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

MULTIDRIVEN

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

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

MULTITOP

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

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

PINCONNECTEMPTY

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

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

PINMISSING

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

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

PINNOCONNECT

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

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

REALCVT

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

REDEFMACRO

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

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

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

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

Warns that a selection index will go out of bounds:

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

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

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

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

    #100 $finish;

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

SYMRSVDWORD

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

SYNCASYNCNET

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

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

TASKNSVAR

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

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

Change this to:

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

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

UNDRIVEN

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

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

UNOPT

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

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

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

UNOPTFLAT

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

UNPACKED

Warns that unpacked structs and unions are not supported.

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

UNSIGNED

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

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

UNUSED

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

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

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

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

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

USERINFO, USERWARN, USERERROR, USERFATAL

A SystemVerilog elaboration-time assertion print was executed.

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 also compiles under Microsoft Visual C++ Version 7 or newer, but this is not tested every release.

Can you provide binaries?

Verilator is available as a RPM for Debian/Ubuntu, 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-commercial-simulator)?

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

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

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

Will Verilator output remain under my own license?

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

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

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

As is standard with Open Source, contributions back to Verilator will be placed under the Verilator copyright and LGPL/Artistic license. Small test cases will be released into the public domain so they can be used anywhere, and 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 generated 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, and very large commercial designs have topped 16GB.

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 examples/tracing_c/sim_main.cpp file of the distribution.

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

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

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

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

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

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

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

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

Verilator makes standard VCD (Value Change Dump) files. They are viewable with the public domain GtkWave (recommended) or Dinotrace (legacy) 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 solid-state disk, instead of to a network disk. Network disks are generally far slower.

How do I do coverage analysis?

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

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

At the end of your test, call VerilatedCov::write passing the name of the coverage data file (typically "logs/coverage.dat").

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

After running all of your tests, verilator_coverage is executed. Verilator_coverage reads the logs/coverage.dat 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 examples/tracing_c/logs directory. Grep for lines starting with '%' to see what lines Verilator believes need more coverage.

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

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

   `ifndef VERILATOR
      Something_Verilator_Dislikes;
   `endif

Most synthesis tools similarly define SYNTHESIS for you.

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. If you use --exe, this is done for you.

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?

Use a recent compiler. Newer compilers tend do be faster, with the now relatively old GCC 3.0 to 3.3 being horrible.

Compile in parallel on many machines and use caching; see 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. Also see the --output-split option.

To reduce the compile time of classes that use a Verilated module (e.g. a top CPP file) you may wish to add /*verilator no_inline_module*/ to your top level module. This will decrease the amount of code in the model's Verilated class, improving compile times of any instantiating top level C++ code, at a relatively small cost of execution performance.

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->our->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 Verilator 3.000 by rewriting Verilator from scratch in C++. This added many optimizations, yielding about a 2-5x performance gain.

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

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

AUTHORS

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

Wilson Snyder <wsnyder@wsnyder.org>

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

CONTRIBUTORS

Many people have provided ideas and other assistance with Verilator.

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

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

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

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

DISTRIBUTION

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

Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.

SEE ALSO

verilator_coverage, verilator_profcfunc, make,

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

and internals.txt in the distribution.

verilator-3.916/internals.txt0000664000177100017500000007361113206353160016267 0ustar wsnyderwsnyderNAME Verilator Internals INTRODUCTION This file discusses internal and programming details for Verilator. It's the first for reference for developers and debugging problems. See also the Verilator internals presentation at http://www.veripool.org. CODE FLOWS Verilator Flow The main flow of Verilator can be followed by reading the Verilator.cpp process() function: First, the files specified on the command line are read. Reading involves preprocessing, then lexical analysis with Flex and parsing with Bison. This produces an abstract syntax tree (AST) representation of the design, which is what is visible in the .tree files described below. Verilator then makes a series of passes over the AST, progressively refining and optimizing it. Cells in the AST first linked, which will read and parse additional files as above. Functions, variable and other references are linked to their definitions. Parameters are resolved and the design is elaborated. Verilator then performs many additional edits and optimizations on the hierarchical design. This includes coverage, assertions, X elimination, inlining, constant propagation, and dead code elimination. References in the design are then pseudo-flattened. Each module's variables and functions get "Scope" references. A scope reference is an occurrence of that un-flattened variable in the flattened hierarchy. A module that occurs only once in the hierarchy will have a single scope and single VarScope for each variable. A module that occurs twice will have a scope for each occurrence, and two VarScopes for each variable. This allows optimizations to proceed across the flattened design, while still preserving the hierarchy. Additional edits and optimizations proceed on the pseudo-flat design. These include module references, function inlining, loop unrolling, variable lifetime analysis, lookup table creation, always splitting, and logic gate simplifications (pushing inverters, etc). Verilator orders the code. Best case, this results in a single "eval" function which has all always statements flowing from top to bottom with no loops. Verilator mostly removes the flattening, so that code may be shared between multiple invocations of the same module. It localizes variables, combines identical functions, expands macros to C primitives, adds branch prediction hints, and performs additional constant propagation. Verilator finally writes the C++ modules. Key Classes Used in the Verilator Flow "AstNode" The AST is represented at the top level by the class "AstNode". This abstract class has derived classes for the individual components (e.g. "AstGenerate" for a generate block) or groups of components (e.g. "AstNodeFTask" for functions and tasks, which in turn has "AstFunc" and "AstTask" as derived classes). Each "AstNode" has pointers to up to four children, accessed by the "op1p" through "op4p" methods. These methods are then abstracted in a specific Ast* node class to a more specific name. For example with the "AstIf" node (for "if" statements), "ifsp" calls "op2p" to give the pointer to the AST for the "then" block, while "elsesp" calls "op3p" to give the pointer to the AST for the "else" block, or NULL if there is not one. "AstNode" has the concept of a next and previous AST - for example the next and previous statements in a block. Pointers to the AST for these statements (if they exist) can be obtained using the "back" and "next" methods. It is useful to remember that the derived class "AstNetlist" is at the top of the tree, so checking for this class is the standard way to see if you are at the top of the tree. By convention, each function/method uses the variable "nodep" as a pointer to the "AstNode" currently being processed. "AstNVisitor" The passes are implemented by AST visitor classes (see "Visitor Functions"). These are implemented by subclasses of the abstract class, "AstNVisitor". Each pass creates an instance of the visitor class, which in turn implements a method to perform the pass. "V3Graph" A number of passes use graph algorithms, and the class "V3Graph" is provided to represent those graphs. Graphs are directed, and algorithms are provided to manipulate the graphs and to output them in *GraphViz* dot format (see ). "V3Graph.h" provides documentation of this class. "V3GraphVertex" This is the base class for vertices in a graph. Vertices have an associated "fanout", "color" and "rank", which may be used in algorithms for ordering the graph. A generic "user"/"userp" member variable is also provided. Virtual methods are provided to specify the name, color, shape and style to be used in dot output. Typically users provide derived classes from "V3GraphVertex" which will reimplement these methods. Iterators are provided to access in and out edges. Typically these are used in the form: for (V3GraphEdge *edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { "V3GraphEdge" This is the base class for directed edges between pairs of vertices. Edges have an associated "weight" and may also be made "cutable". A generic "user"/"userp" member variable is also provided. Accessors, "fromp" and "top" return the "from" and "to" vertices respectively. Virtual methods are provided to specify the label, color and style to be used in dot output. Typically users provided derived classes from "V3GraphEdge" which will reimplement these methods. "V3GraphAlg" This is the base class for graph algorithms. It implements a "bool" method, "followEdge" which algorithms can use to decide whether an edge is followed. This method returns true if the graph edge has weight greater than one and a user function, "edgeFuncp" (supplied in the constructor) returns "true". A number of predefined derived algorithm classes and access methods are provided and documented in "V3GraphAlg.cpp". Verilated Flow The evaluation loop outputted by Verilator is designed to allow a single function to perform evaluation under most situations. On the first evaluation, the Verilated code calls initial blocks, and then "settles" the modules, by evaluating functions (from always statements) until all signals are stable. On other evaluations, the Verilated code detects what input signals have changes. If any are clocks, it calls the appropriate sequential functions (from always @ posedge statements). Interspersed with sequential functions it calls combo functions (from always @*). After this is complete, it detects any changes due to combo loops or internally generated clocks, and if one is found must reevaluate the model again. For SystemC code, the eval() function is wrapped in a SystemC SC_METHOD, sensitive to all inputs. (Ideally it would only be sensitive to clocks and combo inputs, but tracing requires all signals to cause evaluation, and the performance difference is small.) If tracing is enabled, a callback examines all variables in the design for changes, and writes the trace for each change. To accelerate this process the evaluation process records a bitmask of variables that might have changed; if clear, checking those signals for changes may be skipped. CODING CONVENTIONS Indentation style To match the indentation of Verilator C++ sources, use 4 spaces per level, and leave tabs at 8 columns, so every other indent level is a tab stop. All files should contain the magic header to insure standard indentation: // -*- mode: C++; c-file-style: "cc-mode" -*- This sets indentation to the cc-mode defaults. (Verilator predates a CC-mode change of several years ago which overrides the defaults with GNU style indentation; the c-set-style undoes that.) The "astgen" script Some of the code implementing passes is extremely repetitive, and must be implemented for each sub-class of "AstNode". However, while repetitive, there is more variability than can be handled in C++ macros. In Verilator this is implemented by using a Perl script, "astgen" to pre-process the C++ code. For example in "V3Const.cpp" this is used to implement the "visit()" functions for each binary operation using the TREEOP macro. The original C++ source code is transformed into C++ code in the "obj_opt" and "obj_dbg" sub-directories (the former for the optimized version of Verilator, the latter for the debug version). So for example "V3Const.cpp" into "V3Const__gen.cpp". Visitor Functions Verilator uses the *Visitor* design pattern to implement its refinement and optimization passes. This allows separation of the pass algorithm from the AST on which it operates. Wikipedia provides an introduction to the concept at . As noted above, all visitors are derived classes of "AstNVisitor". All derived classes of "AstNode" implement the "accept" method, which takes as argument a reference to an instance or a "AstNVisitor" derived class and applies the visit method of the "AstNVisitor" to the invoking AstNode instance (i.e. "this"). One possible difficulty is that a call to "accept" may perform an edit which destroys the node it receives as argument. The "acceptSubtreeReturnEdits" method of "AstNode" is provided to apply "accept" and return the resulting node, even if the original node is destroyed (if it is not destroyed it will just return the original node). The behavior of the visitor classes is achieved by overloading the "visit" function for the different "AstNode" derived classes. If a specific implementation is not found, the system will look in turn for overloaded implementations up the inheritance hierarchy. For example calling "accept" on "AstIf" will look in turn for: void visit (AstIf* nodep) void visit (AstNodeIf* nodep) void visit (AstNodeStmt* nodep) void visit (AstNode* nodep) There are three ways data is passed between visitor functions. 1. A visitor-class member variable. This is generally for passing "parent" information down to children. "m_modp" is a common example. It's set to NULL in the constructor, where that node ("AstModule" visitor) sets it, then the children are iterated, then it's cleared. Children under an "AstModule" will see it set, while nodes elsewhere will see it clear. If there can be nested items (for example an "AstFor" under an "AstFor") the variable needs to be save-set-restored in the "AstFor" visitor, otherwise exiting the lower for will lose the upper for's setting. 2. User attributes. Each "AstNode" (Note. The AST node, not the visitor) has five user attributes, which may be accessed as an integer using the "user1()" through "user5()" methods, or as a pointer (of type "AstNUser") using the "user1p()" through "user5p()" methods (a common technique lifted from graph traversal packages). A visitor first clears the one it wants to use by calling "AstNode::user#ClearTree()", then it can mark any node's user() with whatever data it wants. Readers just call "nodep->user()", but may need to cast appropriately, so you'll often see "nodep->userp()->castSOMETYPE()". At the top of each visitor are comments describing how the "user()" stuff applies to that visitor class. For example: // NODE STATE // Cleared entire netlist // AstModule::user1p() // bool. True to inline this module This says that at the "AstNetlist" "user1ClearTree()" is called. Each "AstModule"'s "user1()" is used to indicate if we're going to inline it. These comments are important to make sure a "user#()" on a given "AstNode" type is never being used for two different purposes. Note that calling "user#ClearTree" is fast, it doesn't walk the tree, so it's ok to call fairly often. For example, it's commonly called on every module. 3. Parameters can be passed between the visitors in close to the "normal" function caller to callee way. This is the second "vup" parameter of type "AstNUser" that is ignored on most of the visitor functions. V3Width does this, but it proved more messy than the above and is deprecated. (V3Width was nearly the first module written. Someday this scheme may be removed, as it slows the program down to have to pass vup everywhere.) Iterators "AstNode" provides a set of iterators to facilitate walking over the tree. Each takes two arguments, a visitor, "v", of type "AstNVisitor" and an optional pointer user data, "vup", of type "AstNUser*". The second is one of the ways to pass parameters to visitors described in "Visitor Functions", but its use is now deprecated and should *not* be used for new visitor classes. "iterate()" This just applies the "accept" method of the "AstNode" to the visitor function. "iterateAndNextIgnoreEdit" Applies the "accept" method of each "AstNode" in a list (i.e. connected by "nextp" and "backp" pointers). "iterateAndNext" Applies the "accept" method of each "AstNode" in a list. If a node is edited by the call to "accept", apply "accept" again, until the node does not change. "iterateListBackwards" Applies the "accept" method of each "AstNode" in a list, starting with the last one. "iterateChildren" Apply the "iterateAndNext" method on each child "op1p" through "op4p" in turn. "iterateChildrenBackwards" Apply the "iterateListBackwards" method on each child "op1p" through "op4p" in turn. Caution on Using Iterators When Child Changes Visitors often replace one node with another node; V3Width and V3Const are major examples. A visitor which is the parent of such a replacement needs to be aware that calling iteration may cause the children to change. For example: // nodep->lhsp() is 0x1234000 nodep->lhsp()->iterateAndNext(...); // and under covers nodep->lhsp() changes // nodep->lhsp() is 0x5678400 nodep->lhsp()->iterateAndNext(...); Will work fine, as even if the first iterate causes a new node to take the place of the lhsp(), that edit will update nodep->lhsp() and the second call will correctly see the change. Alternatively: lp = nodep->lhsp(); // nodep->lhsp() is 0x1234000, lp is 0x1234000 lp->iterateAndNext(...); **lhsp=NULL;** // and under covers nodep->lhsp() changes // nodep->lhsp() is 0x5678400, lp is 0x1234000 lp->iterateAndNext(...); This will cause bugs or a core dump, as lp is a dangling pointer. Thus it is advisable to set lhsp=NULL shown in the *'s above to make sure these dangles are avoided. Another alternative used in special cases mostly in V3Width is to use acceptSubtreeReturnEdits, which operates on a single node and returns the new pointer if any. Note acceptSubtreeReturnEdits does not follow nextp() links. lp = lp->acceptSubtreeReturnEdits() Identifying derived classes A common requirement is to identify the specific "AstNode" class we are dealing with. For example a visitor might not implement separate "visit" methods for "AstIf" and "AstGenIf", but just a single method for the base class: void visit (AstNodeIf* nodep, AstNUser* vup) However that method might want to specify additional code if it is called for "AstGenIf". Verilator does this by providing a "castSOMETYPE()" method for each possible node type, using C++ "dynamic_cast". This either returns a pointer to the object cast to that type (if it is of class "SOMETYPE", or a derived class of "SOMETYPE") or else NULL. So our "visit" method could use: if (nodep->castAstGenIf()) { } A common test is for "AstNetlist", which is the node at the root of the AST. TESTING For an overview of how to write a test see the BUGS section of the Verilator primary manual. It is important to add tests for failures as well as success (for example to check that an error message is correctly triggered). Tests that fail should by convention have the suffix "_bad" in their name, and include "fails => 1" in either their "compile" or "execute" step as appropriate. Preparing to Run Tests For all tests to pass you must install the following packages: * SystemC to compile the SystemC outputs, see http://systemc.org * Parallel::Forker from CPAN to run tests in parallel, you can install this with e.g. "sudo cpan install Parallel::Forker". * vcddiff to find differences in VCD outputs. See the readme at https://github.com/veripool/vcddiff Controlling the Test Driver Test drivers are written in PERL. All invoke the main test driver script, which can provide detailed help on all the features available when writing a test driver. test_regress/t/driver.pl --help For convenience, a summary of the most commonly used features is provided here. All drivers require a call to "compile" subroutine to compile the test. For run-time tests, this is followed by a call to the "execute" subroutine. Both of these functions can optionally be provided with a hash table as argument specifying additional options. The test driver assumes by default that the source Verilog file name matches the PERL driver name. So a test whose driver is "t/t_mytest.pl" will expect a Verilog source file "t/t_mytest.v". This can be changed using the "top_filename" subroutine, for example top_filename("t/t_myothertest.v"); By default all tests will run with major simulators (Icarus Verilog, NC, VCS, ModelSim) as well as Verilator, to allow results to be compared. However if you wish a test only to be used with Verilator, you can use the following: $Self->{vlt} or $Self->skip("Verilator only test"); Of the many options that can be set through arguments to "compiler" and "execute", the following are particularly useful: "verilator_flags2" A list of flags to be passed to verilator when compiling. "fails" Set to 1 to indicate that the compilation or execution is intended to fail. For example the following would specify that compilation requires two defines and is expected to fail. compile ( verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"], fails => 1, ); Regression Testing for Developers Developers will also want to call ./configure with two extra flags: --enable-ccwarn Causes the build to stop on warnings as well as errors. A good way to ensure no sloppy code gets added, however it can be painful when it comes to testing, since third party code used in the tests (e.g. SystemC) may not be warning free. --enable-longtests In addition to the standard C, SystemC examples, also run the tests in the "test_regress" directory when using *make test*. This is disabled by default as SystemC installation problems would otherwise falsely indicate a Verilator problem. When enabling the long tests, some additional PERL modules are needed, which you can install using cpan. cpan install Unix::Processors There are some traps to avoid when running regression tests * When checking the MANIFEST, the test will barf on unexpected code in the Verilator tree. So make sure to keep any such code outside the tree. * Not all Linux systems install Perldoc by default. This is needed for the *--help* option to Verilator, and also for regression testing. This can be installed using cpan: cpan install Pod::Perldoc Many Linux systems also offer a standard package for this. Red Hat/Fedora/Centos offer *perl-Pod-Perldoc*, while Debian/Ubuntu/Linux Mint offer *perl-doc*. * Running regression may exhaust resources on some Linux systems, particularly file handles and user processes. Increase these to respectively 16,384 and 4,096. The method of doing this is system dependent, but on Fedora Linux it would require editing the "/etc/security/limits.conf" file as root. DEBUGGING --debug When you run with --debug there are two primary output file types placed into the obj_dir, .tree and .dot files. .dot output Dot files are dumps of internal graphs in Graphviz dot format. When a dot file is dumped, Verilator will also print a line on stdout that can be used to format the output, for example: dot -Tps -o ~/a.ps obj_dir/Vtop_foo.dot You can then print a.ps. You may prefer gif format, which doesn't get scaled so can be more useful with large graphs. For dynamic graph viewing consider ZGRViewer . If you know of better viewers let us know; ZGRViewer isn't great for large graphs. .tree output Tree files are dumps of the AST Tree and are produced between every major algorithmic stage. An example: NETLIST 0x90fb00 {a0} 1: MODULE 0x912b20 {a8} top L2 [P] *1:2: VAR 0x91a780 {a22} @dt=0xa2e640(w32) out_wide [O] WIRE 1:2:1: BASICDTYPE 0xa2e640 {e24} @dt=this(sw32) integer kwd=integer range=[31:0] The following summarizes the above example dump, with more detail on each field in the section below. "1:2:" indicates the hierarchy of the "VAR" is the "op2p" pointer under the "MODULE", which in turn is the "op1p" pointer under the "NETLIST" "VAR" is the AstNodeType. "0x91a780" is the address of this node. "" means the 74th edit to the netlist was the last modification to this node. "{a22}" indicates this node is related to line 22 in the source filename "a", where "a" is the first file read, "z" the 26th, and "aa" the 27th. "@dt=0x..." indicates the address of the data type this node contains. "w32" indicates the width is 32 bits. "out_wide" is the name of the node, in this case the name of the variable. "[O]" are flags which vary with the type of node, in this case it means the variable is an output. In more detail the following fields are dumped common to all nodes. They are produced by the "AstNode::dump()" method: Tree Hierarchy The dump lines begin with numbers and colons to indicate the child node hierarchy. As noted above in "Key Classes Used in the Verilator Flow", "AstNode" has lists of items at the same level in the AST, connected by the "nextp()" and "prevp()" pointers. These appear as nodes at the same level. For example after inlining: NETLIST 0x929c1c8 {a0} w0 1: MODULE 0x92bac80 {e14} w0 TOP_t L1 [P] 1:1: CELLINLINE 0x92bab18 {e14} w0 v -> t 1:1: CELLINLINE 0x92bc1d8 {e24} w0 v__DOT__i_test_gen -> test_gen ... 1: MODULE 0x92b9bb0 {e47} w0 test_gen L3 ... AstNode type The textual name of this node AST type (always in capitals). Many of these correspond directly to Verilog entities (for example "MODULE" and "TASK"), but others are internal to Verialtor (for example "NETLIST" and "BASICDTYPE"). Address of the node A hexadecimal address of the node in memory. Useful for examining with the debugger. Last edit number Of the form "" or "" , where "nnnn" is the number of the last edit to modify this node. The trailing "#" indicates the node has been edited since the last tree dump (which typically means in the last refinement or optimization pass). GDB can watch for this, see "Debugging with GDB". Source file and line Of the form "{xxnnnn}", where C{xx} is the filename letter (or letters) and "nnnn" is the line number within that file. The first file is "a", the 26th is "z", the 27th is "aa" and so on. User pointers Shows the value of the node's user1p...user5p, if non-NULL. Data type Many nodes have an explicit data type. "@dt=0x..." indicates the address of the data type (AstNodeDType) this node uses. If a data type is present and is numeric, it then prints the width of the item. This field is a sequence of flag characters and width data as follows: "s" if the node is signed. "d" if the node is a double (i.e a floating point entity). "w" always present, indicating this is the width field. "u" if the node is unsized. "/nnnn" if the node is unsized, where "nnnn" is the minimum width. Name of the entity represented by the node if it exists For example for a "VAR" it is the name of the variable. Many nodes follow these fields with additional node specific information. Thus the "VARREF" node will print either "[LV]" or "[RV]" to indicate a left value or right value, followed by the node of the variable being referred to. For example: 1:2:1:1: VARREF 0x92c2598 {e24} w0 clk [RV] <- VAR 0x92a2e90 {e18} w0 clk [I] INPUT In general, examine the "dump()" method in "V3AstNodes.cpp" of the node type in question to determine additional fields that may be printed. The "MODULE" has a list of "CELLINLINE" nodes referred to by its "op1p()" pointer, connected by "nextp()" and "prevp()" pointers. Similarly the "NETLIST" has a list of modules referred to by its "op1p()" pointer. Debugging with GDB The test_regress/driver.pl script accepts --debug --gdb to start Verilator under gdb and break when an error is hit or the program is about to exit. You can also use --debug --gdbbt to just backtrace and then exit gdb. To debug the Verilated executable, use --gdbsim. If you wish to start Verilator under GDB (or another debugger), then you can use --debug and look at the underlying invocation of verilator_dgb. For example t/t_alw_dly.pl --debug shows it invokes the command: ../verilator_bin_dbg --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v Start GDB, then "start" with the remaining arguments. gdb ../verilator_bin_dbg ... (gdb) start --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v > obj_dir/t_alw_dly/vlt_compile.log ... Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc) at ../Verilator.cpp:615 615 ios::sync_with_stdio(); (gdb) You can then continue execution with breakpoints as required. To break at a specific edit number which changed a node (presumably to find what made a line in the tree dumps): watch AstNode::s_editCntGbl==#### To print a node: pn nodep # or: call nodep->dumpGdb() # aliased to "pn" in src/.gdbinit pnt nodep # or: call nodep->dumpTreeGdb() # aliased to "pnt" in src/.gdbinit When GDB halts, it is useful to understand that the backtrace will commonly show the iterator functions between each invocation of "visit" in the backtrace. You will typically see a frame sequence something like ... visit() iterateChildren() iterateAndNext() accept() visit() ... ADDING A NEW FEATURE Generally what would you do to add a new feature? 1. File a bug (if there isn't already) so others know what you're working on. 2. Make a testcase in the test_regress/t/t_EXAMPLE format, see TESTING. 3. If grammar changes are needed, look at the git version of VerilogPerl's src/VParseGrammar.y, as this grammar supports the full SystemVerilog language and has a lot of back-and-forth with Verilator's grammar. Copy the appropriate rules to src/verilog.y and modify the productions. 4. If a new Ast type is needed, add it to V3AstNodes.h. Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree file which you can examine to see if the parsing worked. See also the sections above on debugging. Modify the later visitor functions to process the new feature as needed. Adding a new pass For more substantial changes you may need to add a new pass. The simplest way to do this is to copy the ".cpp" and ".h" files from an existing pass. You'll need to add a call into your pass from the "process()" function in "src/verilator.cpp". To get your pass to build you'll need to add its binary filename to the list in "src/Makefile_obj.in" and reconfigure. DISTRIBUTION The latest version is available from . Copyright 2008-2017 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.916/configure0000775000177100017500000070564313206352662015453 0ustar wsnyderwsnyder#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Verilator 3.916 2017-11-25. # # # Copyright (C) 1992-1996, 1998-2012 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 # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # 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 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+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} 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 test -x / || 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 : export CONFIG_SHELL # 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 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+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 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_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_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; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # 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 -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' 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 as_test_x='test -x' as_executable_p=as_fn_executable_p # 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.916 2017-11-25' PACKAGE_STRING='Verilator 3.916 2017-11-25' PACKAGE_BUGREPORT='' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS pkgconfigdir pkgdatadir CFG_WITH_THREADED CFG_CXXFLAGS_NO_UNUSED CFG_CXXFLAGS_PARSER CFG_CXXFLAGS_SRC CFG_CXXFLAGS_WEXTRA CFG_CXXFLAGS_STD_OLDEST CFG_CXXFLAGS_STD_NEWEST 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 runstatedir 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' runstatedir='${localstatedir}/run' 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 ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -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 runstatedir 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 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.916 2017-11-25 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] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --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.916 2017-11-25:";; 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.916 2017-11-25 generated by GNU Autoconf 2.69 Copyright (C) 2012 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 # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext 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>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_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. 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_link # ac_fn_cxx_check_member LINENO AGGR MEMBER VAR INCLUDES # ------------------------------------------------------ # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_cxx_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" 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=\$$4 { $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_member 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.916 2017-11-25, which was generated by GNU Autoconf 2.69. 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 # When releasing, also update header of Changes file # and commit using "devel release" or "Version bump" message ac_config_headers="$ac_config_headers src/config_build.h" ac_config_files="$ac_config_files Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc" { $as_echo "$as_me:${as_lineno-$LINENO}: result: configuring for $PACKAGE_STRING" >&5 $as_echo "configuring for $PACKAGE_STRING" >&6; } # Special Substitutions - CFG_WITH_DEFENV { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use hardcoded paths" >&5 $as_echo_n "checking whether to use 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 as_fn_executable_p "$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 as_fn_executable_p "$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 as_fn_executable_p "$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 as_fn_executable_p "$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 as_fn_executable_p "$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 as_fn_executable_p "$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 struct stat; /* 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 as_fn_executable_p "$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 as_fn_executable_p "$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 as_fn_executable_p "$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 as_fn_executable_p "$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 as_fn_executable_p "$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 as_fn_executable_p "$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" as_fn_executable_p "$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" as_fn_executable_p "$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 cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : else as_fn_error $? "$CXX does not seem to successfully compile a simple C++ program" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # Flag to select newest language standard supported # Macros work such that first option that passes is the one we take # gnu++14 is the newest that Verilator supports # std++03 is the oldest that Verilator supports # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_NEWEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=gnu++14 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=gnu++14" >&5 $as_echo_n "checking whether $CXX accepts -std=gnu++14... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=gnu++14" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=gnu++14" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_NEWEST="-std=gnu++14" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_NEWEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=gnu++11 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=gnu++11" >&5 $as_echo_n "checking whether $CXX accepts -std=gnu++11... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=gnu++11" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=gnu++11" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_NEWEST="-std=gnu++11" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_NEWEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=gnu++03 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=gnu++03" >&5 $as_echo_n "checking whether $CXX accepts -std=gnu++03... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=gnu++03" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=gnu++03" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_NEWEST="-std=gnu++03" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_NEWEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=c++14 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=c++14" >&5 $as_echo_n "checking whether $CXX accepts -std=c++14... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=c++14" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=c++14" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_NEWEST="-std=c++14" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_NEWEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=c++11 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=c++11" >&5 $as_echo_n "checking whether $CXX accepts -std=c++11... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=c++11" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=c++11" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_NEWEST="-std=c++11" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_NEWEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=c++03 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=c++03" >&5 $as_echo_n "checking whether $CXX accepts -std=c++03... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=c++03" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=c++03" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_NEWEST="-std=c++03" fi fi # And likewise oldest standard (same list above, backwards) # This is used for internal testing # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_OLDEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=std++03 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=std++03" >&5 $as_echo_n "checking whether $CXX accepts -std=std++03... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=std++03" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=std++03" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_OLDEST="-std=std++03" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_OLDEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=std++11 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=std++11" >&5 $as_echo_n "checking whether $CXX accepts -std=std++11... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=std++11" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=std++11" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_OLDEST="-std=std++11" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_OLDEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=std++14 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=std++14" >&5 $as_echo_n "checking whether $CXX accepts -std=std++14... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=std++14" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=std++14" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_OLDEST="-std=std++14" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_OLDEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=gnu++03 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=gnu++03" >&5 $as_echo_n "checking whether $CXX accepts -std=gnu++03... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=gnu++03" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=gnu++03" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_OLDEST="-std=gnu++03" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_OLDEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=gnu++11 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=gnu++11" >&5 $as_echo_n "checking whether $CXX accepts -std=gnu++11... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=gnu++11" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=gnu++11" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_OLDEST="-std=gnu++11" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_OLDEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=gnu++14 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=gnu++14" >&5 $as_echo_n "checking whether $CXX accepts -std=gnu++14... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=gnu++14" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=gnu++14" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_OLDEST="-std=gnu++14" fi fi # _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options # If it does, set variable to flag, only if not previously set if test "$CFG_CXXFLAGS_STD_OLDEST" = ""; then # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -std=gnu++17 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -std=gnu++17" >&5 $as_echo_n "checking whether $CXX accepts -std=gnu++17... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-std=gnu++17" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-std=gnu++17" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_STD_OLDEST="-std=gnu++17" fi fi # Flags for compiling Verilator internals including parser, and Verilated files # These turn on extra warnings and are only used with 'configure --enable-ccwarn' # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wextra -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wextra" >&5 $as_echo_n "checking whether $CXX accepts -Wextra... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wextra" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wextra" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_WEXTRA="$CFG_CXXFLAGS_WEXTRA -Wextra" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wfloat-conversion -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wfloat-conversion" >&5 $as_echo_n "checking whether $CXX accepts -Wfloat-conversion... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wfloat-conversion" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wfloat-conversion" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_WEXTRA="$CFG_CXXFLAGS_WEXTRA -Wfloat-conversion" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wlogical-op -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wlogical-op" >&5 $as_echo_n "checking whether $CXX accepts -Wlogical-op... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wlogical-op" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wlogical-op" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_WEXTRA="$CFG_CXXFLAGS_WEXTRA -Wlogical-op" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wthread-safety -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wthread-safety" >&5 $as_echo_n "checking whether $CXX accepts -Wthread-safety... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wthread-safety" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wthread-safety" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_WEXTRA="$CFG_CXXFLAGS_WEXTRA -Wthread-safety" fi # Flags for compiling Verilator internals including parser always # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Qunused-arguments -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Qunused-arguments" >&5 $as_echo_n "checking whether $CXX accepts -Qunused-arguments... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Qunused-arguments" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Qunused-arguments" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -Qunused-arguments" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -faligned-new -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -faligned-new" >&5 $as_echo_n "checking whether $CXX accepts -faligned-new... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-faligned-new" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-faligned-new" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -faligned-new" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -fno-delete-null-pointer-checks -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -fno-delete-null-pointer-checks" >&5 $as_echo_n "checking whether $CXX accepts -fno-delete-null-pointer-checks... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-fno-delete-null-pointer-checks" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-fno-delete-null-pointer-checks" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -fno-delete-null-pointer-checks" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin 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. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused-parameter" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-unused-parameter" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -Wno-unused-parameter" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wno-undefined-bool-conversion -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-undefined-bool-conversion" >&5 $as_echo_n "checking whether $CXX accepts -Wno-undefined-bool-conversion... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-undefined-bool-conversion" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-undefined-bool-conversion" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -Wno-undefined-bool-conversion" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wno-shadow -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-shadow" >&5 $as_echo_n "checking whether $CXX accepts -Wno-shadow... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-shadow" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-shadow" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -Wno-shadow" fi # Flags for compiling Verilator parser always (in addition to above CFG_CXXFLAGS_SRC) # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin 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. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-char-subscripts" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-char-subscripts" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_PARSER="$CFG_CXXFLAGS_PARSER -Wno-char-subscripts" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wno-null-conversion -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-null-conversion" >&5 $as_echo_n "checking whether $CXX accepts -Wno-null-conversion... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-null-conversion" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-null-conversion" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_PARSER="$CFG_CXXFLAGS_PARSER -Wno-null-conversion" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wno-parentheses-equality -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-parentheses-equality" >&5 $as_echo_n "checking whether $CXX accepts -Wno-parentheses-equality... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-parentheses-equality" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-parentheses-equality" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_PARSER="$CFG_CXXFLAGS_PARSER -Wno-parentheses-equality" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wno-unused -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-unused" >&5 $as_echo_n "checking whether $CXX accepts -Wno-unused... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-unused" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_PARSER="$CFG_CXXFLAGS_PARSER -Wno-unused" fi # Flags for Verilated makefile # For example, -Wno-div-by-zero isn't in 4.1.2 # 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 # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -faligned-new -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -faligned-new" >&5 $as_echo_n "checking whether $CXX accepts -faligned-new... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-faligned-new" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-faligned-new" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -faligned-new" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -fbracket-depth=4096 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -fbracket-depth=4096" >&5 $as_echo_n "checking whether $CXX accepts -fbracket-depth=4096... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-fbracket-depth=4096" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-fbracket-depth=4096" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -fbracket-depth=4096" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Qunused-arguments -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Qunused-arguments" >&5 $as_echo_n "checking whether $CXX accepts -Qunused-arguments... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Qunused-arguments" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Qunused-arguments" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Qunused-arguments" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wno-parentheses-equality -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-parentheses-equality" >&5 $as_echo_n "checking whether $CXX accepts -Wno-parentheses-equality... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-parentheses-equality" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-parentheses-equality" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-parentheses-equality" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin 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. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-sign-compare" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-sign-compare" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-sign-compare" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin 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. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-uninitialized" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-uninitialized" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-uninitialized" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin 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. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused-but-set-variable" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-unused-but-set-variable" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-unused-but-set-variable" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin 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. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused-parameter" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-unused-parameter" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-unused-parameter" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin 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. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused-variable" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-unused-variable" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-unused-variable" fi # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options # If it does, append flag to variable # _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options # Set $_my_result appropriately ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems # new/delete is needed to find -faligned-new link problem on Darwin CXXFLAGS="$CXXFLAGS -Wno-shadow -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-shadow" >&5 $as_echo_n "checking whether $CXX accepts -Wno-shadow... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int* a=new int; delete a; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-shadow" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # GCC is annoying, trying to be helpful, it postpones unknown -Wno- # options if there's no error We want to see them regardless, so try # forcing an error and see if we get a gcc warning cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ an_error "intentional-error-for-test.h" int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else # Ignore ok exit if test -s conftest.err; then if grep -e "-Wno-shadow" conftest.err >/dev/null; then _my_result=no fi fi 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; } CXXFLAGS="$ACO_SAVE_CXXFLAGS" if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-shadow" fi # Set CFG_WITH_THREADED if can support threading { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports Verilated threads" >&5 $as_echo_n "checking whether $CXX supports Verilated threads... " >&6; } ACO_SAVE_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $CFG_CXXFLAGS_STD_NEWEST $CFG_CXXFLAGS_NO_UNUSED" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "$1" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFG_WITH_THREADED=$_my_result { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CFG_WITH_THREADED" >&5 $as_echo "$CFG_WITH_THREADED" >&6; } # Checks for library functions. ac_fn_cxx_check_member "$LINENO" "struct stat" "st_mtim.tv_nsec" "ac_cv_member_struct_stat_st_mtim_tv_nsec" "#include " if test "x$ac_cv_member_struct_stat_st_mtim_tv_nsec" = xyes; then : $as_echo "#define HAVE_STAT_NSEC 1" >>confdefs.h fi # Checks for system services # Other install directories pkgdatadir=${datadir}/verilator pkgconfigdir=${datadir}/pkgconfig cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' 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 # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # 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.916 2017-11-25, which was generated by GNU Autoconf 2.69. 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.916 2017-11-25 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/config_build.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config_build.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/Makefile_obj") CONFIG_FILES="$CONFIG_FILES src/Makefile_obj" ;; "include/verilated.mk") CONFIG_FILES="$CONFIG_FILES include/verilated.mk" ;; "include/verilated_config.h") CONFIG_FILES="$CONFIG_FILES include/verilated_config.h" ;; "verilator.pc") CONFIG_FILES="$CONFIG_FILES verilator.pc" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Now type 'make' (or sometimes 'gmake') to build Verilator." >&5 $as_echo "Now type 'make' (or sometimes 'gmake') to build Verilator." >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } verilator-3.916/include/0000775000177100017500000000000013206353162015144 5ustar wsnyderwsnyderverilator-3.916/include/verilated_vpi.cpp0000664000177100017500000021055313205574202020512 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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. /// /// Use "verilator --vpi" to add this to the Makefile for the linker. /// /// Code available from: http://www.veripool.org/verilator /// //========================================================================= #if VM_SC # include "verilated_sc.h" #endif #include "verilated.h" #include "verilated_vpi.h" #include #include #include //====================================================================== // Internal constants #define VL_DEBUG_IF_PLI VL_DEBUG_IF #define VL_VPI_LINE_SIZE 8192 //====================================================================== // Internal macros #define _VL_VPI_INTERNAL VerilatedVpiImp::error_info()->setMessage(vpiInternal)->setMessage #define _VL_VPI_SYSTEM VerilatedVpiImp::error_info()->setMessage(vpiSystem )->setMessage #define _VL_VPI_ERROR VerilatedVpiImp::error_info()->setMessage(vpiError )->setMessage #define _VL_VPI_WARNING VerilatedVpiImp::error_info()->setMessage(vpiWarning )->setMessage #define _VL_VPI_NOTICE VerilatedVpiImp::error_info()->setMessage(vpiNotice )->setMessage #define _VL_VPI_ERROR_RESET VerilatedVpiImp::error_info()->resetError // Not supported yet #define _VL_VPI_UNIMP() \ _VL_VPI_ERROR(__FILE__,__LINE__,Verilated::catName("Unsupported VPI function: ",VL_FUNC)); //====================================================================== // Implementation // Base VPI handled object class VerilatedVpio { // MEM MANGLEMENT static VL_THREAD_LOCAL vluint8_t* t_freeHead; public: // CONSTRUCTORS VerilatedVpio() {} virtual ~VerilatedVpio() {} inline static void* operator new(size_t size) VL_MT_SAFE { // 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 const size_t chunk = 96; if (VL_UNLIKELY(size>chunk)) VL_FATAL_MT(__FILE__,__LINE__,"", "increase chunk"); if (VL_LIKELY(t_freeHead)) { vluint8_t* newp = t_freeHead; t_freeHead = *((vluint8_t**)newp); return newp+8; } else { // +8: 8 bytes for next vluint8_t* newp = reinterpret_cast(::operator new(chunk+8)); return newp+8; } } inline static void operator delete(void* obj, size_t size) VL_MT_SAFE { vluint8_t* oldp = ((vluint8_t*)obj)-8; *((void**)oldp) = t_freeHead; t_freeHead = oldp; } // MEMBERS static inline VerilatedVpio* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } inline vpiHandle castVpiHandle() { return reinterpret_cast(this); } // ACCESSORS virtual const char* name() const { return ""; } virtual const char* fullname() const { return ""; } virtual const char* defname() const { return ""; } virtual vluint32_t type() const { return 0; } virtual vluint32_t size() const { return 0; } virtual const VerilatedRange* rangep() const { return NULL; } virtual vpiHandle dovpi_scan() { return 0; } }; typedef PLI_INT32 (*VerilatedPliCb)(struct t_cb_data *); class VerilatedVpioCb : public VerilatedVpio { t_cb_data m_cbData; s_vpi_value m_value; QData m_time; public: // cppcheck-suppress uninitVar // m_value VerilatedVpioCb(const t_cb_data* cbDatap, QData time) : m_cbData(*cbDatap), m_time(time) { m_value.format = cbDatap->value ? cbDatap->value->format : vpiSuppressVal; m_cbData.value = &m_value; } virtual ~VerilatedVpioCb() {} static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual vluint32_t type() const { 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: explicit VerilatedVpioConst(vlsint32_t num) : m_num(num) {} virtual ~VerilatedVpioConst() {} static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual vluint32_t type() const { return vpiUndefined; } vlsint32_t num() const { return m_num; } }; class VerilatedVpioRange : public VerilatedVpio { const VerilatedRange* m_range; vlsint32_t m_iteration; public: explicit VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {} virtual ~VerilatedVpioRange() {} static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual vluint32_t type() const { return vpiRange; } virtual 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: explicit VerilatedVpioScope(const VerilatedScope* scopep) : m_scopep(scopep) {} virtual ~VerilatedVpioScope() {} static inline VerilatedVpioScope* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual vluint32_t type() const { return vpiScope; } const VerilatedScope* scopep() const { return m_scopep; } virtual const char* name() const { return m_scopep->name(); } virtual const char* fullname() const { return m_scopep->name(); } }; class VerilatedVpioVar : public VerilatedVpio { const VerilatedVar* m_varp; const VerilatedScope* m_scopep; vluint8_t* m_prevDatap; // Previous value of data, for cbValueChange union { vluint8_t u8[4]; vluint32_t u32; } m_mask; // memoized variable mask vluint32_t m_entSize; // memoized variable size protected: void* m_varDatap; // varp()->datap() adjusted for array entries vlsint32_t m_index; const VerilatedRange& get_range() const { // Determine number of dimensions and return outermost return (m_varp->dims()>1) ? m_varp->array() : m_varp->range(); } public: VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep) : m_varp(varp), m_scopep(scopep), m_index(0) { m_prevDatap = NULL; m_mask.u32 = VL_MASK_I(varp->range().elements()); m_entSize = varp->entSize(); m_varDatap = varp->datap(); } virtual ~VerilatedVpioVar() { if (m_prevDatap) { delete [] m_prevDatap; m_prevDatap = NULL; } } static inline VerilatedVpioVar* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } const VerilatedVar* varp() const { return m_varp; } const VerilatedScope* scopep() const { return m_scopep; } vluint32_t mask() const { return m_mask.u32; } vluint8_t mask_byte(int idx) { return m_mask.u8[idx & 3]; } vluint32_t entSize() const { return m_entSize; } vluint32_t index() { return m_index; } virtual vluint32_t type() const { if (varp()->vldir() != vpiNoDirection) return vpiPort; return (varp()->dims()>1) ? vpiMemory : vpiReg; // but might be wire, logic } virtual vluint32_t size() const { return get_range().elements(); } virtual const VerilatedRange* rangep() const { return &get_range(); } virtual const char* name() const { return m_varp->name(); } virtual const char* fullname() const { static VL_THREAD_LOCAL std::string out; out = std::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 vluint32_t type() const { return vpiMemoryWord; } virtual vluint32_t size() const { return varp()->range().elements(); } virtual const VerilatedRange* rangep() const { return &(varp()->range()); } virtual const char* fullname() const { static VL_THREAD_LOCAL std::string out; char num[20]; sprintf(num,"%d",m_index); out = std::string(scopep()->name())+"."+name()+"["+num+"]"; return out.c_str(); } }; class VerilatedVpioVarIter : public VerilatedVpio { const VerilatedScope* m_scopep; VerilatedVarNameMap::const_iterator m_it; bool m_started; public: explicit VerilatedVpioVarIter(const VerilatedScope* scopep) : m_scopep(scopep), m_started(false) { } virtual ~VerilatedVpioVarIter() {} static inline VerilatedVpioVarIter* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual vluint32_t type() const { return vpiIterator; } virtual vpiHandle dovpi_scan() { if (VL_LIKELY(m_scopep->varsp())) { VerilatedVarNameMap* varsp = m_scopep->varsp(); if (VL_UNLIKELY(!m_started)) { m_it = varsp->begin(); m_started=true; } else if (VL_UNLIKELY(m_it == varsp->end())) return 0; else ++m_it; if (m_it == varsp->end()) return 0; return ((new VerilatedVpioVar(&(m_it->second), m_scopep)) ->castVpiHandle()); } else { return 0; // End of list - only one deep } } }; class VerilatedVpioMemoryWordIter : public VerilatedVpio { const vpiHandle m_handle; const VerilatedVar* m_varp; vlsint32_t m_iteration; vlsint32_t m_direction; bool m_done; public: VerilatedVpioMemoryWordIter(const vpiHandle handle, const VerilatedVar* varp) : m_handle(handle), m_varp(varp), m_iteration(varp->array().right()), m_direction(VL_LIKELY(varp->array().left()>varp->array().right())?1:-1), m_done(false) { } virtual ~VerilatedVpioMemoryWordIter() {} static inline VerilatedVpioMemoryWordIter* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual vluint32_t type() const { 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 std::pair& a, const std::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 VerilatedVpiImp { enum { CB_ENUM_MAX_VALUE = cbAtEndOfSimTime+1 }; // Maxium callback reason typedef std::list VpioCbList; typedef std::set,VerilatedVpiTimedCbsCmp > VpioTimedCbs; struct product_info { PLI_BYTE8* product; }; 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 VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread static VerilatedVpiImp s_s; // Singleton public: VerilatedVpiImp() { m_errorInfop=NULL; } ~VerilatedVpiImp() {} static void assertOneCheck() { s_s.m_assertOne.check(); } 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_MT(__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(std::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(std::make_pair(cbp->time(),cbp)); if (VL_LIKELY(it != s_s.m_timedCbs.end())) { s_s.m_timedCbs.erase(it); } } static void callTimedCbs() VL_MT_UNSAFE_ONE { assertOneCheck(); 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_DBG_MSGF("- vpi: timed_callback %p\n",vop);); (vop->cb_rtnp()) (vop->cb_datap()); } else { ++it; } } } static QData cbNextDeadline() { VpioTimedCbs::const_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_DBG_MSGF("- vpi: reason_callback %d %p\n",reason,vop);); (vop->cb_rtnp()) (vop->cb_datap()); } } static void callValueCbs() VL_MT_UNSAFE_ONE { assertOneCheck(); VpioCbList& cbObjList = s_s.m_cbObjLists[cbValueChange]; typedef std::set VpioVarSet; VpioVarSet 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_DBG_MSGF("- vpi: 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_DBG_MSGF("- vpi: 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 (VpioVarSet::const_iterator it=update.begin(); it!=update.end(); ++it) { memcpy((*it)->prevDatap(), (*it)->varDatap(), (*it)->entSize()); } } static VerilatedVpiError* error_info() VL_MT_UNSAFE_ONE; // getter for vpi error info }; class VerilatedVpiError { //// Container for vpi error info t_vpi_error_info m_errorInfo; bool m_flag; char m_buff[VL_VPI_LINE_SIZE]; void setError(PLI_BYTE8 *message, PLI_BYTE8 *code, PLI_BYTE8 *file, PLI_INT32 line) { m_errorInfo.message = message; m_errorInfo.file = file; m_errorInfo.line = line; m_errorInfo.code = code; do_callbacks(); } void do_callbacks() { if (getError()->level >= vpiError && Verilated::fatalOnVpiError()) { // Stop on vpi error/unsupported vpi_unsupported(); } // We need to run above code first because in the case that the callback executes further vpi // functions we will loose the error as it will be overwritten. VerilatedVpiImp::callCbs(cbPLIError); } public: VerilatedVpiError() : m_flag(false) { m_buff[0] = '\0'; m_errorInfo.product = (PLI_BYTE8*)Verilated::productName(); } ~VerilatedVpiError() {} static void selfTest() VL_MT_UNSAFE_ONE; VerilatedVpiError* setMessage(PLI_INT32 level) { m_flag=true; m_errorInfo.level = level; return this; } void setMessage(std::string file, PLI_INT32 line, std::string message, ...) { static VL_THREAD_LOCAL std::string filehold; va_list args; va_start(args, message); VL_VSNPRINTF(m_buff, sizeof(m_buff), message.c_str(), args); va_end(args); m_errorInfo.state = vpiPLI; filehold = file; setError((PLI_BYTE8*)m_buff, NULL, (PLI_BYTE8*)filehold.c_str(), line); } p_vpi_error_info getError() { if (m_flag) return &m_errorInfo; return NULL; } void resetError() { m_flag=false; } static void vpi_unsupported() { // Not supported yet p_vpi_error_info error_info_p = VerilatedVpiImp::error_info()->getError(); if (error_info_p) { VL_FATAL_MT(error_info_p->file, error_info_p->line, "", error_info_p->message); return; } VL_FATAL_MT(__FILE__, __LINE__, "", "vpi_unsupported called without error info set"); } static const char* strFromVpiVal(PLI_INT32 vpiVal) VL_MT_SAFE; static const char* strFromVpiObjType(PLI_INT32 vpiVal) VL_MT_SAFE; static const char* strFromVpiMethod(PLI_INT32 vpiVal) VL_MT_SAFE; static const char* strFromVpiCallbackReason(PLI_INT32 vpiVal) VL_MT_SAFE; static const char* strFromVpiProp(PLI_INT32 vpiVal) VL_MT_SAFE; }; //====================================================================== VerilatedVpiImp VerilatedVpiImp::s_s; // Singleton VL_THREAD_LOCAL vluint8_t* VerilatedVpio::t_freeHead = NULL; //====================================================================== // VerilatedVpi implementation void VerilatedVpi::callTimedCbs() VL_MT_UNSAFE_ONE { VerilatedVpiImp::callTimedCbs(); } void VerilatedVpi::callValueCbs() VL_MT_UNSAFE_ONE { VerilatedVpiImp::callValueCbs(); } //====================================================================== // VerilatedVpiImp implementation VerilatedVpiError* VerilatedVpiImp::error_info() VL_MT_UNSAFE_ONE { VerilatedVpiImp::assertOneCheck(); if (VL_UNLIKELY(!s_s.m_errorInfop)) { s_s.m_errorInfop = new VerilatedVpiError(); } return s_s.m_errorInfop; } //====================================================================== // VerilatedVpiError Methods const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) VL_MT_SAFE { static const char* const 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) VL_MT_SAFE { static const char* const 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) VL_MT_SAFE { static const char* const 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 || vpiValreason) { 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_DBG_MSGF("- vpi: vpi_register_cb %d %p delay=%" VL_PRI64 "u\n",cb_data_p->reason,vop,time);); VerilatedVpiImp::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_DBG_MSGF("- vpi: vpi_register_cb %d %p\n",cb_data_p->reason,vop);); VerilatedVpiImp::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_DBG_MSGF("- vpi: vpi_remove_cb %p\n",object);); VerilatedVpiImp::assertOneCheck(); 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) { VerilatedVpiImp::cbTimedRemove(vop); } else { VerilatedVpiImp::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) { VerilatedVpiImp::assertOneCheck(); _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!namep)) return NULL; VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_handle_by_name %s %p\n",namep,scope);); VerilatedVpioScope* voScopep = VerilatedVpioScope::castp(scope); const VerilatedVar* varp; const VerilatedScope* scopep; std::string scopeAndName = namep; if (voScopep) { scopeAndName = std::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(); std::string scopename; const char* dotp = strrchr(namep, '.'); if (VL_LIKELY(dotp)) { baseNamep = dotp+1; scopename = std::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_DBG_MSGF("- vpi: vpi_handle_by_index %p %d\n",object, indx);); VerilatedVpiImp::assertOneCheck(); 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_DBG_MSGF("- vpi: vpi_handle %d %p\n",type,object);); VerilatedVpiImp::assertOneCheck(); _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_DBG_MSGF("- vpi: vpi_iterate %d %p\n",type,object);); VerilatedVpiImp::assertOneCheck(); _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_DBG_MSGF("- vpi: vpi_scan %p\n",object);); VerilatedVpiImp::assertOneCheck(); _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_DBG_MSGF("- vpi: vpi_get %d %p\n",property,object);); VerilatedVpiImp::assertOneCheck(); _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_DBG_MSGF("- vpi: vpi_get_str %d %p\n",property,object);); VerilatedVpiImp::assertOneCheck(); 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_LOCAL char outStr[1+VL_MULS_MAX_WORDS*32]; // Maximum required size is for binary string, one byte per bit plus null termination // cppcheck-suppress variableScope static VL_THREAD_LOCAL int outStrSz = sizeof(outStr)-1; VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_get_value %p\n",object);); VerilatedVpiImp::assertOneCheck(); _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_LOCAL t_vpi_vecval out[VL_MULS_MAX_WORDS*2]; value_p->value.vector = out; switch (vop->varp()->vltype()) { case VLVT_UINT8: out[0].aval = *(reinterpret_cast(vop->varDatap())); out[0].bval = 0; return; case VLVT_UINT16: out[0].aval = *(reinterpret_cast(vop->varDatap())); out[0].bval = 0; return; case VLVT_UINT32: out[0].aval = *(reinterpret_cast(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_MT(__FILE__,__LINE__,"", "vpi_get_value with more than VL_MULS_MAX_WORDS; increase and recompile"); } WDataInP datap = (reinterpret_cast(vop->varDatap())); for (int i=0; i(vop->varDatap())); out[1].aval = static_cast(data>>VL_ULL(32)); out[1].bval = 0; out[0].aval = static_cast(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 = (reinterpret_cast(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 = (reinterpret_cast(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 : VL_SNPRINTF(outStr, outStrSz+1, "%hhu", static_cast(*(reinterpret_cast(vop->varDatap())))); return; case VLVT_UINT16: VL_SNPRINTF(outStr, outStrSz+1, "%hu", static_cast(*(reinterpret_cast(vop->varDatap())))); return; case VLVT_UINT32: VL_SNPRINTF(outStr, outStrSz+1, "%u", static_cast(*(reinterpret_cast(vop->varDatap())))); return; case VLVT_UINT64: VL_SNPRINTF(outStr, outStrSz+1, "%llu", static_cast(*(reinterpret_cast(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 = (reinterpret_cast(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; 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 = (reinterpret_cast(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 = *(reinterpret_cast(vop->varDatap())); return; case VLVT_UINT16: value_p->value.integer = *(reinterpret_cast(vop->varDatap())); return; case VLVT_UINT32: value_p->value.integer = *(reinterpret_cast(vop->varDatap())); return; case VLVT_WDATA: // FALLTHRU case VLVT_UINT64: // FALLTHRU default: value_p->value.integer = 0; _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_DBG_MSGF("- vpi: vpi_put_value %p %p\n",object, value_p);); VerilatedVpiImp::assertOneCheck(); _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_DBG_MSGF("- vpi: vpi_put_value name=%s fmt=%d vali=%d\n", vop->fullname(), value_p->format, value_p->value.integer); VL_DBG_MSGF("- vpi: 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: *(reinterpret_cast(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask(); return object; case VLVT_UINT16: *(reinterpret_cast(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask(); return object; case VLVT_UINT32: *(reinterpret_cast(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 = (reinterpret_cast(vop->varDatap())); for (int i=0; ivalue.vector[i].aval; if (i==(words-1)) { datap[i] &= vop->mask(); } } return object; } case VLVT_UINT64: { *(reinterpret_cast(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 = (reinterpret_cast(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 = (reinterpret_cast(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 : *(reinterpret_cast(vop->varDatap())) = val & vop->mask(); break; case VLVT_UINT16: *(reinterpret_cast(vop->varDatap())) = val & vop->mask(); break; case VLVT_UINT32: *(reinterpret_cast(vop->varDatap())) = val & vop->mask(); break; case VLVT_UINT64: *(reinterpret_cast(vop->varDatap())) = val; (reinterpret_cast(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 = (reinterpret_cast(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 = (reinterpret_cast(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: *(reinterpret_cast(vop->varDatap())) = vop->mask() & value_p->value.integer; return object; case VLVT_UINT16: *(reinterpret_cast(vop->varDatap())) = vop->mask() & value_p->value.integer; return object; case VLVT_UINT32: *(reinterpret_cast(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) { VerilatedVpiImp::assertOneCheck(); // cppcheck-suppress nullPointer 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(); WData 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) { VerilatedVpiImp::assertOneCheck(); _VL_VPI_ERROR_RESET(); // reset vpi error status return VL_FOPEN_S(filenamep,"wb"); } PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) { VerilatedVpiImp::assertOneCheck(); _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, ...) { VerilatedVpiImp::assertOneCheck(); _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, ...) { VerilatedVpiImp::assertOneCheck(); _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) { VerilatedVpiImp::assertOneCheck(); _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) { VerilatedVpiImp::assertOneCheck(); FILE* fp = VL_CVT_I_FP(mcd); _VL_VPI_ERROR_RESET(); // reset vpi error status // cppcheck-suppress nullPointer if (VL_UNLIKELY(!fp)) return 0; int chars = vfprintf(fp, format, ap); return chars; } PLI_INT32 vpi_flush(void) { VerilatedVpiImp::assertOneCheck(); _VL_VPI_ERROR_RESET(); // reset vpi error status Verilated::flushCall(); return 0; } PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) { VerilatedVpiImp::assertOneCheck(); 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 VerilatedVpiImp::assertOneCheck(); p_vpi_error_info _error_info_p = VerilatedVpiImp::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) { VerilatedVpiImp::assertOneCheck(); _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_DBG_MSGF("- vpi: vpi_release_handle %p\n",object);); VerilatedVpiImp::assertOneCheck(); 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_MT_SAFE { VerilatedVpiImp::assertOneCheck(); _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_DBG_MSGF("- vpi: vpi_control %d\n",operation);); VerilatedVpiImp::assertOneCheck(); _VL_VPI_ERROR_RESET(); // reset vpi error status switch (operation) { case vpiFinish: { VL_FINISH_MT(__FILE__,__LINE__,"*VPI*"); return 1; } case vpiStop: { VL_STOP_MT(__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; } verilator-3.916/include/verilated.mk.in0000664000177100017500000001442513205574202020066 0ustar wsnyderwsnyder# -*- Makefile -*- ###################################################################### # DESCRIPTION: Makefile commands for all verilated target files # # Copyright 2003-2017 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. ###################################################################### PERL = @PERL@ CXX = @CXX@ LINK = @CXX@ AR = ar RANLIB = ranlib CFG_WITH_CCWARN = @CFG_WITH_CCWARN@ CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@ # Select newest language CFG_CXXFLAGS_STD_NEWEST = @CFG_CXXFLAGS_STD_NEWEST@ # Select oldest language (for Verilator internal testing only) CFG_CXXFLAGS_STD_OLDEST = @CFG_CXXFLAGS_STD_OLDEST@ # Compiler flags to use to turn off unused and generated code warnings, such as -Wno-div-by-zero CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@ # Compiler flags that turn on extra warnings CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@ ###################################################################### # Programs SP_INCLUDER = $(VERILATOR_INCLUDER) VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer ###################################################################### # Make checks ifneq ($(words $(CURDIR)),1) $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') endif ###################################################################### # C Preprocessor flags # Add -MMD -MP if you're using a recent version of GCC. VK_CPPFLAGS_ALWAYS += \ -MMD \ -I$(VERILATOR_ROOT)/include \ -I$(VERILATOR_ROOT)/include/vltstd \ -DVL_PRINTF=printf \ -DVM_COVERAGE=$(VM_COVERAGE) \ -DVM_SC=$(VM_SC) \ -DVM_TRACE=$(VM_TRACE) \ $(CFG_CXXFLAGS_NO_UNUSED) \ ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users VK_CPPFLAGS_WALL += -Wall $(CFG_CXXFLAGS_WEXTRA) -Werror endif CPPFLAGS += -I. $(VK_CPPFLAGS_WALL) $(VK_CPPFLAGS_ALWAYS) VPATH += .. VPATH += $(VERILATOR_ROOT)/include VPATH += $(VERILATOR_ROOT)/include/vltstd #OPT = -ggdb -DPRINTINITSTR -DDETECTCHANGE #OPT = -ggdb -DPRINTINITSTR CPPFLAGS += $(OPT) CPPFLAGS += $(M32) LDFLAGS += $(M32) # Allow upper level user makefiles to specify flags they want. # These aren't ever set by Verilator, so users are free to override them. CPPFLAGS += $(USER_CPPFLAGS) LDFLAGS += $(USER_LDFLAGS) LDLIBS += $(USER_LDLIBS) # Add flags from -CFLAGS and -LDFLAGS on Verilator command line CPPFLAGS += $(VM_USER_CFLAGS) LDFLAGS += $(VM_USER_LDFLAGS) LDLIBS += $(VM_USER_LDLIBS) # See the benchmarking section of bin/verilator. # Support class optimizations. This includes the tracing and symbol table. # SystemC takes minutes to optimize, thus it is off by default. #OPT_SLOW = # Fast path optimizations. Most time is spent in these classes. #OPT_FAST = -O2 -fstrict-aliasing #OPT_FAST = -O #OPT_FAST = ####################################################################### ##### Aggregates VM_CLASSES += $(VM_CLASSES_FAST) $(VM_CLASSES_SLOW) VM_SUPPORT += $(VM_SUPPORT_FAST) $(VM_SUPPORT_SLOW) ####################################################################### ##### SystemC builds ifeq ($(VM_SC),1) CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE) LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR) SC_LIBS = -lsystemc ifneq ($(wildcard $(SYSTEMC_LIBDIR)/*numeric_bit*),) # Systemc 1.2.1beta SC_LIBS += -lnumeric_bit -lqt endif endif ####################################################################### ##### Threaded builds ifneq ($(VM_THREADS),0) ifneq ($(VM_THREADS),) # Need C++11 at least, so always default to newest CPPFLAGS += -DVL_THREADED $(CFG_CXXFLAGS_STD_NEWEST) endif endif ####################################################################### ##### Stub preproc: ####################################################################### ##### C/H builds LIBS += -lm -lstdc++ ####################################################################### # Overall Objects Linking VK_CLASSES_H = $(addsuffix .h, $(VM_CLASSES)) VK_CLASSES_CPP = $(addsuffix .cpp, $(VM_CLASSES)) VK_SUPPORT_CPP = $(addsuffix .cpp, $(VM_SUPPORT)) VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES)) VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW)) ifneq ($(VM_PARALLEL_BUILDS),1) # Fast building, all .cpp's in one fell swoop # This saves about 5 sec per module, but can be slower if only a little changes VK_OBJS += $(VM_PREFIX)__ALLcls.o $(VM_PREFIX)__ALLsup.o all_cpp: $(VM_PREFIX)__ALLcls.cpp $(VM_PREFIX)__ALLsup.cpp $(VM_PREFIX)__ALLcls.cpp: $(VK_CLASSES_CPP) $(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@ $(VM_PREFIX)__ALLsup.cpp: $(VK_SUPPORT_CPP) $(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@ else #Slow way of building... Each .cpp file by itself VK_OBJS += $(addsuffix .o, $(VM_CLASSES) $(VM_SUPPORT)) endif $(VM_PREFIX)__ALL.a: $(VK_OBJS) @echo " Archiving" $@ ... $(AR) r $@ $^ $(RANLIB) $@ ###################################################################### ### Compile rules ifneq ($(VM_DEFAULT_RULES),0) $(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 $@ $< $(VM_PREFIX)%__Slow.o: $(VM_PREFIX)%__Slow.cpp $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $< $(VM_PREFIX)%.o: $(VM_PREFIX)%.cpp $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $< endif #Default rule embedded in make: #.cpp.o: # $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< ###################################################################### ### Debugging debug-make:: @echo @echo VM_PREFIX: $(VM_PREFIX) @echo VM_CLASSES_FAST: $(VM_CLASSES_FAST) @echo VM_CLASSES_SLOW: $(VM_CLASSES_SLOW) @echo VM_SUPPORT_FAST: $(VM_SUPPORT_FAST) @echo VM_SUPPORT_SLOW: $(VM_SUPPORT_SLOW) @echo VM_GLOBAL_FAST: $(VM_GLOBAL_FAST) @echo VM_GLOBAL_SLOW: $(VM_GLOBAL_SLOW) @echo CPPFLAGS: $(CPPFLAGS) @echo ###################################################################### ### Detect out of date files and rebuild. DEPS := $(wildcard *.d) ifneq ($(DEPS),) include $(DEPS) endif verilator-3.916/include/verilated_cov_key.h0000664000177100017500000001554713205574202021026 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2017 by Wilson Snyder. This program is free software; // you can redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief Coverage item keys /// //============================================================================= #ifndef _VERILATED_COV_KEY_H_ #define _VERILATED_COV_KEY_H_ 1 #include "verilatedos.h" #include //============================================================================= // Data used to edit below file, using vlcovgen #define VLCOVGEN_ITEM(string_parsed_by_vlcovgen) VLCOVGEN_ITEM("name=>'col0_name', short=>'C0', group=>1, default=>undef, descr=>'The column title for the header line of this column'") VLCOVGEN_ITEM("name=>'col1_name', short=>'C1', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'col2_name', short=>'C2', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'col3_name', short=>'C3', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'column', short=>'n', group=>1, default=>0, descr=>'Column number for the item. Used to disambiguate multiple coverage points on the same line number'") VLCOVGEN_ITEM("name=>'filename', short=>'f', group=>1, default=>undef, descr=>'Filename of the item'") VLCOVGEN_ITEM("name=>'groupdesc', short=>'d', group=>1, default=>'', descr=>'Description of the covergroup this item belongs to'") VLCOVGEN_ITEM("name=>'groupname', short=>'g', group=>1, default=>'', descr=>'Group name of the covergroup this item belongs to'") VLCOVGEN_ITEM("name=>'groupcmt', short=>'O', group=>1, default=>'', ") VLCOVGEN_ITEM("name=>'per_instance',short=>'P', group=>1, default=>0, descr=>'True if every hierarchy is independently counted; otherwise all hierarchies will be combined into a single count'") VLCOVGEN_ITEM("name=>'row0_name', short=>'R0', group=>1, default=>undef, descr=>'The row title for the header line of this row'") VLCOVGEN_ITEM("name=>'row1_name', short=>'R1', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'row2_name', short=>'R2', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'row3_name', short=>'R3', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'table', short=>'T', group=>1, default=>undef, descr=>'The name of the table for automatically generated tables'") VLCOVGEN_ITEM("name=>'thresh', short=>'s', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'type', short=>'t', group=>1, default=>'', descr=>'Type of coverage (block, line, fsm, etc)'") // Bin attributes VLCOVGEN_ITEM("name=>'col0', short=>'c0', group=>0, default=>undef, descr=>'The (enumeration) value name for this column in a table cross' ") VLCOVGEN_ITEM("name=>'col1', short=>'c1', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'col2', short=>'c2', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'col3', short=>'c3', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'comment', short=>'o', group=>0, default=>'', descr=>'Textual description for the item'") VLCOVGEN_ITEM("name=>'hier', short=>'h', group=>0, default=>'', descr=>'Hierarchy path name for the item'") VLCOVGEN_ITEM("name=>'limit', short=>'L', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'lineno', short=>'l', group=>0, default=>0, descr=>'Line number for the item'") VLCOVGEN_ITEM("name=>'row0', short=>'r0', group=>0, default=>undef, descr=>'The (enumeration) value name for this row in a table cross'") VLCOVGEN_ITEM("name=>'row1', short=>'r1', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'row2', short=>'r2', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'row3', short=>'r3', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr=>'For totaling items, weight of this item'") // VLCOVGEN_CIK_AUTO_EDIT_BEGIN #define VL_CIK_COL0 "c0" #define VL_CIK_COL0_NAME "C0" #define VL_CIK_COL1 "c1" #define VL_CIK_COL1_NAME "C1" #define VL_CIK_COL2 "c2" #define VL_CIK_COL2_NAME "C2" #define VL_CIK_COL3 "c3" #define VL_CIK_COL3_NAME "C3" #define VL_CIK_COLUMN "n" #define VL_CIK_COMMENT "o" #define VL_CIK_FILENAME "f" #define VL_CIK_GROUPCMT "O" #define VL_CIK_GROUPDESC "d" #define VL_CIK_GROUPNAME "g" #define VL_CIK_HIER "h" #define VL_CIK_LIMIT "L" #define VL_CIK_LINENO "l" #define VL_CIK_PER_INSTANCE "P" #define VL_CIK_ROW0 "r0" #define VL_CIK_ROW0_NAME "R0" #define VL_CIK_ROW1 "r1" #define VL_CIK_ROW1_NAME "R1" #define VL_CIK_ROW2 "r2" #define VL_CIK_ROW2_NAME "R2" #define VL_CIK_ROW3 "r3" #define VL_CIK_ROW3_NAME "R3" #define VL_CIK_TABLE "T" #define VL_CIK_THRESH "s" #define VL_CIK_TYPE "t" #define VL_CIK_WEIGHT "w" // VLCOVGEN_CIK_AUTO_EDIT_END //============================================================================= // VerilatedCovKey /// Verilator coverage global class. /// This class is thread safe. class VerilatedCovKey { public: static std::string shortKey(const std::string& key) VL_PURE { // VLCOVGEN_SHORT_AUTO_EDIT_BEGIN if (key == "col0") return VL_CIK_COL0; if (key == "col0_name") return VL_CIK_COL0_NAME; if (key == "col1") return VL_CIK_COL1; if (key == "col1_name") return VL_CIK_COL1_NAME; if (key == "col2") return VL_CIK_COL2; if (key == "col2_name") return VL_CIK_COL2_NAME; if (key == "col3") return VL_CIK_COL3; if (key == "col3_name") return VL_CIK_COL3_NAME; if (key == "column") return VL_CIK_COLUMN; if (key == "comment") return VL_CIK_COMMENT; if (key == "filename") return VL_CIK_FILENAME; if (key == "groupcmt") return VL_CIK_GROUPCMT; if (key == "groupdesc") return VL_CIK_GROUPDESC; if (key == "groupname") return VL_CIK_GROUPNAME; if (key == "hier") return VL_CIK_HIER; if (key == "limit") return VL_CIK_LIMIT; if (key == "lineno") return VL_CIK_LINENO; if (key == "per_instance") return VL_CIK_PER_INSTANCE; if (key == "row0") return VL_CIK_ROW0; if (key == "row0_name") return VL_CIK_ROW0_NAME; if (key == "row1") return VL_CIK_ROW1; if (key == "row1_name") return VL_CIK_ROW1_NAME; if (key == "row2") return VL_CIK_ROW2; if (key == "row2_name") return VL_CIK_ROW2_NAME; if (key == "row3") return VL_CIK_ROW3; if (key == "row3_name") return VL_CIK_ROW3_NAME; if (key == "table") return VL_CIK_TABLE; if (key == "thresh") return VL_CIK_THRESH; if (key == "type") return VL_CIK_TYPE; if (key == "weight") return VL_CIK_WEIGHT; // VLCOVGEN_SHORT_AUTO_EDIT_END return key; } }; #endif // guard verilator-3.916/include/.gitignore0000664000177100017500000000004012671044616017134 0ustar wsnyderwsnyderverilated.mk verilated_config.h verilator-3.916/include/verilated.v0000664000177100017500000000217613205574202017317 0ustar wsnyderwsnyder//************************************************************************* // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/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.916/include/verilated.cpp0000664000177100017500000016420313205574202017634 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 VerilatedMutex Verilated::m_mutex; VerilatedVoidCb Verilated::s_flushCb = NULL; // Keep below together in one cache line Verilated::Serialized Verilated::s_s; VL_THREAD_LOCAL Verilated::ThreadLocal Verilated::t_s; 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) VL_MT_UNSAFE { if (0 && hier) {} VL_PRINTF("- %s:%d: Verilog $finish\n", filename, linenum); // Not VL_PRINTF_MT, already on main thread if (Verilated::gotFinish()) { VL_PRINTF("- %s:%d: Second verilog $finish, exiting\n", filename, linenum); // Not VL_PRINTF_MT, already on main thread 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) VL_MT_UNSAFE { 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) VL_MT_UNSAFE { if (0 && hier) {} Verilated::gotFinish(true); VL_PRINTF("%%Error: %s:%d: %s\n", filename, linenum, msg); // Not VL_PRINTF_MT, already on main thread Verilated::flushCall(); VL_PRINTF("Aborting...\n"); // Not VL_PRINTF_MT, already on main thread Verilated::flushCall(); // Second flush in case VL_PRINTF does something needing a flush abort(); } #endif //=========================================================================== // Wrapper to call certain functions via messages when multithreaded void VL_FINISH_MT (const char* filename, int linenum, const char* hier) VL_MT_SAFE { #ifdef VL_THREADED VerilatedThreadMsgQueue::post(VerilatedMsg([=](){ vl_finish(filename, linenum, hier); })); #else vl_finish(filename, linenum, hier); #endif } void VL_STOP_MT (const char* filename, int linenum, const char* hier) VL_MT_SAFE { #ifdef VL_THREADED VerilatedThreadMsgQueue::post(VerilatedMsg([=](){ vl_stop(filename, linenum, hier); })); #else vl_stop(filename, linenum, hier); #endif } void VL_FATAL_MT (const char* filename, int linenum, const char* hier, const char* msg) VL_MT_SAFE { #ifdef VL_THREADED VerilatedThreadMsgQueue::post(VerilatedMsg([=](){ vl_fatal(filename, linenum, hier, msg); })); #else vl_fatal(filename, linenum, hier, msg); #endif } //=========================================================================== // Debug prints /// sprintf but return as string (this isn't fast, for print messages only) std::string _vl_string_vprintf(const char* formatp, va_list ap) VL_MT_SAFE { va_list aq; va_copy(aq, ap); int len = VL_VSNPRINTF(NULL, 0, formatp, aq); if (VL_UNLIKELY(len < 1)) return ""; char* bufp = new char[len+1]; VL_VSNPRINTF(bufp, len+1, formatp, ap); std::string out = std::string(bufp, len); delete[] bufp; return out; } vluint64_t _vl_dbg_sequence_number() VL_MT_SAFE { #ifdef VL_THREADED static std::atomic sequence; #else static vluint64_t sequence = 0; #endif return ++sequence; } vluint32_t VL_THREAD_ID() VL_MT_SAFE { #ifdef VL_THREADED // Alternative is to use std::this_thread::get_id, but that returns a hard-to-read number and is very slow static std::atomic s_nextId (0); static VL_THREAD_LOCAL vluint32_t t_myId = ++s_nextId; return t_myId; #else return 0; #endif } void VL_DBG_MSGF(const char* formatp, ...) VL_MT_SAFE { // We're still using c printf formats instead of operator<< so we can avoid the heavy // includes that otherwise would be required in every Verilated module va_list ap; va_start(ap, formatp); std::string out = _vl_string_vprintf(formatp, ap); va_end(ap); // printf("-imm-V{t%d,%" VL_PRI64 "d}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str()); VL_PRINTF_MT("-V{t%d,%" VL_PRI64 "d}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str()); } #ifdef VL_THREADED void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE { va_list ap; va_start(ap, formatp); std::string out = _vl_string_vprintf(formatp, ap); va_end(ap); VerilatedThreadMsgQueue::post(VerilatedMsg([=](){ VL_PRINTF("%s", out.c_str()); })); } #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() VL_MT_SAFE { #ifdef VL_THREADED static VL_THREAD_LOCAL bool t_seeded = false; static VL_THREAD_LOCAL drand48_data t_buffer; static VerilatedMutex s_mutex; if (VL_UNLIKELY(!t_seeded)) { t_seeded = true; long seedval; { VerilatedLockGuard guard(s_mutex); seedval = lrand48()<<16 ^ lrand48(); if (!seedval) seedval++; } srand48_r(seedval, &t_buffer); } long v0; lrand48_r(&t_buffer, &v0); long v1; lrand48_r(&t_buffer, &v1); return (v0<<16) ^ v1; #elif 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) VL_MT_SAFE { return VL_RAND32() & VL_MASK_I(obits); } QData VL_RANDOM_Q(int obits) VL_MT_SAFE { QData data = ((QData)VL_RAND32()<=0; --i) { VL_PRINTF_MT("%08x ",iwp[i]); } VL_PRINTF_MT("\n"); } //=========================================================================== // Slow math WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool is_modulus) VL_MT_SAFE { // 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<(lwp[j])); owp[j] = unw64 / static_cast(rwp[0]); k = unw64 - static_cast(owp[j])*static_cast(rwp[0]); } if (is_modulus) { owp[0] = k; for (int i=1; i> 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 = (static_cast(un[j+vw])<(un[j+vw-1])); vluint64_t qhat = unw64 / static_cast(vn[vw-1]); vluint64_t rhat = unw64 - qhat*static_cast(vn[vw-1]); again: if (qhat >= 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(un[i+j]) + static_cast(vn[i]) + k; un[i+j] = t; k = t >> 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; i0) { // power = power*power VL_ASSIGN_W(obits, lastpowstore, powstore); VL_MUL_W(VL_WORDS_I(obits), powstore, lastpowstore, lastpowstore); } if (VL_BITISSET_W(rwp,bit)) { // out *= power VL_ASSIGN_W(obits, lastoutstore, owp); VL_MUL_W(VL_WORDS_I(obits), owp, lastoutstore, powstore); } } return owp; } WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs) VL_MT_SAFE { WData rhsw[2]; VL_SET_WQ(rhsw, rhs); return VL_POW_WWW(obits,lbits,rbits,owp,lwp,rhsw); } QData VL_POW_QQW(int, int, int rbits, QData lhs, WDataInP rwp) VL_MT_SAFE { // Skip check for rhs == 0, as short-circuit doesn't save time if (VL_UNLIKELY(lhs==0)) return 0; QData power = lhs; QData out = VL_ULL(1); for (int bit=0; bit0) power = power*power; if (VL_BITISSET_W(rwp,bit)) out *= power; } return out; } WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign) VL_MT_SAFE { // obits==lbits, rbits can be different if (rsign && VL_SIGN_W(rbits, rwp)) { int words = VL_WORDS_I(obits); VL_ZERO_W(obits, owp); IData lor = 0; // 0=all zeros, ~0=all ones, else mix for (int i=1; i < (words-1); ++i) { lor |= lwp[i]; } lor |= ( (lwp[words-1] == VL_MASK_I(rbits)) ? ~VL_UL(0) : 0); if (lor==0 && lwp[0]==0) { return owp; } // "X" so return 0 else if (lor==0 && lwp[0]==1) { owp[0] = 1; return owp; } // 1 else if (lsign && lor == ~VL_UL(0) && lwp[0]==~VL_UL(0)) { // -1 if (rwp[0] & 1) { return VL_ALLONES_W(obits, owp); } // -1^odd=-1 else { owp[0] = 1; return owp; } // -1^even=1 } return 0; } return VL_POW_WWW(obits, rbits, rbits, owp, lwp, rwp); } WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign) VL_MT_SAFE { WData rhsw[2]; VL_SET_WQ(rhsw, rhs); return VL_POWSS_WWW(obits,lbits,rbits,owp,lwp,rhsw,lsign,rsign); } QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign, bool rsign) VL_MT_SAFE { // Skip check for rhs == 0, as short-circuit doesn't save time if (rsign && VL_SIGN_W(rbits, rwp)) { if (lhs==0) return 0; // "X" else if (lhs==1) return 1; else if (lsign && lhs==VL_MASK_I(obits)) { // -1 if (rwp[0] & 1) return VL_MASK_I(obits); // -1^odd=-1 else return 1; // -1^even=1 } return 0; } return VL_POW_QQW(obits, rbits, rbits, lhs, rwp); } //=========================================================================== // Formatting // Do a va_arg returning a quad, assuming input argument is anything less than wide #define _VL_VA_ARG_Q(ap, bits) (((bits) <= VL_WORDSIZE) ? va_arg(ap,IData) : va_arg(ap,QData)) void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SAFE { // Format a Verilog $write 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 // // Note uses a single buffer internally; presumes only one usage per printf // Note also assumes variables < 64 are not wide, this assumption is // sometimes not true in low-level routines written here in verilated.cpp static VL_THREAD_LOCAL char tmp[VL_VALUE_STRING_MAX_WIDTH]; static VL_THREAD_LOCAL char tmpf[VL_VALUE_STRING_MAX_WIDTH]; const char* pctp = NULL; // Most recent %##.##g format bool inPct = false; bool widthSet = false; int width = 0; for (const char* pos = formatp; *pos; ++pos) { if (!inPct && pos[0]=='%') { pctp = pos; inPct = true; widthSet = false; width = 0; } else if (!inPct) { // Normal text // Fast-forward to next escape and add to output const char *ep = pos; while (ep[0] && ep[0]!='%') ep++; if (ep != pos) { output.append(pos, ep-pos); pos += ep-pos-1; } } else { // Format character inPct = false; char fmt = pos[0]; switch (fmt) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': inPct = true; // Get more digits widthSet = true; width = width*10 + (fmt - '0'); break; case '.': inPct = true; // Get more digits break; case '%': output += '%'; break; case 'N': { // "C" string with name of module, add . if needed const char* cstrp = va_arg(ap, const char*); if (VL_LIKELY(*cstrp)) { output += cstrp; output += '.'; } break; } case 'S': { // "C" string const char* cstrp = va_arg(ap, const char*); output += cstrp; break; } case '@': { // Verilog/C++ string va_arg(ap, int); // # bits is ignored const std::string* cstrp = va_arg(ap, const std::string*); output += *cstrp; break; } case 'e': case 'f': case 'g': { const int lbits = va_arg(ap, int); double d = va_arg(ap, double); if (lbits) {} // UNUSED - always 64 strncpy(tmpf, pctp, pos-pctp+1); tmpf[pos-pctp+1] = '\0'; sprintf(tmp, tmpf, d); output += tmp; break; } default: { // Deal with all read-and-print somethings const int lbits = va_arg(ap, int); QData ld = 0; WData qlwp[2]; WDataInP lwp; if (lbits <= VL_QUADSIZE) { ld = _VL_VA_ARG_Q(ap, lbits); VL_SET_WQ(qlwp,ld); lwp = qlwp; } else { lwp = va_arg(ap,WDataInP); ld = lwp[0]; if (fmt == 'd' || fmt == '#') fmt = 'x'; // Not supported, but show something } int lsb=lbits-1; if (widthSet && width==0) while (lsb && !VL_BITISSET_W(lwp,lsb)) --lsb; switch (fmt) { case 'c': { IData charval = ld & 0xff; output += charval; break; } case 's': for (; lsb>=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", static_cast(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 '#': { // 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", static_cast(ld/VL_TIME_MULTIPLIER), static_cast(ld%VL_TIME_MULTIPLIER)); } else { VL_FATAL_MT(__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; 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 'u': // Packed 2-state output.reserve(output.size() + 4*VL_WORDS_I(lbits)); for (int i=0; i((lwp[i] ) & 0xff); output += static_cast((lwp[i] >> 8) & 0xff); output += static_cast((lwp[i] >> 16) & 0xff); output += static_cast((lwp[i] >> 24) & 0xff); } break; case 'z': // Packed 4-state output.reserve(output.size() + 8*VL_WORDS_I(lbits)); for (int i=0; i((lwp[i] ) & 0xff); output += static_cast((lwp[i] >> 8) & 0xff); output += static_cast((lwp[i] >> 16) & 0xff); output += static_cast((lwp[i] >> 24) & 0xff); output += "\0\0\0\0"; // No tristate } break; case 'v': // Strength; assume always strong for (lsb=lbits-1; lsb>=0; --lsb) { if ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) output += "St1 "; else output += "St0 "; } 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: std::string msg = std::string("Unknown _vl_vsformat code: ")+pos[0]; VL_FATAL_MT(__FILE__,__LINE__,"",msg.c_str()); break; } // switch } } // switch } } } static inline bool _vl_vsss_eof(FILE* fp, int& floc) VL_MT_SAFE { 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) VL_MT_SAFE { if (fp) fgetc(fp); else floc -= 8; } static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr) VL_MT_SAFE { // Get a character without advancing if (fp) { int data = fgetc(fp); if (data == EOF) return EOF; ungetc(data,fp); return data; } else { if (floc < 0) return EOF; floc = floc & ~7; // Align to closest character if (fromp == NULL) { return fstr[fstr.length()-1 - (floc>>3)]; } else { return (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff; } } } static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr) VL_MT_SAFE { while (1) { int c = _vl_vsss_peek(fp, floc, fromp, fstr); if (c==EOF || !isspace(c)) return; _vl_vsss_advance(fp, floc); } } static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr, char* tmpp, const char* acceptp) VL_MT_SAFE { // Read into tmp, consisting of characters from acceptp list char* cp = tmpp; while (1) { int c = _vl_vsss_peek(fp, floc, fromp, fstr); if (c==EOF || isspace(c)) break; if (acceptp!=NULL // String - allow anything && NULL==strchr(acceptp, c)) break; if (acceptp!=NULL) c = tolower(c); // Non-strings we'll simplify *cp++ = c; _vl_vsss_advance(fp, floc); } *cp++ = '\0'; //VL_DBG_MSGF(" _read got='"<>=1) { VL_ASSIGNBIT_WI(0, lsb, owp, ld & 1); } } static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp, size_t posstart, size_t posend) VL_MT_SAFE { // Read in base "2^^baseLog2" digits from strp[posstart..posend-1] into owp of size obits. int lsb = 0; for (int i=0, pos=static_cast(posend)-1; i=static_cast(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 std::string& fstr, // if a sscanf to string const char* formatp, va_list ap) VL_MT_SAFE { // 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_LOCAL 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_DBG_MSGF("_vlscan fmt='"< VL_QUADSIZE) { owp = va_arg(ap,WDataOutP); } for (int i=0; i(strlen(tmp)))-1; int lsb = 0; for (int i=0; i=0; --lpos) { _vl_vsss_setbit(owp,obits,lsb, 8, tmp[lpos]); lsb+=8; } break; } case 'd': { // Signed decimal _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789+-xXzZ?_"); if (!tmp[0]) goto done; vlsint64_t ld; sscanf(tmp,"%30" VL_PRI64 "d",&ld); VL_SET_WQ(owp,ld); break; } case 'f': case 'e': case 'g': { // Real number _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "+-.0123456789eE"); if (!tmp[0]) goto done; // cppcheck-suppress unusedStructMember // It's used union { double r; vlsint64_t ld; } u; u.r = strtod(tmp, NULL); VL_SET_WQ(owp,u.ld); break; } case 't': // FALLTHRU // Time case '#': { // Unsigned decimal _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789+-xXzZ?_"); if (!tmp[0]) goto done; QData ld; sscanf(tmp,"%30" VL_PRI64 "u",&ld); VL_SET_WQ(owp,ld); break; } case 'b': { _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "01xXzZ?_"); if (!tmp[0]) goto done; _vl_vsss_based(owp,obits, 1, tmp, 0, strlen(tmp)); break; } case 'o': { _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "01234567xXzZ?_"); if (!tmp[0]) goto done; _vl_vsss_based(owp,obits, 3, tmp, 0, strlen(tmp)); break; } case 'x': { _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789abcdefABCDEFxXzZ?_"); if (!tmp[0]) goto done; _vl_vsss_based(owp,obits, 4, tmp, 0, strlen(tmp)); break; } default: std::string msg = std::string("Unknown _vl_vsscanf code: ")+pos[0]; VL_FATAL_MT(__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) VL_MT_SAFE { return VerilatedImp::fdToFp(lhs); } void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) VL_MT_SAFE { // 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 if (!start) while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces } void _VL_STRING_TO_VINT(int obits, void* destp, size_t srclen, const char* srcp) VL_MT_SAFE { // Convert C string to Verilog format size_t bytes = VL_BYTES_I(obits); char* op = reinterpret_cast(destp); if (srclen > bytes) srclen = bytes; // Don't overflow destination size_t i; for (i=0; i VL_TO_STRING_MAX_WORDS*VL_WORDSIZE)) { VL_FATAL_MT(__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); // getc() is threadsafe if (c==EOF) break; *cp++ = c; got++; if (c=='\n') break; } _VL_STRING_TO_VINT(obits, destp, got, buffer); return got; } IData VL_FOPEN_NI(const std::string& filename, IData mode) VL_MT_SAFE { // While threadsafe, each thread can only access different file handles char modez[5]; _VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode); return VL_FOPEN_S(filename.c_str(), modez); } IData VL_FOPEN_QI(QData filename, IData mode) VL_MT_SAFE { // While threadsafe, each thread can only access different file handles WData fnw[2]; VL_SET_WQ(fnw, filename); return VL_FOPEN_WI(2, fnw, mode); } IData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) VL_MT_SAFE { // While threadsafe, each thread can only access different file handles 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) VL_MT_SAFE { return VerilatedImp::fdNew(fopen(filenamep,modep)); } void VL_FCLOSE_I(IData fdi) VL_MT_SAFE { // While threadsafe, each thread can only access different file handles FILE* fp = VL_CVT_I_FP(fdi); if (VL_UNLIKELY(!fp)) return; fclose(fp); VerilatedImp::fdDelete(fdi); } void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE { static VL_THREAD_LOCAL std::string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); _VL_STRING_TO_VINT(obits, &destr, output.length(), output.c_str()); } void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) VL_MT_SAFE { static VL_THREAD_LOCAL std::string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); _VL_STRING_TO_VINT(obits, &destr, output.length(), output.c_str()); } void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) VL_MT_SAFE { static VL_THREAD_LOCAL std::string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); _VL_STRING_TO_VINT(obits, &destr, output.length(), output.c_str()); } void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) VL_MT_SAFE { static VL_THREAD_LOCAL std::string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); _VL_STRING_TO_VINT(obits, &destr, output.length(), output.c_str()); } void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) VL_MT_SAFE { static VL_THREAD_LOCAL std::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, output.length(), output.c_str()); } void VL_SFORMAT_X(int obits_ignored, std::string &output, const char* formatp, ...) VL_MT_SAFE { if (obits_ignored) {} output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); } std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE { static VL_THREAD_LOCAL std::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_MT_SAFE { static VL_THREAD_LOCAL std::string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); VL_PRINTF_MT("%s", output.c_str()); } void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE { // While threadsafe, each thread can only access different file handles static VL_THREAD_LOCAL std::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, ...) VL_MT_SAFE { // While threadsafe, each thread can only access different file handles 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, ...) VL_MT_SAFE { WData 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, ...) VL_MT_SAFE { WData 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, ...) VL_MT_SAFE { va_list ap; va_start(ap,formatp); IData got = _vl_vsscanf(NULL, lbits, lwp, "", formatp, ap); va_end(ap); return got; } IData VL_SSCANF_INX(int, const std::string& ld, const char* formatp, ...) VL_MT_SAFE { va_list ap; va_start(ap,formatp); IData got = _vl_vsscanf(NULL, ld.length()*8, NULL, ld, formatp, ap); va_end(ap); return got; } void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int, QData ofilename, void* memp, IData start, IData end) VL_MT_SAFE { WData 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) VL_MT_SAFE { char ofilenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1]; _VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, ofilenamez, ofilenamep); std::string ofilenames(ofilenamez); return VL_READMEM_N(hex,width,depth,array_lsb,fnwords,ofilenames,memp,start,end); } void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords, const std::string& ofilenamep, void* memp, IData start, IData end) VL_MT_SAFE { if (fnwords) {} FILE* fp = fopen(ofilenamep.c_str(), "r"); if (VL_UNLIKELY(!fp)) { // We don't report the Verilog source filename as it slow to have to pass it down VL_FATAL_MT (ofilenamep.c_str(), 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) || (!reading_addr && (c=='x' || c=='X'))) { c = tolower(c); int value = (c >= 'a' ? (c=='x' ? VL_RAND_RESET_I(4) : (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 >= static_cast(depth+array_lsb) || addr < static_cast(array_lsb))) { VL_FATAL_MT (ofilenamep.c_str(), 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 = &(reinterpret_cast(memp))[entry]; if (!innum) { *datap = 0; } *datap = ((*datap << shift) + value) & VL_MASK_I(width); } else if (width<=16) { SData* datap = &(reinterpret_cast(memp))[entry]; if (!innum) { *datap = 0; } *datap = ((*datap << shift) + value) & VL_MASK_I(width); } else if (width<=VL_WORDSIZE) { IData* datap = &(reinterpret_cast(memp))[entry]; if (!innum) { *datap = 0; } *datap = ((*datap << shift) + value) & VL_MASK_I(width); } else if (width<=VL_QUADSIZE) { QData* datap = &(reinterpret_cast(memp))[entry]; if (!innum) { *datap = 0; } *datap = ((*datap << static_cast(shift)) + static_cast(value)) & VL_MASK_Q(width); } else { WDataOutP datap = &(reinterpret_cast(memp))[ entry*VL_WORDS_I(width) ]; if (!innum) { VL_ZERO_RESET_W(width, datap); } _VL_SHIFTL_INPLACE_W(width, datap, static_cast(shift)); datap[0] |= value; } if (VL_UNLIKELY(value>=(1<> 8; // Want exit status } IData VL_TESTPLUSARGS_I(const char* formatp) VL_MT_SAFE { const std::string& match = VerilatedImp::argPlusMatch(formatp); if (match == "") return 0; else return 1; } IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_MT_SAFE { std::string prefix; bool inPct = false; bool done = false; char fmt = ' '; for (const char* posp = ld.c_str(); !done && *posp; ++posp) { if (!inPct && posp[0]=='%') { inPct = true; } else if (!inPct) { // Normal text prefix += *posp; } else { // Format character switch (tolower(*posp)) { case '%': prefix += *posp; inPct = false; break; default: fmt = *posp; done = true; break; } } } const std::string& match = VerilatedImp::argPlusMatch(prefix.c_str()); const char* dp = match.c_str() + 1 /*leading + */ + prefix.length(); if (match == "") return 0; VL_ZERO_RESET_W(rbits, rwp); switch (tolower(fmt)) { case 'd': vlsint64_t lld; sscanf(dp,"%30" VL_PRI64 "d",&lld); VL_SET_WQ(rwp,lld); break; case 'b': _vl_vsss_based(rwp,rbits, 1, dp, 0, strlen(dp)); break; case 'o': _vl_vsss_based(rwp,rbits, 3, dp, 0, strlen(dp)); break; case 'h': //FALLTHRU case 'x': _vl_vsss_based(rwp,rbits, 4, dp, 0, strlen(dp)); break; case 's': // string/no conversion for (int i=0, lsb=0, posp=static_cast(strlen(dp))-1; i=0; --posp) { _vl_vsss_setbit(rwp,rbits,lsb, 8, dp[posp]); lsb+=8; } break; case 'e': //FALLTHRU - Unsupported case 'f': //FALLTHRU - Unsupported case 'g': //FALLTHRU - Unsupported default: // Other simulators simply return 0 in these cases and don't error out return 0; } _VL_CLEAN_INPLACE_W(rbits,rwp); return 1; } IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) VL_MT_SAFE { std::string prefix; bool inPct = false; bool done = false; for (const char* posp = ld.c_str(); !done && *posp; ++posp) { if (!inPct && posp[0]=='%') { inPct = true; } else if (!inPct) { // Normal text prefix += *posp; } else { // Format character switch (tolower(*posp)) { case '%': prefix += *posp; inPct = false; break; default: done = true; break; } } } const std::string& match = VerilatedImp::argPlusMatch(prefix.c_str()); const char* dp = match.c_str() + 1 /*leading + */ + prefix.length(); if (match == "") return 0; rdr = std::string(dp); return 1; } const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE { const std::string& match = VerilatedImp::argPlusMatch(prefixp); static VL_THREAD_LOCAL 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 std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE { // 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 std::string(destout, len); } //=========================================================================== // Verilated:: Methods Verilated::ThreadLocal::ThreadLocal() : #ifdef VL_THREADED t_trainId(0), #endif t_dpiScopep(NULL), t_dpiFilename(0), t_dpiLineno(0) { } Verilated::ThreadLocal::~ThreadLocal() { } void Verilated::debug(int val) VL_MT_SAFE { VerilatedLockGuard guard(m_mutex); s_s.s_debug = val; if (val) { #ifdef VL_DEBUG VL_DEBUG_IF(VL_DBG_MSGF("- Verilated::debug is on. Message prefix indicates {,}.\n");); #else VL_PRINTF_MT("- Verilated::debug attempted, but compiled without VL_DEBUG, so messages suppressed.\n"); #endif } } void Verilated::randReset(int val) VL_MT_SAFE { VerilatedLockGuard guard(m_mutex); s_s.s_randReset = val; } void Verilated::calcUnusedSigs(bool flag) VL_MT_SAFE { VerilatedLockGuard guard(m_mutex); s_s.s_calcUnusedSigs = flag; } void Verilated::gotFinish(bool flag) VL_MT_SAFE { VerilatedLockGuard guard(m_mutex); s_s.s_gotFinish = flag; } void Verilated::assertOn(bool flag) VL_MT_SAFE { VerilatedLockGuard guard(m_mutex); s_s.s_assertOn = flag; } void Verilated::fatalOnVpiError(bool flag) VL_MT_SAFE { VerilatedLockGuard guard(m_mutex); s_s.s_fatalOnVpiError = flag; } const char* Verilated::catName(const char* n1, const char* n2) VL_MT_SAFE { // Returns new'ed data // Used by symbol table creation to make module names static VL_THREAD_LOCAL char* strp = NULL; static VL_THREAD_LOCAL size_t len = 0; size_t newlen = strlen(n1)+strlen(n2)+2; if (!strp || 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) VL_MT_SAFE { VerilatedLockGuard guard(m_mutex); 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_MT("unknown",0,"", "Verilated::flushCb called twice with different callbacks"); } } void Verilated::flushCall() VL_MT_SAFE { VerilatedLockGuard guard(m_mutex); if (s_flushCb) (*s_flushCb)(); } void Verilated::commandArgs(int argc, const char** argv) VL_MT_SAFE { VerilatedLockGuard guard(m_mutex); s_args.argc = argc; s_args.argv = argv; VerilatedImp::commandArgs(argc,argv); } const char* Verilated::commandArgsPlusMatch(const char* prefixp) VL_MT_SAFE { const std::string& match = VerilatedImp::argPlusMatch(prefixp); static VL_THREAD_LOCAL char outstr[VL_VALUE_STRING_MAX_WIDTH]; if (match == "") return ""; strncpy(outstr, match.c_str(), VL_VALUE_STRING_MAX_WIDTH); outstr[VL_VALUE_STRING_MAX_WIDTH-1] = '\0'; return outstr; } void Verilated::overWidthError(const char* signame) VL_MT_SAFE { // Slowpath - Called only when signal sets too high of a bit std::string msg = (std::string("Testbench C set input '") + signame + "' to value that overflows what the signal's width can fit"); VL_FATAL_MT("unknown",0,"", msg.c_str()); } void Verilated::quiesce() VL_MT_SAFE { #ifdef VL_THREADED // Wait until all threads under this evaluation are quiet // THREADED-TODO #endif } void Verilated::internalsDump() VL_MT_SAFE { VerilatedImp::internalsDump(); } void Verilated::scopesDump() VL_MT_SAFE { VerilatedImp::scopesDump(); } void Verilated::numThreads(unsigned threads) VL_MT_SAFE { VerilatedImp::numThreads(threads); } unsigned Verilated::numThreads() VL_MT_SAFE { return VerilatedImp::numThreads(); } void Verilated::spawnThreads() VL_MT_SAFE { VerilatedImp::spawnThreads(); } const VerilatedScope* Verilated::scopeFind(const char* namep) VL_MT_SAFE { return VerilatedImp::scopeFind(namep); } int Verilated::exportFuncNum(const char* namep) VL_MT_SAFE { return VerilatedImp::exportFind(namep); } const VerilatedScopeNameMap* Verilated::scopeNameMap() VL_MT_SAFE { return VerilatedImp::scopeNameMap(); } #ifdef VL_THREADED void Verilated::endOfThreadTrainGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { VL_DEBUG_IF(VL_DBG_MSGF("End of thread train\n");); VerilatedThreadMsgQueue::flush(evalMsgQp); } void Verilated::endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { VL_DEBUG_IF(VL_DBG_MSGF("End-of-eval cleanup\n");); evalMsgQp->process(); } #endif //====================================================================== // VerilatedSyms:: Methods VerilatedSyms::VerilatedSyms() { #ifdef VL_THREADED __Vm_evalMsgQp = new VerilatedEvalMsgQueue; #endif } VerilatedSyms::~VerilatedSyms() { #ifdef VL_THREADED delete __Vm_evalMsgQp; #endif } //=========================================================================== // VerilatedModule:: Methods VerilatedModule::VerilatedModule(const char* namep) : m_namep(strdup(namep)) { } VerilatedModule::~VerilatedModule() { // Memory cleanup - not called during normal operation 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() { // Memory cleanup - not called during normal operation 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) VL_MT_UNSAFE { // 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) VL_MT_UNSAFE { // 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_MT(__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, ...) VL_MT_UNSAFE { // 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(std::make_pair(namep,var)); } // cppcheck-suppress unusedFunction // Used by applications VerilatedVar* VerilatedScope::varFind(const char* namep) const VL_MT_SAFE_POSTINIT { 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) VL_MT_SAFE { // Slowpath - Called only when find has failed std::string msg = (std::string("Testbench C called '") +VerilatedImp::exportName(funcnum) +"' but scope wasn't set, perhaps due to dpi import call without 'context'"); VL_FATAL_MT("unknown",0,"", msg.c_str()); return NULL; } void* VerilatedScope::exportFindError(int funcnum) const { // Slowpath - Called only when find has failed std::string msg = (std::string("Testbench C called '") +VerilatedImp::exportName(funcnum) +"' but this DPI export function exists only in other scopes, not scope '" +name()+"'"); VL_FATAL_MT("unknown",0,"", msg.c_str()); return NULL; } void VerilatedScope::scopeDump() const { VL_PRINTF_MT(" SCOPE %p: %s\n", this, name()); for (int i=0; ivarsp()) { for (VerilatedVarNameMap::const_iterator it = varsp->begin(); it != varsp->end(); ++it) { VL_PRINTF_MT(" VAR %p: %s\n", &(it->second), it->first); } } } //=========================================================================== // VerilatedOneThreaded:: Methods #ifdef VL_THREADED void VerilatedAssertOneThread::fatal_different() VL_MT_SAFE { VL_FATAL_MT(__FILE__, __LINE__, "", "Routine called that is single threaded, but called from" " a different thread then the expected constructing thread"); } #endif //=========================================================================== verilator-3.916/include/verilated_dpi.h0000664000177100017500000000502213205574202020126 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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) VL_MT_SAFE { int words = VL_WORDS_I(obits); for (int i=0; i #include #include //============================================================================= // VerilatedCovImpBase /// Implementation base class for constants struct VerilatedCovImpBase { // TYPES enum { MAX_KEYS = 33 }; /// Maximum user arguments + filename+lineno enum { KEY_UNDEF = 0 }; /// Magic key # for unspecified values }; //============================================================================= // VerilatedCovImpItem /// Implementation class for a VerilatedCov item class VerilatedCovImpItem : VerilatedCovImpBase { public: // But only local to this file // MEMBERS int m_keys[MAX_KEYS]; ///< Key int m_vals[MAX_KEYS]; ///< Value for specified key // CONSTRUCTORS // Derived classes should call zero() in their constructor VerilatedCovImpItem() { for (int i=0; i class VerilatedCoverItemSpec : public VerilatedCovImpItem { private: // MEMBERS T* m_countp; ///< Count value public: // METHODS // cppcheck-suppress truncLongCastReturn virtual vluint64_t count() const { return *m_countp; } virtual void zero() const { *m_countp = 0; } // CONSTRUCTORS // cppcheck-suppress noExplicitConstructor VerilatedCoverItemSpec(T* countp) : m_countp(countp) { zero(); } virtual ~VerilatedCoverItemSpec() {} }; //============================================================================= // VerilatedCovImp /// Implementation class for VerilatedCov. See that class for public method information. /// All value and keys are indexed into a unique number. Thus we can greatly reduce /// the storage requirements for otherwise identical keys. class VerilatedCovImp : VerilatedCovImpBase { private: // TYPES typedef std::map ValueIndexMap; typedef std::map IndexValueMap; typedef std::deque ItemList; private: // MEMBERS VerilatedMutex m_mutex; ///< Protects all members, when VL_THREADED. Wrapper deals with setting it. ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value ItemList m_items VL_GUARDED_BY(m_mutex); ///< List of all items VerilatedCovImpItem* m_insertp VL_GUARDED_BY(m_mutex); ///< Item about to insert const char* m_insertFilenamep VL_GUARDED_BY(m_mutex); ///< Filename about to insert int m_insertLineno VL_GUARDED_BY(m_mutex); ///< Line number about to insert // CONSTRUCTORS VerilatedCovImp() { m_insertp = NULL; m_insertFilenamep = NULL; m_insertLineno = 0; } VL_UNCOPYABLE(VerilatedCovImp); public: ~VerilatedCovImp() { clearGuts(); } static VerilatedCovImp& imp() VL_MT_SAFE { static VerilatedCovImp s_singleton; return s_singleton; } private: // PRIVATE METHODS int valueIndex(const std::string& value) VL_REQUIRES(m_mutex) { static int nextIndex = KEY_UNDEF+1; ValueIndexMap::iterator iter = m_valueIndexes.find(value); if (iter != m_valueIndexes.end()) return iter->second; nextIndex++; assert(nextIndex>0); m_valueIndexes.insert(std::make_pair(value, nextIndex)); m_indexValues.insert(std::make_pair(nextIndex, value)); return nextIndex; } static std::string dequote(const std::string& text) VL_PURE { // Quote any special characters std::string rtn; for (const char* pos = text.c_str(); *pos; ++pos) { if (!isprint(*pos) || *pos=='%' || *pos=='"') { char hex[10]; sprintf(hex,"%%%02X",pos[0]); rtn += hex; } else { rtn += *pos; } } return rtn; } static bool legalKey(const std::string& key) VL_PURE { // Because we compress long keys to a single letter, and // don't want applications to either get confused if they use // a letter differently, nor want them to rely on our compression... // (Considered using numeric keys, but will remain back compatible.) if (key.length()<2) return false; if (key.length()==2 && isdigit(key[1])) return false; return true; } static std::string keyValueFormatter(const std::string& key, const std::string& value) VL_PURE { std::string name; if (key.length()==1 && isalpha(key[0])) { name += std::string("\001")+key; } else { name += std::string("\001")+dequote(key); } name += std::string("\002")+dequote(value); return name; } static std::string combineHier(const std::string& old, const std::string& add) VL_PURE { // (foo.a.x, foo.b.x) => foo.*.x // (foo.a.x, foo.b.y) => foo.* // (foo.a.x, foo.b) => foo.* if (old == add) return add; if (old == "") return add; if (add == "") return old; const char* a = old.c_str(); const char* b = add.c_str(); // Scan forward to first mismatch const char* apre = a; const char* bpre = b; while (*apre == *bpre) { apre++; bpre++; } // We used to backup and split on only .'s but it seems better to be verbose // and not assume . is the separator std::string prefix = std::string(a,apre-a); // Scan backward to last mismatch const char* apost = a+strlen(a)-1; const char* bpost = b+strlen(b)-1; while (*apost == *bpost && apost>apre && bpost>bpre) { apost--; bpost--; } // Forward to . so we have a whole word std::string suffix = *bpost ? std::string(bpost+1) : ""; std::string out = prefix+"*"+suffix; //cout << "\nch pre="<zero(); } } // We assume there's always call to i/f/p in that order void inserti (VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) { VerilatedLockGuard guard(m_mutex); assert(!m_insertp); m_insertp = itemp; } void insertf (const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) { VerilatedLockGuard guard(m_mutex); m_insertFilenamep = filenamep; m_insertLineno = lineno; } void insertp (const char* ckeyps[MAX_KEYS], const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) { VerilatedLockGuard guard(m_mutex); assert(m_insertp); // First two key/vals are filename ckeyps[0]="filename"; valps[0]=m_insertFilenamep; std::string linestr = vlCovCvtToStr(m_insertLineno); ckeyps[1]="lineno"; valps[1]=linestr.c_str(); // Default page if not specified const char* fnstartp = m_insertFilenamep; while (const char* foundp = strchr(fnstartp,'/')) fnstartp=foundp+1; const char* fnendp = fnstartp; while (*fnendp && *fnendp!='.') fnendp++; std::string page_default = "sp_user/"+std::string(fnstartp,fnendp-fnstartp); ckeyps[2]="page"; valps[2]=page_default.c_str(); // Keys -> strings std::string keys[MAX_KEYS]; for (int i=0; i > EventMap; EventMap eventCounts; for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) { VerilatedCovImpItem* itemp = *(it); std::string name; std::string hier; bool per_instance = false; for (int i=0; im_keys[i] != KEY_UNDEF) { std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]); std::string val = m_indexValues[itemp->m_vals[i]]; if (key == VL_CIK_PER_INSTANCE) { if (val != "0") per_instance = true; } if (key == VL_CIK_HIER) { hier = val; } else { // Print it name += keyValueFormatter(key,val); } } } if (per_instance) { // Not collapsing hierarchies name += keyValueFormatter(VL_CIK_HIER,hier); hier = ""; } // Group versus point labels don't matter here, downstream // deals with it. Seems bad for sizing though and doesn't // allow easy addition of new group codes (would be // inefficient) // Find or insert the named event EventMap::iterator cit = eventCounts.find(name); if (cit != eventCounts.end()) { const std::string& oldhier = cit->second.first; cit->second.second += itemp->count(); cit->second.first = combineHier(oldhier, hier); } else { eventCounts.insert(std::make_pair(name, make_pair(hier,itemp->count()))); } } // Output body for (EventMap::const_iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) { os<<"C '"<first; if (it->second.first != "") os<second.first); os<<"' "<second.second; os<(itemp)); } void VerilatedCov::_inserti(vluint64_t* itemp) VL_MT_SAFE { VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec(itemp)); } void VerilatedCov::_insertf(const char* filename, int lineno) VL_MT_SAFE { VerilatedCovImp::imp().insertf(filename,lineno); } #define K(n) const char* key ## n #define A(n) const char* key ## n, const char* val ## n // Argument list #define C(n) key ## n, val ## n // Calling argument list #define N(n) "","" // Null argument list void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9), A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19), A(20),A(21),A(22),A(23),A(24),A(25),A(26),A(27),A(28),A(29)) VL_MT_SAFE { const char* keyps[VerilatedCovImpBase::MAX_KEYS] = {NULL,NULL,NULL, // filename,lineno,page key0,key1,key2,key3,key4,key5,key6,key7,key8,key9, key10,key11,key12,key13,key14,key15,key16,key17,key18,key19, key20,key21,key22,key23,key24,key25,key26,key27,key28,key29}; const char* valps[VerilatedCovImpBase::MAX_KEYS] = {NULL,NULL,NULL, // filename,lineno,page val0,val1,val2,val3,val4,val5,val6,val7,val8,val9, val10,val11,val12,val13,val14,val15,val16,val17,val18,val19, val20,val21,val22,val23,val24,val25,val26,val27,val28,val29}; VerilatedCovImp::imp().insertp(keyps, valps); } // And versions with fewer arguments (oh for a language with named parameters!) void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) VL_MT_SAFE { _insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9), N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19), N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29)); } void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9), A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) VL_MT_SAFE { _insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9), C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19), N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29)); } // Backward compatibility for Verilator void VerilatedCov::_insertp (A(0), A(1), K(2),int val2, K(3),int val3, K(4),const std::string& val4, A(5),A(6)) VL_MT_SAFE { std::string val2str = vlCovCvtToStr(val2); std::string val3str = vlCovCvtToStr(val3); _insertp(C(0),C(1), key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(), C(5),C(6),N(7),N(8),N(9), N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19), N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29)); } #undef A #undef C #undef N #undef K verilator-3.916/include/verilated_save.cpp0000664000177100017500000001710413205574202020647 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2017 by Wilson Snyder. This program is free software; // you can redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief C++ Tracing in VCD Format /// //============================================================================= #include "verilatedos.h" #include "verilated.h" #include "verilated_save.h" #include #include #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) # include #else # include #endif #ifndef O_LARGEFILE // For example on WIN32 # define O_LARGEFILE 0 #endif #ifndef O_NONBLOCK # define O_NONBLOCK 0 #endif // CONSTANTS static const char* const VLTSAVE_HEADER_STR = "verilatorsave01\n"; ///< Value of first bytes of each file static const char* const VLTSAVE_TRAILER_STR = "vltsaved"; ///< Value of last bytes of each file //============================================================================= //============================================================================= //============================================================================= // Searalization bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE { 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) VL_MT_UNSAFE_ONE { if (VL_UNLIKELY(readDiffers(datap,size))) { std::string fn = filename(); std::string msg = std::string("Can't deserialize save-restore file as was made from different model"); VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str()); close(); } return *this; // For function chaining } void VerilatedSerialize::header() VL_MT_UNSAFE_ONE { 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() VL_MT_UNSAFE_ONE { VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) { std::string fn = filename(); std::string msg = std::string("Can't deserialize; file has wrong header signature"); VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str()); close(); } os.read(Verilated::serializedPtr(), Verilated::serializedSize()); } void VerilatedSerialize::trailer() VL_MT_UNSAFE_ONE { 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() VL_MT_UNSAFE_ONE { VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) { std::string fn = filename(); std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature"); VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str()); close(); } } //============================================================================= //============================================================================= //============================================================================= // Opening/Closing void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE { m_assertOne.check(); if (isOpen()) return; VL_DEBUG_IF(VL_DBG_MSGF("- save: 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) VL_MT_UNSAFE_ONE { m_assertOne.check(); if (isOpen()) return; VL_DEBUG_IF(VL_DBG_MSGF("- restore: 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() VL_MT_UNSAFE_ONE { if (!isOpen()) return; trailer(); flush(); m_isOpen = false; ::close(m_fd); // May get error, just ignore it } void VerilatedRestore::close() VL_MT_UNSAFE_ONE { if (!isOpen()) return; trailer(); flush(); m_isOpen = false; ::close(m_fd); // May get error, just ignore it } //============================================================================= // Buffer management void VerilatedSave::flush() VL_MT_UNSAFE_ONE { m_assertOne.check(); 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) std::string msg = std::string(__FUNCTION__)+": "+strerror(errno); VL_FATAL_MT("",0,"",msg.c_str()); close(); break; } } } m_cp = m_bufp; // Reset buffer } void VerilatedRestore::fill() VL_MT_UNSAFE_ONE { m_assertOne.check(); 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; sp < 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) std::string msg = std::string(__FUNCTION__)+": "+strerror(errno); VL_FATAL_MT("",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.916/include/verilated_cov.h0000664000177100017500000001251313205574202020144 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2017 by Wilson Snyder. This program is free software; // you can redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief Coverage analysis support /// //============================================================================= #ifndef _VERILATED_COV_H_ #define _VERILATED_COV_H_ 1 #include "verilatedos.h" #include #include #include //============================================================================= /// Conditionally compile coverage code #ifdef VM_COVERAGE # define VL_IF_COVER(stmts) do { stmts ; } while(0) #else # define VL_IF_COVER(stmts) do { if(0) { stmts ; } } while(0) #endif //============================================================================= /// Insert a item for coverage analysis. /// The first argument is a pointer to the count to be dumped. /// The remaining arguments occur in pairs: A string key, and a value. /// The value may be a string, or another type which will be auto-converted to a string. /// /// Some typical keys: /// filename File the recording occurs in. Defaults to __FILE__ /// lineno Line number the recording occurs in. Defaults to __LINE__ /// column Column number (or occurrence# for dup file/lines). Defaults to undef. /// hier Hierarchical name. Defaults to name() /// type Type of coverage. Defaults to "user" /// Other types are 'block', 'fsm', 'toggle'. /// comment Description of the coverage event. Should be set by the user. /// Comments for type==block: 'if', 'else', 'elsif', 'case' /// thresh Threshold to consider fully covered. /// If unspecified, downstream tools will determine it. /// /// Examples: /// /// vluint32_t m_cases[10]; /// constructor { /// for (int i=0; i<10; ++i) { m_cases[i]=0; } /// } /// for (int i=0; i<10; ++i) { /// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i)); /// } #define VL_COVER_INSERT(countp,args...) \ VL_IF_COVER(VerilatedCov::_inserti(countp); \ VerilatedCov::_insertf(__FILE__,__LINE__); \ VerilatedCov::_insertp("hier", name(), args)) //============================================================================= /// Convert VL_COVER_INSERT value arguments to strings template< class T> std::string vlCovCvtToStr (const T& t) VL_PURE { std::ostringstream os; os<(scope); Verilated::dpiScope(vscopep); return (svScope)prevScopep; } const char* svGetNameFromScope(const svScope scope) { const VerilatedScope* vscopep = reinterpret_cast(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.916/include/verilated_sc.h0000664000177100017500000000377113205574202017770 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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. // This class is thread safe (though most of SystemC is not). #define VL_SC_BV_DATAP(bv) (VlScBvExposer::sp_datap(bv)) class VlScBvExposer : public sc_bv_base { public: static const vluint32_t* sp_datap(const sc_bv_base& base) VL_MT_SAFE { return static_cast(&base)->sp_datatp(); } const vluint32_t* sp_datatp() const { return reinterpret_cast(m_data); } // Above reads this protected element in sc_bv_base: // sc_digit* m_data; // data array }; //========================================================================= #endif // guard verilator-3.916/include/verilatedos.h0000664000177100017500000003536413205574202017650 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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_PURE __attribute__ ((pure)) # define VL_ATTR_UNUSED __attribute__ ((unused)) # define VL_FUNC __func__ # if defined(__clang__) && defined(VL_THREADED) # define VL_ACQUIRE(...) __attribute__ ((acquire_capability(__VA_ARGS__))) # define VL_ACQUIRE_SHARED(...) __attribute__ ((acquire_shared_capability(__VA_ARGS__))) # define VL_RELEASE(...) __attribute__ ((release_capability(__VA_ARGS__))) # define VL_RELEASE_SHARED(...) __attribute__ ((release_shared_capability(__VA_ARGS__))) # define VL_TRY_ACQUIRE(...) __attribute__ ((try_acquire_capability(__VA_ARGS__))) # define VL_TRY_ACQUIRE_SHARED(...) __attribute__ ((try_acquire_shared_capability(__VA_ARGS__))) # define VL_CAPABILITY(x) __attribute__ ((capability(x))) # define VL_REQUIRES(x) __attribute__ ((requires_capability(x))) # define VL_GUARDED_BY(x) __attribute__ ((guarded_by(x))) # define VL_EXCLUDES(x) __attribute__ ((locks_excluded(x))) # define VL_SCOPED_CAPABILITY __attribute__ ((scoped_lockable)) # endif # define VL_LIKELY(x) __builtin_expect(!!(x), 1) # define VL_UNLIKELY(x) __builtin_expect(!!(x), 0) # define VL_UNREACHABLE __builtin_unreachable(); # define VL_PREFETCH_RD(p) __builtin_prefetch((p),0) # define VL_PREFETCH_RW(p) __builtin_prefetch((p),1) #elif defined(_MSC_VER) # define VL_FUNC __FUNCTION__ #endif // Defaults for unsupported compiler features #ifndef VL_ATTR_ALIGNED # define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment #endif #ifndef VL_ATTR_ALWINLINE # define VL_ATTR_ALWINLINE ///< Inline, even when not optimizing #endif #ifndef VL_ATTR_NORETURN # define VL_ATTR_NORETURN ///< Function does not ever return #endif #ifndef VL_ATTR_PRINTF # define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking #endif #ifndef VL_ATTR_PURE # define VL_ATTR_PURE ///< Function is pure (and thus also VL_MT_SAFE) #endif #ifndef VL_ATTR_UNUSED # define VL_ATTR_UNUSED ///< Function that may be never used #endif #ifndef VL_FUNC # define VL_FUNC "__func__" ///< Name of current function for error macros #endif #ifndef VL_CAPABILITY # define VL_ACQUIRE(...) ///< Function requires a capability/lock (-fthread-safety) # define VL_ACQUIRE_SHARED(...) ///< Function aquires a shared capability/lock (-fthread-safety) # define VL_RELEASE(...) ///< Function releases a capability/lock (-fthread-safety) # define VL_RELEASE_SHARED(...) ///< Function releases a shared capability/lock (-fthread-safety) # define VL_TRY_ACQUIRE(...) ///< Function returns bool if aquired a capability (-fthread-safety) # define VL_TRY_ACQUIRE_SHARED(...) ///< Function returns bool if aquired a shared capability (-fthread-safety) # define VL_REQUIRES(x) ///< Function requires a capability inbound (-fthread-safety) # define VL_EXCLUDES(x) ///< Function requires not having a capability inbound (-fthread-safety) # define VL_CAPABILITY(x) ///< Name of capability/lock (-fthread-safety) # define VL_GUARDED_BY(x) ///< Name of mutex protecting this variable (-fthread-safety) # define VL_SCOPED_CAPABILITY ///< Scoped threaded capability/lock (-fthread-safety) #endif #ifndef VL_LIKELY # define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false # define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true #endif #ifndef VL_UNREACHABLE # define VL_UNREACHABLE ///< Point that may never be reached #endif #ifndef VL_PREFETCH_RD # define VL_PREFETCH_RD(p) ///< Prefetch data with read intent #endif #ifndef VL_PREFETCH_RW # define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent #endif #ifdef VL_THREADED # ifdef __GNUC__ # if (__cplusplus < 201103L) && !defined(VL_THREADED_NO_C11_WARNING) # error "VL_THREADED/--threads support requires C++-11 or newer only; use newer compiler" # endif # else # error "Unsupported compiler for VL_THREADED: No thread-local declarator" # endif # define VL_THREAD_LOCAL thread_local ///< Use new C++ static local thread #else # define VL_THREAD_LOCAL ///< Use new C++ static local thread #endif #define VL_THREAD ///< Deprecated #define VL_STATIC_OR_THREAD static ///< Deprecated #define VL_PURE ///< Comment tag that Function is pure (and thus also VL_MT_SAFE) #define VL_MT_SAFE ///< Comment tag that function is threadsafe when VL_THREADED #define VL_MT_SAFE_POSTINIT ///< Comment tag that function is threadsafe when VL_THREADED, only during normal operation (post-init) #define VL_MT_UNSAFE ///< Comment tag that function is not threadsafe when VL_THREADED #define VL_MT_UNSAFE_ONE ///< Comment tag that function is not threadsafe when VL_THREADED, protected to make sure single-caller #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) (static_cast(c##UL)) ///< Add appropriate suffix to 32-bit constant #if defined(VL_CPPCHECK) || defined(__clang_analyzer__) # define VL_DANGLING(v) #else # define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later #endif //========================================================================= // C++-2011 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) # define VL_EQ_DELETE = delete # define VL_HAS_UNIQUE_PTR # define VL_HAS_UNORDERED_MAP # define VL_HAS_UNORDERED_SET # define vl_unique_ptr std::unique_ptr # define vl_unordered_map std::unordered_map # define vl_unordered_set std::unordered_set # define VL_INCLUDE_UNORDERED_MAP # define VL_INCLUDE_UNORDERED_SET #else # define VL_EQ_DELETE # define vl_unique_ptr std::auto_ptr # define vl_unordered_map std::map # define vl_unordered_set std::set # define VL_INCLUDE_UNORDERED_MAP # define VL_INCLUDE_UNORDERED_SET #endif //========================================================================= // Optimization #ifndef VL_INLINE_OPT # define VL_INLINE_OPT ///< "inline" if compiling all objects in single compiler run #endif //========================================================================= // Warning disabled #ifndef VL_WARNINGS # ifdef _MSC_VER # pragma warning(disable:4099) // C4099: type name first seen using 'class' now seen using 'struct' (V3AstNode) # pragma warning(disable:4100) // C4100: unreferenced formal parameter (L4) # pragma warning(disable:4127) // C4127: conditional expression is constant (L4) # pragma warning(disable:4146) // C4146: unary minus operator applied to unsigned type, result still unsigned # pragma warning(disable:4189) // C4189: local variable is initialized but not referenced (L4) # pragma warning(disable:4244) // C4244: conversion from 'uint64_t' to 'uint_32_t', possible loss of data # pragma warning(disable:4245) // C4245: conversion from 'int' to 'unsigned', signed/unsigned mismatch # pragma warning(disable:4996) // C4996: sscanf/fopen/etc may be unsafe # endif #endif //========================================================================= // Basic integer types #ifdef VL_UINTS_DEFINED #elif defined(__CYGWIN__) # include typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility) typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility) typedef unsigned char vluint8_t; ///< 8-bit unsigned type typedef unsigned short int vluint16_t; ///< 16-bit unsigned type # if defined(__uint32_t_defined) || defined(___int32_t_defined) // Newer Cygwin uint32_t in stdint.h as an unsigned int typedef int32_t vlsint32_t; ///< 32-bit signed type typedef uint32_t vluint32_t; ///< 32-bit unsigned type # else // Older Cygwin has long==uint32_t typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility) typedef long vlsint32_t; ///< 32-bit signed type typedef unsigned long vluint32_t; ///< 32-bit unsigned type # endif # if defined(__WORDSIZE) && (__WORDSIZE == 64) typedef long vlsint64_t; ///< 64-bit signed type typedef unsigned long vluint64_t; ///< 64-bit unsigned type # else typedef long long vlsint64_t; ///< 64-bit signed type typedef unsigned long long vluint64_t; ///< 64-bit unsigned type # endif #elif defined(_WIN32) && defined(_MSC_VER) typedef unsigned __int8 uint8_t; ///< 8-bit unsigned type (backward compatibility) typedef unsigned __int16 uint16_t; ///< 16-bit unsigned type (backward compatibility) typedef unsigned __int32 uint32_t; ///< 32-bit unsigned type (backward compatibility) typedef unsigned __int8 vluint8_t; ///< 8-bit unsigned type typedef unsigned __int16 vluint16_t; ///< 16-bit unsigned type typedef signed __int32 vlsint32_t; ///< 32-bit signed type typedef unsigned __int32 vluint32_t; ///< 32-bit unsigned type typedef signed __int64 vlsint64_t; ///< 64-bit signed type typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type # ifndef _SSIZE_T_DEFINED # ifdef _WIN64 typedef signed __int64 ssize_t; ///< signed size_t; returned from read() # else typedef signed __int32 ssize_t; ///< signed size_t; returned from read() # endif # endif #else // Linux or compliant Unix flavors, -m64 # include // Linux and most flavors # include // Linux ssize_t # include // Solaris typedef uint8_t vluint8_t; ///< 32-bit unsigned type typedef uint16_t vluint16_t; ///< 32-bit unsigned type typedef int vlsint32_t; ///< 32-bit signed type typedef uint32_t vluint32_t; ///< 32-bit signed type # if defined(__WORDSIZE) && (__WORDSIZE == 64) typedef long vlsint64_t; ///< 64-bit signed type typedef unsigned long vluint64_t; ///< 64-bit unsigned type # else typedef long long vlsint64_t; ///< 64-bit signed type typedef unsigned long long vluint64_t; ///< 64-bit unsigned type # endif #endif //========================================================================= // Printing printf/scanf formats // Alas cinttypes isn't that standard yet #ifdef _WIN32 # define VL_PRI64 "I64" #else // Linux or compliant Unix flavors # if defined(__WORDSIZE) && (__WORDSIZE == 64) # define VL_PRI64 "l" # else # define VL_PRI64 "ll" # endif #endif #if defined(_WIN32) && defined(_MSC_VER) # if (_MSC_VER < 1900) # define VL_SNPRINTF _snprintf # else # define VL_SNPRINTF snprintf # endif # define VL_VSNPRINTF vsnprintf #else # define VL_SNPRINTF snprintf # define VL_VSNPRINTF vsnprintf #endif //========================================================================= // File system functions #ifdef _WIN32 # define VL_DEV_NULL "nul" #else // Linux or compliant Unix flavors # define VL_DEV_NULL "/dev/null" #endif //========================================================================= // Integer size macros #define VL_BYTESIZE 8 ///< Bits in a byte #define VL_SHORTSIZE 16 ///< Bits in a short #define VL_WORDSIZE 32 ///< Bits in a word #define VL_QUADSIZE 64 ///< Bits in a quadword #define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE) /// Bytes this number of bits needs (1 bit=1 byte) #define VL_BYTES_I(nbits) (((nbits)+(VL_BYTESIZE-1))/VL_BYTESIZE) /// Words this number of bits needs (1 bit=1 word) #define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE) //========================================================================= // Class definition helpers // Used to declare a class as uncopyable; put after a private: #define VL_UNCOPYABLE(Type) \ Type(const Type& other) VL_EQ_DELETE; \ Type& operator= (const Type&) VL_EQ_DELETE //========================================================================= // 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.916/include/verilated_syms.h0000664000177100017500000000755613205574202020363 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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. /// /// These classes are thread safe on read only. It is constructed /// only when a model is built (from the main thread). /// /// Code available from: http://www.veripool.org/verilator /// //************************************************************************* #ifndef _VERILATED_SYMS_H_ #define _VERILATED_SYMS_H_ 1 ///< Header Guard #include "verilated_heavy.h" #include //=========================================================================== /// Verilator range /// Thread safety: Assume is constructed only with model, then any number of readers // 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 /// Thread safety: Assume is constructed only with model, then any number of readers 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 static_cast(static_cast(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 struct VerilatedCStrCmp { /// Ordering maps keyed by const char*'s bool operator() (const char *a, const char *b) const { return std::strcmp(a, b) < 0; } }; class VerilatedScopeNameMap : public std::map { public: VerilatedScopeNameMap() {} ~VerilatedScopeNameMap() {} }; class VerilatedVarNameMap : public std::map { public: VerilatedVarNameMap() {} ~VerilatedVarNameMap() {} }; #endif // Guard verilator-3.916/include/verilated_vcd_c.h0000664000177100017500000004440513205574202020440 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2017 by Wilson Snyder. This program is free software; // you can redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief C++ Tracing in VCD Format /// //============================================================================= // SPDIFF_OFF #ifndef _VERILATED_VCD_C_H_ #define _VERILATED_VCD_C_H_ 1 #include "verilatedos.h" #include "verilated.h" #include #include #include class VerilatedVcd; class VerilatedVcdCallInfo; // SPDIFF_ON //============================================================================= // VerilatedFile /// File handling routines, which can be overrode for e.g. socket I/O class VerilatedVcdFile { private: int m_fd; ///< File descriptor we're writing to public: // METHODS VerilatedVcdFile() : m_fd(0) {} virtual ~VerilatedVcdFile() {} virtual bool open(const std::string& name) VL_MT_UNSAFE; virtual void close() VL_MT_UNSAFE; virtual ssize_t write(const char* bufp, ssize_t len) VL_MT_UNSAFE; }; //============================================================================= // VerilatedVcdSig /// Internal data on one signal being traced. class VerilatedVcdSig { protected: friend class VerilatedVcd; vluint32_t m_code; ///< VCD file code number int m_bits; ///< Size of value in bits VerilatedVcdSig (vluint32_t code, int bits) : m_code(code), m_bits(bits) {} public: ~VerilatedVcdSig() {} }; //============================================================================= typedef void (*VerilatedVcdCallback_t)(VerilatedVcd* vcdp, void* userthis, vluint32_t code); //============================================================================= // VerilatedVcd /// Base class to create a Verilator VCD dump /// This is an internally used class - see VerilatedVcdC for what to call from applications class VerilatedVcd { private: VerilatedVcdFile* m_filep; ///< File we're writing to bool m_fileNewed; ///< m_filep needs destruction bool m_isOpen; ///< True indicates open file bool m_evcd; ///< True for evcd format std::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 std::string m_modName; ///< Module name being traced now double m_timeRes; ///< Time resolution (ns/ms etc) double m_timeUnit; ///< Time units (ns/ms etc) vluint64_t m_timeLastDump; ///< Last time we did a dump char* m_wrBufp; ///< Output buffer char* m_wrFlushp; ///< Output buffer flush trigger location char* m_writep; ///< Write pointer into output buffer vluint64_t m_wrChunkSize; ///< Output buffer size vluint64_t m_wroteBytes; ///< Number of bytes written to this file vluint32_t* m_sigs_oldvalp; ///< Pointer to old signal values typedef std::vector SigVec; SigVec m_sigs; ///< Pointer to signal information typedef std::vector CallbackVec; CallbackVec m_callbacks; ///< Routines to perform dumping typedef std::map NameMap; NameMap* m_namemapp; ///< List of names for the header VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread void bufferResize(vluint64_t minsize); void bufferFlush() VL_MT_UNSAFE_ONE; inline void bufferCheck() { // Flush the write buffer if there's not enough space left for new information // We only call this once per vector, so we need enough slop for a very wide "b###" line if (VL_UNLIKELY(m_writep > m_wrFlushp)) { bufferFlush(); } } void closePrev(); void closeErr(); void openNext(); void makeNameMap(); void deleteNameMap(); void printIndent (int levelchange); void printStr (const char* str); void printQuad (vluint64_t n); void printTime (vluint64_t timeui); void declare (vluint32_t code, const char* name, const char* wirep, int arraynum, bool tri, bool bussed, int msb, int lsb); void dumpHeader(); void dumpPrep (vluint64_t timeui); void dumpFull (vluint64_t timeui); // cppcheck-suppress functionConst void dumpDone (); inline void printCode (vluint32_t code) { if (code>=(94*94*94)) *m_writep++ = static_cast((code/94/94/94)%94+33); if (code>=(94*94)) *m_writep++ = static_cast((code/94/94)%94+33); if (code>=(94)) *m_writep++ = static_cast((code/94)%94+33); *m_writep++ = static_cast((code)%94+33); } static std::string stringCode (vluint32_t code) VL_PURE { std::string out; if (code>=(94*94*94)) out += static_cast((code/94/94/94)%94+33); if (code>=(94*94)) out += static_cast((code/94/94)%94+33); if (code>=(94)) out += static_cast((code/94)%94+33); return out + static_cast((code)%94+33); } // CONSTRUCTORS VL_UNCOPYABLE(VerilatedVcd); public: explicit VerilatedVcd(VerilatedVcdFile* filep=NULL); ~VerilatedVcd(); // ACCESSORS /// 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) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors void openNext (bool incFilename); ///< Open next data-only file void close() VL_MT_UNSAFE_ONE; ///< Close the file /// Flush any remaining data to this file void flush() VL_MT_UNSAFE_ONE { bufferFlush(); } /// Flush any remaining data from all files static void flush_all() VL_MT_UNSAFE_ONE; void set_time_unit (const char* unit); ///< Set time units (s/ms, defaults to ns) void set_time_unit (const std::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 std::string& unit) { set_time_resolution(unit.c_str()); } double timescaleToDouble (const char* unitp); std::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(static_cast(secs * m_timeRes)); } /// Inside dumping routines, declare callbacks for tracings void addCallback (VerilatedVcdCallback_t init, VerilatedVcdCallback_t full, VerilatedVcdCallback_t change, void* userthis) VL_MT_UNSAFE_ONE; /// Inside dumping routines, declare a module void module (const std::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'+static_cast(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<(&m_sigs_oldvalp[code]))) = newval; *m_writep++='b'; for (int bit=bits-1; bit>=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) { (*(reinterpret_cast(&m_sigs_oldvalp[code]))) = newval; (*(reinterpret_cast(&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<(&m_sigs_oldvalp[code]))) ^ newval; if (VL_UNLIKELY(diff)) { if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<(&m_sigs_oldvalp[code]))) ^ newval) | ((*(reinterpret_cast(&m_sigs_oldvalp[code+1]))) ^ newtri)); if (VL_UNLIKELY(diff)) { if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<(&m_sigs_oldvalp[code]))) != newval)) { fullDouble (code, newval); } } inline void chgFloat (vluint32_t code, const float newval) { // cppcheck-suppress invalidPointerCast if (VL_UNLIKELY((*(reinterpret_cast(&m_sigs_oldvalp[code]))) != newval)) { fullFloat (code, newval); } } protected: // METHODS void evcd(bool flag) { m_evcd = flag; } }; //============================================================================= // VerilatedVcdC /// Create a VCD dump file in C standalone (no SystemC) simulations. /// Also derived for use in SystemC simulations. /// Thread safety: Unless otherwise indicated, every function is VL_MT_UNSAFE_ONE class VerilatedVcdC { VerilatedVcd m_sptrace; ///< Trace file being created // CONSTRUCTORS VL_UNCOPYABLE(VerilatedVcdC); public: explicit VerilatedVcdC(VerilatedVcdFile* filep=NULL) : m_sptrace(filep) {} ~VerilatedVcdC() {} public: // ACCESSORS /// Is file open? bool isOpen() const { return m_sptrace.isOpen(); } // METHODS /// Open a new VCD file /// This includes a complete header dump each time it is called, /// just as if this object was deleted and reconstructed. void open(const char* filename) VL_MT_UNSAFE_ONE { m_sptrace.open(filename); } /// Continue a VCD dump by rotating to a new file name /// The header is only in the first file created, this allows /// "cat" to be used to combine the header plus any number of data files. void openNext(bool incFilename=true) VL_MT_UNSAFE_ONE { m_sptrace.openNext(incFilename); } /// Set size in megabytes after which new file should be created void rolloverMB(size_t rolloverMB) { m_sptrace.rolloverMB(rolloverMB); }; /// Close dump void close() VL_MT_UNSAFE_ONE { m_sptrace.close(); } /// Flush dump void flush() VL_MT_UNSAFE_ONE { m_sptrace.flush(); } /// Write one cycle of dump data void dump (vluint64_t timeui) { m_sptrace.dump(timeui); } /// Write one cycle of dump data - backward compatible and to reduce /// conversion warnings. It's better to use a vluint64_t time instead. void dump (double timestamp) { dump(static_cast(timestamp)); } void dump (vluint32_t timestamp) { dump(static_cast(timestamp)); } void dump (int timestamp) { dump(static_cast(timestamp)); } /// Set time units (s/ms, defaults to ns) /// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h void set_time_unit (const char* unit) { m_sptrace.set_time_unit(unit); } void set_time_unit (const std::string& unit) { set_time_unit(unit.c_str()); } /// Set time resolution (s/ms, defaults to ns) /// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h void set_time_resolution (const char* unit) { m_sptrace.set_time_resolution(unit); } void set_time_resolution (const std::string& unit) { set_time_resolution(unit.c_str()); } /// Internal class access inline VerilatedVcd* spTrace () { return &m_sptrace; }; }; #endif // guard verilator-3.916/include/vltstd/0000775000177100017500000000000013206353162016464 5ustar wsnyderwsnyderverilator-3.916/include/vltstd/svdpi.h0000664000177100017500000004417413205574202017773 0ustar wsnyderwsnyder/* -*- C -*- * * svdpi.h * * SystemVerilog Direct Programming Interface (DPI). * * This file contains the constant definitions, structure definitions, * and routine declarations used by SystemVerilog DPI. * * This file is from the SystemVerilog IEEE 1800-2012 Annex I. */ #ifndef INCLUDED_SVDPI #define INCLUDED_SVDPI #ifdef __cplusplus extern "C" { #endif /* 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(__APPLE__) #include #elif defined(__linux) || (defined(__APPLE__) && defined(__MACH__)) #include #else #include #endif /* Use to import a symbol into dll */ #ifndef DPI_DLLISPEC #if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)) #define DPI_DLLISPEC __declspec(dllimport) #else #define DPI_DLLISPEC #endif #endif /* Use to export a symbol from dll */ #ifndef DPI_DLLESPEC #if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)) #define DPI_DLLESPEC __declspec(dllexport) #else #define DPI_DLLESPEC #endif #endif /* Use to mark a function as external */ #ifndef DPI_EXTERN #define DPI_EXTERN #endif #ifndef DPI_PROTOTYPES #define DPI_PROTOTYPES /* object is defined imported by the application */ #define XXTERN DPI_EXTERN DPI_DLLISPEC /* object is exported by the application */ #define EETERN DPI_EXTERN DPI_DLLESPEC #endif /* canonical representation */ #define sv_0 0 #define sv_1 1 #define sv_z 2 #define sv_x 3 /* common type for 'bit' and 'logic' scalars. */ typedef uint8_t svScalar; typedef svScalar svBit; /* scalar */ typedef svScalar svLogic; /* scalar */ /* * DPI representation of packed arrays. * 2-state and 4-state vectors, exactly the same as PLI's avalue/bvalue. */ #ifndef VPI_VECVAL #define VPI_VECVAL typedef struct t_vpi_vecval { uint32_t aval; uint32_t bval; } s_vpi_vecval, *p_vpi_vecval; #endif /* (a chunk of) packed logic array */ typedef s_vpi_vecval svLogicVecVal; /* (a chunk of) packed bit array */ typedef uint32_t svBitVecVal; /* Number of chunks required to represent the given width packed array */ #define SV_PACKED_DATA_NELEMS(WIDTH) (((WIDTH) + 31) >> 5) /* * Because the contents of the unused bits is undetermined, * the following macros can be handy. */ #define SV_MASK(N) (~(-1 << (N))) #define SV_GET_UNSIGNED_BITS(VALUE, N) \ ((N) == 32 ? (VALUE) : ((VALUE) & SV_MASK(N))) #define SV_GET_SIGNED_BITS(VALUE, N) \ ((N) == 32 ? (VALUE) : \ (((VALUE) & (1 << (N))) ? ((VALUE) | ~SV_MASK(N)) : ((VALUE) & SV_MASK(N)))) /* * Implementation-dependent representation. */ /* * Return implementation version information string ("1800-2005" or "SV3.1a"). */ XXTERN const char* svDpiVersion(); /* a handle to a scope (an instance of a module or interface) */ XXTERN typedef void* svScope; /* a handle to a generic object (actually, unsized array) */ XXTERN typedef void* svOpenArrayHandle; /* * Bit-select utility functions. * * Packed arrays are assumed to be indexed n-1:0, * where 0 is the index of LSB */ /* s=source, i=bit-index */ XXTERN svBit svGetBitselBit(const svBitVecVal* s, int i); XXTERN svLogic svGetBitselLogic(const svLogicVecVal* s, int i); /* d=destination, i=bit-index, s=scalar */ XXTERN void svPutBitselBit(svBitVecVal* d, int i, svBit s); XXTERN void svPutBitselLogic(svLogicVecVal* d, int i, svLogic s); /* * Part-select utility functions. * * A narrow (<=32 bits) part-select is extracted from the * source representation and written into the destination word. * * Normalized ranges and indexing [n-1:0] are used for both arrays. * * s=source, d=destination, i=starting bit index, w=width * like for variable part-selects; limitations: w <= 32 */ XXTERN void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w); XXTERN void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w); XXTERN void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w); XXTERN void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w); /* * Open array querying functions * These functions are modeled upon the SystemVerilog array * querying functions and use the same semantics. * * If the dimension is 0, then the query refers to the * packed part of an array (which is one-dimensional). * Dimensions > 0 refer to the unpacked part of an array. */ /* h= handle to open array, d=dimension */ XXTERN int svLeft(const svOpenArrayHandle h, int d); XXTERN int svRight(const svOpenArrayHandle h, int d); XXTERN int svLow(const svOpenArrayHandle h, int d); XXTERN int svHigh(const svOpenArrayHandle h, int d); XXTERN int svIncrement(const svOpenArrayHandle h, int d); XXTERN int svSize(const svOpenArrayHandle h, int d); XXTERN int svDimensions(const svOpenArrayHandle h); /* * Pointer to the actual representation of the whole array of any type * NULL if not in C layout */ XXTERN void *svGetArrayPtr(const svOpenArrayHandle); /* total size in bytes or 0 if not in C layout */ XXTERN int svSizeOfArray(const svOpenArrayHandle); /* * Return a pointer to an element of the array * or NULL if index outside the range or null pointer */ XXTERN void *svGetArrElemPtr(const svOpenArrayHandle, int indx1, ...); /* specialized versions for 1-, 2- and 3-dimensional arrays: */ XXTERN void *svGetArrElemPtr1(const svOpenArrayHandle, int indx1); XXTERN void *svGetArrElemPtr2(const svOpenArrayHandle, int indx1, int indx2); XXTERN void *svGetArrElemPtr3(const svOpenArrayHandle, int indx1, int indx2, int indx3); /* * Functions for copying between simulator storage and user space. * These functions copy the whole packed array in either direction. * The user is responsible for allocating an array to hold the * canonical representation. */ /* s=source, d=destination */ /* From user space into simulator storage */ XXTERN void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, ...); XXTERN void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1); XXTERN void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2); XXTERN void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2, int indx3); XXTERN void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, ...); XXTERN void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1); XXTERN void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, int indx2); XXTERN void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, int indx2, int indx3); /* From simulator storage into user space */ XXTERN void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, ...); XXTERN void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1); XXTERN void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2); XXTERN void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, ...); XXTERN void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1); XXTERN void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2); XXTERN void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...); XXTERN svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1); XXTERN svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2); XXTERN svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...); XXTERN svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1); XXTERN svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2); XXTERN svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...); XXTERN void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1); XXTERN void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2); XXTERN void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2, int indx3); XXTERN void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...); XXTERN void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1); XXTERN void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1, int indx2); XXTERN void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1, int indx2, int indx3); /* Functions for working with DPI context */ /* * Retrieve the active instance scope currently associated with the executing * imported function. Unless a prior call to svSetScope has occurred, this * is the scope of the function's declaration site, not call site. * Returns NULL if called from C code that is *not* an imported function. */ XXTERN svScope svGetScope(); /* * Set context for subsequent export function execution. * This function must be called before calling an export function, unless * the export function is called while executing an import function. In that * case the export function shall inherit the scope of the surrounding import * function. This is known as the "default scope". * The return is the previous active scope (per svGetScope) */ XXTERN svScope svSetScope(const svScope scope); /* Gets the fully qualified name of a scope handle */ XXTERN const char* svGetNameFromScope(const svScope); /* * Retrieve svScope to instance scope of an arbitrary function declaration. * (can be either module, program, interface, or generate scope) * The return value shall be NULL for unrecognized scope names. */ XXTERN svScope svGetScopeFromName(const char* scopeName); /* * Store an arbitrary user data pointer for later retrieval by svGetUserData() * The userKey is generated by the user. It must be guaranteed by the user to * be unique from all other userKey's for all unique data storage requirements * It is recommended that the address of static functions or variables in the * user's C code be used as the userKey. * It is illegal to pass in NULL values for either the scope or userData * arguments. It is also an error to call svPutUserData() with an invalid * svScope. This function returns -1 for all error cases, 0 upon success. It is * suggested that userData values of 0 (NULL) not be used as otherwise it can * be impossible to discern error status returns when calling svGetUserData() */ XXTERN int svPutUserData(const svScope scope, void *userKey, void* userData); /* * Retrieve an arbitrary user data pointer that was previously * stored by a call to svPutUserData(). See the comment above * svPutUserData() for an explanation of userKey, as well as * restrictions on NULL and illegal svScope and userKey values. * This function returns NULL for all error cases, 0 upon success. * This function also returns NULL in the event that a prior call * to svPutUserData() was never made. */ XXTERN void* svGetUserData(const svScope scope, void* userKey); /* * Returns the file and line number in the SV code from which the import call * was made. If this information available, returns TRUE and updates fileName * and lineNumber to the appropriate values. Behavior is unpredictable if * fileName or lineNumber are not appropriate pointers. If this information is * not available return FALSE and contents of fileName and lineNumber not * modified. Whether this information is available or not is implementation- * specific. Note that the string provided (if any) is owned by the SV * implementation and is valid only until the next call to any SV function. * Applications must not modify this string or free it */ XXTERN int svGetCallerInfo(const char** fileName, int *lineNumber); /* * Returns 1 if the current execution thread is in the disabled state. * Disable protocol must be adhered to if in the disabled state. */ XXTERN int svIsDisabledState(); /* * Imported functions call this API function during disable processing to * acknowledge that they are correctly participating in the DPI disable protocol. * This function must be called before returning from an imported function that is * in the disabled state. */ XXTERN void svAckDisabledState(); /* ********************************************************** * DEPRECATED PORTION OF FILE STARTS FROM HERE. * IEEE-1800-compliant tools may not provide * support for the following functionality. ********************************************************** */ /* * Canonical representation of packed arrays * 2-state and 4-state vectors, modeled upon PLI's avalue/bvalue */ #define SV_CANONICAL_SIZE(WIDTH) (((WIDTH)+31)>>5) typedef unsigned int svBitVec32;/* (a chunk of) packed bit array */ typedef struct { unsigned int c; unsigned int d;} svLogicVec32; /* (a chunk of) packed logic array */ /* reference to a standalone packed array */ typedef void* svBitPackedArrRef; typedef void* svLogicPackedArrRef; /* * total size in bytes of the simulator's representation of a packed array * width in bits */ XXTERN int svSizeOfBitPackedArr(int width); XXTERN int svSizeOfLogicPackedArr(int width); /* Translation between the actual representation and the canonical representation */ /* s=source, d=destination, w=width */ /* actual <-- canonical */ XXTERN void svPutBitVec32(svBitPackedArrRef d, const svBitVec32* s, int w); XXTERN void svPutLogicVec32(svLogicPackedArrRef d, const svLogicVec32* s, int w); /* canonical <-- actual */ XXTERN void svGetBitVec32(svBitVec32* d, const svBitPackedArrRef s, int w); XXTERN void svGetLogicVec32(svLogicVec32* d, const svLogicPackedArrRef s, int w); /* * Bit-select functions * Packed arrays are assumed to be indexed n-1:0, * where 0 is the index of LSB */ /* s=source, i=bit-index */ XXTERN svBit svGetSelectBit(const svBitPackedArrRef s, int i); XXTERN svLogic svGetSelectLogic(const svLogicPackedArrRef s, int i); /* d=destination, i=bit-index, s=scalar */ XXTERN void svPutSelectBit(svBitPackedArrRef d, int i, svBit s); XXTERN void svPutSelectLogic(svLogicPackedArrRef d, int i, svLogic s); /* * functions for part-select * * a narrow (<=32 bits) part-select is copied between * the implementation representation and a single chunk of * canonical representation * Normalized ranges and indexing [n-1:0] are used for both arrays: * the array in the implementation representation and the canonical array. * * s=source, d=destination, i=starting bit index, w=width * like for variable part-selects; limitations: w <= 32 */ /* canonical <-- actual */ XXTERN void svGetPartSelectBit(svBitVec32* d, const svBitPackedArrRef s, int i, int w); XXTERN svBitVec32 svGetBits(const svBitPackedArrRef s, int i, int w); XXTERN svBitVec32 svGet32Bits(const svBitPackedArrRef s, int i); /* 32-bits */ XXTERN uint64_t svGet64Bits(const svBitPackedArrRef s, int i); /* 64-bits */ XXTERN void svGetPartSelectLogic(svLogicVec32* d, const svLogicPackedArrRef s, int i, int w); /* actual <-- canonical */ XXTERN void svPutPartSelectBit(svBitPackedArrRef d, const svBitVec32 s, int i, int w); XXTERN void svPutPartSelectLogic(svLogicPackedArrRef d, const svLogicVec32* s, int i, int w); /* * Functions for open array translation between simulator and canonical * representations. These functions copy the whole packed array in either * direction. The user is responsible for allocating an array in the * canonical representation. */ /* s=source, d=destination */ /* actual <-- canonical */ XXTERN void svPutBitArrElemVec32(const svOpenArrayHandle d, const svBitVec32* s, int indx1, ...); XXTERN void svPutBitArrElem1Vec32(const svOpenArrayHandle d, const svBitVec32* s, int indx1); XXTERN void svPutBitArrElem2Vec32(const svOpenArrayHandle d, const svBitVec32* s, int indx1, int indx2); XXTERN void svPutBitArrElem3Vec32(const svOpenArrayHandle d, const svBitVec32* s, int indx1, int indx2, int indx3); XXTERN void svPutLogicArrElemVec32(const svOpenArrayHandle d, const svLogicVec32* s, int indx1, ...); XXTERN void svPutLogicArrElem1Vec32(const svOpenArrayHandle d, const svLogicVec32* s, int indx1); XXTERN void svPutLogicArrElem2Vec32(const svOpenArrayHandle d, const svLogicVec32* s, int indx1, int indx2); XXTERN void svPutLogicArrElem3Vec32(const svOpenArrayHandle d, const svLogicVec32* s, int indx1, int indx2, int indx3); /* canonical <-- actual */ XXTERN void svGetBitArrElemVec32(svBitVec32* d, const svOpenArrayHandle s, int indx1, ...); XXTERN void svGetBitArrElem1Vec32(svBitVec32* d, const svOpenArrayHandle s, int indx1); XXTERN void svGetBitArrElem2Vec32(svBitVec32* d, const svOpenArrayHandle s, int indx1, int indx2); XXTERN void svGetBitArrElem3Vec32(svBitVec32* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN void svGetLogicArrElemVec32(svLogicVec32* d, const svOpenArrayHandle s, int indx1, ...); XXTERN void svGetLogicArrElem1Vec32(svLogicVec32* d, const svOpenArrayHandle s, int indx1); XXTERN void svGetLogicArrElem2Vec32(svLogicVec32* d, const svOpenArrayHandle s, int indx1, int indx2); XXTERN void svGetLogicArrElem3Vec32(svLogicVec32* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3); /* ********************************************************** * DEPRECATED PORTION OF FILE ENDS HERE. ********************************************************** */ #undef DPI_EXTERN #ifdef DPI_PROTOTYPES #undef DPI_PROTOTYPES #undef XXTERN #undef EETERN #endif #ifdef __cplusplus } #endif #endif verilator-3.916/include/vltstd/vpi_user.h0000664000177100017500000013072213205574202020475 0ustar wsnyderwsnyder/******************************************************************************* * vpi_user.h * * IEEE Std 1800-2012 Programming Language Interface (PLI) * * This file contains the constant definitions, structure definitions, and * routine declarations used by the SystemVerilog Verification Procedural * Interface (VPI) access routines. * ******************************************************************************/ /******************************************************************************* * NOTE: the constant values 1 through 299 are reserved for use in this * vpi_user.h file. ******************************************************************************/ #ifndef VPI_USER_H #define VPI_USER_H #include #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------------------------*/ /*----------------------------- Portability Help -----------------------------*/ /*----------------------------------------------------------------------------*/ /* Define size-critical types on all OS platforms. */ #if defined (_MSC_VER) typedef unsigned __int64 uint64_t; typedef unsigned __int32 uint32_t; typedef unsigned __int8 uint8_t; typedef signed __int64 int64_t; typedef signed __int32 int32_t; typedef signed __int8 int8_t; #elif defined(__MINGW32__) #include #elif defined(__linux) || (defined(__APPLE__) && defined(__MACH__)) #include #else #include #endif /* Sized variables */ #ifndef SVPI_TYPES #define SVPI_TYPES typedef int64_t PLI_INT64; typedef uint64_t PLI_UINT64; #endif #ifndef PLI_TYPES #define PLI_TYPES typedef int PLI_INT32; typedef unsigned int PLI_UINT32; typedef short PLI_INT16; typedef unsigned short PLI_UINT16; typedef char PLI_BYTE8; typedef unsigned char PLI_UBYTE8; #endif /* Use to import a symbol */ #if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)) #ifndef PLI_DLLISPEC #define PLI_DLLISPEC __declspec(dllimport) #define VPI_USER_DEFINED_DLLISPEC 1 #endif #else #ifndef PLI_DLLISPEC #define PLI_DLLISPEC #endif #endif /* Use to export a symbol */ #if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)) #ifndef PLI_DLLESPEC #define PLI_DLLESPEC __declspec(dllexport) #define VPI_USER_DEFINED_DLLESPEC 1 #endif #else #ifndef PLI_DLLESPEC #define PLI_DLLESPEC #endif #endif /* Use to mark a function as external */ #ifndef PLI_EXTERN #define PLI_EXTERN #endif /* Use to mark a variable as external */ #ifndef PLI_VEXTERN #define PLI_VEXTERN extern #endif #ifndef PLI_PROTOTYPES #define PLI_PROTOTYPES #define PROTO_PARAMS(params) params /* object is defined imported by the application */ #undef XXTERN #define XXTERN PLI_EXTERN PLI_DLLISPEC /* object is exported by the application */ #undef EETERN #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.916/include/verilated_vcd_c.cpp0000664000177100017500000006412613205574202020775 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2017 by Wilson Snyder. This program is free software; // you can redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief C++ Tracing in VCD Format /// //============================================================================= // SPDIFF_OFF #include "verilatedos.h" #include "verilated.h" #include "verilated_vcd_c.h" #include #include #include #include #include #include #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) # include #else # include #endif // SPDIFF_ON #ifndef O_LARGEFILE // For example on WIN32 # define O_LARGEFILE 0 #endif #ifndef O_NONBLOCK # define O_NONBLOCK 0 #endif //============================================================================= // VerilatedVcdImp /// Base class to hold some static state /// This is an internally used class class VerilatedVcdSingleton { private: typedef std::vector VcdVec; struct Singleton { VerilatedMutex s_vcdMutex; ///< Protect the singleton VcdVec s_vcdVecp VL_GUARDED_BY(s_vcdMutex); ///< List of all created traces }; static Singleton& singleton() { static Singleton s; return s; } public: static void pushVcd(VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) { VerilatedLockGuard guard(singleton().s_vcdMutex); singleton().s_vcdVecp.push_back(vcdp); } static void removeVcd(const VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) { VerilatedLockGuard guard(singleton().s_vcdMutex); VcdVec::iterator pos = find(singleton().s_vcdVecp.begin(), singleton().s_vcdVecp.end(), vcdp); if (pos != singleton().s_vcdVecp.end()) { singleton().s_vcdVecp.erase(pos); } } static void flush_all() VL_EXCLUDES(singleton().s_vcdMutex) VL_MT_UNSAFE_ONE { // Thread safety: Although this function is protected by a mutex so perhaps // in the future we can allow tracing in separate threads, vcdp->flush() assumes call from single thread VerilatedLockGuard guard(singleton().s_vcdMutex); for (VcdVec::const_iterator it=singleton().s_vcdVecp.begin(); it!=singleton().s_vcdVecp.end(); ++it) { VerilatedVcd* vcdp = *it; vcdp->flush(); } } }; //============================================================================= // VerilatedVcdCallInfo /// Internal callback routines for each module being traced. //// /// Each module that wishes to be traced registers a set of /// callbacks stored in this class. When the trace file is being /// constructed, this class provides the callback routines to be executed. class VerilatedVcdCallInfo { protected: friend class VerilatedVcd; VerilatedVcdCallback_t m_initcb; ///< Initialization Callback function VerilatedVcdCallback_t m_fullcb; ///< Full Dumping Callback function VerilatedVcdCallback_t m_changecb; ///< Incremental Dumping Callback function void* m_userthis; ///< Fake "this" for caller vluint32_t m_code; ///< Starting code number // CONSTRUCTORS 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) {}; ~VerilatedVcdCallInfo() {} }; //============================================================================= //============================================================================= //============================================================================= // VerilatedVcdFile bool VerilatedVcdFile::open(const std::string& name) VL_MT_UNSAFE { m_fd = ::open(name.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK, 0666); return (m_fd>=0); } void VerilatedVcdFile::close() VL_MT_UNSAFE { ::close(m_fd); } ssize_t VerilatedVcdFile::write(const char* bufp, ssize_t len) VL_MT_UNSAFE { return ::write(m_fd, bufp, len); } //============================================================================= //============================================================================= //============================================================================= // Opening/Closing VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep) : m_isOpen(false), m_rolloverMB(0), m_modDepth(0), m_nextCode(1) { // Not in header to avoid link issue if header is included without this .cpp file m_fileNewed = (filep == NULL); m_filep = m_fileNewed ? new VerilatedVcdFile : filep; m_namemapp = NULL; m_timeRes = m_timeUnit = 1e-9; m_timeLastDump = 0; m_sigs_oldvalp = NULL; m_evcd = false; m_scopeEscape = '.'; // Backward compatibility m_fullDump = true; m_wrChunkSize = 8*1024; m_wrBufp = new char [m_wrChunkSize*8]; m_wrFlushp = m_wrBufp + m_wrChunkSize * 6; m_writep = m_wrBufp; m_wroteBytes = 0; } void VerilatedVcd::open (const char* filename) { m_assertOne.check(); if (isOpen()) return; // Set member variables m_filename = filename; VerilatedVcdSingleton::pushVcd(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. m_assertOne.check(); closePrev(); // Close existing if (incFilename) { // Find _0000.{ext} in filename std::string name = m_filename; size_t pos=name.rfind("."); if (pos>8 && 0==strncmp("_cat",name.c_str()+pos-8,4) && isdigit(name.c_str()[pos-4]) && isdigit(name.c_str()[pos-3]) && isdigit(name.c_str()[pos-2]) && isdigit(name.c_str()[pos-1])) { // Increment code. if ((++(name[pos-1])) > '9') { name[pos-1] = '0'; if ((++(name[pos-2])) > '9') { name[pos-2] = '0'; if ((++(name[pos-3])) > '9') { name[pos-3] = '0'; if ((++(name[pos-4])) > '9') { name[pos-4] = '0'; }}}} } else { // Append _cat0000 name.insert(pos,"_cat0000"); } m_filename = name; } if (m_filename[0]=='|') { assert(0); // Not supported yet. } else { // cppcheck-suppress duplicateExpression if (!m_filep->open(m_filename)) { // User code can check isOpen() m_isOpen = false; return; } } m_isOpen = true; m_fullDump = true; // First dump must be full m_wroteBytes = 0; } void VerilatedVcd::makeNameMap() { // Take signal information from each module and build m_namemapp deleteNameMap(); m_nextCode = 1; m_namemapp = new NameMap; for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) { VerilatedVcdCallInfo *cip = m_callbacks[ent]; cip->m_code = m_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::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) { const std::string& hiername = it->first; if (hiername.size() >= 1 && hiername[0] == '\t') nullScope=true; } if (nullScope) { NameMap* newmapp = new NameMap; for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) { const std::string& hiername = it->first; const std::string& decl = it->second; std::string newname = std::string("top"); if (hiername[0] != '\t') newname += ' '; newname += hiername; newmapp->insert(std::make_pair(newname,decl)); } deleteNameMap(); m_namemapp = newmapp; } } void VerilatedVcd::deleteNameMap() { if (m_namemapp) { delete m_namemapp; m_namemapp=NULL; } } VerilatedVcd::~VerilatedVcd() { close(); if (m_wrBufp) { delete[] m_wrBufp; m_wrBufp=NULL; } if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; } deleteNameMap(); if (m_filep && m_fileNewed) { delete m_filep; m_filep = NULL; } for (CallbackVec::const_iterator it=m_callbacks.begin(); it!=m_callbacks.end(); ++it) { delete (*it); } m_callbacks.clear(); VerilatedVcdSingleton::removeVcd(this); } void VerilatedVcd::closePrev () { // This function is on the flush() call path if (!isOpen()) return; bufferFlush(); m_isOpen = false; m_filep->close(); } void VerilatedVcd::closeErr () { // This function is on the flush() call path // Close due to an error. We might abort before even getting here, // depending on the definition of vl_fatal. if (!isOpen()) return; // No buffer flush, just fclose m_isOpen = false; m_filep->close(); // May get error, just ignore it } void VerilatedVcd::close() { // This function is on the flush() call path m_assertOne.check(); 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 VL_THREAD_LOCAL bool backTime = false; if (!backTime) { backTime = true; VL_PRINTF_MT("%%Warning: VCD time is moving backwards, wave file may be incorrect.\n"); } } m_timeLastDump = timeui; printQuad(timeui); } void VerilatedVcd::bufferResize(vluint64_t minsize) { // minsize is size of largest write. We buffer at least 8 times as much data, // writing when we are 3/4 full (with thus 2*minsize remaining free) if (VL_UNLIKELY(minsize > m_wrChunkSize)) { char* oldbufp = m_wrBufp; m_wrChunkSize = minsize*2; m_wrBufp = new char [m_wrChunkSize * 8]; memcpy(m_wrBufp, oldbufp, m_writep - oldbufp); m_writep = m_wrBufp + (m_writep - oldbufp); m_wrFlushp = m_wrBufp + m_wrChunkSize * 6; delete oldbufp; oldbufp=NULL; } } void VerilatedVcd::bufferFlush () VL_MT_UNSAFE_ONE { // This function is on the flush() call path // 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 m_assertOne.check(); if (VL_UNLIKELY(!isOpen())) return; char* wp = m_wrBufp; while (1) { ssize_t remaining = (m_writep - wp); if (remaining==0) break; errno = 0; ssize_t got = m_filep->write(wp, remaining); if (got>0) { wp += got; m_wroteBytes += got; } else if (got < 0) { if (errno != EAGAIN && errno != EINTR) { // write failed, presume error (perhaps out of disk space) std::string msg = std::string("VerilatedVcd::bufferFlush: ")+strerror(errno); VL_FATAL_MT("",0,"",msg.c_str()); closeErr(); break; } } } // Reset buffer m_writep = m_wrBufp; } //============================================================================= // Simple methods void VerilatedVcd::set_time_unit (const char* unitp) { //cout<<" set_time_unit ("<=1e0) { suffixp="s"; value *= 1e0; } else if (value>=1e-3 ) { suffixp="ms"; value *= 1e3; } else if (value>=1e-6 ) { suffixp="us"; value *= 1e6; } else if (value>=1e-9 ) { suffixp="ns"; value *= 1e9; } else if (value>=1e-12) { suffixp="ps"; value *= 1e12; } else if (value>=1e-15) { suffixp="fs"; value *= 1e15; } else if (value>=1e-18) { suffixp="as"; value *= 1e18; } char valuestr[100]; sprintf(valuestr,"%3.0f%s", value, suffixp); return valuestr; // Gets converted to string, so no ref to stack } //============================================================================= // Definitions void VerilatedVcd::printIndent (int level_change) { if (level_change<0) m_modDepth += level_change; assert(m_modDepth>=0); for (int i=0; i0) m_modDepth += level_change; } void VerilatedVcd::dumpHeader () { printStr("$version Generated by VerilatedVcd $end\n"); time_t time_str = time(NULL); printStr("$date "); printStr(ctime(&time_str)); printStr(" $end\n"); printStr("$timescale "); const std::string& timeResStr = doubleToTimescale(m_timeRes); printStr(timeResStr.c_str()); printStr(" $end\n"); makeNameMap(); // Signal header assert (m_modDepth==0); printIndent(1); printStr("\n"); // We detect the spaces in module names to determine hierarchy. This // allows signals to be declared without fixed ordering, which is // required as Verilog signals might be separately declared from // SC module signals. // Print the signal names const char* lastName = ""; for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) { const std::string& hiernamestr = it->first; const std::string& decl = it->second; // Determine difference between the old and new names const char* hiername = hiernamestr.c_str(); const char* lp = lastName; const char* np = hiername; lastName = hiername; // Skip common prefix, it must break at a space or tab for (; *np && (*np == *lp); np++, lp++) {} while (np!=hiername && *np && *np!=' ' && *np!='\t') { np--; lp--; } //printf("hier %s\n lp=%s\n np=%s\n",hiername,lp,np); // Any extra spaces in last name are scope ups we need to do bool first = true; for (; *lp; lp++) { if (*lp==' ' || (first && *lp!='\t')) { printIndent(-1); printStr("$upscope $end\n"); } first = false; } // Any new spaces are scope downs we need to do while (*np) { if (*np==' ') np++; if (*np=='\t') break; // tab means signal name starts printIndent(1); printStr("$scope module "); for (; *np && *np!=' ' && *np!='\t'; np++) { if (*np=='[') printStr("("); else if (*np==']') printStr(")"); else *m_writep++=*np; } printStr(" $end\n"); } printIndent(0); printStr(decl.c_str()); } while (m_modDepth>1) { printIndent(-1); printStr("$upscope $end\n"); } printIndent(-1); printStr("$enddefinitions $end\n\n\n"); assert (m_modDepth==0); // Reclaim storage deleteNameMap(); } void VerilatedVcd::module (const std::string& name) { m_assertOne.check(); 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_MT(__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 = std::max(m_nextCode, code+codesNeeded); if (m_sigs.capacity() <= m_nextCode) { m_sigs.reserve(m_nextCode*2); // Power-of-2 allocation speeds things up } // Make sure write buffer is large enough (one character per bit), plus header bufferResize(bits+1024); // Save declaration info VerilatedVcdSig sig = VerilatedVcdSig(code, bits); m_sigs.push_back(sig); // Split name into basename // Spaces and tabs aren't legal in VCD signal names, so: // Space separates each level of scope // Tab separates final scope from signal name // Tab sorts before spaces, so signals nicely will print before scopes // Note the hiername may be nothing, if so we'll add "\t{name}" std::string nameasstr = name; if (m_modName!="") { nameasstr = m_modName+m_scopeEscape+nameasstr; } // Optional ->module prefix std::string hiername; std::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 std::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(std::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) { // cppcheck-suppress invalidPointerCast (*(reinterpret_cast(&m_sigs_oldvalp[code]))) = newval; // Buffer can't overflow before sprintf; we sized during declaration sprintf(m_writep, "r%.16g", newval); m_writep += strlen(m_writep); *m_writep++=' '; printCode(code); *m_writep++='\n'; bufferCheck(); } void VerilatedVcd::fullFloat (vluint32_t code, const float newval) { // cppcheck-suppress invalidPointerCast (*(reinterpret_cast(&m_sigs_oldvalp[code]))) = newval; // Buffer can't overflow before sprintf; we sized during declaration sprintf(m_writep, "r%.16g", static_cast(newval)); m_writep += strlen(m_writep); *m_writep++=' '; printCode(code); *m_writep++='\n'; bufferCheck(); } //============================================================================= // Callbacks void VerilatedVcd::addCallback VL_MT_UNSAFE_ONE ( VerilatedVcdCallback_t initcb, VerilatedVcdCallback_t fullcb, VerilatedVcdCallback_t changecb, void* userthis) { m_assertOne.check(); if (VL_UNLIKELY(isOpen())) { std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file"; VL_FATAL_MT(__FILE__,__LINE__,"",msg.c_str()); } VerilatedVcdCallInfo* vci = new VerilatedVcdCallInfo(initcb, fullcb, changecb, userthis, m_nextCode); m_callbacks.push_back(vci); } //============================================================================= // Dumping void VerilatedVcd::dumpFull (vluint64_t timeui) { m_assertOne.check(); dumpPrep (timeui); Verilated::quiesce(); 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); } } void VerilatedVcd::dump (vluint64_t timeui) { m_assertOne.check(); 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); Verilated::quiesce(); 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); } } void VerilatedVcd::dumpPrep (vluint64_t timeui) { printStr("#"); printTime(timeui); printStr("\n"); } //====================================================================== // Static members void VerilatedVcd::flush_all() VL_MT_UNSAFE_ONE { VerilatedVcdSingleton::flush_all(); } //====================================================================== //====================================================================== //====================================================================== #ifdef VERILATED_VCD_TEST vluint32_t v1, v2, s1, s2[3]; vluint32_t tri96[3]; vluint32_t tri96__tri[3]; vluint8_t ch; vluint64_t timestamp = 1; double doub = 0; void vcdInit (VerilatedVcd* vcdp, void* userthis, vluint32_t code) { vcdp->scopeEscape('.'); vcdp->module ("top"); vcdp->declBus (0x2, "v1",-1,5,1); vcdp->declBus (0x3, "v2",-1,6,0); vcdp->module ("top.sub1"); vcdp->declBit (0x4, "s1",-1); vcdp->declBit (0x5, "ch",-1); vcdp->module ("top.sub2"); vcdp->declArray (0x6, "s2",-1, 40,3); // Note need to add 3 for next code. vcdp->module ("top2"); vcdp->declBus (0x2, "t2v1",-1,4,1); vcdp->declTriBit (0x10, "io1", -1); vcdp->declTriBus (0x12, "io5", -1,4,0); vcdp->declTriArray (0x16, "io96",-1,95,0); // Note need to add 6 for next code. vcdp->declDouble (0x1c, "doub",-1); // Note need to add 2 for next code. } void vcdFull (VerilatedVcd* vcdp, void* userthis, vluint32_t code) { vcdp->fullBus (0x2, v1,5); vcdp->fullBus (0x3, v2,7); vcdp->fullBit (0x4, s1); vcdp->fullBus (0x5, ch,2); vcdp->fullArray(0x6, &s2[0], 38); vcdp->fullTriBit (0x10, tri96[0]&1, tri96__tri[0]&1); vcdp->fullTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5); vcdp->fullTriArray (0x16, tri96, tri96__tri, 96); vcdp->fullDouble(0x1c, doub); } void vcdChange (VerilatedVcd* vcdp, void* userthis, vluint32_t code) { vcdp->chgBus (0x2, v1,5); vcdp->chgBus (0x3, v2,7); vcdp->chgBit (0x4, s1); vcdp->chgBus (0x5, ch,2); vcdp->chgArray(0x6, &s2[0], 38); vcdp->chgTriBit (0x10, tri96[0]&1, tri96__tri[0]&1); vcdp->chgTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5); vcdp->chgTriArray (0x16, tri96, tri96__tri, 96); vcdp->chgDouble (0x1c, doub); } main() { cout<<"test: O_LARGEFILE="<spTrace()->addCallback (&vcdInit, &vcdFull, &vcdChange, 0); vcdp->open ("test.vcd"); // Dumping vcdp->dump(timestamp++); v1 = 0xfff; tri96[2] = 4; tri96[1] = 2; tri96[0] = 1; tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = ~0; // Still tri doub = 1.5; vcdp->dump(timestamp++); v2 = 0x1; s2[1] = 2; tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = 0; // enable w/o data change doub = -1.66e13; vcdp->dump(timestamp++); ch = 2; tri96[2] = ~4; tri96[1] = ~2; tri96[0] = ~1; doub = -3.33e-13; vcdp->dump(timestamp++); vcdp->dump(timestamp++); # ifdef VERILATED_VCD_TEST_64BIT vluint64_t bytesPerDump = 15ULL; for (vluint64_t i=0; i<((1ULL<<32) / bytesPerDump); i++) { v1 = i; vcdp->dump(timestamp++); } # endif vcdp->close(); } } #endif //******************************************************************** // Local Variables: // compile-command: "mkdir -p ../test_dir && cd ../test_dir && c++ -DVERILATED_VCD_TEST ../src/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd" // End: verilator-3.916/include/verilated_imp.h0000664000177100017500000004244513205574202020151 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 #include #ifdef VL_THREADED # include # include #endif class VerilatedScope; //====================================================================== // Threaded message passing #ifdef VL_THREADED /// Message, enqueued on a train, and consumed on the main eval thread class VerilatedMsg { public: // TYPES struct Cmp { bool operator() (const VerilatedMsg& a, const VerilatedMsg& b) { return a.trainId() < b.trainId(); } }; private: // MEMBERS vluint32_t m_trainId; ///< Train that did enqueue std::function m_cb; ///< Lambda to execute when message received public: // CONSTRUCTORS VerilatedMsg(const std::function& cb) : m_trainId(Verilated::trainId()), m_cb(cb) {} ~VerilatedMsg() {} // METHODS vluint32_t trainId() const { return m_trainId; } /// Execute the lambda function void run() const { m_cb(); } }; /// Each thread has a queue it pushes to /// This assumes no thread starts pushing the next tick until the previous has drained. /// If more aggressiveness is needed, a double-buffered scheme might work well. class VerilatedEvalMsgQueue { typedef std::multiset VerilatedThreadQueue; std::atomic m_depth; ///< Current depth of queue (see comments below) VerilatedMutex m_mutex; ///< Mutex protecting queue VerilatedThreadQueue m_queue VL_GUARDED_BY(m_mutex); ///< Message queue public: // CONSTRUCTORS VerilatedEvalMsgQueue() : m_depth(0) { } ~VerilatedEvalMsgQueue() { } private: VL_UNCOPYABLE(VerilatedEvalMsgQueue); public: // METHODS //// Add message to queue (called by producer) void post(const VerilatedMsg& msg) VL_EXCLUDES(m_mutex) { Verilated::endOfEvalReqdInc(); // No mutex, threadsafe VerilatedLockGuard guard(m_mutex); m_queue.insert(msg); // Pass by value to copy the message into queue ++m_depth; } /// Service queue until completion (called by consumer) void process() VL_EXCLUDES(m_mutex) { // Tracking m_depth is redundant to e.g. getting the mutex and looking at queue size, // but on the reader side it's 4x faster to test an atomic then getting a mutex while (m_depth) { // Wait for a message to be added to the queue // We don't use unique_lock as want to unlock with the message copy still in scope m_mutex.lock(); assert(!m_queue.empty()); // Otherwise m_depth is wrong // Unfortunately to release the lock we need to copy the message // (Or have the message be a pointer, but then new/delete cost on each message) // We assume messages are small, so copy auto it = m_queue.begin(); const VerilatedMsg msg = *(it); m_queue.erase(it); m_mutex.unlock(); m_depth--; // Ok if outside critical section as only this code checks the value Verilated::endOfEvalReqdDec(); // No mutex, threadsafe { VL_DEBUG_IF(VL_DBG_MSGF("Executing callback from trainId=%d\n", msg.trainId());); msg.run(); } } } }; /// Each thread has a local queue to build up messages until the end of the eval() call class VerilatedThreadMsgQueue { std::queue m_queue; public: // CONSTRUCTORS VerilatedThreadMsgQueue() { } ~VerilatedThreadMsgQueue() { // The only call of this with a non-empty queue is a fatal error. // So this does not flush the queue, as the destination queue is not known to this class. } private: VL_UNCOPYABLE(VerilatedThreadMsgQueue); // METHODS static VerilatedThreadMsgQueue& threadton() { static VL_THREAD_LOCAL VerilatedThreadMsgQueue t_s; return t_s; } public: /// Add message to queue, called by producer static void post(const VerilatedMsg& msg) VL_MT_SAFE { Verilated::endOfEvalReqdInc(); threadton().m_queue.push(msg); // Pass by value to copy the message into queue } /// Push all messages to the eval's queue static void flush(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { while (!threadton().m_queue.empty()) { evalMsgQp->post(threadton().m_queue.front()); threadton().m_queue.pop(); Verilated::endOfEvalReqdDec(); } } }; #endif // VL_THREADED //====================================================================== // VerilatedImp class VerilatedImp { // Whole class is internal use only - Global information shared between verilated*.cpp files. // TYPES typedef std::vector ArgVec; typedef std::map,void*> UserMap; typedef std::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 VerilatedMutex m_argMutex; ///< Protect m_argVec, m_argVecLoaded ArgVec m_argVec VL_GUARDED_BY(m_argMutex); ///< Argument list (NOT save-restored, may want different results) bool m_argVecLoaded VL_GUARDED_BY(m_argMutex); ///< Ever loaded argument list VerilatedMutex m_userMapMutex; ///< Protect m_userMap UserMap m_userMap VL_GUARDED_BY(m_userMapMutex); ///< Map of <(scope,userkey), userData> VerilatedMutex m_nameMutex; ///< Protect m_nameMap VerilatedScopeNameMap m_nameMap VL_GUARDED_BY(m_nameMutex); ///< Map of // Slow - somewhat static: VerilatedMutex m_exportMutex; ///< Protect m_nameMap ExportNameMap m_exportMap VL_GUARDED_BY(m_exportMutex); ///< Map of int m_exportNext VL_GUARDED_BY(m_exportMutex); ///< Next export funcnum // File I/O VerilatedMutex m_fdMutex; ///< Protect m_fdps, m_fdFree std::vector m_fdps VL_GUARDED_BY(m_fdMutex); ///< File descriptors std::deque m_fdFree VL_GUARDED_BY(m_fdMutex); ///< List of free descriptors (SLOW - FOPEN/CLOSE only) // Threads VerilatedMutex m_threadMutex; ///< Protect m_numThreads, etc bool m_spawned VL_GUARDED_BY(m_threadMutex); ///< Already called spawnThreads() unsigned m_numThreads VL_GUARDED_BY(m_threadMutex); ///< Number of threads user requested, 0x0=all cpus public: // But only for verilated*.cpp // CONSTRUCTORS VerilatedImp() : m_argVecLoaded(false), m_exportNext(0), m_spawned(false), m_numThreads(0) { m_fdps.resize(3); m_fdps[0] = stdin; m_fdps[1] = stdout; m_fdps[2] = stderr; } ~VerilatedImp() {} private: VL_UNCOPYABLE(VerilatedImp); public: static void internalsDump() VL_MT_SAFE { VerilatedLockGuard guard(s_s.m_argMutex); VL_PRINTF_MT("internalsDump:\n"); VL_PRINTF_MT(" Argv:"); for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) { VL_PRINTF_MT(" %s",it->c_str()); } VL_PRINTF_MT("\n"); VL_PRINTF_MT(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion()); scopesDump(); exportsDump(); userDump(); } // METHODS - arguments public: static void commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) { VerilatedLockGuard guard(s_s.m_argMutex); s_s.m_argVec.clear(); // Always clear commandArgsAddGuts(argc, argv); } static void commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) { VerilatedLockGuard guard(s_s.m_argMutex); commandArgsAddGuts(argc, argv); } static std::string argPlusMatch(const char* prefixp) VL_EXCLUDES(s_s.m_argMutex) { VerilatedLockGuard guard(s_s.m_argMutex); // Note prefixp does not include the leading "+" size_t len = strlen(prefixp); if (VL_UNLIKELY(!s_s.m_argVecLoaded)) { s_s.m_argVecLoaded = true; // Complain only once VL_FATAL_MT("unknown",0,"", "%Error: Verilog called $test$plusargs or $value$plusargs without" " testbench C first calling Verilated::commandArgs(argc,argv)."); } for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) { if ((*it)[0]=='+') { if (0==strncmp(prefixp, it->c_str()+1, len)) return *it; } } return ""; } private: static void commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex) { if (!s_s.m_argVecLoaded) s_s.m_argVec.clear(); for (int i=0; isecond = userData; // When we support VL_THREADs, we need a lock around this insert, as it's runtime else s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep,userKey),userData)); } static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE { VerilatedLockGuard guard(s_s.m_userMapMutex); UserMap::const_iterator it=s_s.m_userMap.find(std::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) VL_MT_SAFE { // Slow ok - called once/scope on destruction, so we simply iterate. VerilatedLockGuard guard(s_s.m_userMapMutex); 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() VL_MT_SAFE { VerilatedLockGuard guard(s_s.m_userMapMutex); // Avoid it changing in middle of dump bool first = true; for (UserMap::const_iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) { if (first) { VL_PRINTF_MT(" userDump:\n"); first=false; } VL_PRINTF_MT(" 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) VL_MT_SAFE { // Slow ok - called once/scope at construction VerilatedLockGuard guard(s_s.m_nameMutex); VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name()); if (it == s_s.m_nameMap.end()) { s_s.m_nameMap.insert(it, std::make_pair(scopep->name(),scopep)); } } static inline const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE { VerilatedLockGuard guard(s_s.m_nameMutex); // If too slow, can assume this is only VL_MT_SAFE_POSINIT VerilatedScopeNameMap::const_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) VL_MT_SAFE { // Slow ok - called once/scope at destruction VerilatedLockGuard guard(s_s.m_nameMutex); userEraseScope(scopep); VerilatedScopeNameMap::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_MT_SAFE { VerilatedLockGuard guard(s_s.m_nameMutex); VL_PRINTF_MT(" scopesDump:\n"); for (VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) { const VerilatedScope* scopep = it->second; scopep->scopeDump(); } VL_PRINTF_MT("\n"); } static const VerilatedScopeNameMap* scopeNameMap() VL_MT_SAFE_POSTINIT { // Thread save only assuming this is called only after model construction completed return &s_s.m_nameMap; } 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) VL_MT_SAFE { // Slow ok - called once/function at creation VerilatedLockGuard guard(s_s.m_exportMutex); ExportNameMap::iterator it=s_s.m_exportMap.find(namep); if (it == s_s.m_exportMap.end()) { s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++)); return s_s.m_exportNext++; } else { return it->second; } } static int exportFind(const char* namep) VL_MT_SAFE { VerilatedLockGuard guard(s_s.m_exportMutex); ExportNameMap::const_iterator it=s_s.m_exportMap.find(namep); if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second; std::string msg = (std::string("%Error: Testbench C called ")+namep +" but no such DPI export function name exists in ANY model"); VL_FATAL_MT("unknown",0,"", msg.c_str()); return -1; } static const char* exportName(int funcnum) VL_MT_SAFE { // Slowpath; find name for given export; errors only so no map to reverse-map it VerilatedLockGuard guard(s_s.m_exportMutex); for (ExportNameMap::const_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() VL_MT_SAFE { VerilatedLockGuard guard(s_s.m_exportMutex); bool first = true; for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) { if (first) { VL_PRINTF_MT(" exportDump:\n"); first=false; } VL_PRINTF_MT(" 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) VL_MT_SAFE { if (VL_UNLIKELY(!fp)) return 0; // Bit 31 indicates it's a descriptor not a MCD VerilatedLockGuard guard(s_s.m_fdMutex); 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(i)); } IData idx = s_s.m_fdFree.back(); s_s.m_fdFree.pop_back(); s_s.m_fdps[idx] = fp; return (idx | (1UL<<31)); // bit 31 indicates not MCD } static void fdDelete(IData fdi) VL_MT_SAFE { IData idx = VL_MASK_I(31) & fdi; VerilatedLockGuard guard(s_s.m_fdMutex); if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= 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) VL_MT_SAFE { IData idx = VL_MASK_I(31) & fdi; VerilatedLockGuard guard(s_s.m_fdMutex); // This might get slow, if it does we can cache it if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return NULL; return s_s.m_fdps[idx]; } public: // But only for verilated*.cpp // METHODS - Threading static void numThreads(unsigned threads) VL_MT_SAFE { VerilatedLockGuard guard(s_s.m_threadMutex); if (!s_s.m_spawned) s_s.m_numThreads = threads; } static unsigned numThreads() VL_MT_SAFE { VerilatedLockGuard guard(s_s.m_threadMutex); #ifdef VL_THREADED unsigned threads = s_s.m_numThreads; if (threads == 0x0) { threads = std::thread::hardware_concurrency(); // Or 0=unknown, C++11 } if (threads<1) threads = 1; return threads; #else return 0; #endif } static void spawnThreads() VL_MT_SAFE { VerilatedLockGuard guard(s_s.m_threadMutex); if (!s_s.m_spawned) { // Convert numThreads from 0 to the spawned number numThreads(numThreads()); s_s.m_spawned = true; #ifdef VL_THREADED // THREADED-TODO startup threads #endif } } }; //====================================================================== #endif // Guard verilator-3.916/include/verilated_vpi.h0000664000177100017500000000335613205574202020160 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 _VERILATED_VPI_H_ #define _VERILATED_VPI_H_ 1 ///< Header Guard #include "verilated.h" #include "verilated_syms.h" //====================================================================== // From IEEE 1800-2009 annex K #include "vltstd/vpi_user.h" //====================================================================== class VerilatedVpi { public: /// Call timed callbacks /// Users should call this from their main loops static void callTimedCbs() VL_MT_UNSAFE_ONE; /// Call value based callbacks /// Users should call this from their main loops static void callValueCbs() VL_MT_UNSAFE_ONE; /// Self test, for internal use only static void selfTest() VL_MT_UNSAFE_ONE; }; #endif // Guard verilator-3.916/include/verilated.h0000664000177100017500000026401713205574202017305 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 #ifdef VL_THREADED # include # include # include #endif // avoided to reduce compile time // avoided and instead in verilated_heavy.h to reduce compile time // avoided and instead in verilated_heavy.h to reduce compile time //============================================================================= // Switches #if VM_TRACE // Verilator tracing requested # define WAVES 1 // Set backward compatibility flag #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 VerilatedEvalMsgQueue; class VerilatedScopeNameMap; 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 }; //========================================================================= /// Mutex and threading support /// Return current thread ID (or 0), not super fast, cache if needed extern vluint32_t VL_THREAD_ID() VL_MT_SAFE; #if VL_THREADED /// Mutex, wrapped to allow -fthread_safety checks class VL_CAPABILITY("mutex") VerilatedMutex { private: std::mutex m_mutex; // Mutex public: VerilatedMutex() {} ~VerilatedMutex() {} /// Acquire/lock mutex void lock() VL_ACQUIRE() { m_mutex.lock(); } /// Release/unlock mutex void unlock() VL_RELEASE() { m_mutex.unlock(); } /// Try to acquire mutex. Returns true on success, and false on failure. bool try_lock() VL_TRY_ACQUIRE(true) { return m_mutex.try_lock(); } }; /// Lock guard for mutex (ala std::lock_guard), wrapped to allow -fthread_safety checks class VL_SCOPED_CAPABILITY VerilatedLockGuard { VL_UNCOPYABLE(VerilatedLockGuard); private: VerilatedMutex& m_mutexr; public: explicit VerilatedLockGuard(VerilatedMutex& mutexr) VL_ACQUIRE(mutexr) : m_mutexr(mutexr) { m_mutexr.lock(); } ~VerilatedLockGuard() VL_RELEASE() { m_mutexr.unlock(); } }; #else // !VL_THREADED // Empty classes to avoid #ifdefs everywhere class VerilatedMutex {}; class VerilatedLockGuard { VL_UNCOPYABLE(VerilatedLockGuard); public: explicit VerilatedLockGuard(VerilatedMutex&) {} ~VerilatedLockGuard() {} }; #endif // VL_THREADED /// Remember the calling thread at construction time, and make sure later calls use same thread class VerilatedAssertOneThread { // MEMBERS #if defined(VL_THREADED) && defined(VL_DEBUG) vluint32_t m_threadid; /// Thread that is legal public: // CONSTRUCTORS /// The constructor establishes the thread id for all later calls. /// If necessary, a different class could be made that inits it otherwise. VerilatedAssertOneThread() : m_threadid(VL_THREAD_ID()) { } ~VerilatedAssertOneThread() { check(); } // METHODS /// Check that the current thread ID is the same as the construction thread ID void check() VL_MT_UNSAFE_ONE { // Memoize results in local thread, to prevent slow get_id() call VL_THREAD_LOCAL bool t_okThread = (m_threadid == VL_THREAD_ID()); if (!VL_LIKELY(t_okThread)) { fatal_different(); } } static void fatal_different() VL_MT_SAFE; #else // !VL_THREADED || !VL_DEBUG public: void check() {} #endif }; //========================================================================= /// Base class for all Verilated module classes class VerilatedModule { VL_UNCOPYABLE(VerilatedModule); private: const char* m_namep; ///< Module name public: explicit 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 // (Internals however must use VL_PRINTF_MT, which calls these.) #ifndef VL_PRINTF # define VL_PRINTF printf ///< Print ala printf, called from main thread; may redefine if desired #endif #ifndef VL_VPRINTF # define VL_VPRINTF vprintf ///< Print ala vprintf, called from main thread; may redefine if desired #endif //=========================================================================== /// Verilator symbol table base class class VerilatedSyms { public: // But for internal use only #ifdef VL_THREADED VerilatedEvalMsgQueue* __Vm_evalMsgQp; #endif VerilatedSyms(); ~VerilatedSyms(); }; //=========================================================================== /// Verilator global class information class /// This class is initialized by main thread only. Reading post-init is thread safe. 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) VL_MT_UNSAFE; void exportInsert(int finalize, const char* namep, void* cb) VL_MT_UNSAFE; void varInsert(int finalize, const char* namep, void* datap, VerilatedVarType vltype, int vlflags, int dims, ...) VL_MT_UNSAFE; // ACCESSORS const char* name() const { return m_namep; } inline VerilatedSyms* symsp() const { return m_symsp; } VerilatedVar* varFind(const char* namep) const VL_MT_SAFE_POSTINIT; VerilatedVarNameMap* varsp() const VL_MT_SAFE_POSTINIT { return m_varsp; } void scopeDump() const; void* exportFindError(int funcnum) const; static void* exportFindNullError(int funcnum) VL_MT_SAFE; static inline void* exportFind(const VerilatedScope* scopep, int funcnum) VL_MT_SAFE { if (VL_UNLIKELY(!scopep)) return exportFindNullError(funcnum); if (VL_LIKELY(funcnum < scopep->m_funcnumMax)) { // m_callbacksp must be declared, as Max'es are > 0 return scopep->m_callbacksp[funcnum]; } else { return scopep->exportFindError(funcnum); } } }; //=========================================================================== /// Verilator global static information class class Verilated { // MEMBERS // Slow path variables static VerilatedMutex m_mutex; ///< Mutex for all static members, when VL_THREADED 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; // 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; // Not covered by mutex, as per-thread static VL_THREAD_LOCAL struct ThreadLocal { #ifdef VL_THREADED vluint32_t t_trainId; ///< Current train# executing on this thread vluint32_t t_endOfEvalReqd; ///< Messages may be pending, thread needs endOf-eval calls #endif const VerilatedScope* t_dpiScopep; ///< DPI context scope const char* t_dpiFilename; ///< DPI context filename int t_dpiLineno; ///< DPI context line number ThreadLocal(); ~ThreadLocal(); } t_s; private: // CONSTRUCTORS VL_UNCOPYABLE(Verilated); 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) VL_MT_SAFE; static int randReset() VL_MT_SAFE { return s_s.s_randReset; } ///< Return randReset value /// Enable debug of internal verilated code static void debug(int level) VL_MT_SAFE; #ifdef VL_DEBUG /// Return debug level /// When multithreaded this may not immediately react to another thread changing the level (no mutex) static inline int debug() VL_MT_SAFE { return s_s.s_debug; } #else static inline int debug() VL_PURE { return 0; } ///< Return constant 0 debug level, so C++'s optimizer rips up #endif /// Enable calculation of unused signals static void calcUnusedSigs(bool flag) VL_MT_SAFE; static bool calcUnusedSigs() VL_MT_SAFE { return s_s.s_calcUnusedSigs; } ///< Return calcUnusedSigs value /// Did the simulation $finish? static void gotFinish(bool flag) VL_MT_SAFE; static bool gotFinish() VL_MT_SAFE { 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) VL_MT_SAFE { if (flag) { calcUnusedSigs(flag); } } /// Enable/disable assertions static void assertOn(bool flag) VL_MT_SAFE; static bool assertOn() VL_MT_SAFE { return s_s.s_assertOn; } /// Enable/disable vpi fatal static void fatalOnVpiError(bool flag) VL_MT_SAFE; static bool fatalOnVpiError() VL_MT_SAFE { return s_s.s_fatalOnVpiError; } /// Flush callback for VCD waves static void flushCb(VerilatedVoidCb cb) VL_MT_SAFE; static void flushCall() VL_MT_SAFE; /// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs static void commandArgs(int argc, const char** argv) VL_MT_SAFE; static void commandArgs(int argc, char** argv) VL_MT_SAFE { commandArgs(argc, const_cast(argv)); } static void commandArgsAdd(int argc, const char** argv); static CommandArgValues* getCommandArgs() VL_MT_SAFE { return &s_args; } /// Match plusargs with a given prefix. Returns static char* valid only for a single call static const char* commandArgsPlusMatch(const char* prefixp) VL_MT_SAFE; /// Produce name & version for (at least) VPI static const char* productName() VL_PURE { return VERILATOR_PRODUCT; } static const char* productVersion() VL_PURE { return VERILATOR_VERSION; } /// When multithreaded, quiesce the model to prepare for trace/saves/coverage /// This may only be called when no locks are held. static void quiesce() VL_MT_SAFE; /// 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() VL_MT_SAFE; /// 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() VL_MT_SAFE; /// Set the number of threads to execute on. /// 0x0 = use all available CPU threads, or 1 if no support compiled in /// Ignored after spawnThreads() has been called static void numThreads(unsigned threads) VL_MT_SAFE; static unsigned numThreads() VL_MT_SAFE; /// Spawn child threads, using numThreads() as # of threads /// Verilator calls this automatically on the first eval() call /// User code may call it earlier if desired /// Once called the first time, later calls are ignored static void spawnThreads() VL_MT_SAFE; public: // METHODS - INTERNAL USE ONLY (but public due to what uses it) // Internal: Create a new module name by concatenating two strings static const char* catName(const char* n1, const char* n2); // Returns static data // Internal: Throw signal assertion static void overWidthError(const char* signame) VL_MT_SAFE; // Internal: Find scope static const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE; static const VerilatedScopeNameMap* scopeNameMap() VL_MT_SAFE; // Internal: Get and set DPI context static const VerilatedScope* dpiScope() VL_MT_SAFE { return t_s.t_dpiScopep; } static void dpiScope(const VerilatedScope* scopep) VL_MT_SAFE { t_s.t_dpiScopep=scopep; } static void dpiContext(const VerilatedScope* scopep, const char* filenamep, int lineno) VL_MT_SAFE { t_s.t_dpiScopep = scopep; t_s.t_dpiFilename = filenamep; t_s.t_dpiLineno = lineno; } static void dpiClearContext() VL_MT_SAFE { t_s.t_dpiScopep = NULL; } static bool dpiInContext() VL_MT_SAFE { return t_s.t_dpiScopep != NULL; } static const char* dpiFilenamep() VL_MT_SAFE { return t_s.t_dpiFilename; } static int dpiLineno() VL_MT_SAFE { return t_s.t_dpiLineno; } static int exportFuncNum(const char* namep) VL_MT_SAFE; static size_t serializedSize() VL_PURE { return sizeof(s_s); } static void* serializedPtr() VL_MT_UNSAFE { return &s_s; } // Unsafe, for Serialize only #ifdef VL_THREADED /// Set the trainId, called when a train starts static void trainId(vluint32_t id) VL_MT_SAFE { t_s.t_trainId = id; } static vluint32_t trainId() VL_MT_SAFE { return t_s.t_trainId; } static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; } static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; } /// Called at end of each thread train, before finishing eval static void endOfThreadTrain(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) { endOfThreadTrainGuts(evalMsgQp); } } /// Called at end of eval loop static void endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) { endOfEvalGuts(evalMsgQp); } } #endif private: #ifdef VL_THREADED static void endOfThreadTrainGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE; static void endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE; #endif }; //========================================================================= // Extern functions -- User may override -- See verilated.cpp /// Routine to call for $finish /// User code may wish to replace this function, to do so, define VL_USER_FINISH. /// This code does not have to be thread safe. /// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this. extern void vl_finish (const char* filename, int linenum, const char* hier); /// Routine to call for $stop /// User code may wish to replace this function, to do so, define VL_USER_STOP. /// This code does not have to be thread safe. /// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this. extern void vl_stop (const char* filename, int linenum, const char* hier); /// Routine to call for a couple of fatal messages /// User code may wish to replace this function, to do so, define VL_USER_FATAL. /// This code does not have to be thread safe. /// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this. extern void vl_fatal (const char* filename, int linenum, const char* hier, const char* msg); //========================================================================= // Extern functions -- Slow path /// Multithread safe wrapper for calls to $finish extern void VL_FINISH_MT (const char* filename, int linenum, const char* hier) VL_MT_SAFE; /// Multithread safe wrapper for calls to $stop extern void VL_STOP_MT (const char* filename, int linenum, const char* hier) VL_MT_SAFE; /// Multithread safe wrapper to call for a couple of fatal messages extern void VL_FATAL_MT (const char* filename, int linenum, const char* hier, const char* msg) VL_MT_SAFE; /// Print a string, multithread safe. Eventually VL_PRINTF will get called. #ifdef VL_THREADED extern void VL_PRINTF_MT(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE; #else # define VL_PRINTF_MT VL_PRINTF // The following parens will take care of themselves #endif /// Print a debug message from internals with standard prefix, with printf style format extern void VL_DBG_MSGF(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE; 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 (slow - else use VL_ZERO_W) /// 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) VL_MT_SAFE { 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_MT_SAFE { VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); } extern void VL_WRITEF(const char* formatp, ...); extern void VL_FWRITEF(IData fpi, const char* formatp, ...); extern IData VL_FSCANF_IX(IData fpi, const char* formatp, ...); extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...); extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...); extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...); extern IData VL_SYSTEM_IW(int lhsnwords, WDataInP lhs); extern IData VL_SYSTEM_IQ(QData lhs); inline IData VL_SYSTEM_II(IData lhs) VL_MT_SAFE { return VL_SYSTEM_IQ(lhs); } extern IData VL_TESTPLUSARGS_I(const char* formatp); extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish //========================================================================= // Base macros /// Return true if data[bit] set; not 0/1 return, but 0/non-zero return. #define VL_BITISSET_I(data,bit) (data & (VL_UL(1)<(data); owp[1]=static_cast((data)>>VL_WORDSIZE); } #define VL_SET_WI(owp,data) { owp[0]=static_cast(data); owp[1]=0; } #define VL_SET_QW(lwp) ( (static_cast(lwp[0])) | (static_cast(lwp[1])<<(static_cast(VL_WORDSIZE)) )) #define _VL_SET_QII(ld,rd) ( (static_cast(ld)<(rd) ) /// Return FILE* from IData extern FILE* VL_CVT_I_FP(IData lhs); // Use a union to avoid cast-to-different-size warnings /// Return void* from QData static inline void* VL_CVT_Q_VP(QData lhs) VL_PURE { union { void* fp; QData q; } u; u.q=lhs; return u.fp; } /// Return QData from void* static inline QData VL_CVT_VP_Q(void* fp) VL_PURE { union { void* fp; QData q; } u; u.q=0; u.fp=fp; return u.q; } /// Return double from QData (bits, not numerically) static inline double VL_CVT_D_Q(QData lhs) VL_PURE { union { double d; QData q; } u; u.q=lhs; return u.d; } /// Return QData from double (bits, not numerically) static inline QData VL_CVT_Q_D(double lhs) VL_PURE { union { double d; QData q; } u; u.d=lhs; return u.q; } /// Return double from QData (numeric) static inline double VL_ITOR_D_I(IData lhs) VL_PURE { return static_cast(static_cast(lhs)); } /// Return QData from double (numeric) static inline IData VL_RTOI_I_D(double lhs) VL_PURE { return static_cast(VL_TRUNC(lhs)); } /// Return QData from double (numeric) static inline IData VL_RTOIROUND_I_D(double lhs) VL_PURE { return static_cast(VL_ROUND(lhs)); } // Sign extend such that if MSB set, we get ffff_ffff, else 0s // (Requires clean input) #define VL_SIGN_I(nbits,lhs) ((lhs) >> VL_BITBIT_I((nbits) - VL_UL(1))) #define VL_SIGN_Q(nbits,lhs) ((lhs) >> VL_BITBIT_Q((nbits) - VL_ULL(1))) #define VL_SIGN_W(nbits,rwp) ((rwp)[VL_BITWORD_I((nbits)-VL_UL(1))] >> VL_BITBIT_I((nbits)-VL_UL(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) VL_PURE { return (-((lhs)&(VL_UL(1)<<(lbits-1)))); } static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) VL_PURE { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); } // Debugging prints extern 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() (static_cast(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER)) # define VL_TIME_Q() (static_cast(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER)) # define VL_TIME_D() (static_cast(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER)) #else # define VL_TIME_I() (static_cast(sc_time_stamp()*VL_TIME_MULTIPLIER)) # define VL_TIME_Q() (static_cast(sc_time_stamp()*VL_TIME_MULTIPLIER)) # define VL_TIME_D() (static_cast(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) VL_MT_SAFE { 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) VL_MT_SAFE { 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); } static inline WDataOutP VL_ZERO_W(int obits, WDataOutP owp) VL_MT_SAFE { int words = VL_WORDS_I(obits); for (int i=0; i < words; ++i) owp[i] = 0; return owp; } static inline WDataOutP VL_ALLONES_W(int obits, WDataOutP owp) VL_MT_SAFE { int words = VL_WORDS_I(obits); for (int i=0; (i < (words-1)); ++i) owp[i] = ~VL_UL(0); owp[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) VL_MT_SAFE { 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) VL_PURE { lhsr = ((lhsr & ~(VL_UL(1)<(svar.read().get_word(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, static_cast(rd)); \ _bvtemp.set_word(1, static_cast((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) (static_cast(lhs)) #define VL_EXTEND_QQ(obits,lbits,lhs) ((lhs)) static inline WDataOutP VL_EXTEND_WI(int obits, int, WDataOutP owp, IData ld) VL_MT_SAFE { // 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_MT_SAFE { 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) VL_MT_SAFE { 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) VL_PURE { return VL_EXTENDSIGN_I(lbits,lhs) | lhs; } static inline QData VL_EXTENDS_QI(int, int lbits, QData lhs/*Q_as_need_extended*/) VL_PURE { return VL_EXTENDSIGN_Q(lbits,lhs) | lhs; } static inline QData VL_EXTENDS_QQ(int, int lbits, QData lhs) VL_PURE { return VL_EXTENDSIGN_Q(lbits,lhs) | lhs; } static inline WDataOutP VL_EXTENDS_WI(int obits, int lbits, WDataOutP owp, IData ld) VL_MT_SAFE { 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_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_PURE { // Experiments show VL_REDXOR_2 is faster than __builtin_parityl r=(r^(r>>1)); return r; } static inline IData VL_REDXOR_4(IData r) VL_PURE { #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) VL_PURE { #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) VL_PURE { #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) VL_PURE { #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) VL_PURE { #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 static_cast(r); #endif } static inline IData VL_REDXOR_W(int words, WDataInP lwp) VL_MT_SAFE { 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) VL_PURE { // 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) VL_PURE { return VL_COUNTONES_I(static_cast(lhs)) + VL_COUNTONES_I(static_cast(lhs>>32)); } static inline IData VL_COUNTONES_W(int words, WDataInP lwp) VL_MT_SAFE { 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) VL_PURE { return (((lhs & (lhs-1))==0) & (lhs!=0)); } static inline IData VL_ONEHOT_Q(QData lhs) VL_PURE { return (((lhs & (lhs-1))==0) & (lhs!=0)); } static inline IData VL_ONEHOT_W(int words, WDataInP lwp) VL_MT_SAFE { 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) VL_PURE { return ((lhs & (lhs-1))==0); } static inline IData VL_ONEHOT0_Q(QData lhs) VL_PURE { return ((lhs & (lhs-1))==0); } static inline IData VL_ONEHOT0_W(int words, WDataInP lwp) VL_MT_SAFE { 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) VL_PURE { // 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) VL_PURE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { // 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_PURE { // 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) VL_PURE { 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) VL_PURE { 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) VL_PURE { 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) VL_PURE { 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) VL_PURE { 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) VL_PURE { 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) VL_PURE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { QData carry = 0; for (int i=0; i(lwp[i]) + static_cast(rwp[i]); owp[i] = (carry & VL_ULL(0xffffffff)); carry = (carry >> VL_ULL(32)) & VL_ULL(0xffffffff); } return(owp); } static inline WDataOutP VL_SUB_W(int words, WDataOutP owp,WDataInP lwp,WDataInP rwp) VL_MT_SAFE { QData carry = 0; for (int i=0; i(lwp[i]) + static_cast(static_cast(~rwp[i])); if (i==0) carry++; // Negation of temp2 owp[i] = (carry & VL_ULL(0xffffffff)); carry = (carry >> 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) VL_PURE { return -data; } static inline QData VL_NEGATE_Q(QData data) VL_PURE { return -data; } static inline WDataOutP VL_NEGATE_W(int words, WDataOutP owp,WDataInP lwp) VL_MT_SAFE { QData carry = 0; for (int i=0; i(static_cast(~lwp[i])); if (i==0) carry++; // Negation of temp2 owp[i] = (carry & VL_ULL(0xffffffff)); carry = (carry >> VL_ULL(32)) & VL_ULL(0xffffffff); } return(owp); } static inline WDataOutP VL_MUL_W(int words, WDataOutP owp,WDataInP lwp,WDataInP rwp) VL_MT_SAFE { for (int i=0; i(lwp[lword]) * static_cast(rwp[rword]); for (int qword=lword+rword; qword(owp[qword]); owp[qword] = (mul & VL_ULL(0xffffffff)); mul = (mul >> 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) VL_PURE { 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) VL_PURE { 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) VL_MT_SAFE { int words = VL_WORDS_I(lbits); // cppcheck-suppress variableScope WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here // cppcheck-suppress variableScope WData 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(static_cast(~owp[i])); if (i==0) carry++; // Negation of temp2 owp[i] = (carry & VL_ULL(0xffffffff)); carry = (carry >> 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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) (-(static_cast(ld))) // Iff lbits==1 static inline IData VL_REPLICATE_III(int, int lbits, int, IData ld, IData rep) VL_PURE { 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) VL_PURE { QData returndata = ld; for (unsigned i=1; i < rep; ++i){ returndata = returndata << lbits; returndata |= static_cast(ld); } return (returndata); } static inline WDataOutP VL_REPLICATE_WII(int obits, int lbits, int, WDataOutP owp, IData ld, IData rep) VL_MT_SAFE { 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_MT_SAFE { 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) VL_MT_SAFE { for (int i=0; i < VL_WORDS_I(lbits); ++i) owp[i] = lwp[i]; for (unsigned i=1; i < rep; ++i){ _VL_INSERT_WW(obits,owp,lwp,i*lbits+lbits-1,i*lbits); } return(owp); } // Left stream operator. Output will always be clean. LHS and RHS must be clean. // Special "fast" versions for slice sizes that are a power of 2. These use // shifts and masks to execute faster than the slower for-loop approach where a // subset of bits is copied in during each iteration. static inline IData VL_STREAML_FAST_III(int, int lbits, int, IData ld, IData rd_log2) VL_PURE { // Pre-shift bits in most-significant slice: // // If lbits is not a multiple of the slice size (i.e., lbits % rd != 0), // then we end up with a "gap" in our reversed result. For example, if we // have a 5-bit Verlilog signal (lbits=5) in an 8-bit C data type: // // ld = ---43210 // // (where numbers are the Verilog signal bit numbers and '-' is an unused bit). // Executing the switch statement below with a slice size of two (rd=2, // rd_log2=1) produces: // // ret = 1032-400 // // Pre-shifting the bits in the most-significant slice allows us to avoid // this gap in the shuffled data: // // ld_adjusted = --4-3210 // ret = 10324--- IData ret = ld; if (rd_log2) { vluint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2); // max multiple of rd <= lbits vluint32_t lbitsRem = lbits - lbitsFloor; // number of bits in most-sig slice (MSS) IData msbMask = VL_MASK_I(lbitsRem) << lbitsFloor; // mask to sel only bits in MSS ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_UL(1) << rd_log2) - lbitsRem)); } switch (rd_log2) { case 0: ret = ((ret >> 1) & VL_UL(0x55555555)) | ((ret & VL_UL(0x55555555)) << 1); // FALLTHRU case 1: ret = ((ret >> 2) & VL_UL(0x33333333)) | ((ret & VL_UL(0x33333333)) << 2); // FALLTHRU case 2: ret = ((ret >> 4) & VL_UL(0x0f0f0f0f)) | ((ret & VL_UL(0x0f0f0f0f)) << 4); // FALLTHRU case 3: ret = ((ret >> 8) & VL_UL(0x00ff00ff)) | ((ret & VL_UL(0x00ff00ff)) << 8); // FALLTHRU case 4: ret = ((ret >> 16) | (ret << 16)); } return ret >> (VL_WORDSIZE - lbits); } static inline QData VL_STREAML_FAST_QQI(int, int lbits, int, QData ld, IData rd_log2) VL_PURE { // Pre-shift bits in most-significant slice (see comment in VL_STREAML_FAST_III) QData ret = ld; if (rd_log2) { vluint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2); vluint32_t lbitsRem = lbits - lbitsFloor; QData msbMask = VL_MASK_Q(lbitsRem) << lbitsFloor; ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_ULL(1) << rd_log2) - lbitsRem)); } switch (rd_log2) { case 0: ret = ((ret >> 1) & VL_ULL(0x5555555555555555)) | ((ret & VL_ULL(0x5555555555555555)) << 1); // FALLTHRU case 1: ret = ((ret >> 2) & VL_ULL(0x3333333333333333)) | ((ret & VL_ULL(0x3333333333333333)) << 2); // FALLTHRU case 2: ret = ((ret >> 4) & VL_ULL(0x0f0f0f0f0f0f0f0f)) | ((ret & VL_ULL(0x0f0f0f0f0f0f0f0f)) << 4); // FALLTHRU case 3: ret = ((ret >> 8) & VL_ULL(0x00ff00ff00ff00ff)) | ((ret & VL_ULL(0x00ff00ff00ff00ff)) << 8); // FALLTHRU case 4: ret = ((ret >> 16) & VL_ULL(0x0000ffff0000ffff)) | ((ret & VL_ULL(0x0000ffff0000ffff)) << 16); // FALLTHRU case 5: ret = ((ret >> 32) | (ret << 32)); } return ret >> (VL_QUADSIZE - lbits); } // Regular "slow" streaming operators static inline IData VL_STREAML_III(int, int lbits, int, IData ld, IData rd) VL_PURE { IData ret = 0; // Slice size should never exceed the lhs width IData mask = VL_MASK_I(rd); for (int istart=0; istart 0 ? ostart : 0; ret |= ((ld >> istart) & mask) << ostart; } return ret; } static inline QData VL_STREAML_QQI(int, int lbits, int, QData ld, IData rd) VL_PURE { QData ret = 0; // Slice size should never exceed the lhs width QData mask = VL_MASK_Q(rd); for (int istart=0; istart 0 ? ostart : 0; ret |= ((ld >> istart) & mask) << ostart; } return ret; } static inline WDataOutP VL_STREAML_WWI(int, int lbits, int, WDataOutP owp, WDataInP lwp, IData rd) VL_MT_SAFE { VL_ZERO_W(lbits, owp); // Slice size should never exceed the lhs width int ssize = (rd < static_cast(lbits)) ? rd : (static_cast(lbits)); for (int istart=0; istart 0 ? ostart : 0; for (int sbit=0; sbit> VL_BITBIT_I(istart+sbit)) & 1) << VL_BITBIT_I(ostart+sbit); owp[VL_BITWORD_I(ostart+sbit)] |= bit; } } return owp; } // Because concats are common and wide, it's valuable to always have a clean output. // Thus we specify inputs must be clean, so we don't need to clean the output. // Note the bit shifts are always constants, so the adds in these constify out. // Casts required, as args may be 8 bit entities, and need to shift to appropriate output size #define VL_CONCAT_III(obits,lbits,rbits,ld,rd) (static_cast(ld)<<(rbits) | static_cast(rd)) #define VL_CONCAT_QII(obits,lbits,rbits,ld,rd) (static_cast(ld)<<(rbits) | static_cast(rd)) #define VL_CONCAT_QIQ(obits,lbits,rbits,ld,rd) (static_cast(ld)<<(rbits) | static_cast(rd)) #define VL_CONCAT_QQI(obits,lbits,rbits,ld,rd) (static_cast(ld)<<(rbits) | static_cast(rd)) #define VL_CONCAT_QQQ(obits,lbits,rbits,ld,rd) (static_cast(ld)<<(rbits) | static_cast(rd)) static inline WDataOutP VL_CONCAT_WII(int obits,int lbits,int rbits,WDataOutP owp,IData ld,IData rd) VL_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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_MT_SAFE { 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) VL_MT_SAFE { 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_MT_SAFE { 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_MT_SAFE { 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) VL_MT_SAFE { 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) VL_MT_SAFE { 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*/) VL_MT_SAFE { 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]<= static_cast(obits)) { // rd may be huge with MSB set for (int i=0; i < VL_WORDS_I(obits); ++i) owp[i] = 0; } else if (bit_shift==0) { // Aligned word shift (<<0,<<32,<<64 etc) for (int i=0; i < word_shift; ++i) owp[i] = 0; for (int i=word_shift; i < VL_WORDS_I(obits); ++i) owp[i] = lwp[i-word_shift]; } else { for (int i=0; i < VL_WORDS_I(obits); ++i) owp[i] = 0; _VL_INSERT_WW(obits,owp,lwp,obits-1,rd); } return(owp); } static inline WDataOutP VL_SHIFTL_WWW(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, WDataInP rwp) VL_MT_SAFE { for (int i=1; i < VL_WORDS_I(rbits); ++i) { if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more return VL_ZERO_W(obits, owp); } } return VL_SHIFTL_WWI(obits,lbits,32,owp,lwp,rwp[0]); } static inline IData VL_SHIFTL_IIW(int obits,int,int rbits,IData lhs, WDataInP rwp) VL_MT_SAFE { for (int i=1; i < VL_WORDS_I(rbits); ++i) { if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more return 0; } } return VL_CLEAN_II(obits,obits,lhs<= static_cast(obits)) { // rd may be huge with MSB set for (int i=0; i < VL_WORDS_I(obits); ++i) owp[i] = 0; } else if (bit_shift==0) { // Aligned word shift (>>0,>>32,>>64 etc) int copy_words = (VL_WORDS_I(obits)-word_shift); for (int i=0; i < copy_words; ++i) owp[i] = lwp[i+word_shift]; for (int i=copy_words; i < VL_WORDS_I(obits); ++i) owp[i] = 0; } else { int loffset = rd & VL_SIZEBITS_I; int nbitsonright = 32-loffset; // bits that end up in lword (know loffset!=0) // Middle words int words = VL_WORDS_I(obits-rd); for (int i=0; i>loffset; int upperword = i+word_shift+1; if (upperword < VL_WORDS_I(obits)) { owp[i] |= lwp[upperword]<< nbitsonright; } } for (int i=words; i>32 or more return VL_ZERO_W(obits, owp); } } return VL_SHIFTR_WWI(obits,lbits,32,owp,lwp,rwp[0]); } static inline IData VL_SHIFTR_IIW(int obits,int,int rbits,IData lhs, WDataInP rwp) VL_MT_SAFE { for (int i=1; i < VL_WORDS_I(rbits); ++i) { if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more return 0; } } return VL_CLEAN_II(obits,obits,lhs>>rwp[0]); } // EMIT_RULE: VL_SHIFTRS: oclean=false; lclean=clean, rclean==clean; static inline IData VL_SHIFTRS_III(int obits, int lbits, int, IData lhs, IData rhs) VL_PURE { // Note the C standard does not specify the >> 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) VL_PURE { 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) VL_PURE { return static_cast(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) VL_MT_SAFE { int word_shift = VL_BITWORD_I(rd); int bit_shift = VL_BITBIT_I(rd); int lmsw = VL_WORDS_I(obits)-1; IData sign = VL_SIGNONES_I(lbits,lwp[lmsw]); if (rd >= static_cast(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>32 or more int lmsw = VL_WORDS_I(obits)-1; IData sign = VL_SIGNONES_I(lbits,lwp[lmsw]); for (int j=0; j <= lmsw; ++j) owp[j] = sign; owp[lmsw] &= VL_MASK_I(lbits); return owp; } } return VL_SHIFTRS_WWI(obits,lbits,32,owp,lwp,rwp[0]); } static inline IData VL_SHIFTRS_IIW(int obits,int lbits,int rbits,IData lhs, WDataInP rwp) VL_MT_SAFE { for (int i=1; i < VL_WORDS_I(rbits); ++i) { if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more IData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative return VL_CLEAN_II(obits,obits,sign); } } return VL_SHIFTRS_III(obits,lbits,32,lhs,rwp[0]); } static inline QData VL_SHIFTRS_QQW(int obits,int lbits,int rbits,QData lhs, WDataInP rwp) VL_MT_SAFE { for (int i=1; i < VL_WORDS_I(rbits); ++i) { if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more QData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative return VL_CLEAN_QQ(obits,obits,sign); } } return VL_SHIFTRS_QQI(obits,lbits,32,lhs,rwp[0]); } static inline IData VL_SHIFTRS_IIQ(int obits,int lbits,int rbits,IData lhs, QData rhs) VL_PURE { WData rwp[2]; VL_SET_WQ(rwp,rhs); return VL_SHIFTRS_IIW(obits,lbits,rbits,lhs,rwp); } static inline QData VL_SHIFTRS_QQQ(int obits,int lbits,int rbits,QData lhs, QData rhs) VL_PURE { WData rwp[2]; VL_SET_WQ(rwp,rhs); return VL_SHIFTRS_QQW(obits,lbits,rbits,lhs,rwp); } //=================================================================== // Bit selection // EMIT_RULE: VL_BITSEL: oclean=dirty; rclean==clean; #define VL_BITSEL_IIII(obits,lbits,rbits,zbits,lhs,rhs) ((lhs)>>(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) (static_cast((lhs)>>(rhs))) static inline IData VL_BITSEL_IWII(int, int lbits, int, int, WDataInP lwp, IData rd) VL_MT_SAFE { int word = VL_BITWORD_I(rd); if (VL_UNLIKELY(rd > static_cast(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) (static_cast((lhs)>>(lsb))) static inline IData VL_SEL_IWII(int, int lbits, int, int, WDataInP lwp, IData lsb, IData width) VL_MT_SAFE { 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(static_cast(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) VL_MT_SAFE { 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(static_cast(lsb))) { return (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)); } else if (VL_BITWORD_I(msb)==1+VL_BITWORD_I(static_cast(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 <= static_cast(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_MT_SAFE { _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_MT_SAFE { _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_MT_SAFE { _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) VL_MT_SAFE { int words = VL_WORDS_I(obits); for (int i=0; i < words; ++i) owp[i] = cond ? w1p[i] : w2p[i]; return(owp); } //====================================================================== // Constification // VL_CONST_W_#X(int obits, WDataOutP owp, IData data0, .... IData data(#-1)) // Sets wide vector words to specified constant words. // These macros are used when o might represent more words then are given as constants, // hence all upper words must be zeroed. // If changing the number of functions here, also change EMITCINLINES_NUM_CONSTW #define _END(obits,wordsSet) \ for(int i=(wordsSet);i //============================================================================= // VerilatedSerialize - convert structures to a stream representation // This class is not thread safe, it must be called by a single thread class VerilatedSerialize { 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 std::string m_filename; ///< Filename, for error messages VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation inline static size_t bufferInsertSize() { return 16*1024; } void header() VL_MT_UNSAFE_ONE; void trailer() VL_MT_UNSAFE_ONE; // CONSTRUCTORS VL_UNCOPYABLE(VerilatedSerialize); public: VerilatedSerialize() { m_isOpen = false; m_bufp = new vluint8_t [bufferSize()]; m_cp = m_bufp; } virtual ~VerilatedSerialize() { close(); if (m_bufp) { delete m_bufp; m_bufp=NULL; } } // METHODS bool isOpen() const { return m_isOpen; } std::string filename() const { return m_filename; } virtual void close() VL_MT_UNSAFE_ONE { flush(); } virtual void flush() VL_MT_UNSAFE_ONE {} inline VerilatedSerialize& write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE { 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 } private: VerilatedSerialize& bufferCheck() VL_MT_UNSAFE_ONE { // 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 } }; //============================================================================= // VerilatedDeserial - load structures from a stream representation // This class is not thread safe, it must be called by a single thread class VerilatedDeserialize { 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 vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer bool m_isOpen; ///< True indicates open file/stream std::string m_filename; ///< Filename, for error messages VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation inline static size_t bufferInsertSize() { return 16*1024; } virtual void fill() = 0; void header() VL_MT_UNSAFE_ONE; void trailer() VL_MT_UNSAFE_ONE; // CONSTRUCTORS VL_UNCOPYABLE(VerilatedDeserialize); public: VerilatedDeserialize() { m_isOpen = false; m_bufp = new vluint8_t [bufferSize()]; m_cp = m_bufp; m_endp = NULL; } virtual ~VerilatedDeserialize() { close(); if (m_bufp) { delete m_bufp; m_bufp=NULL; } } // METHODS bool isOpen() const { return m_isOpen; } std::string filename() const { return m_filename; } virtual void close() VL_MT_UNSAFE_ONE { flush(); } virtual void flush() VL_MT_UNSAFE_ONE {} inline VerilatedDeserialize& read(void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE { 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 VerilatedDeserialize& readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE; VerilatedDeserialize& readAssert(vluint64_t data) VL_MT_UNSAFE_ONE { return readAssert(&data, sizeof(data)); } private: bool readDiffers(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE; VerilatedDeserialize& bufferCheck() VL_MT_UNSAFE_ONE { // 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 // This class is not thread safe, it must be called by a single thread class VerilatedSave : public VerilatedSerialize { private: int m_fd; ///< File descriptor we're writing to public: // CONSTRUCTORS VerilatedSave() { m_fd=-1; } virtual ~VerilatedSave() { close(); } // METHODS void open(const char* filenamep) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); } virtual void close() VL_MT_UNSAFE_ONE; virtual void flush() VL_MT_UNSAFE_ONE; }; //============================================================================= // VerilatedRestore - deserialize from a file // This class is not thread safe, it must be called by a single thread class VerilatedRestore : public VerilatedDeserialize { private: int m_fd; ///< File descriptor we're writing to public: // CONSTRUCTORS VerilatedRestore() { m_fd=-1; } virtual ~VerilatedRestore() { close(); } // METHODS void open(const char* filenamep) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); } virtual void close() VL_MT_UNSAFE_ONE; virtual void flush() VL_MT_UNSAFE_ONE {} virtual void fill() VL_MT_UNSAFE_ONE; }; //============================================================================= 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, std::string& rhs) { vluint32_t len=rhs.length(); os<>(VerilatedDeserialize& os, std::string& rhs) { vluint32_t len=0; os>>len; rhs.resize(len); return os.read((void*)rhs.data(), len); } #endif // guard verilator-3.916/include/verilated_vcd_sc.cpp0000664000177100017500000001347113205574202021155 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2017 by Wilson Snyder. This program is free software; // you can redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief Verilator tracing in VCD Format /// //============================================================================= // SPDIFF_OFF #include "verilatedos.h" #include "verilated_vcd_sc.h" // SPDIFF_ON //====================================================================== //====================================================================== //-------------------------------------------------- #if (SYSTEMC_VERSION>=20050714) // SystemC 2.1.v1 // cppcheck-suppress unusedFunction 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 // cppcheck-suppress unusedFunction 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 // cppcheck-suppress unusedFunction 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.916/include/verilated_heavy.h0000664000177100017500000000675613205574202020505 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2017 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License. // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT 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 std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE; inline std::string VL_CVT_PACK_STR_NQ(QData lhs) VL_PURE { WData lw[2]; VL_SET_WQ(lw, lhs); return VL_CVT_PACK_STR_NW(2, lw); } inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) VL_PURE { return lhs; } inline std::string VL_CVT_PACK_STR_NI(IData lhs) VL_PURE { WData lw[1]; lw[0] = lhs; return VL_CVT_PACK_STR_NW(1, lw); } inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) VL_PURE { return lhs+rhs; } inline std::string VL_REPLICATEN_NNQ(int,int,int, const std::string& lhs, IData rep) VL_PURE { std::string out; out.reserve(lhs.length() * rep); for (unsigned times=0; timesadd_trace_file(this); # if (SYSTEMC_VERSION>=20060505) // We want to avoid a depreciated warning, but still be back compatible. // Turning off the message just for this still results in an annoying "to turn off" message. sc_time t1sec(1,SC_SEC); if (t1sec.to_default_time_units()!=0) { sc_time tunits(1.0/t1sec.to_default_time_units(),SC_SEC); spTrace()->set_time_unit(tunits.to_string()); } spTrace()->set_time_resolution(sc_get_time_resolution().to_string()); # elif (SYSTEMC_VERSION>20011000) // To confuse matters 2.1.beta returns a char* here, while 2.1.v1 returns a std::string // we allow both flavors with overloaded set_time_* functions. spTrace()->set_time_unit(sc_get_default_time_unit().to_string()); spTrace()->set_time_resolution(sc_get_time_resolution().to_string()); # endif } virtual ~VerilatedVcdSc() {} // METHODS /// 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