#! /usr/bin/env python2.7

# Copyright (c) 2011 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Pipeline activity viewer for the O3 CPU model.

import optparse
import os
import sys
import copy

# Temporary storage for instructions. The queue is filled in out-of-order
# until it reaches 'max_threshold' number of instructions. It is then
# sorted out and instructions are printed out until their number drops to
# 'min_threshold'.
# It is assumed that the instructions are not out of order for more then
# 'min_threshold' places - otherwise they will appear out of order.
insts = {
    'queue': [] ,         # Instructions to print.
    'max_threshold':2000, # Instructions are sorted out and printed when
                          # their number reaches this threshold.
    'min_threshold':1000, # Printing stops when this number is reached.
    'sn_start':0,         # The first instruction seq. number to be printed.
    'sn_stop':0,          # The last instruction seq. number to be printed.
    'tick_start':0,       # The first tick to be printed
    'tick_stop':0,        # The last tick to be printed
    'tick_drift':2000,    # Used to calculate the start and the end of main
                          # loop. We assume here that the instructions are not
                          # out of order for more then 2000 CPU ticks,
                          # otherwise the print may not start/stop
                          # at the time specified by tick_start/stop.
    'only_committed':0,   # Set if only committed instructions are printed.
}

def process_trace(trace, outfile, cycle_time, width, color, timestamps,
                  committed_only, store_completions, start_tick, stop_tick, start_sn, stop_sn):
    global insts

    insts['sn_start'] = start_sn
    insts['sn_stop'] = stop_sn
    insts['tick_start'] = start_tick
    insts['tick_stop'] = stop_tick
    insts['tick_drift'] = insts['tick_drift'] * cycle_time
    insts['only_committed'] = committed_only
    line = None
    fields = None

    # Skip lines up to the starting tick
    if start_tick != 0:
        while True:
            line = trace.readline()
            if not line: return
            fields = line.split(':')
            if fields[0] != 'O3PipeView': continue
            if int(fields[2]) >= start_tick: break
    elif start_sn != 0:
        while True:
            line = trace.readline()
            if not line: return
            fields = line.split(':')
            if fields[0] != 'O3PipeView': continue
            if fields[1] == 'fetch' and int(fields[5]) >= start_sn: break
    else:
        line = trace.readline()
        if not line: return
        fields = line.split(':')

    # Skip lines up to next instruction fetch
    while fields[0] != 'O3PipeView' or fields[1] != 'fetch':
        line = trace.readline()
        if not line: return
        fields = line.split(':')

    # Print header
    outfile.write('// f = fetch, d = decode, n = rename, p = dispatch, '
                  'i = issue, c = complete, r = retire')

    if store_completions:
        outfile.write(', s = store-complete')
    outfile.write('\n\n')

    outfile.write(' ' + 'timeline'.center(width) +
                  '   ' + 'tick'.center(15) +
                  '  ' + 'pc.upc'.center(12) +
                  '  ' + 'disasm'.ljust(25) +
                  '  ' + 'seq_num'.center(10))
    if timestamps:
        outfile.write('timestamps'.center(25))
    outfile.write('\n')

    # Region of interest
    curr_inst = {}
    while True:
        if fields[0] == 'O3PipeView':
            curr_inst[fields[1]] = int(fields[2])
            if fields[1] == 'fetch':
                if ((stop_tick > 0 and int(fields[2]) > stop_tick+insts['tick_drift']) or
                    (stop_sn > 0 and int(fields[5]) > (stop_sn+insts['max_threshold']))):
                    print_insts(outfile, cycle_time, width, color, timestamps, 0)
                    return
                (curr_inst['pc'], curr_inst['upc']) = fields[3:5]
                curr_inst['sn'] = int(fields[5])
                curr_inst['disasm'] = ' '.join(fields[6][:-1].split())
            elif fields[1] == 'retire':
                if curr_inst['retire'] == 0:
                    curr_inst['disasm'] = '-----' + curr_inst['disasm']
                if store_completions:
                    curr_inst[fields[3]] = int(fields[4])
                queue_inst(outfile, curr_inst, cycle_time, width, color, timestamps, store_completions)

        line = trace.readline()
        if not line:
            print_insts(outfile, cycle_time, width, color, timestamps, store_completions, 0)
            return
        fields = line.split(':')


#Sorts out instructions according to sequence number
def compare_by_sn(a, b):
    return cmp(a['sn'], b['sn'])

# Puts new instruction into the print queue.
# Sorts out and prints instructions when their number reaches threshold value
def queue_inst(outfile, inst, cycle_time, width, color, timestamps, store_completions):
    global insts
    l_copy = copy.deepcopy(inst)
    insts['queue'].append(l_copy)
    if len(insts['queue']) > insts['max_threshold']:
        print_insts(outfile, cycle_time, width, color, timestamps, store_completions, insts['min_threshold'])

# Sorts out and prints instructions in print queue
def print_insts(outfile, cycle_time, width, color, timestamps, store_completions, lower_threshold):
    global insts
    insts['queue'].sort(compare_by_sn)
    while len(insts['queue']) > lower_threshold:
        print_item=insts['queue'].pop(0)
        # As the instructions are processed out of order the main loop starts
        # earlier then specified by start_sn/tick and finishes later then what
        # is defined in stop_sn/tick.
        # Therefore, here we have to filter out instructions that reside out of
        # the specified boundaries.
        if (insts['sn_start'] > 0 and print_item['sn'] < insts['sn_start']):
            continue; # earlier then the starting sequence number
        if (insts['sn_stop'] > 0 and print_item['sn'] > insts['sn_stop']):
            continue; # later then the ending sequence number
        if (insts['tick_start'] > 0 and print_item['fetch'] < insts['tick_start']):
            continue; # earlier then the starting tick number
        if (insts['tick_stop'] > 0 and print_item['fetch'] > insts['tick_stop']):
            continue; # later then the ending tick number

        if (insts['only_committed'] != 0 and print_item['retire'] == 0):
            continue; # retire is set to zero if it hasn't been completed
        print_inst(outfile,  print_item, cycle_time, width, color, timestamps, store_completions)

# Prints a single instruction
def print_inst(outfile, inst, cycle_time, width, color, timestamps, store_completions):
    if color:
        from m5.util.terminal import termcap
    else:
        from m5.util.terminal import no_termcap as termcap
    # Pipeline stages
    stages = [{'name': 'fetch',
               'color': termcap.Blue + termcap.Reverse,
               'shorthand': 'f'},
              {'name': 'decode',
               'color': termcap.Yellow + termcap.Reverse,
               'shorthand': 'd'},
              {'name': 'rename',
               'color': termcap.Magenta + termcap.Reverse,
               'shorthand': 'n'},
              {'name': 'dispatch',
               'color': termcap.Green + termcap.Reverse,
               'shorthand': 'p'},
              {'name': 'issue',
               'color': termcap.Red + termcap.Reverse,
               'shorthand': 'i'},
              {'name': 'complete',
               'color': termcap.Cyan + termcap.Reverse,
               'shorthand': 'c'},
              {'name': 'retire',
               'color': termcap.Blue + termcap.Reverse,
               'shorthand': 'r'}
              ]
    if store_completions:
        stages.append(
            {'name': 'store',
             'color': termcap.Yellow + termcap.Reverse,
             'shorthand': 's'})

    # Print

    time_width = width * cycle_time
    base_tick = (inst['fetch'] / time_width) * time_width

    # Find out the time of the last event - it may not
    # be 'retire' if the instruction is not comlpeted.
    last_event_time = max(inst['fetch'], inst['decode'],inst['rename'],
                      inst['dispatch'],inst['issue'], inst['complete'], inst['retire'])
    if store_completions:
        last_event_time = max(last_event_time, inst['store'])

    # Timeline shorter then time_width is printed in compact form where
    # the print continues at the start of the same line.
    if ((last_event_time - inst['fetch']) < time_width):
        num_lines = 1 # compact form
    else:
        num_lines = ((last_event_time - base_tick) / time_width) + 1

    curr_color = termcap.Normal

    # This will visually distinguish completed and abandoned intructions.
    if inst['retire'] == 0: dot = '=' # abandoned instruction
    else:                   dot = '.' # completed instruction

    for i in range(num_lines):
        start_tick = base_tick + i * time_width
        end_tick = start_tick + time_width
        if num_lines == 1:  # compact form
            end_tick += (inst['fetch'] - base_tick)
        events = []
        for stage_idx in range(len(stages)):
            tick = inst[stages[stage_idx]['name']]
            if tick != 0:
                if tick >= start_tick and tick < end_tick:
                    events.append((tick % time_width,
                                   stages[stage_idx]['name'],
                                   stage_idx, tick))
        events.sort()
        outfile.write('[')
        pos = 0
        if num_lines == 1 and events[0][2] != 0:  # event is not fetch
            curr_color = stages[events[0][2] - 1]['color']
        for event in events:
            if (stages[event[2]]['name'] == 'dispatch' and
                inst['dispatch'] == inst['issue']):
                continue
            outfile.write(curr_color + dot * ((event[0] / cycle_time) - pos))
            outfile.write(stages[event[2]]['color'] +
                          stages[event[2]]['shorthand'])

            if event[3] != last_event_time:  # event is not the last one
                curr_color = stages[event[2]]['color']
            else:
                curr_color = termcap.Normal

            pos = (event[0] / cycle_time) + 1
        outfile.write(curr_color + dot * (width - pos) + termcap.Normal +
                      ']-(' + str(base_tick + i * time_width).rjust(15) + ') ')
        if i == 0:
            outfile.write('%s.%s %s [%s]' % (
                    inst['pc'].rjust(10),
                    inst['upc'],
                    inst['disasm'].ljust(25),
                    str(inst['sn']).rjust(10)))
            if timestamps:
                outfile.write('  f=%s, r=%s' % (inst['fetch'], inst['retire']))
            outfile.write('\n')
        else:
            outfile.write('...'.center(12) + '\n')


def validate_range(my_range):
    my_range = [int(i) for i in my_range.split(':')]
    if (len(my_range) != 2 or
        my_range[0] < 0 or
        my_range[1] > 0 and my_range[0] >= my_range[1]):
        return None
    return my_range


def main():
    # Parse options
    usage = ('%prog [OPTION]... TRACE_FILE')
    parser = optparse.OptionParser(usage=usage)
    parser.add_option(
        '-o',
        dest='outfile',
        default=os.path.join(os.getcwd(), 'o3-pipeview.out'),
        help="output file (default: '%default')")
    parser.add_option(
        '-t',
        dest='tick_range',
        default='0:-1',
        help="tick range (default: '%default'; -1 == inf.)")
    parser.add_option(
        '-i',
        dest='inst_range',
        default='0:-1',
        help="instruction range (default: '%default'; -1 == inf.)")
    parser.add_option(
        '-w',
        dest='width',
        type='int', default=80,
        help="timeline width (default: '%default')")
    parser.add_option(
        '--color',
        action='store_true', default=False,
        help="enable colored output (default: '%default')")
    parser.add_option(
        '-c', '--cycle-time',
        type='int', default=1000,
        help="CPU cycle time in ticks (default: '%default')")
    parser.add_option(
        '--timestamps',
        action='store_true', default=False,
        help="print fetch and retire timestamps (default: '%default')")
    parser.add_option(
        '--only_committed',
        action='store_true', default=False,
        help="display only committed (completed) instructions (default: '%default')")
    parser.add_option(
        '--store_completions',
        action='store_true', default=False,
        help="additionally display store completion ticks (default: '%default')")
    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error('incorrect number of arguments')
        sys.exit(1)
    tick_range = validate_range(options.tick_range)
    if not tick_range:
        parser.error('invalid range')
        sys.exit(1)
    inst_range = validate_range(options.inst_range)
    if not inst_range:
        parser.error('invalid range')
        sys.exit(1)
    # Process trace
    print 'Processing trace... ',
    with open(args[0], 'r') as trace:
        with open(options.outfile, 'w') as out:
            process_trace(trace, out, options.cycle_time, options.width,
                          options.color, options.timestamps,
                          options.only_committed, options.store_completions,
                          *(tick_range + inst_range))
    print 'done!'


if __name__ == '__main__':
    sys.path.append(os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            '..', 'src', 'python'))
    main()
