diff options
Diffstat (limited to 'src/occ/tools/OccSimicsAutomate.pm')
-rwxr-xr-x | src/occ/tools/OccSimicsAutomate.pm | 1010 |
1 files changed, 1010 insertions, 0 deletions
diff --git a/src/occ/tools/OccSimicsAutomate.pm b/src/occ/tools/OccSimicsAutomate.pm new file mode 100755 index 0000000..f385243 --- /dev/null +++ b/src/occ/tools/OccSimicsAutomate.pm @@ -0,0 +1,1010 @@ +############################################################################## +# +# @file OccSimicsAutomate.pm +# +# @author Timothy Hallett +# +# @package OccSimicsAutomate +# +# @brief Perl class for automating simics for OCC. +# +# @verbatim +# +# Updates: 11/28/2011 -- thallet -- File/Class created +# 11/29/2011 -- thallet -- Methods for automating tracing and simics +# added and tested. Integration into Code +# Coverage Tool (HOCCT) works as well. +# v0.2 01/17/2012 -- thallet -- Made change to handle post_model_hook.simics +# v0.2.1 01/19/2012 -- thallet -- Clear accum on Expect calls. Changed simics +# prompt string. +# +# @endverbatim +# +# +############################################################################## + +package OccSimicsAutomate; + +use strict; +use Expect; + + + +############################################################################## +#----------------------------------------------------------------------------- +# +# Package Config/Default Parms +# +#----------------------------------------------------------------------------- +############################################################################## + +# @brief VERSION - contains VERSION of this class +my $VERSION = "0.2.1"; + +# @brief DEBUG_LEVEL - sets debug level of this class's print output +my $DEBUG_LEVEL = 1; + +# @brief CMD_PROMPT - sets what Expect should see for Linux bash prompt +my $CMD_PROMPT = '^.*[$%>#]\s'; + +# @brief CMD_PROMPT - sets what Expect should see for Simics prompt +my $SIMICS_PROMPT = "simics> \x1b.*m"; + +# @brief EXPECT_COMMAND - sets what Expect should run to get a bash prompt +my $EXPECT_COMMAND = "bash -i"; + +# @brief DEFAULT_TRACE_FILE - sets default filename for simics execution trace +my $DEFAULT_TRACE_FILE = "occ_exe_trace"; + +# @brief DEFAULT_INSTRUCTION_FILE - sets default filename for parsed out instruction trace +my $DEFAULT_INSTRUCTION_FILE = "/tmp/occ_instructions.txt"; + +# @brief SIMICS_CYCLES_PER_MS - sets timing for how many simics cycles are in 1ms. +my $SIMICS_CYCLES_PER_MS = (150016 * 4); + + +############################################################################## +#----------------------------------------------------------------------------- +# +# Package Global Variables +# +#----------------------------------------------------------------------------- +############################################################################## + +# @var G_occ_start_cmds +# +# @brief Holds commands that need to run to initialize simics for OCC execution +# +my @G_occ_start_cmds = +( + "enable-magic-breakpoint", + "new-symtable st_auto ../src/occ/occ.out", + "\@conf.OccComplex.OccSimpleSlot.cpu.current_context.symtable = conf.st_auto", +); + +# @var G_trace_start_cmds +# +# @brief Holds commands that need to run to initialize simics for tracing instructions +# +my @G_trace_start_cmds = +( + "load-module trace", + "new-tracer", + "trace0->trace_data = 0", + "trace0->trace_exceptions = 0", + "trace0->print_virtual_address = 0", + "trace0->print_memory_type = 0", + "trace0->print_linear_address = 0", + "trace0->print_data = 0", +); + + +############################################################################## +#----------------------------------------------------------------------------- +# +# Constructor +# +#----------------------------------------------------------------------------- +############################################################################## + +#------------------------------------------------ +# @fn new +# +# @brief Constructor, spawns bash shell with expect. +# +# @param None +# +# @return self - Pointer to $self as class pointer +#------------------------------------------------ +sub new +{ + my $class = shift; + my $self = + { + debug_lvl => $DEBUG_LEVEL, + prompt => $CMD_PROMPT, + shell_cmd => $EXPECT_COMMAND, + cyc_per_ms => $SIMICS_CYCLES_PER_MS, + trace_file => $DEFAULT_TRACE_FILE, + instr_file => $DEFAULT_INSTRUCTION_FILE, + expect_obj => undef, + last_rc => undef, + temp_file1 => undef, + temp_file2 => undef, + }; + + # Spawn a bash shell to run in + my @params; + $self->{expect_obj} = Expect->spawn($self->{shell_cmd}, @params) or die "Cannot spawn $self->{shell_cmd}: $!\n"; + #$self->{expect_obj}->log_file("filename", "w"); #Later, add option to log all expect activity? + #$self->{expect_obj}->log_file("filename"); #Later, add option to log all expect activity? + $self->{last_rc} = $self->{expect_obj}->expect(10,'-re',$self->{prompt}); + + #If call fails, print out error + if(0 == $self->{last_rc}) + { + print "Could not get bash prompt!"; die; + } + + # For now, lets die if we aren't in a sandbox + if( !defined($ENV{"sb"}) ){die "This script needs to run in an ODE sandbox!\n";} + + + bless ($self, $class); + return $self; +} + +############################################################################## +#----------------------------------------------------------------------------- +# +# Destructor +# +#----------------------------------------------------------------------------- +############################################################################## + +#------------------------------------------------ +# @fn DESTROY +# +# @brief Cleans up class, closes simics & expect. +# +# @param None +# +# @return None +#------------------------------------------------ +sub DESTROY +{ + my ( $self ) = @_; + + simics_cmd($self,"exit"); + + $self->{expect_obj}->soft_close(); +} + + +############################################################################## +#----------------------------------------------------------------------------- +# +# Base Methods +# +#----------------------------------------------------------------------------- +############################################################################## + +#------------------------------------------------ +# @fn prereq_simics +# +# @brief Makes sure that prereqs are in place to starts the simics session +# +# @param None +# +# @return rc - Return code of expect operation +#------------------------------------------------ +sub prereq_simics +{ + my ( $self ) = @_; + + # Make sure we have the simics command script setup to run + #if( !(-e $ENV{"sb"}."/../post_model_hook.simics") ) + { + if( -e $ENV{"sb"}."/occ/tools/occ_post_model_hook.simics" ) + { + print "Setting up Symlinks...\n"; + system("rm ".$ENV{"sb"}."/../simics/post_model_hook.simics"); + system("ln -s ".$ENV{"sb"}."/occ/tools/occ_post_model_hook.simics ".$ENV{"sb"}."/../simics/post_model_hook.simics"); + } + } +} + +#------------------------------------------------ +# @fn start_simics +# +# @brief Starts the simics session via expect +# +# @param None +# +# @return rc - Return code of expect operation +#------------------------------------------------ +sub start_simics +{ + my ( $self ) = @_; + + prereq_simics($self); + + $self->{expect_obj}->clear_accum(); + $self->{expect_obj}->send("start_simics -m occ_alone -st -batch_mode\n"); + $self->{last_rc} = $self->{expect_obj}->expect(300,'-re',$SIMICS_PROMPT); + + #If call fails, print out error + if(0 == $self->{last_rc}) + { + print "Couldn't get simics prompt ".$self->{last_rc}." \n"; die; + } + + return $self->{last_rc}; +} + +#------------------------------------------------ +# @fn close +# +# @brief Exits & Closes the simics session via expect +# +# @param None +# +# @return None +#------------------------------------------------ +sub close +{ + my ( $self ) = @_; + + simics_cmd_w_timeout($self,1,"exit"); + + $self->{expect_obj}->soft_close(); +} + +#------------------------------------------------ +# @fn simics_cmd +# +# @brief Runs a simics command, watis for "simics>" +# +# @param cmd - String with command that will be sent +# +# @return rc - Return code of expect operation +#------------------------------------------------ +sub simics_cmd +{ + my ( $self, $cmd ) = @_; + + $self->{expect_obj}->clear_accum(); + $self->{expect_obj}->send("$cmd\n"); + $self->{last_rc} = $self->{expect_obj}->expect(10,'-re',$SIMICS_PROMPT) or return; + + #If a person wanted to parse out the command, you would use this + #expect call here: + # @lines = $self->{expect_obj}->before(); + # foreach(@lines){do something to $_}; + + return $self->{last_rc}; +} + + +#------------------------------------------------ +# @fn simics_cmd_w_response +# +# @brief Runs a simics command, watis for "simics>" +# +# @param cmd - String with command that will be sent +# +# @return rc - Return code of expect operation +#------------------------------------------------ +sub simics_cmd_w_response +{ + my ( $self, $cmd ) = @_; + + $self->{expect_obj}->clear_accum(); + $self->{expect_obj}->send("$cmd\n"); + $self->{last_rc} = $self->{expect_obj}->expect(10,'-re',$SIMICS_PROMPT) or return; + + #If a person wanted to parse out the command, you would use this + #expect call here: + my @lines = $self->{expect_obj}->before(); + # foreach(@lines){do something to $_}; + return @lines; +} + +#------------------------------------------------ +# @fn get_last_simics_cmd_response +# +# @brief Returns what expect read before last prompt +# +# @return All response from last command before prompt +#------------------------------------------------ +sub get_last_simics_cmd_response +{ + my ( $self ) = @_; + + return $self->{expect_obj}->before(); +} + +#------------------------------------------------ +# @fn simics_cmd_w_timeout +# +# @brief Runs a simics command, watis for "simics>" +# +# @param t - Timeout in seconds of expect operation +# @param cmd - String with command that will be sent +# +# @return rc - Return code of expect operation +#------------------------------------------------ +sub simics_cmd_w_timeout +{ + my ($self, $t, $cmd) = @_; + + $self->{expect_obj}->clear_accum(); + $self->{expect_obj}->send("$cmd\n"); + $self->{last_rc} = $self->{expect_obj}->expect($t,'-re',$SIMICS_PROMPT) or return; + + return $self->{last_rc}; +} + +#------------------------------------------------ +# @fn simics_cmd_w_timeout_w_running +# +# @brief Runs a simics command, watis for "running>" +# +# @param t - Timeout in seconds of expect operation +# @param cmd - String with command that will be sent +# +# @return rc - Return code of expect operation +#------------------------------------------------ +sub simics_cmd_w_timeout_w_running +{ + my ($self, $t, $cmd) = @_; + + $self->{expect_obj}->clear_accum(); + $self->{expect_obj}->send("$cmd\n"); + $self->{last_rc} = $self->{expect_obj}->expect($t,'-re','running> ') or return; + + return $self->{last_rc}; +} + +#------------------------------------------------ +# @fn simics_cmd_w_running +# +# @brief Runs a simics command, watis for "running>" +# +# @param cmd - String with command that will be sent +# +# @return rc - Return code of expect operation +#------------------------------------------------ +sub simics_cmd_w_running +{ + my ( $self, $cmd ) = @_; + + $self->{expect_obj}->clear_accum(); + $self->{expect_obj}->send("$cmd\n"); + $self->{last_rc} = $self->{expect_obj}->expect(10,'-re','running> ') or return; + + return $self->{last_rc}; +} + +#------------------------------------------------ +# @fn DEBUG +# +# @brief Prints out debug data, based on debug_lvl +# +# @param lvl - Min Level of debug at which string will print +# @param str - String that will be printed +# +# @return None +#------------------------------------------------ +sub DEBUG +{ + my ($self,$lvl,$str) = @_; + if($lvl <= $self->{debug_lvl}) + { + print $str; + } +} + +#------------------------------------------------ +# @fn DEBUG +# +# @brief Prints out debug data, based on debug_lvl +# +# @param lvl - Min Level of debug at which string will print +# @param str - String that will be printed +# +# @return None +#------------------------------------------------ +sub SET_DEBUG_LVL +{ + my ($self,$lvl) = @_; + + $self->{debug_lvl} = $lvl; + + if($lvl <= 5) + { + print "Turning on Expect debugging\n\n"; + $self->{expect_obj}->debug(3); + $self->{expect_obj}->exp_internal(1); + } +} + + + +#----------------------------------------------------------------------------- +# Base Utilities (generic, based off base methods) +#----------------------------------------------------------------------------- + +#------------------------------------------------ +# @fn waitForSimicsPrompt +# +# @brief Helper function, returns when "simics>" is seen +# +# @return None +#------------------------------------------------ +sub waitForSimicsPrompt +{ + my ( $self ) = @_; + + simics_cmd($self,"echo"); +} + +#------------------------------------------------ +# @fn waitForRunningPrompt +# +# @brief Helper function, returns when "running>" is seen +# +# @return None +#------------------------------------------------ +sub waitForRunningPrompt +{ + my ( $self ) = @_; + + simics_cmd_w_timeout_w_running($self,10,"echo"); +} + +#------------------------------------------------ +# @fn getSimicsTime +# +# @brief Helper function +# +# @return None +#------------------------------------------------ +sub getSimicsTime +{ + my ( $self ) = @_; + + simics_cmd($self,"print-time"); + simics_cmd($self,"print-time -t"); +} + +#------------------------------------------------ +# @fn dumpOccStackTrace +# +# @brief Helper function +# +# @return None +#------------------------------------------------ +sub dumpOccStackTrace +{ + my ( $self ) = @_; + + simics_cmd($self,"stack-trace"); +} + +#------------------------------------------------ +# @fn interact +# +# @brief Swithes to interactive mode so that user can +# interact directly with simics, when script wants +# that to happen +# +# @return rc - Return code of expect operation +#------------------------------------------------ +sub interact +{ + my ( $self ) = @_; + + waitForSimicsPrompt($self); + waitForSimicsPrompt($self); + waitForSimicsPrompt($self); + waitForSimicsPrompt($self); + waitForSimicsPrompt($self); + waitForSimicsPrompt($self); + waitForSimicsPrompt($self); + waitForSimicsPrompt($self); + waitForSimicsPrompt($self); + + print "Switching to Interactive Mode: Type \"END\" and hit \"<Return>\" twice to return to script\n\n"; + + $self->{expect_obj}->interact(\*STDIN, "END"); + + return $self->{last_rc}; +} + +#------------------------------------------------ +# @fn setOccVariable +# +# @brief Sets variable abstracting weird simics syntax +# +# @param var - String with variable name +# @param value - Value to write to variable +# +# @return None +#------------------------------------------------ +sub setOccVariable +{ + my ( $self, $var, $value ) = @_; + + simics_cmd($self,"set (sym \"&$var\") $value (sym \"sizeof($var)\")"); +} + +#------------------------------------------------ +# @fn getOccVariable +# +# @brief Gets variable abstracting weird simics syntax +# +# @param var - String with variable name +# +# @return None +#------------------------------------------------ +sub getOccVariable +{ + my ( $self, $var) = @_; + + simics_cmd($self,"psym \"$var\""); +} + + + +############################################################################## +#----------------------------------------------------------------------------- +# +# OCC Simics Execution +# +#----------------------------------------------------------------------------- +############################################################################## + +#------------------------------------------------ +# @fn startAndRunOccUntilMain +# +# @brief Automates all steps needed to reach OCC +# application code main(), then stops on +# breakpoint there. +# +# @return None +#------------------------------------------------ +sub startAndRunOccUntilMain +{ + my ( $self ) = @_; + + start_simics($self); + runOccSimicsInitCmds($self); + runOccSimicsTraceInitCmds($self); + setOccBreakpointOnFunction($self,"main"); + runOccToBreakpoint($self); + deleteOccBreakpoints($self); + getSimicsTime($self); +} + +#------------------------------------------------ +# @fn startAndRunOccUntilSsxBoot +# +# @brief Automates all steps needed to reach SSX +# entry point __ssx_boot(), then stops on +# breakpoint there. +# +# @return None +#------------------------------------------------ +sub startAndRunOccUntilSsxBoot +{ + my ( $self ) = @_; + + start_simics($self); + runOccSimicsInitCmds($self); + runOccSimicsTraceInitCmds($self); + setOccBreakpointOnFunction($self,"__ssx_boot"); + runOccToBreakpoint($self); + deleteOccBreakpoints($self); + getSimicsTime($self); +} + + +#------------------------------------------------ +# @fn runOccSimicsInitCmds +# +# @brief Runs batch of simics commands to init OCC +# Simics Environment +# +# @return None +#------------------------------------------------ +sub runOccSimicsInitCmds +{ + my ( $self ) = @_; + + foreach(@G_occ_start_cmds) + { + simics_cmd($self,$_); + } +} + +#------------------------------------------------ +# @fn setOccBreakpointOnFunction +# +# @brief Sets breakpoint +# +# @param func - String with name of function to break on +# +# @return None +#------------------------------------------------ +sub setOccBreakpointOnFunction +{ + my ( $self, $func ) = @_; + + simics_cmd($self,"break (sym $func)"); +} + +#------------------------------------------------ +# @fn setOccBreakpointOnWriteToVariable +# +# @brief Sets breakpoint +# +# @param var - String with name of variable to break on +# when it is written to +# +# @return None +#------------------------------------------------ +sub setOccBreakpointOnWriteToVariable +{ + my ( $self, $var ) = @_; + + setOccBreakpointOnAddressWrite($self,"(sym \"&$var\")"); +} + +#------------------------------------------------ +# @fn setOccBreakpointOnCycles +# +# @brief Sets breakpoint +# +# @param num_cycles - Number of cycles until now that +# simics will run until it breaks. +# +# @return None +#------------------------------------------------ +sub setOccBreakpointOnCycles +{ + my ( $self, $num_cycles ) = @_; + + simics_cmd($self,"OccComplex.OccSimpleSlot.cpu.cycle-break $num_cycles"); +} + +#------------------------------------------------ +# @fn setOccBreakpointOnSource +# +# @brief Sets breakpoint +# +# @param file - Filename that breakpoint is in +# @param line - Line in filename that breakpoint is on +# +# @return None +#------------------------------------------------ +sub setOccBreakpointOnSource +{ + my ( $self, $file, $line ) = @_; + + simics_cmd($self,"break -x (pos $file:$line)"); +} + +#------------------------------------------------ +# @fn setOccBreakpointOnAddress +# +# @brief Sets breakpoint +# +# @param hex_addr - "0x"-prefixed string with address +# to break on when accessed as read, +# write, or executed (see $flags) +# @param flags - String; can be -r, -w, -x. -x is default +# +# @return None +#------------------------------------------------ +sub setOccBreakpointOnAddress +{ + # flags can be -r, -w, -x. -x is default + my ( $self, $hex_addr, $flags ) = @_; + + simics_cmd($self,"break $hex_addr $flags"); +} + +#------------------------------------------------ +# @fn setOccBreakpointOnAddressExecute +# +# @brief Sets breakpoint +# +# @param hex_addr - "0x"-prefixed string with address +# to break on when accessed as execute, +# +# @return None +#------------------------------------------------ +sub setOccBreakpointOnAddressExecute +{ + my ( $self, $hex_addr) = @_; + + setOccBreakpointOnAddress($self, $hex_addr, "-x"); +} + +#------------------------------------------------ +# @fn setOccBreakpointOnAddressWrite +# +# @brief Sets breakpoint +# +# @param hex_addr - "0x"-prefixed string with address +# to break on when accessed as write, +# +# @return None +#------------------------------------------------ +sub setOccBreakpointOnAddressWrite +{ + my ( $self, $hex_addr) = @_; + + setOccBreakpointOnAddress($self, $hex_addr, "-w"); +} + +#------------------------------------------------ +# @fn runOccToBreakpoint +# +# @brief Runs simics until breakpoint is set, or +# timeout (60 seconds) is reached. +# +# @return None +#------------------------------------------------ +sub runOccToBreakpoint +{ + my ( $self ) = @_; + + simics_cmd_w_timeout_w_running($self,60,"r"); + waitForSimicsPrompt($self); +} + +#------------------------------------------------ +# @fn deleteOccBreakpoints +# +# @brief Deletes all breakpoints +# +# @return None +#------------------------------------------------ +sub deleteOccBreakpoints +{ + my ( $self ) = @_; + + simics_cmd($self,"delete -all"); +} + + +#------------------------------------------------ +# @fn runOccForTimeInterval +# +# @brief Runs OCC for time interval of x ms +# +# @param time_in_ms - Time in ms that simics should run +# before stopping. +# +# @return None +#------------------------------------------------ +sub runOccForTimeInterval +{ + my ( $self, $time_in_ms ) = @_; + + # x = 150016 cycles ~= 250us; + # x * 40 = 10ms + + my $ms_per_loop = 10; + my $cyc_per_ms = $self->{cyc_per_ms}; + my $cyc_per_loop = $cyc_per_ms * 10; + + my $loops = int($time_in_ms / $ms_per_loop); + my $cyc_in_last_loop = ($time_in_ms % $ms_per_loop) * $cyc_per_ms; + + for (my $f=0; $f<$loops; $f++) + { + setOccBreakpointOnCycles($self,$cyc_per_loop); + runOccToBreakpoint($self); + } + + setOccBreakpointOnCycles($self,$cyc_in_last_loop); + runOccToBreakpoint($self); +} + + +############################################################################## +#----------------------------------------------------------------------------- +# +# OCC Simics Instruction Trace +# +#----------------------------------------------------------------------------- +############################################################################## + +#------------------------------------------------ +# @fn runOccSimicsTraceInitCmds +# +# @brief Initializes Simics and filesyste to grab +# OCC instruction trace +# +# @return None +#------------------------------------------------ +sub runOccSimicsTraceInitCmds +{ + my ( $self ) = @_; + + $self->{temp_file1} = "/tmp/temp_a".time().".txt"; + $self->{temp_file2} = "/tmp/temp_b".time().".txt"; + + if ( -e $self->{instr_file} ) + { + system("rm ".$self->{instr_file}.""); + } + system("touch ".$self->{instr_file}.""); + + system("touch ".$self->{trace_file}.""); + system("cat /dev/null >| ".$self->{trace_file}.""); + + + foreach(@G_trace_start_cmds) + { + simics_cmd($self,$_); + } +} + +#------------------------------------------------ +# @fn startOccSimicsTrace +# +# @brief Starts the simics instruction trace +# +# @return None +#------------------------------------------------ +sub startOccSimicsTrace +{ + my ( $self ) = @_; + + simics_cmd($self,"trace0.start ".$self->{trace_file}.""); + simics_cmd($self,"!touch ".$self->{trace_file}.""); +} + +#------------------------------------------------ +# @fn stopOccSimicsTrace +# +# @brief Stops the simics instruction trace and +# verifies file exists before returning. +# +# @return None +#------------------------------------------------ +sub stopOccSimicsTrace +{ + my ( $self ) = @_; + + # Stop the trace + simics_cmd_w_timeout($self,200,"trace0.stop"); + + # Flush the filesystem (not sure this actually does anything useful) + simics_cmd($self,"!sync"); + + # Used to see an issue where the file wouldn't get updated in GSA between + # the simics pool system and the sandbox pool system, so this is a check + # making sure the file update occurs + if( (-z $ENV{"sb"}."/../simics/".$self->{trace_file}."") ){print "..";sleep(5);} + if( (-z $ENV{"sb"}."/../simics/".$self->{trace_file}."") ){print "..";sleep(5);} + if( (-z $ENV{"sb"}."/../simics/".$self->{trace_file}."") ){print "..";sleep(5);} + if( (-z $ENV{"sb"}."/../simics/".$self->{trace_file}."") ){print "..";sleep(5);} + if( (-z $ENV{"sb"}."/../simics/".$self->{trace_file}."") ){print "..";sleep(5);} + if( (-z $ENV{"sb"}."/../simics/".$self->{trace_file}."") ){print "..";sleep(5);} + if( (-z $ENV{"sb"}."/../simics/".$self->{trace_file}."") ){system("sync"); DEBUG($self,1,"ERROR: Don't see trace file ".$ENV{"sb"}."/../simics/".$self->{trace_file}."");} +} + + +#------------------------------------------------ +# @fn parseOccSimicsTraceFile +# +# @brief Parses the simics instruction trace and +# prepares files for another pass. +# +# @return None +#------------------------------------------------ +sub parseOccSimicsTraceFile +{ + my ( $self ) = @_; + + my $trace_file = $self->{trace_file}; + DEBUG($self,1,"Lines in Trace file: "); + system("wc -l \$sb/../simics/$trace_file"); + + DEBUG($self,1,"Get instructions\n"); + system("strings \$sb/../simics/$trace_file | head -n 2"); + + # Simics sometimes dumps some garbage into the trace file, so need to pass it through + # strings first. + system("\\strings \$sb/../simics/$trace_file | \\grep inst | \\grep -ho \"p:0x........\" | \\grep -ho \"........\$\" | sort | uniq > ".$self->{temp_file1}.""); + + system("cat ".$self->{instr_file}." ".$self->{temp_file1}." | sort | uniq > ".$self->{temp_file2}.""); + system("mv ".$self->{temp_file2}." ".$self->{instr_file}.""); + + DEBUG($self,1,"Emptying Trace files to save space\n"); + DEBUG($self,1,"Lines in Inst file: "); + system("wc -l ".$self->{instr_file}.""); + system("LINES=`wc -l \$sb/../simics/$trace_file | cut -d\" \" -f1`; if [ \"\$LINES\" -lt 3 ]; then mv \$sb/../simics/$trace_file /tmp/failure__t_ccov_".int(rand(1000)).".txt; fi"); + system("LINES=`wc -l ".$self->{instr_file}." | cut -d\" \" -f1`; if [ \"\$LINES\" -eq 0 ]; then mv \$sb/../simics/$trace_file /tmp/failure_ccov_".int(rand(1000)).".txt; fi"); + #if( (-z $ENV{"sb"}."/../simics/".$self->{instr_file}."") ){system("mv $self->{instr_file} /tmp/failure_ccov.txt"); die "Instruction File Empty!!!\n";} + + system("echo \"\" > \$sb/../simics/$trace_file"); + system("echo \"\" > ".$self->{temp_file1}.""); +} + + +#------------------------------------------------ +# @fn runOccWithInstructionTrace +# +# @brief Runs simics w/ instruction trace, parses instructions +# out of trace file, and appends to overall instruction +# trace. +# +# @param time_in_ms - Time in ms that simics should +# execute OCC and grab the instruction +# trace. +# +# @return None +#------------------------------------------------ +sub runOccWithInstructionTrace +{ + my ( $self, $time_in_ms ) = @_; + + # x = 150016 cycles ~= 250us; + # x * 40 = 10ms + + my $ms_per_loop = 10; + my $cyc_per_ms = $self->{cyc_per_ms}; + my $cyc_per_loop = $cyc_per_ms * 10; + + my $loops = int($time_in_ms / $ms_per_loop); + my $cyc_in_last_loop = ($time_in_ms % $ms_per_loop) * $cyc_per_ms; + + #WORKAROUND: First Loop (10 cycles for workaround) + startOccSimicsTrace($self); + setOccBreakpointOnCycles($self,10); + runOccToBreakpoint($self); + stopOccSimicsTrace($self); + parseOccSimicsTraceFile($self); + + for (my $f=0; $f<$loops; $f++) + { + startOccSimicsTrace($self); + setOccBreakpointOnCycles($self,$cyc_per_loop); + runOccToBreakpoint($self); + stopOccSimicsTrace($self); + parseOccSimicsTraceFile($self); + } + + #Last Loop + startOccSimicsTrace($self); + setOccBreakpointOnCycles($self,$cyc_in_last_loop); + runOccToBreakpoint($self); + stopOccSimicsTrace($self); + parseOccSimicsTraceFile($self); +} + + +############################################################################## +#----------------------------------------------------------------------------- +# +# End of Package +# +#----------------------------------------------------------------------------- +############################################################################## + +1; + +############################################################################## +#----------------------------------------------------------------------------- +# +# End of File +# +#----------------------------------------------------------------------------- +############################################################################## + |