#! /usr/bin/env python2

# 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.
#
# Authors: Giacomo Gabrielli

# 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()
