110066Sandreas.hansson@arm.com/* 210066Sandreas.hansson@arm.com * Copyright (c) 2013 ARM Limited 310066Sandreas.hansson@arm.com * All rights reserved 410066Sandreas.hansson@arm.com * 510066Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 610066Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 710066Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 810066Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 910066Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 1010066Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 1110066Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 1210066Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 1310066Sandreas.hansson@arm.com * 1410066Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 1510066Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 1610066Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 1710066Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 1810066Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1910066Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 2010066Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 2110066Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 2210066Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 2310066Sandreas.hansson@arm.com * this software without specific prior written permission. 2410066Sandreas.hansson@arm.com * 2510066Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610066Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710066Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810066Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910066Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010066Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110066Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210066Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310066Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410066Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510066Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610066Sandreas.hansson@arm.com * 3710066Sandreas.hansson@arm.com * Authors: Andreas Hansson 3810066Sandreas.hansson@arm.com */ 3910066Sandreas.hansson@arm.com 4010066Sandreas.hansson@arm.com#include <cassert> 4110066Sandreas.hansson@arm.com 4210066Sandreas.hansson@arm.com/** 4310066Sandreas.hansson@arm.com * When building the debug binary, we need to undo the command-line 4410066Sandreas.hansson@arm.com * definition of DEBUG not to clash with DRAMSim2 print macros that 4510066Sandreas.hansson@arm.com * are included for no obvious reason. 4610066Sandreas.hansson@arm.com */ 4710066Sandreas.hansson@arm.com#ifdef DEBUG 4810066Sandreas.hansson@arm.com#undef DEBUG 4910066Sandreas.hansson@arm.com#endif 5010066Sandreas.hansson@arm.com 5111793Sbrandon.potter@amd.com#include "mem/dramsim2_wrapper.hh" 5211793Sbrandon.potter@amd.com 5310066Sandreas.hansson@arm.com#include <fstream> 5410066Sandreas.hansson@arm.com 5510066Sandreas.hansson@arm.com#include "DRAMSim2/MultiChannelMemorySystem.h" 5610066Sandreas.hansson@arm.com#include "base/compiler.hh" 5712334Sgabeblack@google.com#include "base/logging.hh" 5810066Sandreas.hansson@arm.com 5910066Sandreas.hansson@arm.com/** 6010066Sandreas.hansson@arm.com * DRAMSim2 requires SHOW_SIM_OUTPUT to be defined (declared extern in 6110066Sandreas.hansson@arm.com * the DRAMSim2 print macros), otherwise we get linking errors due to 6210066Sandreas.hansson@arm.com * undefined references 6310066Sandreas.hansson@arm.com */ 6410066Sandreas.hansson@arm.comint SHOW_SIM_OUTPUT = 0; 6510066Sandreas.hansson@arm.com 6610066Sandreas.hansson@arm.comDRAMSim2Wrapper::DRAMSim2Wrapper(const std::string& config_file, 6710066Sandreas.hansson@arm.com const std::string& system_file, 6810066Sandreas.hansson@arm.com const std::string& working_dir, 6910066Sandreas.hansson@arm.com const std::string& trace_file, 7010066Sandreas.hansson@arm.com unsigned int memory_size_mb, 7110066Sandreas.hansson@arm.com bool enable_debug) : 7210066Sandreas.hansson@arm.com dramsim(new DRAMSim::MultiChannelMemorySystem(config_file, system_file, 7310066Sandreas.hansson@arm.com working_dir, trace_file, 7410066Sandreas.hansson@arm.com memory_size_mb, NULL, NULL)), 7510066Sandreas.hansson@arm.com _clockPeriod(0.0), _queueSize(0), _burstSize(0) 7610066Sandreas.hansson@arm.com{ 7710066Sandreas.hansson@arm.com // tell DRAMSim2 to ignore its internal notion of a CPU frequency 7810066Sandreas.hansson@arm.com dramsim->setCPUClockSpeed(0); 7910066Sandreas.hansson@arm.com 8010066Sandreas.hansson@arm.com // switch on debug output if requested 8110066Sandreas.hansson@arm.com if (enable_debug) 8210066Sandreas.hansson@arm.com SHOW_SIM_OUTPUT = 1; 8310066Sandreas.hansson@arm.com 8410066Sandreas.hansson@arm.com // there is no way of getting DRAMSim2 to tell us what frequency 8510066Sandreas.hansson@arm.com // it is assuming, so we have to extract it ourselves 8610066Sandreas.hansson@arm.com _clockPeriod = extractConfig<double>("tCK=", 8710066Sandreas.hansson@arm.com working_dir + '/' + config_file); 8810066Sandreas.hansson@arm.com 8910066Sandreas.hansson@arm.com if (!_clockPeriod) 9010066Sandreas.hansson@arm.com fatal("DRAMSim2 wrapper failed to get clock\n"); 9110066Sandreas.hansson@arm.com 9210066Sandreas.hansson@arm.com // we also need to know what transaction queue size DRAMSim2 is 9310066Sandreas.hansson@arm.com // using so we can stall when responses are blocked 9410066Sandreas.hansson@arm.com _queueSize = extractConfig<unsigned int>("TRANS_QUEUE_DEPTH=", 9510066Sandreas.hansson@arm.com working_dir + '/' + system_file); 9610066Sandreas.hansson@arm.com 9710066Sandreas.hansson@arm.com if (!_queueSize) 9810066Sandreas.hansson@arm.com fatal("DRAMSim2 wrapper failed to get queue size\n"); 9910066Sandreas.hansson@arm.com 10010066Sandreas.hansson@arm.com 10110066Sandreas.hansson@arm.com // finally, get the data bus bits and burst length so we can add a 10210066Sandreas.hansson@arm.com // sanity check for the burst size 10310066Sandreas.hansson@arm.com unsigned int dataBusBits = 10410066Sandreas.hansson@arm.com extractConfig<unsigned int>("JEDEC_DATA_BUS_BITS=", 10510066Sandreas.hansson@arm.com working_dir + '/' + system_file); 10610066Sandreas.hansson@arm.com unsigned int burstLength = 10710066Sandreas.hansson@arm.com extractConfig<unsigned int>("BL=", working_dir + '/' + config_file); 10810066Sandreas.hansson@arm.com 10910066Sandreas.hansson@arm.com if (!dataBusBits || !burstLength) 11010066Sandreas.hansson@arm.com fatal("DRAMSim22 wrapper failed to get burst size\n"); 11110066Sandreas.hansson@arm.com 11210066Sandreas.hansson@arm.com _burstSize = dataBusBits * burstLength / 8; 11310066Sandreas.hansson@arm.com} 11410066Sandreas.hansson@arm.com 11510066Sandreas.hansson@arm.comDRAMSim2Wrapper::~DRAMSim2Wrapper() 11610066Sandreas.hansson@arm.com{ 11710066Sandreas.hansson@arm.com delete dramsim; 11810066Sandreas.hansson@arm.com} 11910066Sandreas.hansson@arm.com 12010066Sandreas.hansson@arm.comtemplate <typename T> 12110066Sandreas.hansson@arm.comT 12210066Sandreas.hansson@arm.comDRAMSim2Wrapper::extractConfig(const std::string& field_name, 12310066Sandreas.hansson@arm.com const std::string& file_name) const 12410066Sandreas.hansson@arm.com{ 12510066Sandreas.hansson@arm.com std::ifstream file_stream(file_name.c_str(), ios::in); 12610066Sandreas.hansson@arm.com 12710066Sandreas.hansson@arm.com if (!file_stream.good()) 12810066Sandreas.hansson@arm.com fatal("DRAMSim2 wrapper could not open %s for reading\n", file_name); 12910066Sandreas.hansson@arm.com 13010066Sandreas.hansson@arm.com bool found = false; 13110066Sandreas.hansson@arm.com T res; 13210066Sandreas.hansson@arm.com std::string line; 13310066Sandreas.hansson@arm.com while (!found && file_stream) { 13410066Sandreas.hansson@arm.com getline(file_stream, line); 13510066Sandreas.hansson@arm.com if (line.substr(0, field_name.size()) == field_name) { 13610066Sandreas.hansson@arm.com found = true; 13710066Sandreas.hansson@arm.com istringstream iss(line.substr(field_name.size())); 13810066Sandreas.hansson@arm.com iss >> res; 13910066Sandreas.hansson@arm.com } 14010066Sandreas.hansson@arm.com } 14110066Sandreas.hansson@arm.com 14210066Sandreas.hansson@arm.com file_stream.close(); 14310066Sandreas.hansson@arm.com 14410066Sandreas.hansson@arm.com if (!found) 14510066Sandreas.hansson@arm.com fatal("DRAMSim2 wrapper could not find %s in %s\n", field_name, 14610066Sandreas.hansson@arm.com file_name); 14710066Sandreas.hansson@arm.com 14810066Sandreas.hansson@arm.com return res; 14910066Sandreas.hansson@arm.com} 15010066Sandreas.hansson@arm.com 15110066Sandreas.hansson@arm.comvoid 15210066Sandreas.hansson@arm.comDRAMSim2Wrapper::printStats() 15310066Sandreas.hansson@arm.com{ 15410066Sandreas.hansson@arm.com dramsim->printStats(true); 15510066Sandreas.hansson@arm.com} 15610066Sandreas.hansson@arm.com 15710066Sandreas.hansson@arm.comvoid 15810066Sandreas.hansson@arm.comDRAMSim2Wrapper::setCallbacks(DRAMSim::TransactionCompleteCB* read_callback, 15910066Sandreas.hansson@arm.com DRAMSim::TransactionCompleteCB* write_callback) 16010066Sandreas.hansson@arm.com{ 16110066Sandreas.hansson@arm.com // simply pass it on, for now we ignore the power callback 16210066Sandreas.hansson@arm.com dramsim->RegisterCallbacks(read_callback, write_callback, NULL); 16310066Sandreas.hansson@arm.com} 16410066Sandreas.hansson@arm.com 16510066Sandreas.hansson@arm.combool 16610066Sandreas.hansson@arm.comDRAMSim2Wrapper::canAccept() const 16710066Sandreas.hansson@arm.com{ 16810066Sandreas.hansson@arm.com return dramsim->willAcceptTransaction(); 16910066Sandreas.hansson@arm.com} 17010066Sandreas.hansson@arm.com 17110066Sandreas.hansson@arm.comvoid 17210066Sandreas.hansson@arm.comDRAMSim2Wrapper::enqueue(bool is_write, uint64_t addr) 17310066Sandreas.hansson@arm.com{ 17410066Sandreas.hansson@arm.com bool success M5_VAR_USED = dramsim->addTransaction(is_write, addr); 17510066Sandreas.hansson@arm.com assert(success); 17610066Sandreas.hansson@arm.com} 17710066Sandreas.hansson@arm.com 17810066Sandreas.hansson@arm.comdouble 17910066Sandreas.hansson@arm.comDRAMSim2Wrapper::clockPeriod() const 18010066Sandreas.hansson@arm.com{ 18110066Sandreas.hansson@arm.com return _clockPeriod; 18210066Sandreas.hansson@arm.com} 18310066Sandreas.hansson@arm.com 18410066Sandreas.hansson@arm.comunsigned int 18510066Sandreas.hansson@arm.comDRAMSim2Wrapper::queueSize() const 18610066Sandreas.hansson@arm.com{ 18710066Sandreas.hansson@arm.com return _queueSize; 18810066Sandreas.hansson@arm.com} 18910066Sandreas.hansson@arm.com 19010066Sandreas.hansson@arm.comunsigned int 19110066Sandreas.hansson@arm.comDRAMSim2Wrapper::burstSize() const 19210066Sandreas.hansson@arm.com{ 19310066Sandreas.hansson@arm.com return _burstSize; 19410066Sandreas.hansson@arm.com} 19510066Sandreas.hansson@arm.com 19610066Sandreas.hansson@arm.comvoid 19710066Sandreas.hansson@arm.comDRAMSim2Wrapper::tick() 19810066Sandreas.hansson@arm.com{ 19910066Sandreas.hansson@arm.com dramsim->update(); 20010066Sandreas.hansson@arm.com} 201