44a45
> import copy
45a47,68
> # 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.
> }
48c71,79
< start_tick, stop_tick, start_sn, stop_sn):
---
> committed_only, 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
51c82,88
< # Skip lines up to region of interest
---
>
> # Read the first line
> line = trace.readline()
> if not line: return
> fields = line.split(':')
>
> # Skip lines up to the starting tick
53a91,93
> if fields[0] != 'O3PipeView': continue
> if (int(fields[2]) > 0 and
> int(fields[2]) >= start_tick-insts['tick_drift']): break
57,59c97,99
< if fields[0] != 'O3PipeView': continue
< if int(fields[2]) >= start_tick: break
< elif start_sn != 0:
---
>
> # Skip lines up to the starting sequence number
> if start_sn != 0:
60a101,104
> if fields[0] != 'O3PipeView': continue
> if (fields[1] == 'fetch' and
> int(fields[5]) >= (start_sn-insts['max_threshold'])):
> break
64,69c108
< 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(':')
---
>
74a114
>
85a126
>
92,93c133,135
< if ((stop_tick > 0 and int(fields[2]) > stop_tick) or
< (stop_sn > 0 and int(fields[5]) > stop_sn)):
---
> 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)
99,100c141
< print_inst(outfile, curr_inst, cycle_time, width, color,
< timestamps)
---
> queue_inst(outfile, curr_inst, cycle_time, width, color, timestamps)
105a147,184
> #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):
> 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, insts['min_threshold'])
>
> # Sorts out and prints instructions in print queue
> def print_insts(outfile, cycle_time, width, color, timestamps, 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)
>
> # Prints a single instruction
132a212
>
133a214
>
135a217,222
>
> # 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'])
>
138c225
< if ((inst['retire'] - inst['fetch']) < time_width):
---
> if ((last_event_time - inst['fetch']) < time_width):
141c228
< num_lines = ((inst['retire'] - base_tick) / time_width) + 1
---
> num_lines = ((last_event_time - base_tick) / time_width) + 1
143a231,235
>
> # This will visually distinguish completed and abandoned intructions.
> if inst['retire'] == 0: dot = '=' # abandoned instruction
> else: dot = '.' # completed instruction
>
152,155c244,248
< if tick >= start_tick and tick < end_tick:
< events.append((tick % time_width,
< stages[stage_idx]['name'],
< stage_idx))
---
> if tick != 0:
> if tick >= start_tick and tick < end_tick:
> events.append((tick % time_width,
> stages[stage_idx]['name'],
> stage_idx, tick))
165c258
< outfile.write(curr_color + '.' * ((event[0] / cycle_time) - pos))
---
> outfile.write(curr_color + dot * ((event[0] / cycle_time) - pos))
168c261,262
< if event[2] != len(stages) - 1: # event is not retire
---
>
> if event[3] != last_event_time: # event is not the last one
171a266
>
173c268
< outfile.write(curr_color + '.' * (width - pos) + termcap.Normal +
---
> outfile.write(curr_color + dot * (width - pos) + termcap.Normal +
232a328,331
> parser.add_option(
> '--only_committed',
> action='store_true', default=False,
> help="display only committed (completed) instructions (default: '%default')")
251c350
< *(tick_range + inst_range))
---
> options.only_committed, *(tick_range + inst_range))