Trace generator script.

Trace generator script for a given address mapping. This script can be easily
modified for your needs.
This commit is contained in:
Éder F. Zulian
2018-05-24 09:53:58 +02:00
parent 2c0e6ece30
commit 9891f0f77f

View File

@@ -0,0 +1,130 @@
#!/usr/bin/env python
# vim: set fileencoding=utf-8
# Copyright (c) 2018, University of Kaiserslautern
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. 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.
#
# 3. Neither the name of the copyright holder 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 HOLDER
# 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.
#
# Author: Éder F. Zulian
import ctypes
# A trace file is a pre-recorded file containing memory transactions. Each
# memory transaction has a timestamp that tells the simulator when it shall
# happen, a transaction type (read or write) and a memory address given in
# hexadecimal.
#
# Here is an example syntax:
#
# ```
# # Comment lines begin with #
# # [clock-cyle]: [write|read] [hex-address]
# 31: read 0x400140
# 33: read 0x400160
# 56: write 0x7fff8000
# 81: read 0x400180
# ```
#
# The timestamp corresponds to the time the request is to be issued and it is
# given in cycles of the bus master device. Example: the device is a FPGA with
# frequency 200 MHz (clock period of 5 ns). If the timestamp is 10 it means
# that the request is to be issued when time is 50 ns.
#
# The default values given as example assume the following address mapping:
#
# DIMM Characteristics:
# Byte Offset (Y): 8 [0:2] (8-byte-wide memory module, i.e., 64-bit-wide data bus) -> 3 bit
# Cols (C): 1K [3:12] (A0 - A9) -> 10 bit
# Rows (R): 128K [13:29] (A0 - A16) -> 17 bit
# Bank (B): 8 [30:32] (BA0 - BA2) -> 3 bit
#
# 3 3 3 | 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 | 1 1 1
# 2 1 0 | 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 | 2 1 0 9 8 7 6 5 4 3 | 2 1 0
# B B B | R R R R R R R R R R R R R R R R R | C C C C C C C C C C | Y Y Y
#
# Transaction type (read or write)
transaction = 'read'
# Channel information. This is DRAMSys specific. The channel bits come after
# the last regular address bit.
num_ch = 1 # Number of channels
ch_shift = 33 # Shift to reach the frist bit reserved for channels in the address
ch_mask = 0x3 # Mask for all channel bits in the address
# Bank information
num_banks = 8 # Number of banks
bank_shift = 30 # Shift to reach the frist bit reserved for banks in the address
bank_mask = 0x7 # Mask for all bank bits in the address
# Row information
num_rows = 128 * 1024 # Number of rows
row_shift = 13 # Shift to reach the frist bit reserved for rows in the address
row_mask = 0x1ffff # Mask for all row bits in the address
# Column information
num_col = 1 * 1024 # Number of columns
col_shift = 3 # Shift to reach the frist bit reserved for columns in the address
col_mask = 0x3ff # Mask for all column bits in the address
# Burst length of 8 columns. 8 columns written/read per access (in 4 full
# clock cycles of the memory bus).
burst_len = 8
# Initial clock cycle
clock_cycle = 0
# Clock cycle increment between two accesses
clock_increment = 10
def clear_bits(mask, shift, val):
m = ctypes.c_uint64(~(mask << shift)).value
return ctypes.c_uint64(val & m).value
def set_bits(mask, shift, val, v):
val = clear_bits(mask, shift, val)
return ctypes.c_uint64(val | (v << shift)).value
address = 0
for ch in range(0, num_ch):
address = set_bits(ch_mask, ch_shift, address, ch)
for b in range(0, num_banks):
address = set_bits(bank_mask, bank_shift, address, b)
for row in range(0, num_rows):
address = set_bits(row_mask, row_shift, address, row)
clock_cycle = clock_cycle + clock_increment
for col in range(0, num_col, burst_len):
address = set_bits(col_mask, col_shift, address, col)
print "# clock cycle: {0:d} | {1} | address: 0x{2:010X} | channel: {3} | bank: {4} | row: {5} | column: {6}".format(clock_cycle, transaction, address, ch, b, row, col)
print "{0:d}:\t{1}\t0x{2:010X}".format(clock_cycle, transaction, address)
clock_cycle = clock_cycle + clock_increment