/* * 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 /** * 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 "mem/dramsim2_wrapper.hh" #include #include "DRAMSim2/MultiChannelMemorySystem.h" #include "base/compiler.hh" #include "base/logging.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("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("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("JEDEC_DATA_BUS_BITS=", working_dir + '/' + system_file); unsigned int burstLength = extractConfig("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 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(); }