Mercurial > pygar
view scripts/run-null.bmark @ 42:ced2ebd41347 pygar svn.43
[svn r43] bunch of updates that almost work...
author | punk |
---|---|
date | Wed, 05 May 2010 01:09:09 -0400 |
parents | 90197e3375e2 |
children |
line wrap: on
line source
1 #!/usr/bin/env perl2 # -*- perl -*-4 use strict;5 use warnings;6 use Getopt::Long qw(:config no_auto_abbrev no_ignore_case pass_through);7 use IO::Pty;9 #10 # Turn on warnings11 #12 $^W = 1;14 ##15 ## Benchmark run script16 ##18 sub ExecModel($);19 sub Exec($$);20 sub CompareOutput();21 sub ReadConfig($$);24 #############################################################################25 #############################################################################26 ##27 ## Start by figuring out the model location and type.28 ##29 #############################################################################30 #############################################################################32 my %config;34 ReadConfig("config/env.sh", 1);35 ReadConfig("$config{modelDir}/config/env.sh", 1);36 ReadConfig("$config{modelDir}/config/signature.sh", 0);38 ##39 ## Pseudo-enumeration of possible model types40 ##41 my $MODEL_NONE = 0;42 my $MODEL_FPGA = 1; # Model runs on FPGA hardware43 my $MODEL_BLUESIM = 2; # Bluesim44 my $MODEL_VSIM = 3; # Verilog simulator46 my $mType = $MODEL_NONE;49 #############################################################################50 #############################################################################51 ##52 ## Process command line arguments53 ##54 #############################################################################55 #############################################################################57 my $help = 0;58 my $onlyCompare = 0;59 my $noCompare = 0;60 my $forceLoad = 0;61 my $gdb = 0;62 my $noProgram = 0;63 my $noReserve = 0;64 my $funcpPrefix = "";65 my $funcpSuffix = "";66 my $printCycle = undef;67 my $bluesimCmd = undef;68 my $vcdStart = undef;69 my $vcdCycles = 20000;70 my $m5run = 0;72 my $status = GetOptions("help!" => \$help,73 "gdb!" => \$gdb,74 "noprogram!" => \$noProgram,75 "noreserve!" => \$noReserve,76 "force-load!" => \$forceLoad,77 "funcp-prefix=s" => \$funcpPrefix,78 "funcp-suffix=s" => \$funcpSuffix,79 "onlycompare!" => \$onlyCompare,80 "nocompare!" => \$noCompare,81 "pc=s" => \$printCycle,82 "bluesim=s" => \$bluesimCmd,83 "vcdstart=i" => \$vcdStart,84 "vcdcycles=i" => \$vcdCycles,85 "m5!" => \$m5run,86 );88 # Put quotation marks back on arguments that have spaces since they will be89 # passed through a shell once more.90 foreach my $i ( 0 .. $#ARGV ) {91 if (($ARGV[$i] =~ /\s/) && ! ($ARGV[$i] =~ /['"]$/)) {92 $ARGV[$i] = '"' . $ARGV[$i] . '"';93 }94 }96 if ($onlyCompare != 0) {97 exit(CompareOutput());98 }100 if ($m5run != 0) {101 $mType = $MODEL_NONE;102 }103 elsif (-f "$config{modelDir}/$config{model}_hw.errinfo") {104 $mType = $MODEL_FPGA;105 }106 elsif (-f "$config{modelDir}/$config{model}_hw.exe") {107 $mType = $MODEL_BLUESIM;108 }109 elsif (-f "$config{modelDir}/$config{model}_hw.vexe") {110 $mType = $MODEL_VSIM;111 }112 else {113 die("Can't determine model type");114 }116 if ($help || ! $status) {117 print STDERR "\nArguments:\n";118 print STDERR " [--gdb] Invokes the software side in gdb\n";119 print STDERR " [--noprogram] Skips the FPGA load and reservation steps\n";120 print STDERR " [--noreserve] Skips the FPGA reservation steps\n";121 print STDERR " [--funcp-prefix=\"<prefix>\"]\n";122 print STDERR " Prepend prefix to HAsim's --funcp argument\n";123 print STDERR " [--funcp-suffix=\"<suffix>\"]\n";124 print STDERR " Append suffix to HAsim's --funcp argument\n";125 print STDERR " [--onlycompare] Only compare output files (without running)\n";126 print STDERR " [--nocompare] Skip comparison of output files\n";127 print STDERR " [--m5] Run workload in m5 without HAsim\n";129 if ($mType == $MODEL_FPGA) {130 print STDERR " [--force-load] Load a bitfile to the FPGA even if it has errors\n";131 }133 if ($mType == $MODEL_BLUESIM) {134 print STDERR " [--vcdstart=<cycle>] Generate VCD dump for wave viewer (e.g. gtkwave)\n";135 print STDERR " [--vcdcycles=<cycles>] VCD dump length (default = 20000)\n";136 }138 if ($config{isHybridModel}) {139 my $cmd = "$config{modelDir}/$config{model} --help-run-append";140 system($cmd);141 }143 exit(1);144 }146 #############################################################################147 #############################################################################148 ##149 ## Adjust model arguments150 ##151 #############################################################################152 #############################################################################154 my $feedFlags = "${funcpPrefix} $config{feedFlags} ${funcpSuffix}";156 if ($config{feeder} eq 'm5') {157 # Tell m5 to be quiet and not to enable the remote gdb port. Under netbatch158 # it appears there are sometimes attempts to connect to the port, which159 # stops simulation.160 $feedFlags = "--quiet --remote-gdb-port=0 ${feedFlags}";161 }163 my $cmd;165 if ($m5run == 0) {166 # Normal run167 $cmd = "$config{modelDir}/$config{model} --modeldir=$config{modelDir} --workload=$config{workload} --funcp=\"${feedFlags}\" $config{genFlags}";168 foreach my $c (@ARGV) {169 $cmd .= " $c";170 }172 if (defined($printCycle)) {173 $cmd .= " --pc=${printCycle}";174 }175 }176 else {177 if ($config{feeder} ne 'm5') {178 die("This workload does not use m5");179 }181 # Running inside m5 without HAsim182 my $m5cmd;183 if (exists($ENV{M5BIN})) {184 $m5cmd = $ENV{M5BIN};185 }186 else {187 my $m5bin = "platform/m5/build/ALPHA_SE/m5." . ($gdb ? "debug" : "opt");188 $m5cmd = `awb-resolver ${m5bin}`;189 chomp($m5cmd);190 die("Failed to find $m5bin") if ($m5cmd eq '');191 }193 $cmd = "${m5cmd} ${feedFlags}";195 # Drop --hasim-sim196 $cmd =~ s/--hasim-sim //;197 # Drop escaping of quotes198 $cmd =~ s/\\"/"/g;200 $noProgram = 1;201 }203 #204 # Bluesim arguments205 #207 # Generate dump.vcd for wave viewer (e.g. gtkwave)?208 if (defined($vcdStart)) {209 my $vcdCmd = "sim vcd on; sim step $vcdCycles; sim stop";210 if ($vcdStart > 0) {211 $vcdCmd = "sim step ${vcdStart}; ${vcdCmd}";212 }214 if (defined($bluesimCmd)) {215 $bluesimCmd .= " ";216 }217 else {218 $bluesimCmd = "";219 }220 $bluesimCmd .= "-c \"$vcdCmd\"";221 }223 if (defined($bluesimCmd)) {224 $cmd .= " --bluesim=\'$bluesimCmd\'";225 }227 # Adjust the arguments for Bluesim if it is being invoked directly228 if (! $config{isHybridModel} && ($mType == $MODEL_BLUESIM)) {229 $cmd =~ s/\s--/ +--/g;231 # Bluesim may expect to load a program from a well known file232 unlink('program.vmh');233 link("program/$config{workload}.$config{ISA}.vmh", 'program.vmh');234 }237 #############################################################################238 #############################################################################239 ##240 ## Load the FPGA and run the model241 ##242 #############################################################################243 #############################################################################245 #246 # Move old stats file so we are sure statistics come from this run247 #248 if (-f "$config{workload}.stats") {249 rename("$config{workload}.stats", "$config{workload}.stats.old");250 }252 if ($mType == $MODEL_FPGA) {253 if (! defined($printCycle)) {254 # User didn't specify a cycle printing interval. Pick one more reasonable255 # for HW.256 #$cmd .= " --pc=10000000";257 }259 # Load FPGA260 $ENV{FPGA_BIT_FILE} = "$config{modelDir}/.xilinx/$config{model}_par.bit";262 if (! $noProgram) {263 if (! $forceLoad && -s "$config{modelDir}/$config{model}_hw.errinfo") {264 print STDERR "FPGA bit file has errors:\n\n";265 system("cat $config{modelDir}/$config{model}_hw.errinfo > /dev/stderr");266 print STDERR "\nUse --force-load to ignore the error.\n";267 exit(1);268 }270 if (! $noReserve) {271 Exec("hasim-fpga-ctrl --reserve", "Failed to reserve FPGA");272 }274 # Does a download script exist to program the FPGA?275 my $needProgram = (-f "$config{modelDir}/config/$config{model}.download");277 $needProgram = 1;279 # Is the FPGA already programmed with the correct bit file?280 if (exists($config{signature})) {281 my $curSignature = `hasim-fpga-ctrl --getsignature`;282 chomp($curSignature);283 if ($curSignature eq $config{signature}) {284 print "FPGA is already programmed (signature match)...\n";285 #$needProgram = 0;286 }287 }289 if ($needProgram) {290 Exec("hasim-fpga-ctrl --program", "Failed to enter FPGA programming mode");292 my $dir = `pwd`;293 chomp($dir);294 Exec("(cd $config{modelDir}; ./config/$config{model}.download ${dir}/FPGA_programming.log)", "Failed to program FPGA");296 if (exists($config{signature})) {297 Exec("hasim-fpga-ctrl --setsignature=$config{signature}", "Failed to set FPGA bit image signature");298 }299 }301 Exec("hasim-fpga-ctrl --activate", "Failed to activate FPGA or driver");302 }303 }305 # Run the software side or a hardware simulator306 my $run_status = 0;307 if ($config{isHybridModel} || ($mType != $MODEL_FPGA)) {308 $run_status = ExecModel($cmd);309 }311 # Create a stats file for null workloads to make regression.launcher happy (HACK)312 if ( $config{workload} eq "null" ) {313 system("touch null.stats");314 }316 if (-f "hasim_events.out") {317 system("sort hasim_events.out -o hasim_events.out.$$; mv -f hasim_events.out.$$ hasim_events.out");318 }319 if (-f "$config{workload}.stats") {320 system("sort $config{workload}.stats -o $config{workload}.stats.$$; mv -f $config{workload}.stats.$$ $config{workload}.stats");321 }323 if (($mType == $MODEL_FPGA) && ! $noProgram && ! $noReserve) {324 Exec("hasim-fpga-ctrl --drop-reservation", "Failed to drop FPGA reservation");325 }327 if ($run_status != 0) {328 exit($run_status);329 }330 else {331 exit(CompareOutput());332 }335 sub ErrorExit($) {336 my $msg = shift;338 print STDERR "${msg}\n";340 if (($mType == $MODEL_FPGA) && ! $noProgram && ! $noReserve) {341 system("hasim-fpga-ctrl --drop-reservation");342 }344 exit(1);345 }348 ##349 ## ExecModel --350 ## This is the routine that actually invokes the model. stdout and stderr351 ## are logged in a file. The return value is the exit status of the model.352 ##353 sub ExecModel($) {354 my $cmd = shift;356 if ($gdb) {357 ## gdb needs stdin. Just use system() and don't do logging.358 system("gdb -args " . $cmd);359 return 0;360 }362 ##363 ## Invoke the model, but log its output both to stdout and to a file.364 ## Use a pty so the invoked program will use line buffering instead365 ## of fully buffered writes. (Libc sets up stdout line buffered when366 ## it thinks it is writing to a terminal. It uses fully buffered367 ## writing to a pipe.)368 ##370 my $pty = new IO::Pty;371 my $slave = $pty->slave();373 my $pid = fork();374 die "Couldn't fork: $!" unless defined $pid;376 if (! $pid) {377 # Child process is the monitoring process378 $pty->make_slave_controlling_terminal();380 my $output = "$config{workload}.$config{ISA}.out";381 if(exists($config{silent})) {382 $output = "/dev/null";383 }385 if (! open(LOG, ">$output")) {386 print STDERR "Error opening log file $output\n";387 }389 # Unbuffered I/O loop390 while (1) {391 my $buf;392 my $n = sysread($slave, $buf, 4096);394 last if ($n == 0);396 syswrite(STDOUT, $buf);397 syswrite(LOG, $buf);398 }400 close(LOG);401 exit(0);402 }404 # Bind new PTY to STDOUT (but save old STDOUT)405 $pty->close_slave();406 open(my $oldOut, ">&", STDOUT) or die $!;407 open(STDOUT, ">&", $pty) or die $!;409 # Run model410 my $result = system("${cmd} 2>&1");412 # Send ^d to end child logging thread413 print "\cD";415 # Return to normal STDOUT416 close(STDOUT);417 open(STDOUT, ">&", $oldOut) or die $!;418 close($oldOut);420 # Compute exit status of model421 my $status = 0;422 if ($result == -1) {423 print STDERR "Model execution failed\n";424 $status = 1;425 }426 elsif ($result & 127) {427 print STDERR "Child died with signal " . ($result & 127) . ", " . (($result & 128) ? 'with' : 'without') . " coredump\n";428 $status = 1;429 }430 elsif (($result >> 8) != 0) {431 $status = $result >> 8;432 print "Model exited with status $status\n";433 }435 return $status;436 }439 sub Exec($$) {440 my $cmd = shift;441 my $errmsg = shift;443 system($cmd);444 if ($? == -1) {445 ErrorExit("Failed to execute $cmd: $!");446 }447 elsif ($? & 127) {448 ErrorExit("Child died with signal " . ($? & 127) . ", " . (($? & 128) ? 'with' : 'without') . " coredump");449 }450 elsif (($? >> 8) != 0) {451 ErrorExit("${errmsg}");452 }453 }456 sub CompareOutput() {457 return 0 if ($noCompare != 0);458 return 0 if (! exists($config{compare}) || ($config{compare} eq ''));460 }463 #464 # Read the configuration file465 #466 sub ReadConfig($$) {467 my $conf = shift;468 my $required = shift;470 my $status = open(CONFIG, "< $conf");471 if (! $status) {472 return if (! $required);473 die("Failed to open $conf");474 }476 while (<CONFIG>) {477 chomp;478 my $t = $_;479 $t =~ s/#.*//;480 if ($t =~ /^\s*([^\s]+)\s*=\s*"(.*)"\s*$/) {481 my $c = $1;482 my $v = $2;483 $v =~ s/^["'](.*)["']$/$1/; # Drop quotation marks484 $config{$c} = $v;485 }486 elsif ($t =~ /^\s*([^\s]+)\s*=\s*([^\s]+)\s*$/) {487 my $c = $1;488 my $v = $2;489 $config{$c} = $v;490 }491 }492 }