annotate scripts/run-null.bmark @ 65:cf8bb3038cbd pygar svn.66

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