Implement b_transport and add tests for it

This commit is contained in:
2023-03-06 14:09:14 +01:00
parent 0268350a8e
commit ac9351c025
13 changed files with 544 additions and 8 deletions

1
.gitignore vendored
View File

@@ -26,3 +26,4 @@ DRAMSys/docs/doxygen
.vscode
cmake-build*
.idea
.cache

View File

@@ -413,6 +413,11 @@ tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &,
return TLM_ACCEPTED;
}
void Controller::b_transport(tlm_generic_payload &trans, sc_time &delay)
{
iSocket->b_transport(trans, delay);
}
unsigned int Controller::transport_dbg(tlm_generic_payload &trans)
{
return iSocket->transport_dbg(trans);

View File

@@ -61,6 +61,7 @@ protected:
sc_core::sc_time& delay) override;
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase,
sc_core::sc_time& delay) override;
void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) override;
unsigned int transport_dbg(tlm::tlm_generic_payload& trans) override;
virtual void sendToFrontend(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay);

View File

@@ -111,6 +111,7 @@ protected:
{
tSocket.register_nb_transport_fw(this, &ControllerIF::nb_transport_fw);
tSocket.register_transport_dbg(this, &ControllerIF::transport_dbg);
tSocket.register_b_transport(this, &ControllerIF::b_transport);
iSocket.register_nb_transport_bw(this, &ControllerIF::nb_transport_bw);
idleTimeCollector.start();
@@ -121,6 +122,7 @@ protected:
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase,
sc_core::sc_time& delay) = 0;
virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans) = 0;
virtual void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) = 0;
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase,
sc_core::sc_time& delay) = 0;

View File

@@ -59,6 +59,7 @@ Arbiter::Arbiter(const sc_module_name& name, const Configuration& config,
{
iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw);
tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw);
tSocket.register_b_transport(this, &Arbiter::b_transport);
tSocket.register_transport_dbg(this, &Arbiter::transport_dbg);
}
@@ -161,6 +162,14 @@ tlm_sync_enum Arbiter::nb_transport_bw(int, tlm_generic_payload& payload,
return TLM_ACCEPTED;
}
void Arbiter::b_transport(int, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
{
trans.set_address(trans.get_address() - addressOffset);
DecodedAddress decodedAddress = addressDecoder.decodeAddress(trans.get_address());
iSocket[static_cast<int>(decodedAddress.channel)]->b_transport(trans, delay);
}
unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload& trans)
{
trans.set_address(trans.get_address() - addressOffset);

View File

@@ -86,6 +86,7 @@ protected:
tlm::tlm_phase& phase, sc_core::sc_time& fwDelay);
tlm::tlm_sync_enum nb_transport_bw(int, tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase, sc_core::sc_time& bwDelay);
void b_transport(int, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload& trans);
const sc_core::sc_time tCK;

View File

@@ -35,6 +35,7 @@
* Peter Ehses
* Eder F. Zulian
* Felipe S. Prado
* Derek Christ
*/
#include "Dram.h"
@@ -62,6 +63,9 @@ using namespace tlm;
using namespace DRAMPower;
#endif
const sc_core::sc_time Dram::BLOCKING_READ_LATENCY = sc_core::sc_time(60, sc_core::SC_NS);
const sc_core::sc_time Dram::BLOCKING_WRITE_LATENCY = sc_core::sc_time(60, sc_core::SC_NS);
Dram::Dram(const sc_module_name& name, const Configuration& config)
: sc_module(name), memSpec(*config.memSpec), tSocket("socket"), storeMode(config.storeMode),
powerAnalysis(config.powerAnalysis), useMalloc(config.useMalloc)
@@ -88,6 +92,7 @@ Dram::Dram(const sc_module_name& name, const Configuration& config)
}
tSocket.register_nb_transport_fw(this, &Dram::nb_transport_fw);
tSocket.register_b_transport(this, &Dram::b_transport);
tSocket.register_transport_dbg(this, &Dram::transport_dbg);
}
@@ -163,17 +168,13 @@ unsigned int Dram::transport_dbg(tlm_generic_payload &trans)
else
{
tlm_command cmd = trans.get_command();
//uint64_t adr = trans.get_address(); // TODO: - offset;
unsigned char *ptr = trans.get_data_ptr();
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;
if (cmd == TLM_READ_COMMAND)
{
if (storeMode == Configuration::StoreMode::Store)
{ // Use Storage
{
unsigned char *phyAddr = memory + trans.get_address();
memcpy(ptr, phyAddr, trans.get_data_length());
}
@@ -186,7 +187,7 @@ unsigned int Dram::transport_dbg(tlm_generic_payload &trans)
else if (cmd == TLM_WRITE_COMMAND)
{
if (storeMode == Configuration::StoreMode::Store)
{ // Use Storage
{
unsigned char *phyAddr = memory + trans.get_address();
memcpy(phyAddr, ptr, trans.get_data_length());
}
@@ -200,3 +201,38 @@ unsigned int Dram::transport_dbg(tlm_generic_payload &trans)
}
return 0;
}
void Dram::b_transport(tlm_generic_payload &trans, sc_time &delay)
{
static bool printedWarning = false;
if (!printedWarning)
{
SC_REPORT_WARNING("DRAM", BLOCKING_WARNING.data());
printedWarning = true;
}
delay += trans.is_write() ? BLOCKING_WRITE_LATENCY : BLOCKING_READ_LATENCY;
if (storeMode == Configuration::StoreMode::Store)
{
tlm_command cmd = trans.get_command();
unsigned char *ptr = trans.get_data_ptr();
unsigned int len = trans.get_data_length();
if (cmd == TLM_READ_COMMAND)
{
unsigned char *phyAddr = memory + trans.get_address();
memcpy(ptr, phyAddr, trans.get_data_length());
}
else if (cmd == TLM_WRITE_COMMAND)
{
unsigned char *phyAddr = memory + trans.get_address();
memcpy(phyAddr, ptr, trans.get_data_length());
}
}
else if (storeMode != Configuration::StoreMode::NoStorage)
{
SC_REPORT_FATAL("DRAM", "Blocking transport not supported with error model yet.");
}
}

View File

@@ -35,6 +35,7 @@
* Peter Ehses
* Eder F. Zulian
* Felipe S. Prado
* Derek Christ
*/
#ifndef DRAM_H
@@ -70,10 +71,16 @@ protected:
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload,
tlm::tlm_phase& phase, sc_core::sc_time& delay);
virtual void b_transport(tlm::tlm_generic_payload& payload, sc_core::sc_time& delay);
virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
public:
static const sc_core::sc_time BLOCKING_READ_LATENCY;
static const sc_core::sc_time BLOCKING_WRITE_LATENCY;
static constexpr std::string_view BLOCKING_WARNING =
"Use the blocking mode of DRAMSys with caution! "
"The simulated timings do not reflect the real system!";
tlm_utils::simple_target_socket<Dram> tSocket;
virtual void reportPower();

View File

@@ -19,6 +19,8 @@ target_link_libraries(${PROJECT_NAME}
gtest_main
)
gtest_discover_tests(${PROJECT_NAME})
gtest_discover_tests(${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
build_source_group()

View File

@@ -0,0 +1,166 @@
/*
* Copyright (c) 2023, Technische Universität 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:
* Derek Christ
*/
#include <gtest/gtest.h>
#include <DRAMSys/simulation/DRAMSys.h>
#include <DRAMSys/simulation/dram/Dram.h>
class SystemCTest : public testing::Test
{
public:
~SystemCTest() override { sc_core::sc_get_curr_simcontext()->reset(); }
};
class BTransportNoStorage : public SystemCTest
{
protected:
BTransportNoStorage()
: no_storage_config(DRAMSys::Config::from_path("b_transport/configs/no_storage.json")),
dramSysNoStorage("NoStorageDRAMSys", no_storage_config)
{
}
DRAMSys::Config::Configuration no_storage_config;
DRAMSys::DRAMSys dramSysNoStorage;
};
class BTransportStorage : public SystemCTest
{
protected:
BTransportStorage()
: storage_config(DRAMSys::Config::from_path("b_transport/configs/storage.json")),
dramSysStorage("StorageDRAMSys", storage_config)
{
}
DRAMSys::Config::Configuration storage_config;
DRAMSys::DRAMSys dramSysStorage;
};
struct BlockingInitiator : sc_core::sc_module
{
tlm_utils::simple_initiator_socket<BlockingInitiator> iSocket;
static constexpr std::array<uint64_t, 8> TEST_DATA = {0xDEADBEEF};
SC_CTOR(BlockingInitiator)
{
SC_THREAD(readAccess);
SC_THREAD(writeAccess);
}
void readAccess()
{
tlm::tlm_generic_payload payload;
payload.set_command(tlm::TLM_READ_COMMAND);
sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
iSocket->b_transport(payload, delay);
EXPECT_EQ(delay, Dram::BLOCKING_READ_LATENCY);
}
void writeAccess()
{
std::array<uint64_t, 8> data{TEST_DATA};
tlm::tlm_generic_payload payload;
payload.set_command(tlm::TLM_WRITE_COMMAND);
payload.set_data_length(64);
payload.set_data_ptr(reinterpret_cast<unsigned char *>(&data));
sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
iSocket->b_transport(payload, delay);
EXPECT_EQ(delay, Dram::BLOCKING_WRITE_LATENCY);
}
};
TEST_F(BTransportNoStorage, RWDelay)
{
BlockingInitiator initiator("initiator");
initiator.iSocket.bind(dramSysNoStorage.tSocket);
sc_core::sc_start(sc_core::sc_time(1, sc_core::SC_US));
}
TEST_F(BTransportStorage, RWDelay)
{
BlockingInitiator initiator("initiator");
initiator.iSocket.bind(dramSysStorage.tSocket);
sc_core::sc_start(sc_core::sc_time(1, sc_core::SC_US));
}
TEST_F(BTransportStorage, DataWritten)
{
BlockingInitiator initiator("initiator");
initiator.iSocket.bind(dramSysStorage.tSocket);
sc_core::sc_start(sc_core::sc_time(1, sc_core::SC_US));
// Debug transaction to check if data really has been written
std::array<uint64_t, 8> data{};
tlm::tlm_generic_payload payload;
payload.set_command(tlm::TLM_READ_COMMAND);
payload.set_data_length(64);
payload.set_data_ptr(reinterpret_cast<unsigned char *>(&data));
initiator.iSocket->transport_dbg(payload);
EXPECT_EQ(data, BlockingInitiator::TEST_DATA);
}
TEST_F(BTransportNoStorage, Warning)
{
BlockingInitiator initiator("initiator");
initiator.iSocket.bind(dramSysNoStorage.tSocket);
// Redirect stdout to buffer
std::stringstream buffer;
std::streambuf *sbuf = std::cout.rdbuf();
std::cout.rdbuf(buffer.rdbuf());
sc_core::sc_start(sc_core::sc_time(1, sc_core::SC_US));
// Try to find the warning string
std::string output = buffer.str();
auto warning_pos = output.find(Dram::BLOCKING_WARNING);
// Warning should be printed once ...
EXPECT_NE(warning_pos, std::string::npos);
// ... but not twice
warning_pos = output.find(Dram::BLOCKING_WARNING, warning_pos + 1);
EXPECT_EQ(warning_pos, std::string::npos);
// Restore stdout
std::cout.rdbuf(sbuf);
}

View File

@@ -0,0 +1,153 @@
{
"simulation": {
"addressmapping": {
"CONGEN": {
"BANKGROUP_BIT": [
28,
29
],
"BANK_BIT": [
30,
31
],
"BYTE_BIT": [
0,
1,
2
],
"COLUMN_BIT": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12
],
"ROW_BIT": [
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27
]
}
},
"mcconfig": {
"Arbiter": "Simple",
"CmdMux": "Oldest",
"MaxActiveTransactions": 128,
"PagePolicy": "Open",
"PowerDownPolicy": "NoPowerDown",
"RefreshManagement": false,
"RefreshMaxPostponed": 0,
"RefreshMaxPulledin": 0,
"RefreshPolicy": "AllBank",
"RequestBufferSize": 8,
"RespQueue": "Fifo",
"Scheduler": "FrFcfs",
"SchedulerBuffer": "Bankwise"
},
"memspec": {
"memarchitecturespec": {
"burstLength": 8,
"dataRate": 2,
"nbrOfBankGroups": 4,
"nbrOfBanks": 16,
"nbrOfChannels": 1,
"nbrOfColumns": 1024,
"nbrOfDevices": 8,
"nbrOfRanks": 1,
"nbrOfRows": 32768,
"width": 8
},
"memoryId": "MICRON_4Gb_DDR4-1866_8bit_A",
"memoryType": "DDR4",
"mempowerspec": {
"idd0": 56.25,
"idd02": 4.05,
"idd2n": 33.75,
"idd2p0": 17.0,
"idd2p1": 17.0,
"idd3n": 39.5,
"idd3p0": 22.5,
"idd3p1": 22.5,
"idd4r": 157.5,
"idd4w": 135.0,
"idd5": 118.0,
"idd6": 20.25,
"idd62": 2.6,
"vdd": 1.2,
"vdd2": 2.5
},
"memtimingspec": {
"ACTPDEN": 1,
"AL": 0,
"CCD_L": 5,
"CCD_S": 4,
"CKE": 6,
"CKESR": 7,
"CL": 13,
"DQSCK": 2,
"FAW": 22,
"PRPDEN": 1,
"RAS": 32,
"RC": 45,
"RCD": 13,
"REFI": 7280,
"REFM": 1,
"REFPDEN": 1,
"RFC": 243,
"RFC2": 150,
"RFC4": 103,
"RL": 13,
"RP": 13,
"RPRE": 1,
"RRD_L": 5,
"RRD_S": 4,
"RTP": 8,
"RTRS": 1,
"WL": 12,
"WPRE": 1,
"WR": 14,
"WTR_L": 7,
"WTR_S": 3,
"XP": 8,
"XPDLL": 255,
"XS": 252,
"XSDLL": 512,
"clkMhz": 933
}
},
"simconfig": {
"AddressOffset": 0,
"CheckTLM2Protocol": false,
"DatabaseRecording": true,
"Debug": false,
"EnableWindowing": false,
"ErrorCSVFile": "",
"ErrorChipSeed": 42,
"PowerAnalysis": false,
"SimulationName": "example",
"SimulationProgressBar": true,
"StoreMode": "NoStorage",
"ThermalSimulation": false,
"UseMalloc": false,
"WindowSize": 1000
},
"simulationid": "ddr4-example"
}
}

View File

@@ -0,0 +1,153 @@
{
"simulation": {
"addressmapping": {
"CONGEN": {
"BANKGROUP_BIT": [
28,
29
],
"BANK_BIT": [
30,
31
],
"BYTE_BIT": [
0,
1,
2
],
"COLUMN_BIT": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12
],
"ROW_BIT": [
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27
]
}
},
"mcconfig": {
"Arbiter": "Simple",
"CmdMux": "Oldest",
"MaxActiveTransactions": 128,
"PagePolicy": "Open",
"PowerDownPolicy": "NoPowerDown",
"RefreshManagement": false,
"RefreshMaxPostponed": 0,
"RefreshMaxPulledin": 0,
"RefreshPolicy": "AllBank",
"RequestBufferSize": 8,
"RespQueue": "Fifo",
"Scheduler": "FrFcfs",
"SchedulerBuffer": "Bankwise"
},
"memspec": {
"memarchitecturespec": {
"burstLength": 8,
"dataRate": 2,
"nbrOfBankGroups": 4,
"nbrOfBanks": 16,
"nbrOfChannels": 1,
"nbrOfColumns": 1024,
"nbrOfDevices": 8,
"nbrOfRanks": 1,
"nbrOfRows": 32768,
"width": 8
},
"memoryId": "MICRON_4Gb_DDR4-1866_8bit_A",
"memoryType": "DDR4",
"mempowerspec": {
"idd0": 56.25,
"idd02": 4.05,
"idd2n": 33.75,
"idd2p0": 17.0,
"idd2p1": 17.0,
"idd3n": 39.5,
"idd3p0": 22.5,
"idd3p1": 22.5,
"idd4r": 157.5,
"idd4w": 135.0,
"idd5": 118.0,
"idd6": 20.25,
"idd62": 2.6,
"vdd": 1.2,
"vdd2": 2.5
},
"memtimingspec": {
"ACTPDEN": 1,
"AL": 0,
"CCD_L": 5,
"CCD_S": 4,
"CKE": 6,
"CKESR": 7,
"CL": 13,
"DQSCK": 2,
"FAW": 22,
"PRPDEN": 1,
"RAS": 32,
"RC": 45,
"RCD": 13,
"REFI": 7280,
"REFM": 1,
"REFPDEN": 1,
"RFC": 243,
"RFC2": 150,
"RFC4": 103,
"RL": 13,
"RP": 13,
"RPRE": 1,
"RRD_L": 5,
"RRD_S": 4,
"RTP": 8,
"RTRS": 1,
"WL": 12,
"WPRE": 1,
"WR": 14,
"WTR_L": 7,
"WTR_S": 3,
"XP": 8,
"XPDLL": 255,
"XS": 252,
"XSDLL": 512,
"clkMhz": 933
}
},
"simconfig": {
"AddressOffset": 0,
"CheckTLM2Protocol": false,
"DatabaseRecording": true,
"Debug": false,
"EnableWindowing": false,
"ErrorCSVFile": "",
"ErrorChipSeed": 42,
"PowerAnalysis": false,
"SimulationName": "example",
"SimulationProgressBar": true,
"StoreMode": "Store",
"ThermalSimulation": false,
"UseMalloc": false,
"WindowSize": 1000
},
"simulationid": "ddr4-example"
}
}

View File