encode_packet_trace.py revision 9706
16691Stjones1@inf.ed.ac.uk#!/usr/bin/env python
26691Stjones1@inf.ed.ac.uk
36691Stjones1@inf.ed.ac.uk# Copyright (c) 2013 ARM Limited
46691Stjones1@inf.ed.ac.uk# All rights reserved
56691Stjones1@inf.ed.ac.uk#
66691Stjones1@inf.ed.ac.uk# The license below extends only to copyright in the software and shall
76691Stjones1@inf.ed.ac.uk# not be construed as granting a license to any other intellectual
86691Stjones1@inf.ed.ac.uk# property including but not limited to intellectual property relating
96691Stjones1@inf.ed.ac.uk# to a hardware implementation of the functionality of the software
106691Stjones1@inf.ed.ac.uk# licensed hereunder.  You may use the software subject to the license
116691Stjones1@inf.ed.ac.uk# terms below provided that you ensure that this notice is replicated
126691Stjones1@inf.ed.ac.uk# unmodified and in its entirety in all distributions of the software,
136691Stjones1@inf.ed.ac.uk# modified or unmodified, in source code or in binary form.
146691Stjones1@inf.ed.ac.uk#
156691Stjones1@inf.ed.ac.uk# Redistribution and use in source and binary forms, with or without
166691Stjones1@inf.ed.ac.uk# modification, are permitted provided that the following conditions are
176691Stjones1@inf.ed.ac.uk# met: redistributions of source code must retain the above copyright
186691Stjones1@inf.ed.ac.uk# notice, this list of conditions and the following disclaimer;
196691Stjones1@inf.ed.ac.uk# redistributions in binary form must reproduce the above copyright
206691Stjones1@inf.ed.ac.uk# notice, this list of conditions and the following disclaimer in the
216691Stjones1@inf.ed.ac.uk# documentation and/or other materials provided with the distribution;
226691Stjones1@inf.ed.ac.uk# neither the name of the copyright holders nor the names of its
236691Stjones1@inf.ed.ac.uk# contributors may be used to endorse or promote products derived from
246691Stjones1@inf.ed.ac.uk# this software without specific prior written permission.
256691Stjones1@inf.ed.ac.uk#
266691Stjones1@inf.ed.ac.uk# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
276691Stjones1@inf.ed.ac.uk# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
286691Stjones1@inf.ed.ac.uk# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
296691Stjones1@inf.ed.ac.uk# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
306691Stjones1@inf.ed.ac.uk# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
316691Stjones1@inf.ed.ac.uk# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
326691Stjones1@inf.ed.ac.uk# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
336691Stjones1@inf.ed.ac.uk# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
346691Stjones1@inf.ed.ac.uk# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
356691Stjones1@inf.ed.ac.uk# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
366691Stjones1@inf.ed.ac.uk# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
376691Stjones1@inf.ed.ac.uk#
386691Stjones1@inf.ed.ac.uk# Copyright 2008 Google Inc.  All rights reserved.
396691Stjones1@inf.ed.ac.uk# http://code.google.com/p/protobuf/
408232Snate@binkert.org#
416691Stjones1@inf.ed.ac.uk# Redistribution and use in source and binary forms, with or without
426691Stjones1@inf.ed.ac.uk# modification, are permitted provided that the following conditions are
436691Stjones1@inf.ed.ac.uk# met:
446691Stjones1@inf.ed.ac.uk#
456691Stjones1@inf.ed.ac.uk#     * Redistributions of source code must retain the above copyright
466691Stjones1@inf.ed.ac.uk# notice, this list of conditions and the following disclaimer.
476691Stjones1@inf.ed.ac.uk#     * Redistributions in binary form must reproduce the above
486691Stjones1@inf.ed.ac.uk# copyright notice, this list of conditions and the following disclaimer
496691Stjones1@inf.ed.ac.uk# in the documentation and/or other materials provided with the
506691Stjones1@inf.ed.ac.uk# distribution.
516691Stjones1@inf.ed.ac.uk#     * Neither the name of Google Inc. nor the names of its
526691Stjones1@inf.ed.ac.uk# contributors may be used to endorse or promote products derived from
536691Stjones1@inf.ed.ac.uk# this software without specific prior written permission.
546691Stjones1@inf.ed.ac.uk#
556691Stjones1@inf.ed.ac.uk# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
566691Stjones1@inf.ed.ac.uk# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
576691Stjones1@inf.ed.ac.uk# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
586691Stjones1@inf.ed.ac.uk# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
596691Stjones1@inf.ed.ac.uk# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
606691Stjones1@inf.ed.ac.uk# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
616691Stjones1@inf.ed.ac.uk# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
626691Stjones1@inf.ed.ac.uk# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
636691Stjones1@inf.ed.ac.uk# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
646691Stjones1@inf.ed.ac.uk# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
656691Stjones1@inf.ed.ac.uk# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
666691Stjones1@inf.ed.ac.uk#
677532Ssteve.reinhardt@amd.com# Authors: Andreas Hansson
686691Stjones1@inf.ed.ac.uk#
697532Ssteve.reinhardt@amd.com
707532Ssteve.reinhardt@amd.com# This script is used to migrate ASCII packet traces to the protobuf
716691Stjones1@inf.ed.ac.uk# format currently used in gem5. It assumes that protoc has been
726691Stjones1@inf.ed.ac.uk# executed and already generated the Python package for the packet
736691Stjones1@inf.ed.ac.uk# messages. This can be done manually using:
746691Stjones1@inf.ed.ac.uk# protoc --python_out=. --proto_path=src/proto src/proto/packet.proto
756691Stjones1@inf.ed.ac.uk#
766691Stjones1@inf.ed.ac.uk# The ASCII trace format uses one line per request on the format cmd,
776691Stjones1@inf.ed.ac.uk# addr, size, tick. For example:
786691Stjones1@inf.ed.ac.uk# r,128,64,4000
796691Stjones1@inf.ed.ac.uk# w,232123,64,500000
806691Stjones1@inf.ed.ac.uk# This trace reads 64 bytes from decimal address 128 at tick 4000,
816691Stjones1@inf.ed.ac.uk# then writes 64 bytes to address 232123 at tick 500000.
826691Stjones1@inf.ed.ac.uk#
836691Stjones1@inf.ed.ac.uk# This script can of course also be used as a template to convert
846691Stjones1@inf.ed.ac.uk# other trace formats into the gem5 protobuf format
856691Stjones1@inf.ed.ac.uk
866691Stjones1@inf.ed.ac.ukimport struct
876691Stjones1@inf.ed.ac.ukimport sys
886691Stjones1@inf.ed.ac.uk
896691Stjones1@inf.ed.ac.uk# Import the packet proto definitions. If they are not found, attempt
906691Stjones1@inf.ed.ac.uk# to generate them automatically. This assumes that the script is
916691Stjones1@inf.ed.ac.uk# executed from the gem5 root.
926691Stjones1@inf.ed.ac.uktry:
936691Stjones1@inf.ed.ac.uk    import packet_pb2
946691Stjones1@inf.ed.ac.ukexcept:
956691Stjones1@inf.ed.ac.uk    print "Did not find packet proto definitions, attempting to generate"
966691Stjones1@inf.ed.ac.uk    from subprocess import call
976691Stjones1@inf.ed.ac.uk    error = call(['protoc', '--python_out=util', '--proto_path=src/proto',
986691Stjones1@inf.ed.ac.uk                  'src/proto/packet.proto'])
996691Stjones1@inf.ed.ac.uk    if not error:
1006691Stjones1@inf.ed.ac.uk        import packet_pb2
1016691Stjones1@inf.ed.ac.uk        print "Generated packet proto definitions"
1026691Stjones1@inf.ed.ac.uk    else:
1036691Stjones1@inf.ed.ac.uk        print "Failed to import packet proto definitions"
1046691Stjones1@inf.ed.ac.uk        exit(-1)
1056691Stjones1@inf.ed.ac.uk
1066691Stjones1@inf.ed.ac.ukdef EncodeVarint(out_file, value):
1076691Stjones1@inf.ed.ac.uk  """
1086691Stjones1@inf.ed.ac.uk  The encoding of the Varint32 is copied from
1096691Stjones1@inf.ed.ac.uk  google.protobuf.internal.encoder and is only repeated here to
1106691Stjones1@inf.ed.ac.uk  avoid depending on the internal functions in the library.
1116691Stjones1@inf.ed.ac.uk  """
1126691Stjones1@inf.ed.ac.uk  bits = value & 0x7f
1136691Stjones1@inf.ed.ac.uk  value >>= 7
1146691Stjones1@inf.ed.ac.uk  while value:
1156691Stjones1@inf.ed.ac.uk    out_file.write(struct.pack('<B', 0x80|bits))
1166691Stjones1@inf.ed.ac.uk    bits = value & 0x7f
1176691Stjones1@inf.ed.ac.uk    value >>= 7
1186691Stjones1@inf.ed.ac.uk  out_file.write(struct.pack('<B', bits))
1196691Stjones1@inf.ed.ac.uk
1206691Stjones1@inf.ed.ac.ukdef encodeMessage(out_file, message):
1216691Stjones1@inf.ed.ac.uk    """
1226691Stjones1@inf.ed.ac.uk    Encoded a message with the length prepended as a 32-bit varint.
1236691Stjones1@inf.ed.ac.uk    """
1246691Stjones1@inf.ed.ac.uk    out = message.SerializeToString()
1256691Stjones1@inf.ed.ac.uk    EncodeVarint(out_file, len(out))
1266691Stjones1@inf.ed.ac.uk    out_file.write(out)
1276691Stjones1@inf.ed.ac.uk
1286691Stjones1@inf.ed.ac.ukdef main():
1296691Stjones1@inf.ed.ac.uk    if len(sys.argv) != 3:
1306691Stjones1@inf.ed.ac.uk        print "Usage: ", sys.argv[0], " <ASCII input> <protobuf output>"
1316691Stjones1@inf.ed.ac.uk        exit(-1)
1326691Stjones1@inf.ed.ac.uk
1336691Stjones1@inf.ed.ac.uk    try:
1346691Stjones1@inf.ed.ac.uk        ascii_in = open(sys.argv[1], 'r')
1356691Stjones1@inf.ed.ac.uk    except IOError:
1366691Stjones1@inf.ed.ac.uk        print "Failed to open ", sys.argv[1], " for reading"
1376691Stjones1@inf.ed.ac.uk        exit(-1)
1386691Stjones1@inf.ed.ac.uk
1396691Stjones1@inf.ed.ac.uk    try:
1406691Stjones1@inf.ed.ac.uk        proto_out = open(sys.argv[2], 'wb')
1416691Stjones1@inf.ed.ac.uk    except IOError:
1426691Stjones1@inf.ed.ac.uk        print "Failed to open ", sys.argv[2], " for writing"
1436691Stjones1@inf.ed.ac.uk        exit(-1)
1446691Stjones1@inf.ed.ac.uk
1456691Stjones1@inf.ed.ac.uk    # Write the magic number in 4-byte Little Endian, similar to what
1466691Stjones1@inf.ed.ac.uk    # is done in src/proto/protoio.cc
1476691Stjones1@inf.ed.ac.uk    proto_out.write("gem5")
1486691Stjones1@inf.ed.ac.uk
1496691Stjones1@inf.ed.ac.uk    # Add the packet header
1506691Stjones1@inf.ed.ac.uk    header = packet_pb2.PacketHeader()
1516691Stjones1@inf.ed.ac.uk    header.obj_id = "Converted ASCII trace " + sys.argv[1]
1526691Stjones1@inf.ed.ac.uk    # Assume the default tick rate
1536691Stjones1@inf.ed.ac.uk    header.tick_freq = 1000000000
1546691Stjones1@inf.ed.ac.uk    encodeMessage(proto_out, header)
1556691Stjones1@inf.ed.ac.uk
1566691Stjones1@inf.ed.ac.uk    # For each line in the ASCII trace, create a packet message and
1576691Stjones1@inf.ed.ac.uk    # write it to the encoded output
1586691Stjones1@inf.ed.ac.uk    for line in ascii_in:
1596691Stjones1@inf.ed.ac.uk        cmd, addr, size, tick = line.split(',')
1606691Stjones1@inf.ed.ac.uk        packet = packet_pb2.Packet()
1616691Stjones1@inf.ed.ac.uk        packet.tick = long(tick)
1626691Stjones1@inf.ed.ac.uk        # ReadReq is 1 and WriteReq is 4 in src/mem/packet.hh Command enum
1636691Stjones1@inf.ed.ac.uk        packet.cmd = 1 if cmd == 'r' else 4
1646691Stjones1@inf.ed.ac.uk        packet.addr = long(addr)
1656691Stjones1@inf.ed.ac.uk        packet.size = int(size)
1666691Stjones1@inf.ed.ac.uk        encodeMessage(proto_out, packet)
1676691Stjones1@inf.ed.ac.uk
1686691Stjones1@inf.ed.ac.uk    # We're done
1696691Stjones1@inf.ed.ac.uk    ascii_in.close()
1706691Stjones1@inf.ed.ac.uk    proto_out.close()
1716691Stjones1@inf.ed.ac.uk
1726691Stjones1@inf.ed.ac.ukif __name__ == "__main__":
1736691Stjones1@inf.ed.ac.uk    main()
1746691Stjones1@inf.ed.ac.uk