diff options
Diffstat (limited to 'src/mem/dramsim2_wrapper.cc')
-rw-r--r-- | src/mem/dramsim2_wrapper.cc | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/src/mem/dramsim2_wrapper.cc b/src/mem/dramsim2_wrapper.cc new file mode 100644 index 000000000..34a7ad5d5 --- /dev/null +++ b/src/mem/dramsim2_wrapper.cc @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2013 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: Andreas Hansson + */ + +#include <cassert> + +/** + * When building the debug binary, we need to undo the command-line + * definition of DEBUG not to clash with DRAMSim2 print macros that + * are included for no obvious reason. + */ +#ifdef DEBUG +#undef DEBUG +#endif + +#include <fstream> + +#include "DRAMSim2/MultiChannelMemorySystem.h" +#include "base/compiler.hh" +#include "base/misc.hh" +#include "mem/dramsim2_wrapper.hh" + +/** + * DRAMSim2 requires SHOW_SIM_OUTPUT to be defined (declared extern in + * the DRAMSim2 print macros), otherwise we get linking errors due to + * undefined references + */ +int SHOW_SIM_OUTPUT = 0; + +DRAMSim2Wrapper::DRAMSim2Wrapper(const std::string& config_file, + const std::string& system_file, + const std::string& working_dir, + const std::string& trace_file, + unsigned int memory_size_mb, + bool enable_debug) : + dramsim(new DRAMSim::MultiChannelMemorySystem(config_file, system_file, + working_dir, trace_file, + memory_size_mb, NULL, NULL)), + _clockPeriod(0.0), _queueSize(0), _burstSize(0) +{ + // tell DRAMSim2 to ignore its internal notion of a CPU frequency + dramsim->setCPUClockSpeed(0); + + // switch on debug output if requested + if (enable_debug) + SHOW_SIM_OUTPUT = 1; + + // there is no way of getting DRAMSim2 to tell us what frequency + // it is assuming, so we have to extract it ourselves + _clockPeriod = extractConfig<double>("tCK=", + working_dir + '/' + config_file); + + if (!_clockPeriod) + fatal("DRAMSim2 wrapper failed to get clock\n"); + + // we also need to know what transaction queue size DRAMSim2 is + // using so we can stall when responses are blocked + _queueSize = extractConfig<unsigned int>("TRANS_QUEUE_DEPTH=", + working_dir + '/' + system_file); + + if (!_queueSize) + fatal("DRAMSim2 wrapper failed to get queue size\n"); + + + // finally, get the data bus bits and burst length so we can add a + // sanity check for the burst size + unsigned int dataBusBits = + extractConfig<unsigned int>("JEDEC_DATA_BUS_BITS=", + working_dir + '/' + system_file); + unsigned int burstLength = + extractConfig<unsigned int>("BL=", working_dir + '/' + config_file); + + if (!dataBusBits || !burstLength) + fatal("DRAMSim22 wrapper failed to get burst size\n"); + + _burstSize = dataBusBits * burstLength / 8; +} + +DRAMSim2Wrapper::~DRAMSim2Wrapper() +{ + delete dramsim; +} + +template <typename T> +T +DRAMSim2Wrapper::extractConfig(const std::string& field_name, + const std::string& file_name) const +{ + std::ifstream file_stream(file_name.c_str(), ios::in); + + if (!file_stream.good()) + fatal("DRAMSim2 wrapper could not open %s for reading\n", file_name); + + bool found = false; + T res; + std::string line; + while (!found && file_stream) { + getline(file_stream, line); + if (line.substr(0, field_name.size()) == field_name) { + found = true; + istringstream iss(line.substr(field_name.size())); + iss >> res; + } + } + + file_stream.close(); + + if (!found) + fatal("DRAMSim2 wrapper could not find %s in %s\n", field_name, + file_name); + + return res; +} + +void +DRAMSim2Wrapper::printStats() +{ + dramsim->printStats(true); +} + +void +DRAMSim2Wrapper::setCallbacks(DRAMSim::TransactionCompleteCB* read_callback, + DRAMSim::TransactionCompleteCB* write_callback) +{ + // simply pass it on, for now we ignore the power callback + dramsim->RegisterCallbacks(read_callback, write_callback, NULL); +} + +bool +DRAMSim2Wrapper::canAccept() const +{ + return dramsim->willAcceptTransaction(); +} + +void +DRAMSim2Wrapper::enqueue(bool is_write, uint64_t addr) +{ + bool success M5_VAR_USED = dramsim->addTransaction(is_write, addr); + assert(success); +} + +double +DRAMSim2Wrapper::clockPeriod() const +{ + return _clockPeriod; +} + +unsigned int +DRAMSim2Wrapper::queueSize() const +{ + return _queueSize; +} + +unsigned int +DRAMSim2Wrapper::burstSize() const +{ + return _burstSize; +} + +void +DRAMSim2Wrapper::tick() +{ + dramsim->update(); +} |