From 4dfe12089e5cf2948f4a9bffdbf087e53e74f284 Mon Sep 17 00:00:00 2001 From: "Felipe S. Prado" Date: Thu, 1 Sep 2016 14:49:06 +0200 Subject: [PATCH 1/8] evaluation test --- DRAMSys/tests/evaluation/fifoStrict.xml | 15 ++++ DRAMSys/tests/evaluation/sim-batch.xml | 52 ++++++++++++++ DRAMSys/tests/evaluation/test.pl | 95 +++++++++++++++++++++++++ DRAMSys/tests/tests.pri | 5 ++ 4 files changed, 167 insertions(+) create mode 100644 DRAMSys/tests/evaluation/fifoStrict.xml create mode 100644 DRAMSys/tests/evaluation/sim-batch.xml create mode 100644 DRAMSys/tests/evaluation/test.pl diff --git a/DRAMSys/tests/evaluation/fifoStrict.xml b/DRAMSys/tests/evaluation/fifoStrict.xml new file mode 100644 index 00000000..270d9037 --- /dev/null +++ b/DRAMSys/tests/evaluation/fifoStrict.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/DRAMSys/tests/evaluation/sim-batch.xml b/DRAMSys/tests/evaluation/sim-batch.xml new file mode 100644 index 00000000..b68f43b1 --- /dev/null +++ b/DRAMSys/tests/evaluation/sim-batch.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mediabench-c-ray-1.1_32.stl + + + + + diff --git a/DRAMSys/tests/evaluation/test.pl b/DRAMSys/tests/evaluation/test.pl new file mode 100644 index 00000000..fc64caa6 --- /dev/null +++ b/DRAMSys/tests/evaluation/test.pl @@ -0,0 +1,95 @@ +#!/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 '^' ../../DRAMSys/tests/evaluation/sim-batch.xml"); + system("sed -i '" . $bankwiseLogicLine . "s^.*^ ^' ../../DRAMSys/tests/evaluation/fifoStrict.xml"); + system("sed -i '" . $powerDownModeLine . "s^.*^ ^' ../../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^.*^ ^' ../../DRAMSys/tests/evaluation/sim-batch.xml"); + system("sed -i '" . $bankwiseLogicLine . "s^.*^ ^' ../../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; + } + } + +} +print("OK"); + +exit 0; + + diff --git a/DRAMSys/tests/tests.pri b/DRAMSys/tests/tests.pri index 12b30fbe..c5ceed89 100644 --- a/DRAMSys/tests/tests.pri +++ b/DRAMSys/tests/tests.pri @@ -17,3 +17,8 @@ OTHER_FILES += tests/error/fr_fcfs.xml OTHER_FILES += tests/error/generateErrorTest.pl OTHER_FILES += tests/error/WideIO.xml +# evaluation test +OTHER_FILES += tests/evaluation/sim-batch.xml +OTHER_FILES += tests/evaluation/fifoStrict.xml +OTHER_FILES += tests/evaluation/test.pl + From c2c28dd36565907cde7ed28c5c5b64a770d40c43 Mon Sep 17 00:00:00 2001 From: "Felipe S. Prado" Date: Thu, 1 Sep 2016 14:55:29 +0200 Subject: [PATCH 2/8] Small fix --- DRAMSys/tests/evaluation/test.pl | 2 -- 1 file changed, 2 deletions(-) diff --git a/DRAMSys/tests/evaluation/test.pl b/DRAMSys/tests/evaluation/test.pl index fc64caa6..10968545 100644 --- a/DRAMSys/tests/evaluation/test.pl +++ b/DRAMSys/tests/evaluation/test.pl @@ -88,8 +88,6 @@ foreach (@powerDownModes) } } -print("OK"); - exit 0; From aa044160335334fc6d799e7c07af7f5cef0e641d Mon Sep 17 00:00:00 2001 From: Tran Anh Quoc Date: Thu, 15 Sep 2016 15:29:50 +0200 Subject: [PATCH 3/8] Add Payload Extension diagram, Transaction object with Memory Manager diagram and Architecture of ackend TLM diagram to README file --- DRAMSys/docs/images/PayloadExtension.svg | 2449 ++++++++++++++++++ DRAMSys/docs/images/PayloadMemoryManager.svg | 988 +++++++ DRAMSys/docs/images/TransactionPhase.svg | 2026 +++++++++++++++ README.md | 18 + 4 files changed, 5481 insertions(+) create mode 100644 DRAMSys/docs/images/PayloadExtension.svg create mode 100644 DRAMSys/docs/images/PayloadMemoryManager.svg create mode 100644 DRAMSys/docs/images/TransactionPhase.svg diff --git a/DRAMSys/docs/images/PayloadExtension.svg b/DRAMSys/docs/images/PayloadExtension.svg new file mode 100644 index 00000000..fd0cb966 --- /dev/null +++ b/DRAMSys/docs/images/PayloadExtension.svg @@ -0,0 +1,2449 @@ + + + +Trace +file n +Trace +file +1 +Trace Player +1 +Trace Player n +Arbiter +Controller +Scheduler +ControllerCore +Controller +Scheduler +ControllerCore +DRAM +DRAM +GenerationExtension +sc +_ +time +( +timeOfGeneration +) +Generic Payload +Command +Address +Data pointer +Data length +Byte enable pointer +Byte enable length +Streaming width +DMI hint +Response status +Generic Payload +Command +Address +Data pointer +Data length +Byte enable pointer +Byte enable length +Streaming width +DMI hint +Response status +GenerationExtension +sc +_ +time +( +timeOfGeneration +) +DramExtension +Thread +Chanel +Bank +BankGroup +Row +Column +Burstlength +Generic Payload +Command +Address +Data pointer +Data length +Byte enable pointer +Byte enable length +Streaming width +DMI hint +Response status +GenerationExtension +sc +_ +time +( +timeOfGeneration +) +DramExtension +Thread +Chanel +Bank +BankGroup +Row +Column +Burstlength +Generic Payload +Command +Address +Data pointer +Data length +Byte enable pointer +Byte enable length +Streaming width +DMI hint +Response status +GenerationExtension +sc +_ +time +( +timeOfGeneration +) +DramExtension +Thread +Chanel +Bank +BankGroup +Row +Column +Burstlength + \ No newline at end of file diff --git a/DRAMSys/docs/images/PayloadMemoryManager.svg b/DRAMSys/docs/images/PayloadMemoryManager.svg new file mode 100644 index 00000000..3cf9fd46 --- /dev/null +++ b/DRAMSys/docs/images/PayloadMemoryManager.svg @@ -0,0 +1,988 @@ + + + +TracePlayer +BEGIN +_ +REQ +BEGIN +_ +REQ +END +_ +REQ +END +_ +REQ +BEGIN +_ +PRE +END +_ +PRE +BEGIN +_ +ACT +END +_ +ACT +BEGIN +_ +RD or BEGIN +_ +WR +END +_ +RD or END +_ +WR +BEGIN +_ +RESP +BEGIN +_ +RESP +END +_ +RESP +END +_ +RESP +Arbiter +Controller +DRAM +Allocate Payload +acquire +() +Set auto extension +( +GenerationExtension +) +acquire +() +Set auto extension +( +DramExtension +) +Get extension DramExtension +: +getBank +, +getRow +Get extension +DramExtension +: +getThread +Get extension +DramExtension +: +getBank +acquire +() +Get extension +DramExtension +: +getRow +release +() +release +() +release +() + \ No newline at end of file diff --git a/DRAMSys/docs/images/TransactionPhase.svg b/DRAMSys/docs/images/TransactionPhase.svg new file mode 100644 index 00000000..4a2973f4 --- /dev/null +++ b/DRAMSys/docs/images/TransactionPhase.svg @@ -0,0 +1,2026 @@ + + + +PEQFrontEnd +Scheduler +rowBufferIsOpen +( +Bank +) +Command +:: +Activate +FALSE +RowInRowBuffer += +getRow +( +Payload +) +TRUE +Command +:: +Precharge +FALSE +Command +:: +READ +Command +:: +WRITE +TRUE +& +READ +_ +COMMAND +TRUE +& +WRITE +_ +COMMAND +BEGIN +_ +ACT +BEGIN +_ +PRE +BEGIN +_ +RD +BEGIN +_ +WR +ControllerCore +( +PowerDownManager +, +RefreshManager +) +ControllerCorePEQ +Initiator Socket +Target Socket +Receive +nb +_ +transport +_ +fw +END +_ +ACT +END +_ +PRE +END +_ +RD +END +_ +WR +BEGIN +_ +ACT +BEGIN +_ +PRE +BEGIN +_ +RD +BEGIN +_ +WR +DramPEQ +nb +_ +transport +_ +bw +Controller +DRAM +Target Socket +nb +_ +transport +_ +fw +nb +_ +transport +_ +bw +From +/ +to Arbiter +END +_ +RD or END +_ +WR +END +_ +ACT or END +_ +PRE + \ No newline at end of file diff --git a/README.md b/README.md index d2330084..c2949924 100644 --- a/README.md +++ b/README.md @@ -804,6 +804,24 @@ 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. + + ![Payload Extension information](DRAMSys/docs/images/PayloadExtension.png) + +- **Transaction object with Memory Manager** + + The acquire method is called before passing the transaction object and the release method is called after the component is done with the transaction object. + + ![Payload Memory Manager](DRAMSys/docs/images/PayloadMemoryManager.png) + +- **Architecture of the backend TLM model** + + ![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 From 36312974d9bfb840eeafa58fb890de9d244bf582 Mon Sep 17 00:00:00 2001 From: Tran Anh Quoc Date: Thu, 15 Sep 2016 23:13:11 +0200 Subject: [PATCH 4/8] Implement coherence check for all payload extensions --- DRAMSys/simulator/src/simulation/Arbiter.h | 56 ++++++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/DRAMSys/simulator/src/simulation/Arbiter.h b/DRAMSys/simulator/src/simulation/Arbiter.h index d41273cd..6ddd56f1 100644 --- a/DRAMSys/simulator/src/simulation/Arbiter.h +++ b/DRAMSys/simulator/src/simulation/Arbiter.h @@ -101,10 +101,18 @@ private: std::vector tlmRecorders; + //used to map the transaction from devices to the arbiter's target socket ID. + std::map 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; @@ -122,12 +130,17 @@ private: // 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 +160,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 +192,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 +209,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 +239,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) From 3f241b21010f41a970d41f30b290e65143a9ce24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Sun, 18 Sep 2016 01:41:45 +0200 Subject: [PATCH 5/8] Add DRAMSys' first python unit test. --- DRAMSys/tests/unit_test.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 DRAMSys/tests/unit_test.py diff --git a/DRAMSys/tests/unit_test.py b/DRAMSys/tests/unit_test.py new file mode 100644 index 00000000..9d2a6c3c --- /dev/null +++ b/DRAMSys/tests/unit_test.py @@ -0,0 +1,28 @@ +import unittest +import subprocess +import os +import shutil +import multiprocessing + +devnull = None + + +class TestBuild(unittest.TestCase): + def test_build_project(self): + """ The project's build process should succeed """ + builddir = "../../build" + if os.path.exists(builddir): + shutil.rmtree(builddir) + os.makedirs(builddir) + os.chdir(builddir) + self.assertEqual(subprocess.call(['qmake', + '../DRAMSys/dram.vp.system.pro'], stdout=devnull, + stderr=devnull), 0) + makejobs = "-j" + str(multiprocessing.cpu_count()) + self.assertEqual(subprocess.call(['make', makejobs], stdout=devnull, + stderr=devnull), 0) + + +if __name__ == '__main__': + with open(os.devnull, 'wb') as devnull: + unittest.main() From 633d3b886ed5546290ccbfb85d254b88e0f5cadd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Mon, 19 Sep 2016 00:06:55 +0200 Subject: [PATCH 6/8] DRAMSys unit tests. - Build test improved to used a temp dir which is removed after the test. - New test: Run dramSys without arguments. - Tests are totally independent. - New utility functions to get data from config/specs XML files. - Unit test files will now appear in qtcreator. - Info header added to the files. --- .gitignore | 1 + DRAMSys/tests/tests.pri | 3 + DRAMSys/tests/unit/mem_util.py | 70 ++++++++++++++++++++++ DRAMSys/tests/unit/unit_test.py | 103 ++++++++++++++++++++++++++++++++ DRAMSys/tests/unit_test.py | 28 --------- 5 files changed, 177 insertions(+), 28 deletions(-) create mode 100644 DRAMSys/tests/unit/mem_util.py create mode 100644 DRAMSys/tests/unit/unit_test.py delete mode 100644 DRAMSys/tests/unit_test.py diff --git a/.gitignore b/.gitignore index f1ef5004..b0259661 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ build*/ *.swo cscope* DRAMSys/analyzer/scripts/__pycache__/ +*.pyc diff --git a/DRAMSys/tests/tests.pri b/DRAMSys/tests/tests.pri index c5ceed89..b264d78f 100644 --- a/DRAMSys/tests/tests.pri +++ b/DRAMSys/tests/tests.pri @@ -22,3 +22,6 @@ 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 diff --git a/DRAMSys/tests/unit/mem_util.py b/DRAMSys/tests/unit/mem_util.py new file mode 100644 index 00000000..cb487a37 --- /dev/null +++ b/DRAMSys/tests/unit/mem_util.py @@ -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) diff --git a/DRAMSys/tests/unit/unit_test.py b/DRAMSys/tests/unit/unit_test.py new file mode 100644 index 00000000..aacc500b --- /dev/null +++ b/DRAMSys/tests/unit/unit_test.py @@ -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() diff --git a/DRAMSys/tests/unit_test.py b/DRAMSys/tests/unit_test.py deleted file mode 100644 index 9d2a6c3c..00000000 --- a/DRAMSys/tests/unit_test.py +++ /dev/null @@ -1,28 +0,0 @@ -import unittest -import subprocess -import os -import shutil -import multiprocessing - -devnull = None - - -class TestBuild(unittest.TestCase): - def test_build_project(self): - """ The project's build process should succeed """ - builddir = "../../build" - if os.path.exists(builddir): - shutil.rmtree(builddir) - os.makedirs(builddir) - os.chdir(builddir) - self.assertEqual(subprocess.call(['qmake', - '../DRAMSys/dram.vp.system.pro'], stdout=devnull, - stderr=devnull), 0) - makejobs = "-j" + str(multiprocessing.cpu_count()) - self.assertEqual(subprocess.call(['make', makejobs], stdout=devnull, - stderr=devnull), 0) - - -if __name__ == '__main__': - with open(os.devnull, 'wb') as devnull: - unittest.main() From ab990643e24ddf931df1922a7e7901648c777a12 Mon Sep 17 00:00:00 2001 From: Tran Anh Quoc Date: Mon, 19 Sep 2016 00:31:32 +0200 Subject: [PATCH 7/8] Improve README.md file and remove TODOs in Arbiter.h --- DRAMSys/docs/images/PayloadMemoryManager.svg | 20 + DRAMSys/docs/images/TransactionPhase.svg | 2548 +++++++++--------- DRAMSys/simulator/src/simulation/Arbiter.h | 3 - README.md | 14 +- 4 files changed, 1310 insertions(+), 1275 deletions(-) diff --git a/DRAMSys/docs/images/PayloadMemoryManager.svg b/DRAMSys/docs/images/PayloadMemoryManager.svg index 3cf9fd46..56a0547f 100644 --- a/DRAMSys/docs/images/PayloadMemoryManager.svg +++ b/DRAMSys/docs/images/PayloadMemoryManager.svg @@ -985,4 +985,24 @@ y="0" id="tspan640" style="font-size:13.99967957px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">() +free +() \ No newline at end of file diff --git a/DRAMSys/docs/images/TransactionPhase.svg b/DRAMSys/docs/images/TransactionPhase.svg index 4a2973f4..06e2d73b 100644 --- a/DRAMSys/docs/images/TransactionPhase.svg +++ b/DRAMSys/docs/images/TransactionPhase.svg @@ -6,23 +6,23 @@ xmlns="http://www.w3.org/2000/svg" version="1.1" width="765.9375" - height="1935.9375" + height="990.9375" id="svg2" xml:space="preserve">PEQFrontEnd Scheduler rowBufferIsOpen ( Bank ) Command + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">Command :: + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">:: Activate + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">Activate FALSE + style="font-size:7.99992132px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">FALSE RowInRowBuffer = getRow ( Payload ) TRUE + style="font-size:7.99989271px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">TRUE Command + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">Command :: + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">:: Precharge + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">Precharge FALSE -Command + id="tspan346" + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">Command :: + id="tspan350" + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">:: READ + id="tspan354" + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">READ Command + id="tspan388" + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">Command :: + id="tspan392" + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">:: WRITE +WRITE -TRUE + style="font-size:6.99995613px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">TRUE & + id="tspan410" + style="font-size:6.99995613px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">& READ + id="tspan414" + style="font-size:6.99995613px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">READ _ + id="tspan418" + style="font-size:6.99995613px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">_ COMMAND +COMMAND -TRUE + style="font-size:7.99992132px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">TRUE & + id="tspan436" + style="font-size:7.99992132px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">& WRITE + id="tspan440" + style="font-size:7.99992132px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">WRITE _ + id="tspan444" + style="font-size:7.99992132px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">_ COMMAND + id="tspan448" + style="font-size:7.99992132px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">COMMAND BEGIN _ ACT BEGIN _ PRE BEGIN _ RD BEGIN _ WR ControllerCore ( PowerDownManager , RefreshManager ) ControllerCorePEQ +ControllerCorePEQ -Initiator Socket + id="tspan766" + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">Initiator Socket Target Socket + id="tspan770" + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">Target Socket Receive nb + id="tspan884" + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">nb _ + id="tspan888" + style="font-size:11.00016022px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">_ transport +_ +fw +transport + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">END _ + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">_ fw + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">ACT END + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">END _ + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">_ ACT + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">PRE END + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">END _ + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">_ PRE + style="font-size:12.00024033px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">RD END _ RD -END -_ -WR BEGIN + id="tspan1078" + style="font-size:10.00013447px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">BEGIN _ + id="tspan1082" + style="font-size:10.00013447px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">_ ACT + id="tspan1086" + style="font-size:10.00013447px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">ACT BEGIN + id="tspan1096" + style="font-size:10.00003147px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">BEGIN _ + id="tspan1100" + style="font-size:10.00003147px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">_ PRE + id="tspan1104" + style="font-size:10.00003147px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:CALIBRI;-inkscape-font-specification:CALIBRI">PRE BEGIN +_ +RD +BEGIN +_ +WR +BEGIN -_ -RD -BEGIN -_ -WR -DramPEQ nb -_ -transport -_ -bw -Controller -DRAM -Target Socket -nb -_ -transport -_ -fw -nb _ transport _ bw Controller +DRAM +Target Socket +nb +_ +transport +_ +fw +nb +_ +transport +_ +bw +From / to Arbiter END +_ +RD or END +_ +WR +END +_ +ACT or END +_ +PRE +FALSE +END -_ -RD or END -_ -WR -END -_ -ACT or END -_ -PRE - \ No newline at end of file + style="fill:none;stroke:#404040;stroke-width:0.25;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> \ No newline at end of file diff --git a/DRAMSys/simulator/src/simulation/Arbiter.h b/DRAMSys/simulator/src/simulation/Arbiter.h index 6ddd56f1..79e6aa97 100644 --- a/DRAMSys/simulator/src/simulation/Arbiter.h +++ b/DRAMSys/simulator/src/simulation/Arbiter.h @@ -123,9 +123,6 @@ 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) diff --git a/README.md b/README.md index 88aa6cd6..70149a5f 100644 --- a/README.md +++ b/README.md @@ -814,17 +814,23 @@ A description of the content each directory follows. - **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 acquire method is called before passing the transaction object and the release method is called after the component is done with the transaction object. - + 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 From 165347c8f1237a06d73130b73b5da424b6eea089 Mon Sep 17 00:00:00 2001 From: Tran Anh Quoc Date: Mon, 19 Sep 2016 00:35:23 +0200 Subject: [PATCH 8/8] Improve README.md file --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 70149a5f..539b4e51 100644 --- a/README.md +++ b/README.md @@ -814,21 +814,26 @@ A description of the content each directory follows. - **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 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 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)