Conflicts resolved

This commit is contained in:
Felipe S. Prado
2016-10-11 15:01:16 +02:00
12 changed files with 5917 additions and 12 deletions

1
.gitignore vendored
View File

@@ -17,3 +17,4 @@ build*/
*.swo
cscope*
DRAMSys/analyzer/scripts/__pycache__/
*.pyc

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 130 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 58 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 114 KiB

View File

@@ -101,10 +101,18 @@ private:
std::vector<TlmRecorder*> tlmRecorders;
//used to map the transaction from devices to the arbiter's target socket ID.
std::map<tlm_generic_payload*,int> routeMap;
// Initiated by dram side
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)
{
// Check channel ID
assert((unsigned int)channelId < iSocket.size());
if ((unsigned int)channelId != DramExtension::getExtension(payload).getChannel().ID()) {
SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted");
}
sc_time recTime = bwDelay + sc_time_stamp();
sc_time notDelay = bwDelay;
@@ -115,19 +123,21 @@ private:
return TLM_ACCEPTED;
}
// TODO: check this id. How the payload extension propagates and is used...
// TODO: check the index mechanism for initiator and target sockets. Assert the index to be valid.
// Initiated by initiator side
// This function is called when an arbiter's target socket receives a transaction from a device
tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay)
{
assert ((unsigned int)id < tSocket.size());
if (phase == BEGIN_REQ) {
// 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) {
// Erase before the payload is released.
routeMap.erase(&payload);
payload.release();
}
@@ -147,7 +157,9 @@ private:
unsigned int initiatorSocket = DramExtension::getExtension(payload).getThread().ID()-1;
unsigned int channelId = DramExtension::getExtension(payload).getChannel().ID();
// TODO: here check if the channel and the initiatorSocket ID are valid. If not, the payload extension was corrupted.
// Check the valid range of initiatorSocket ID and channel Id
assert(initiatorSocket < Configuration::getInstance().NumberOfTracePlayers);
assert(channelId < Configuration::getInstance().NumberOfMemChannels);
// Phases initiated by the intiator side from arbiter's point of view (devices performing memory requests to the arbiter)
if (phase == BEGIN_REQ) {
@@ -177,6 +189,10 @@ private:
// Phases initiated by the target side from arbiter's point of view (memory side)
else if (phase == END_REQ) {
channelIsFree[channelId] = true;
// Validate the initiatorSocket ID
if ((int)initiatorSocket != routeMap[&payload]) {
SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted");
}
// The arbiter receives a transaction which phase is END_REQ from memory controller and forwards it to the requester device.
sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME);
@@ -190,6 +206,10 @@ private:
channelIsFree[channelId] = false;
}
} else if (phase == BEGIN_RESP) {
// Validate the initiatorSocket ID
if ((int)initiatorSocket != routeMap[&payload]) {
SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted");
}
// The arbiter receives a transaction in BEGIN_RESP phase (that came from the memory side) and forwards it to the requester device
if (receivedResponses[initiatorSocket].empty())
sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME);
@@ -216,12 +236,35 @@ private:
void appendDramExtension(int socketId, tlm_generic_payload& payload)
{
// TODO: check if channel valid before appending.
// TODO: check if all parts of the decodedAddress are inside the valid range (devices should not perform invalid requests to the arbiter, right?).
unsigned int burstlength = payload.get_streaming_width();
DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(payload.get_address());
DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength);
payload.set_auto_extension(extension);
// Check the valid range of decodedAddress
if (addressIsValid(decodedAddress)) {
DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength);
payload.set_auto_extension(extension);
} else {
SC_REPORT_FATAL("Arbiter", "Decoded Address are not inside the valid range");
}
}
bool addressIsValid(DecodedAddress& decodedAddress)
{
if (decodedAddress.channel >= xmlAddressDecoder::getInstance().amount["channel"]) {
return false;
}
if (decodedAddress.bank >= xmlAddressDecoder::getInstance().amount["bank"]) {
return false;
}
if (decodedAddress.bankgroup > xmlAddressDecoder::getInstance().amount["bankgroup"]) {
return false;
}
if (decodedAddress.column >= xmlAddressDecoder::getInstance().amount["column"]) {
return false;
}
if (decodedAddress.row >= xmlAddressDecoder::getInstance().amount["row"]) {
return false;
}
return true;
}
void printDebugMessage(std::string message)

View File

@@ -0,0 +1,15 @@
<memconfig>
<BankwiseLogic value="0"/>
<OpenPagePolicy value="1" />
<MaxNrOfTransactions value="8" />
<Scheduler value="FIFO_STRICT" />
<Capsize value="5" />
<PowerDownMode value="NoPowerDown" />
<PowerDownTimeout value="100" />
<!-- Error Modelling -->
<ErrorChipSeed value="42" />
<ErrorCSVFile value="../../DRAMSys/simulator/src/error/error.csv" />
<!-- Modes: NoStorage, Store (store data without errormodel), ErrorModel (store data with errormodel) -->
<StoreMode value="NoStorage" />
</memconfig>

View File

@@ -0,0 +1,52 @@
<simulation>
<!-- General Simulator Configuration (used for all simulation setups) -->
<simconfig>
<Debug value="0" />
<DatabaseRecording value="1" />
<PowerAnalysis value="1" />
<EnableWindowing value = "0" />
<WindowSize value="1000" />
<NumberOfTracePlayers value="1"/>
<NumberOfMemChannels value="4"/>
<ControllerCoreDisableRefresh value="0"/>
<ThermalSimulation value="0"/>
<SimulationProgressBar value="1"/>
<NumberOfDevicesOnDIMM value = "1" />
<CheckTLM2Protocol value = "0" />
</simconfig>
<!-- Temperature Simulator Configuration (used for all simulation setups) -->
<thermalsimconfig>
<TemperatureScale value="Celsius" />
<StaticTemperatureDefaultValue value="89" />
<ThermalSimPeriod value="10" />
<ThermalSimUnit value="ms" />
<PowerInfoFile value="../../DRAMSys/simulator/resources/configs/thermalsim/powerInfo.xml"/>
<IceServerIp value="127.0.0.1" />
<IceServerPort value="11880" />
<SimPeriodAdjustFactor value="10" />
<NPowStableCyclesToIncreasePeriod value="5" />
<GenerateTemperatureMap value="1" />
<GeneratePowerMap value="1" />
</thermalsimconfig>
<memspecs>
<memspec src="../../DRAMSys/simulator/resources/configs/memspecs/WideIO.xml"></memspec>
</memspecs>
<addressmappings>
<addressmapping src="../../DRAMSys/simulator/resources/configs/amconfigs/am_wideio.xml"></addressmapping>
</addressmappings>
<memconfigs>
<memconfig src="../../DRAMSys/tests/evaluation/fifoStrict.xml"/>
</memconfigs>
<tracesetups>
<tracesetup id="evaluation_test_fifoStrict">
<device clkMhz="200">mediabench-c-ray-1.1_32.stl</device>
</tracesetup>
</tracesetups>
</simulation>

View File

@@ -0,0 +1,93 @@
#!/usr/bin/perl -w
# Copyright (c) 2016, University of Kaiserslautern
# 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, Felipe S. Prado
#
# Test Evaluation:
# This test runs the simulation with standard configuration
# Run Simulation:
$bankwiseLogicLine = `grep -n '<BankwiseLogic value=' fifoStrict.xml | cut -d: -f 1`;
chomp $bankwiseLogicLine;
$powerAnalysisLine = `grep -n '<PowerAnalysis value=' sim-batch.xml | cut -d: -f 1`;
chomp $powerAnalysisLine;
$powerDownModeLine = `grep -n '<PowerDownMode value=' fifoStrict.xml | cut -d: -f 1`;
chomp $powerDownModeLine;
$powerDownModes = `grep 'enum class EPowerDownMode' ../../simulator/src/controller/core/configuration/Configuration.h | cut -d } -f 1 | sed 's/ //g' | cut -d { -f 2`;
@powerDownModes = split(/,/,$powerDownModes);
chomp @powerDownModes;
chdir("../../../build/simulator/");
foreach (@powerDownModes)
{
system("sed -i '" . $powerAnalysisLine . "s^.*^ <PowerAnalysis value=\"1\" />^' ../../DRAMSys/tests/evaluation/sim-batch.xml");
system("sed -i '" . $bankwiseLogicLine . "s^.*^ <BankwiseLogic value=\"0\"/>^' ../../DRAMSys/tests/evaluation/fifoStrict.xml");
system("sed -i '" . $powerDownModeLine . "s^.*^ <PowerDownMode value=\"$_\" />^' ../../DRAMSys/tests/evaluation/fifoStrict.xml");
`./dramSys ../../DRAMSys/tests/evaluation/sim-batch.xml`;
@files = `ls sim-batch/evaluation_test_fifoStrict_channel*.tdb`;
chomp @files;
foreach (@files)
{
`python3.5 ../../DRAMSys/analyzer/scripts/tests.py $_ > ../../DRAMSys/tests/evaluation/output.txt`;
if("All tests passed\n" ne `grep "All tests passed" ../../DRAMSys/tests/evaluation/output.txt`)
{
exit -1;
}
}
system("sed -i '" . $powerAnalysisLine . "s^.*^ <PowerAnalysis value=\"0\" />^' ../../DRAMSys/tests/evaluation/sim-batch.xml");
system("sed -i '" . $bankwiseLogicLine . "s^.*^ <BankwiseLogic value=\"1\"/>^' ../../DRAMSys/tests/evaluation/fifoStrict.xml");
`./dramSys ../../DRAMSys/tests/evaluation/sim-batch.xml`;
foreach (@files)
{
`python3.5 ../../DRAMSys/analyzer/scripts/tests.py $_ > ../../DRAMSys/tests/evaluation/output.txt`;
if("All tests passed\n" ne `grep "All tests passed" ../../DRAMSys/tests/evaluation/output.txt`)
{
exit -1;
}
}
}
exit 0;

View File

@@ -17,8 +17,12 @@ OTHER_FILES += tests/error/fr_fcfs.xml
OTHER_FILES += tests/error/generateErrorTest.pl
OTHER_FILES += tests/error/WideIO.xml
# timing compliance test
OTHER_FILES += tests/timing_compliance/sim-batch.xml
OTHER_FILES += tests/timing_compliance/fifoStrict.xml
OTHER_FILES += tests/timing_compliance/test.pl
# evaluation test
OTHER_FILES += tests/evaluation/sim-batch.xml
OTHER_FILES += tests/evaluation/fifoStrict.xml
OTHER_FILES += tests/evaluation/test.pl
# python unit tests
OTHER_FILES += tests/unit/unit_test.py
OTHER_FILES += tests/unit/mem_util.py

View File

@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2016, University of Kaiserslautern
# 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: Éder F. Zulian
#
import xml.etree.ElementTree as ET
class MemConfig(object):
""" Memory Configuration Class
The format used in memory specification XML files differs from the
format used in memory configuration XML files. Each class uses the
proper format when searching for elements.
"""
def getValue(self, id):
return self.xmlMemConfig.findall(id)[0].attrib['value']
def getIntValue(self, id):
return int(self.getValue(id))
def __init__(self, xmlfile):
self.xmlMemConfig = ET.parse(xmlfile)
class MemSpec(object):
""" Memory Specification Class
The format used in memory specification XML files differs from the
format used in memory configuration XML files. Each class uses the
proper format when searching for elements.
"""
def getValue(self, id):
return self.xmlMemSpec.findall(".//parameter[@id='{0}']".
format(id))[0].attrib['value']
def getIntValue(self, id):
return int(self.getValue(id))
def __init__(self, xmlfile):
self.xmlMemSpec = ET.parse(xmlfile)

View File

@@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2016, University of Kaiserslautern
# 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: Éder F. Zulian
#
import unittest
import subprocess
import os
import shutil
import multiprocessing
import sys
import tempfile
from mem_util import *
devnull = None
rootdir = '../../..'
tempfile.tempdir = os.getcwd() + '/' + rootdir
builddir = tempfile.mkdtemp()
simdir = builddir + '/simulator'
memConfigPath = rootdir + '/DRAMSys/simulator/resources/configs/memconfigs'
memSpecsPath = rootdir + '/DRAMSys/simulator/resources/configs/memspecs'
def build_project():
if os.path.exists(builddir):
shutil.rmtree(builddir)
os.makedirs(builddir)
os.chdir(builddir)
qmakeprojfile = '../DRAMSys/dram.vp.system.pro'
subprocess.call(['qmake', qmakeprojfile], stdout=devnull, stderr=devnull)
makejobs = '-j' + str(multiprocessing.cpu_count())
ret = subprocess.call(['make', makejobs], stdout=devnull, stderr=devnull)
return ret
class TestBuild(unittest.TestCase):
def test_build_project(self):
""" The project's build process should succeed """
self.assertEqual(build_project(), 0)
def tearDown(self):
shutil.rmtree(builddir)
class TestOutput(unittest.TestCase):
def setUp(self):
build_project()
def test_run_without_arguments(self):
""" running dramSys without arguments returns 0 """
os.chdir(simdir)
self.assertEqual(subprocess.call(['./dramSys'], stdout=devnull), 0)
def tearDown(self):
shutil.rmtree(builddir)
@unittest.skip("skipping this")
class TestDummy(unittest.TestCase):
def test_list_files(self):
for file in os.listdir(memConfigPath):
if file.endswith(".xml"):
print(file)
for file in os.listdir(memSpecsPath):
if file.endswith(".xml"):
print(file)
if __name__ == '__main__':
with open(os.devnull, 'wb') as devnull:
unittest.main()

View File

@@ -809,6 +809,35 @@ A description of the content each directory follows.
- **traces**: trace files for simulations. They contain accesses to memory
in certain known scenarios.
#### DRAMsys Diagrams
- **Payload Extension information**
GenerationExtension is added in TracePlayer and DramExtension is added in Arbiter.
DramExtension indicates the decoded address (channel, bank, colums, row) and the socket id (thread) of a payload. It is added in the Arbiter and is sent to the Controller.
![Payload Extension information](DRAMSys/docs/images/PayloadExtension.png)
- **Transaction object with Memory Manager**
The TracePlayer allocates the memory for the transaction object by calling allocatePayload method.
The acquire method is called before passing the transaction object in TracePlayer, Arbiter and Controller.
The release method is called after each component is done with the transaction object. After the final call of release method, the free method of the memory manager is called to free the transaction object.
![Payload Memory Manager](DRAMSys/docs/images/PayloadMemoryManager.png)
- **Architecture of the backend TLM model**
The below figure shows our custom TLM protocol between the Controller and the Dram. A new transaction enters the Controller with the BEGIN_REQ phase is stored in frontendPEQ. The callback function of the frontendPEQ is called and send the payload to the Scheduler.
The Scheduler checks the address of payload and the current state to determine proper command (Active, Precharge, Read or Write). Then the ControllerCore sends the payload with the corresponding phase (BEGIN_ACT, BEGIN_PRE, BEGIN_RD or BEGIN_WR) to the Dram by calling nb_transport_fw method.
The Dram receives the transaction then send back to the Controller by calling nb_transport_bw with appropriate END phase (END_ACT, END_PRE, END_RD or END_WR).
![Architecture backend TLM](DRAMSys/docs/images/TransactionPhase.png)
#### References
[1] TLM Modelling of 3D Stacked Wide I/O DRAM Subsystems, A Virtual Platform for Memory Controller Design Space Exploration