diff --git a/DRAMSys/DRAMSys.pro b/DRAMSys/DRAMSys.pro index 71f57bdc..0530961c 100644 --- a/DRAMSys/DRAMSys.pro +++ b/DRAMSys/DRAMSys.pro @@ -16,6 +16,20 @@ SUBDIRS += simulator/library.pro SUBDIRS += simulator/simulator.pro SUBDIRS += analyzer/traceAnalyzer.pro + +# Check if gem5 is installed: +gem5 = $$(GEM5) +isEmpty(gem5) +{ + DEFINES += DRAMSYS_GEM5 +} + +contains(DEFINES,DRAMSYS_GEM5) +{ + message(Gem5 Simulation Feature Enabled) + SUBDIRS += gem5/gem5.pro +} + # Build Sub Projects in the order given above CONFIG += ordered diff --git a/DRAMSys/analyzer/scripts/scripts.pri b/DRAMSys/analyzer/scripts/scripts.pri index 2e78599c..2e99f781 100644 --- a/DRAMSys/analyzer/scripts/scripts.pri +++ b/DRAMSys/analyzer/scripts/scripts.pri @@ -5,4 +5,5 @@ OTHER_FILES += scripts/memUtil.py OTHER_FILES += scripts/metrics.py OTHER_FILES += scripts/tests.py OTHER_FILES += scripts/plots.py +OTHER_FILES += scripts/sonification.pl diff --git a/DRAMSys/analyzer/scripts/sonification.pl b/DRAMSys/analyzer/scripts/sonification.pl new file mode 100644 index 00000000..75f5d615 --- /dev/null +++ b/DRAMSys/analyzer/scripts/sonification.pl @@ -0,0 +1,84 @@ +#!/bin/perl -w +use MIDI; # ...which "use"s MIDI::Track et al +use DBI; +use Data::Dumper; +use warnings; +use strict; + +my $dbfile = shift || die("No File"); +my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile","",""); + + +# Get time: +my $sth = $dbh->prepare("SELECT clk FROM GeneralInfo"); +$sth->execute(); +my $result = $sth->fetch; +my $timebase = $result->[0]; + +$sth = $dbh->prepare("SELECT p.PhaseName, p.PhaseBegin, p.PhaseEnd, t.TBank + FROM Phases p, Transactions t + WHERE (p.PhaseName = 'WR' OR p.PhaseName = 'RD') + AND p.Transact = t.ID + ORDER BY PhaseBegin"); +$sth->execute(); + +my @score; + +push(\@score, ['text_event', 0, 'Sonification']); +push(\@score, ['patch_change', 0, 1, 8]); +push(\@score, ['instrument_name', 0, 81]); + +while(my @row = $sth->fetchrow_array) +{ + #print $row[0]."\t".$row[1]."\t".$row[2]."\t".$row[3]."\n"; + # ('note', starttime, duration, channel, note, velocity) + my $note; + if($row[3] == 0) + { + $note = 72; #C + } + elsif($row[3] == 1) + { + $note = 75; #Eb + } + elsif($row[3] == 2) + { + $note = 76; #E + } + elsif($row[3] == 3) + { + $note = 77; #F + } + elsif($row[3] == 4) + { + $note = 78; #Gb + } + elsif($row[3] == 5) + { + $note = 79; #G + } + elsif($row[3] == 6) + { + $note = 82; #Bb + } + elsif($row[3] == 7) + { + $note = 84; #C + } + push(\@score, ['note', $row[1]/$timebase, 1, 1, $note, 96]); +} + +#print Dumper(\@score); + +#MIDI::Score::dump_score( \@score ); + +my $track = MIDI::Track->new; +my @events = @{MIDI::Score::score_r_to_events_r( \@score )}; + +$track->events(@events); +#$track->dump(); + +my $opus = MIDI::Opus->new({ 'format' => 0, 'ticks' => 240, 'tracks' => [ $track ] }); +$opus->write_to_file('cowbell.mid'); + + diff --git a/DRAMSys/gem5/gem5.pro b/DRAMSys/gem5/gem5.pro new file mode 100644 index 00000000..cb3dcc2d --- /dev/null +++ b/DRAMSys/gem5/gem5.pro @@ -0,0 +1,75 @@ +TARGET = DRAMSys_gem5 +TEMPLATE = app +CONFIG += console +CONFIG -= app_bundle +CONFIG -= qt + +# gem5 parameters: +gem5_arch = 'ARM' +gem5_variant = 'opt' +gem5_root = $$(GEM5) + +systemc_home = $$(SYSTEMC_HOME) +isEmpty(systemc_home) { + systemc_home = /opt/systemc +} +message(SystemC home is $${systemc_home}) + +systemc_target_arch = $$(SYSTEMC_TARGET_ARCH) +isEmpty(systemc_target_arch) { + systemc_target_arch = linux64 +} + +message(SystemC target architecture is $${systemc_target_arch}) + +unix:!macx { + message(Building on a GNU/Linux) + QMAKE_RPATHDIR += $${systemc_home}/lib-$${systemc_target_arch} + message(Linker options QMAKE_RPATHDIR is $${QMAKE_RPATHDIR}) +} + +DEFINES += TIXML_USE_STL +DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES +DEFINES += DRAMSYS_GEM5 + +unix:!macx { + QMAKE_CXXFLAGS += -std=c++11 -O0 -g +} + +macx: { + CONFIG += c++11 + QMAKE_CXXFLAGS += -std=c++0x -stdlib=libc++ -O0 -g +} + +INCLUDEPATH += ../simulator/src/simulation/ +INCLUDEPATH += $${systemc_home}/include +INCLUDEPATH += ../simulator/src/common/third_party/DRAMPower/src +INCLUDEPATH += ../simulator/src/common/third_party/DRAMPower/src/libdrampower +INCLUDEPATH += $${gem5_root}/build/$${gem5_arch}/ +INCLUDEPATH += $${gem5_root}/util/tlm/examples/slave_port +INCLUDEPATH += $${gem5_root}/util/tlm/examples/common +INCLUDEPATH += $${gem5_root}/util/tlm/ +INCLUDEPATH += $${gem5_root}/util/systemc + +LIBS += -L$${systemc_home}/lib-$${systemc_target_arch} -lsystemc +LIBS += ../simulator/libDRAMSys.a +LIBS += ../../DRAMSys/simulator/src/common/third_party/DRAMPower/src/libdrampower.a +LIBS += -lsqlite3 +LIBS += -L$${gem5_root}/build/$${gem5_arch} -lgem5_$${gem5_variant} + +SOURCES += $${gem5_root}/util/systemc/sc_gem5_control.cc +SOURCES += $${gem5_root}/util/systemc/sc_logger.cc +SOURCES += $${gem5_root}/util/systemc/sc_module.cc +SOURCES += $${gem5_root}/util/systemc/stats.cc +SOURCES += $${gem5_root}/util/tlm/examples/common/cli_parser.cc +SOURCES += $${gem5_root}/util/tlm/examples/common/report_handler.cc +SOURCES += $${gem5_root}/util/tlm/master_transactor.cc +SOURCES += $${gem5_root}/util/tlm/sc_master_port.cc +SOURCES += $${gem5_root}/util/tlm/sc_slave_port.cc +SOURCES += $${gem5_root}/util/tlm/slave_transactor.cc +SOURCES += $${gem5_root}/util/tlm/sc_ext.cc +SOURCES += $${gem5_root}/util/tlm/sc_mm.cc +SOURCES += $${gem5_root}/util/tlm/sim_control.cc + +SOURCES += main.cpp + diff --git a/DRAMSys/gem5/main.cpp b/DRAMSys/gem5/main.cpp new file mode 100644 index 00000000..a7dc0d21 --- /dev/null +++ b/DRAMSys/gem5/main.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015, University of Kaiserslautern + * Copyright (c) 2016, Dresden University of Technology (TU Dresden) + * 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. + * + * Authors: Matthias Jung + * Christian Menard + * Abdul Mutaal Ahmad + */ + +#include +#include +#include +#include + +#include "DRAMSys.h" +#include "TraceSetup.h" + +#include "report_handler.hh" +#include "sc_target.hh" +#include "sim_control.hh" +#include "slave_transactor.hh" +#include "stats.hh" + +using namespace std; + +class Gem5SimControlDRAMsys: public Gem5SystemC::Gem5SimControl +{ +public: + Gem5SimControlDRAMsys(string configFile) : + Gem5SystemC::Gem5SimControl("gem5",configFile,0,"") + { + } + + void afterSimulate() + { + sc_stop(); + } +}; + +string pathOfFile(string file) +{ + return file.substr(0, file.find_last_of('/')); +} + +int sc_main(int argc, char **argv) +{ + SC_REPORT_INFO("sc_main", "Simulation Setup"); + + string SimulationXML; + string gem5ConfigFile; + string resources; + + if(argc > 1) + { + // Get path of resources: + resources = pathOfFile(argv[0]) + + string("/../../DRAMSys/simulator/resources/"); + + SimulationXML = argv[1]; + gem5ConfigFile = argv[2]; + } + else + { + SC_REPORT_FATAL("sc_main","Please provide configuration files"); + } + + // Instantiate DRAMSys: + DRAMSys dramSys("DRAMSys", SimulationXML, resources); + + // Instantiate gem5: + Gem5SimControlDRAMsys sim_control(gem5ConfigFile); + Gem5SystemC::Gem5SlaveTransactor transactor("transactor", "transactor"); + + transactor.socket.bind(dramSys.tSocket); + transactor.sim_control.bind(sim_control); + + SC_REPORT_INFO("sc_main", "Start of Simulation"); + + sc_core::sc_set_stop_mode(SC_STOP_FINISH_DELTA); + sc_core::sc_start(); + + if (!sc_core::sc_end_of_simulation_invoked()) + { + SC_REPORT_INFO("sc_main","Simulation stopped without explicit sc_stop()"); + sc_core::sc_stop(); + } + + SC_REPORT_INFO("sc_main", "End of Simulation"); + + return EXIT_SUCCESS; +} diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml index 3dec948e..059d3ee1 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml @@ -10,4 +10,6 @@ + + diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3.xml index d13a4acc..431f052d 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3.xml @@ -10,4 +10,12 @@ + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/wideio.xml b/DRAMSys/simulator/resources/configs/simulator/wideio.xml index c811e71a..8ba8f3ba 100644 --- a/DRAMSys/simulator/resources/configs/simulator/wideio.xml +++ b/DRAMSys/simulator/resources/configs/simulator/wideio.xml @@ -7,7 +7,7 @@ - + diff --git a/DRAMSys/simulator/resources/simulations/wideio-example.xml b/DRAMSys/simulator/resources/simulations/wideio-example.xml index 8c068c25..c0847e17 100644 --- a/DRAMSys/simulator/resources/simulations/wideio-example.xml +++ b/DRAMSys/simulator/resources/simulations/wideio-example.xml @@ -4,7 +4,7 @@ - + diff --git a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp index d8650e70..45b3bd47 100644 --- a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp @@ -160,11 +160,16 @@ void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload & sc_time start = clkAlign(sc_time_stamp()); state->cleanUp(start); ScheduledCommand scheduledCommand = schedule(command, start, payload); - if(!((command == Command::Precharge || command == Command::Activate) - && refreshManager->hasCollision(scheduledCommand))) - { + if (config.ControllerCoreDisableRefresh == true) { state->change(scheduledCommand); controller.send(scheduledCommand, payload); + } else { + if(!((command == Command::Precharge || command == Command::Activate) + && refreshManager->hasCollision(scheduledCommand))) + { + state->change(scheduledCommand); + controller.send(scheduledCommand, payload); + } } } diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 85f0a250..d460c6b2 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -73,6 +73,11 @@ int string2int(string s) return std::stoi(s); } +unsigned long long string2ull(string s) +{ + return std::stoull(s); +} + StorageMode string2StoreMode(string s) { if(s == "NoStorage") @@ -185,6 +190,13 @@ void Configuration::setParameter(std::string name, std::string value) SC_REPORT_FATAL("Configuration", ("Invalid value for parameter " + name + ". This parameter must be at least one.").c_str()); } else NumberOfDevicesOnDIMM = string2int(value); + else if(name == "gem5") + gem5 = string2bool(value); + else if(name == "AddressOffset") + { + AddressOffset = string2ull(value); + cout << "Address Offset: " << AddressOffset << endl; + } else if(name == "CheckTLM2Protocol") CheckTLM2Protocol = string2bool(value); else if(name == "EnableControllerECC") diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index bff51af5..1e5326c9 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -82,6 +82,8 @@ struct Configuration unsigned int NumberOfDevicesOnDIMM = 1; bool CheckTLM2Protocol = false; bool EnableControllerECC = false; + bool gem5 = false; + unsigned long long int AddressOffset = 0; // MemSpec (from DRAM-Power XML) MemSpec memSpec; diff --git a/DRAMSys/simulator/src/simulation/Arbiter.h b/DRAMSys/simulator/src/simulation/Arbiter.h index c12ff14f..114e3d03 100644 --- a/DRAMSys/simulator/src/simulation/Arbiter.h +++ b/DRAMSys/simulator/src/simulation/Arbiter.h @@ -124,13 +124,19 @@ private: { if (phase == BEGIN_REQ) { + // adjust address offset: + payload.set_address(payload.get_address() - Configuration::getInstance().AddressOffset); + // Map the payload with socket id. routeMap[&payload] = id; + // In the begin request phase the socket ID is appended to the payload. // It will extracted from the payload and used later. appendDramExtension(id, payload); payload.acquire(); - } else if (phase == END_RESP) { + } + else if (phase == END_RESP) + { // Erase before the payload is released. routeMap.erase(&payload); payload.release(); @@ -142,9 +148,11 @@ private: virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) { + // adjust address offset: + trans.set_address(trans.get_address() - Configuration::getInstance().AddressOffset); + DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(trans.get_address()); return iSocket[decodedAddress.channel]->transport_dbg(trans); - } void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase) diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 26375fcf..3710a8ae 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -391,7 +391,10 @@ struct Dram : sc_module else if (phase == BEGIN_WR) { #ifndef DRAMSYS_PCT - assert(payload.get_data_length() == bytesPerBurst); + if(Configuration::getInstance().gem5 == false) + { + assert(payload.get_data_length() == bytesPerBurst); + } #endif if(powerAnalysis == true){DRAMPower->doCommand(MemCommand::WR, bank, cycle);} @@ -415,7 +418,12 @@ struct Dram : sc_module } else if (phase == BEGIN_RD) { - assert(payload.get_data_length() == bytesPerBurst); +#ifndef DRAMSYS_PCT + if(Configuration::getInstance().gem5 == false) + { + assert(payload.get_data_length() == bytesPerBurst); + } +#endif numberOfTransactionsServed++; if(powerAnalysis == true){DRAMPower->doCommand(MemCommand::RD, bank, cycle);} @@ -445,7 +453,6 @@ struct Dram : sc_module } else if (StoreMode == StorageMode::Store) // Use Storage { - unsigned char *phyAddr = memory + payload.get_address(); memcpy(phyAddr, payload.get_data_ptr(), payload.get_data_length()); } @@ -550,12 +557,8 @@ struct Dram : sc_module virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans) { - printDebugMessage("transport_dgb"); - // FIXME: maybe the initiator wants to write more than burst size at once - assert(trans.get_data_length() == bytesPerBurst); - // TODO: This part is not tested yet, neither with traceplayers neither with GEM5 coupling if (StoreMode == StorageMode::NoStorage) { @@ -569,7 +572,7 @@ struct Dram : sc_module unsigned int len = trans.get_data_length(); //unsigned int bank = DramExtension::getExtension(trans).getBank().ID(); - cout << "cmd " << (cmd ? "write" : "read") << " adr " << hex << adr << " len " << len << endl; + //cout << "cmd " << (cmd ? "write" : "read") << " adr " << hex << adr << " len " << len << endl; if ( cmd == tlm::TLM_READ_COMMAND ) { diff --git a/DRAMSys/tests/error/generateErrorTest_4ch.pl b/DRAMSys/tests/error/generateErrorTest_4ch.pl new file mode 100644 index 00000000..1bad5d65 --- /dev/null +++ b/DRAMSys/tests/error/generateErrorTest_4ch.pl @@ -0,0 +1,72 @@ +#!/usr/bin/perl -w +use warnings; +use strict; + +# Assuming this address mapping: +# +# +# +# +# +# +# + +# This is how it should look like later: +# 31: write 0x0 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +my $numberOfRows = 8192; +my $numberOfColumnsPerRow = 128; +my $bytesPerColumn = 16; +my $burstLength = 4; # burst length of 4 columns --> 4 columns written or read per access +my $dataLength = $bytesPerColumn * $burstLength; + +my $rowOffset = 0x4000; +my $colOffset = 0x80; + +# Generate Data Pattern: +my $dataPatternByte = "ff"; + +my $dataPattern = ""; +for(my $i = 0; $i < $dataLength; $i++) +{ + $dataPattern .= $dataPatternByte; +} + +my $clkCounter = 0; +my $addr = 0; + +# Generate Trace file (writes): + +for(my $ch = 0; $ch < 4; $ch++) { + $addr = 0; + $addr |= $ch << 27; + for(my $row = 0; $row < ($numberOfRows * $rowOffset); $row = $row + $rowOffset) + { + for(my $col = 0; $col < ($numberOfColumnsPerRow * $colOffset); $col = $col + ($colOffset * $burstLength)) + { + my $addrHex = sprintf("0x%x", $addr); + print "$clkCounter:\twrite\t$addrHex\t$dataPattern\n"; + $clkCounter++; + $addr += $colOffset * $burstLength; + } + } +} + +$clkCounter = 350000000; +$addr = 0; + +# Generate Trace file (reads): +for(my $ch = 0; $ch < 4; $ch++) { + $addr = 0; + $addr |= $ch << 27; + for(my $row = 0; $row < ($numberOfRows * $rowOffset); $row = $row + $rowOffset) + { + for(my $col = 0; $col < ($numberOfColumnsPerRow * $colOffset); $col = $col + ($colOffset * $burstLength)) + { + my $addrHex = sprintf("0x%x", $addr); + print "$clkCounter:\tread\t$addrHex\t$dataPattern\n"; + $clkCounter++; + $addr += $colOffset * $burstLength; + } + } +}