diff --git a/DRAMSys/library/resources/scripts/trace_gen.py b/DRAMSys/library/resources/scripts/trace_gen.py new file mode 100755 index 00000000..6b51235b --- /dev/null +++ b/DRAMSys/library/resources/scripts/trace_gen.py @@ -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