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