From a4fe32703cf2b7f659d7b5f5a78d8c70e270a4ac Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 27 Jan 2023 12:08:51 +0100 Subject: [PATCH] Set up testing infrastructure for Cache --- src/simulator/CMakeLists.txt | 21 +- src/simulator/{simulator => }/main.cpp | 14 +- src/simulator/simulator/Cache.cpp | 7 +- src/simulator/simulator/Cache.h | 5 +- src/simulator/simulator/EccModule.cpp | 313 ++++++++++++++++++ src/simulator/simulator/EccModule.h | 107 ++++++ tests/CMakeLists.txt | 1 + tests/tests_simulator/CMakeLists.txt | 27 ++ tests/tests_simulator/cache/ListInitiator.cpp | 189 +++++++++++ tests/tests_simulator/cache/ListInitiator.h | 104 ++++++ tests/tests_simulator/cache/TargetMemory.cpp | 231 +++++++++++++ tests/tests_simulator/cache/TargetMemory.h | 83 +++++ tests/tests_simulator/cache/tests_cache.cpp | 93 ++++++ tests/tests_simulator/main.cpp | 43 +++ 14 files changed, 1221 insertions(+), 17 deletions(-) rename src/simulator/{simulator => }/main.cpp (96%) create mode 100644 src/simulator/simulator/EccModule.cpp create mode 100644 src/simulator/simulator/EccModule.h create mode 100644 tests/tests_simulator/CMakeLists.txt create mode 100644 tests/tests_simulator/cache/ListInitiator.cpp create mode 100644 tests/tests_simulator/cache/ListInitiator.h create mode 100644 tests/tests_simulator/cache/TargetMemory.cpp create mode 100644 tests/tests_simulator/cache/TargetMemory.h create mode 100644 tests/tests_simulator/cache/tests_cache.cpp create mode 100644 tests/tests_simulator/main.cpp diff --git a/src/simulator/CMakeLists.txt b/src/simulator/CMakeLists.txt index bae5c739..2db1df94 100644 --- a/src/simulator/CMakeLists.txt +++ b/src/simulator/CMakeLists.txt @@ -43,14 +43,25 @@ project(DRAMSys_Simulator) file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp) file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp) -add_executable(DRAMSys ${SOURCE_FILES} ${HEADER_FILES}) -target_include_directories(DRAMSys PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +list(FILTER SOURCE_FILES EXCLUDE REGEX "main.cpp") + +add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES}) + +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(${PROJECT_NAME} + PUBLIC + Threads::Threads + DRAMSys::libdramsys +) + +add_executable(DRAMSys + main.cpp +) target_link_libraries(DRAMSys PRIVATE - Threads::Threads - SystemC::systemc - DRAMSys::libdramsys + DRAMSys_Simulator ) build_source_group() diff --git a/src/simulator/simulator/main.cpp b/src/simulator/main.cpp similarity index 96% rename from src/simulator/simulator/main.cpp rename to src/simulator/main.cpp index 4c986102..06c26503 100644 --- a/src/simulator/simulator/main.cpp +++ b/src/simulator/main.cpp @@ -33,13 +33,13 @@ * Derek Christ */ -#include "Initiator.h" -#include "MemoryManager.h" -#include "SimpleInitiator.h" -#include "generator/TrafficGenerator.h" -#include "hammer/RowHammer.h" -#include "player/StlPlayer.h" -#include "util.h" +#include "simulator/Initiator.h" +#include "simulator/MemoryManager.h" +#include "simulator/SimpleInitiator.h" +#include "simulator/generator/TrafficGenerator.h" +#include "simulator/hammer/RowHammer.h" +#include "simulator/player/StlPlayer.h" +#include "simulator/util.h" #include diff --git a/src/simulator/simulator/Cache.cpp b/src/simulator/simulator/Cache.cpp index 96ff8868..06739cfe 100644 --- a/src/simulator/simulator/Cache.cpp +++ b/src/simulator/simulator/Cache.cpp @@ -23,7 +23,8 @@ Cache::Cache(const sc_module_name &name, std::size_t maxTargetListSize, bool storageEnabled, sc_core::sc_time cycleTime, - std::size_t hitCycles) : + std::size_t hitCycles, + MemoryManager &memoryManager) : sc_module(name), payloadEventQueue(this, &Cache::peqCallback), storageEnabled(storageEnabled), @@ -39,7 +40,7 @@ Cache::Cache(const sc_module_name &name, mshrDepth(mshrDepth), writeBufferDepth(writeBufferDepth), maxTargetListSize(maxTargetListSize), - memoryManager(storageEnabled) + memoryManager(memoryManager) { iSocket.register_nb_transport_bw(this, &Cache::nb_transport_bw); tSocket.register_nb_transport_fw(this, &Cache::nb_transport_fw); @@ -601,7 +602,7 @@ void Cache::processMshrResponse() else { hitIt->hitDelayStarted = true; - payloadEventQueue.notify(returnTrans, MISS_HANDLING, hitLatency + sc_time(1, SC_NS)); + payloadEventQueue.notify(returnTrans, MISS_HANDLING, hitLatency); return; } diff --git a/src/simulator/simulator/Cache.h b/src/simulator/simulator/Cache.h index 7dd9ff5b..0e64bf67 100644 --- a/src/simulator/simulator/Cache.h +++ b/src/simulator/simulator/Cache.h @@ -61,7 +61,8 @@ public: std::size_t maxTargetListSize, bool storageEnabled, sc_core::sc_time cycleTime, - std::size_t hitCycles); + std::size_t hitCycles, + MemoryManager &memoryManager); SC_HAS_PROCESS(Cache); private: @@ -196,5 +197,5 @@ private: sc_core::sc_time ceilTime(const sc_core::sc_time &inTime) const; sc_core::sc_time ceilDelay(const sc_core::sc_time &inDelay) const; - MemoryManager memoryManager; + MemoryManager &memoryManager; }; diff --git a/src/simulator/simulator/EccModule.cpp b/src/simulator/simulator/EccModule.cpp new file mode 100644 index 00000000..6b3caa4f --- /dev/null +++ b/src/simulator/simulator/EccModule.cpp @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2022, 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: + * Christian Malek + * Derek Christ + */ + +#include "EccModule.h" + +#include "DRAMSys/common/dramExtensions.h" + +#include + +using namespace sc_core; +using namespace tlm; + +EccModule::EccModule(sc_module_name name, AddressDecoder const &addressDecoder) : + sc_core::sc_module(name), + payloadEventQueue(this, &EccModule::peqCallback), + addressDecoder(addressDecoder), + memoryManager(false) +{ + iSocket.register_nb_transport_bw(this, &EccModule::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &EccModule::nb_transport_fw); +} + +tlm::tlm_sync_enum EccModule::nb_transport_fw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &fwDelay) +{ + if (phase == BEGIN_REQ) + { + payload.acquire(); + } + + payloadEventQueue.notify(payload, phase, fwDelay); + return TLM_ACCEPTED; +} + +tlm::tlm_sync_enum EccModule::nb_transport_bw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &bwDelay) +{ + payloadEventQueue.notify(payload, phase, bwDelay); + return TLM_ACCEPTED; +} + +void EccModule::peqCallback(tlm::tlm_generic_payload &cbPayload, const tlm::tlm_phase &cbPhase) +{ + if (cbPhase == BEGIN_REQ) // from initiator + { + // Put transaction into latency map + payloadMap.emplace(&cbPayload, sc_time_stamp()); + + if (!targetBusy) + { + targetBusy = true; + + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = SC_ZERO_TIME; + + DecodedAddress decodedAddress = addressDecoder.decodeAddress(cbPayload.get_address()); + decodedAddress = calculateOffsetAddress(decodedAddress); + + // Update the original address to account for the offsets + cbPayload.set_address(addressDecoder.encodeAddress(decodedAddress)); + + auto currentBlock = alignToBlock(decodedAddress.column); + + // In case there is no entry yet. + activeEccBlocks.try_emplace(decodedAddress.bank); + +#ifdef ECC_ENABLE + if (!activeEccBlock(decodedAddress.bank, decodedAddress.row, currentBlock)) + { + blockedRequest = &cbPayload; + + auto &eccFifo = activeEccBlocks[decodedAddress.bank]; + eccFifo.push_back({currentBlock, decodedAddress.row}); + + // Only hold 4 elements at max. + if (eccFifo.size() >= 4) + eccFifo.pop_front(); + + tlm::tlm_generic_payload *eccPayload = generateEccPayload(decodedAddress); + + iSocket->nb_transport_fw(*eccPayload, tPhase, tDelay); + } + else +#endif + { + iSocket->nb_transport_fw(cbPayload, tPhase, tDelay); + } + } + else + { + pendingRequest = &cbPayload; + } + } + else if (cbPhase == END_REQ) // from target + { + // Send payload to inititator in case it is not an ECC transaction + if (cbPayload.get_extension() == nullptr) + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + + tSocket->nb_transport_bw(cbPayload, tPhase, tDelay); + } + + if (blockedRequest != nullptr) + { + tlm_generic_payload &tPayload = *blockedRequest; + blockedRequest = nullptr; + + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = SC_ZERO_TIME; + + iSocket->nb_transport_fw(tPayload, tPhase, tDelay); + + // Do not attempt to send another pending request and hold targetBusy high + return; + } + + if (pendingRequest != nullptr) + { + tlm_generic_payload &tPayload = *pendingRequest; + + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = SC_ZERO_TIME; + + DecodedAddress decodedAddress = addressDecoder.decodeAddress(tPayload.get_address()); + decodedAddress = calculateOffsetAddress(decodedAddress); + auto currentBlock = alignToBlock(decodedAddress.column); +#ifdef ECC_ENABLE + if (!activeEccBlock(decodedAddress.bank, decodedAddress.row, currentBlock)) + { + blockedRequest = pendingRequest; + pendingRequest = nullptr; + + auto &eccFifo = activeEccBlocks[decodedAddress.bank]; + eccFifo.push_back({currentBlock, decodedAddress.row}); + + // Only hold 4 elements at max. + if (eccFifo.size() >= 4) + eccFifo.pop_front(); + + tlm::tlm_generic_payload *eccPayload = generateEccPayload(decodedAddress); + + iSocket->nb_transport_fw(*eccPayload, tPhase, tDelay); + } + else +#endif + { + iSocket->nb_transport_fw(tPayload, tPhase, tDelay); + pendingRequest = nullptr; + } + } + else + { + assert(!pendingRequest); + assert(!blockedRequest); + targetBusy = false; + } + } + else if (cbPhase == BEGIN_RESP) // from memory controller + { + // Send payload to inititator in case it is not an ECC transaction + if (cbPayload.get_extension() == nullptr) + { + tlm_phase tPhase = BEGIN_RESP; + sc_time tDelay = SC_ZERO_TIME; + + tlm_sync_enum returnValue = tSocket->nb_transport_bw(cbPayload, tPhase, tDelay); + + // Early completion from initiator + if (returnValue == TLM_UPDATED) + { + payloadEventQueue.notify(cbPayload, tPhase, tDelay); + } + + Latency latency = sc_time_stamp() - payloadMap.at(&cbPayload); + payloadMap.erase(&cbPayload); + + latency = roundLatency(latency); + latencyMap.try_emplace(latency, 0); + latencyMap.at(latency)++; + } + else + { + // Send END_RESP by ourselfes + tlm_phase tPhase = END_RESP; + sc_time tDelay = SC_ZERO_TIME; + + iSocket->nb_transport_fw(cbPayload, tPhase, tDelay); + } + } + else if (cbPhase == END_RESP) // from initiator + { + { + tlm_phase tPhase = END_RESP; + sc_time tDelay = SC_ZERO_TIME; + + iSocket->nb_transport_fw(cbPayload, tPhase, tDelay); + } + + cbPayload.release(); + } + else + { + SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase"); + } +} + +tlm::tlm_generic_payload *EccModule::generateEccPayload(DecodedAddress decodedAddress) +{ + unsigned int eccAtom = decodedAddress.column / 512; + uint64_t eccColumn = 1792 + eccAtom * 32; + + decodedAddress.column = eccColumn; + uint64_t eccAddress = addressDecoder.encodeAddress(decodedAddress); + + tlm_generic_payload &payload = memoryManager.allocate(32); + payload.acquire(); + payload.set_address(eccAddress); + payload.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + payload.set_dmi_allowed(false); + payload.set_byte_enable_length(0); + payload.set_data_length(32); + payload.set_streaming_width(32); + payload.set_command(tlm::TLM_READ_COMMAND); + payload.set_extension(new EccExtension); + + return &payload; +} + +unsigned int EccModule::alignToBlock(unsigned column) +{ + return column & ~(512 - 1); +} + +DecodedAddress EccModule::calculateOffsetAddress(DecodedAddress decodedAddress) +{ + unsigned int newRow = + std::floor((decodedAddress.row * 256 + decodedAddress.column) / 1792) + decodedAddress.row; + unsigned int newColumn = (decodedAddress.row * 256 + decodedAddress.column) % 1792; + + DecodedAddress offsetAddress(decodedAddress); + offsetAddress.row = newRow; + offsetAddress.column = newColumn; + return offsetAddress; +} + +void EccModule::end_of_simulation() +{ + uint64_t latencies = 0; + uint64_t numberOfLatencies = 0; + + for (auto const &[latency, occurences] : latencyMap) + { + latencies += (latency.to_double() / 1000.0) * occurences; + numberOfLatencies += occurences; + } + + std::cout << "Average latency: " << static_cast(latencies) / numberOfLatencies << std::endl; +} + +sc_time EccModule::roundLatency(sc_time latency) +{ + static const sc_time BUCKET_SIZE = sc_time(1, SC_NS); + latency += BUCKET_SIZE / 2; + latency = latency - (latency % BUCKET_SIZE); + return latency; +} + +bool EccModule::activeEccBlock(Bank bank, Row row, Block block) const +{ + auto eccIt = std::find_if(activeEccBlocks.at(bank).cbegin(), activeEccBlocks.at(bank).cend(), + [block, row](EccIdentifier identifier) { + return (identifier.first == block) && (identifier.second == row); + }); + + return eccIt != activeEccBlocks.at(bank).cend(); +} diff --git a/src/simulator/simulator/EccModule.h b/src/simulator/simulator/EccModule.h new file mode 100644 index 00000000..15817db3 --- /dev/null +++ b/src/simulator/simulator/EccModule.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022, 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: + * Christian Malek + * Derek Christ + */ + +#ifndef ECCMODULE_H +#define ECCMODULE_H + +#include "simulator/MemoryManager.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +class EccModule : public sc_core::sc_module +{ +public: + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; + + EccModule(sc_core::sc_module_name name, AddressDecoder const &addressDecoder); + SC_HAS_PROCESS(EccModule); + +private: + using Block = uint64_t; + using Row = uint64_t; + using Bank = unsigned int; + using EccIdentifier = std::pair; + using EccQueue = std::deque; + + static DecodedAddress calculateOffsetAddress(DecodedAddress decodedAddress); + static sc_core::sc_time roundLatency(sc_core::sc_time latency); + bool activeEccBlock(Bank bank, Row row, Block block) const; + + void end_of_simulation() override; + + void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); + + tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &fwDelay); + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &bwDelay); + + tlm::tlm_generic_payload *generateEccPayload(DecodedAddress decodedAddress); + + static unsigned int alignToBlock(unsigned int column); + + tlm_utils::peq_with_cb_and_phase payloadEventQueue; + + tlm::tlm_generic_payload *pendingRequest = nullptr; + tlm::tlm_generic_payload *blockedRequest = nullptr; + bool targetBusy = false; + + const sc_core::sc_time tCK; + MemoryManager memoryManager; + AddressDecoder const &addressDecoder; + + std::unordered_map activeEccBlocks; + + using EccPayload = tlm::tlm_generic_payload *; + using StartTime = sc_core::sc_time; + std::unordered_map payloadMap; + + using Latency = sc_core::sc_time; + std::map latencyMap; +}; + +#endif // ECCMODULE_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4702149b..a89ad8d0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,3 +4,4 @@ add_subdirectory(tests_configuration) add_subdirectory(tests_dramsys) add_subdirectory(tests_regression) add_subdirectory(tests_util) +add_subdirectory(tests_simulator) diff --git a/tests/tests_simulator/CMakeLists.txt b/tests/tests_simulator/CMakeLists.txt new file mode 100644 index 00000000..0383d14b --- /dev/null +++ b/tests/tests_simulator/CMakeLists.txt @@ -0,0 +1,27 @@ +############################################### +### tests_simulator ### +############################################### + +cmake_minimum_required(VERSION 3.1.0) + +project(tests_simulator) + +add_executable(${PROJECT_NAME} + main.cpp + cache/tests_cache.cpp + cache/TargetMemory.cpp + cache/ListInitiator.cpp +) + +set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER tests/simulator) + +target_link_libraries(${PROJECT_NAME} PRIVATE + DRAMSys_Simulator + gtest_main +) + +gtest_discover_tests(${PROJECT_NAME} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + +build_source_group() diff --git a/tests/tests_simulator/cache/ListInitiator.cpp b/tests/tests_simulator/cache/ListInitiator.cpp new file mode 100644 index 00000000..a4e5906a --- /dev/null +++ b/tests/tests_simulator/cache/ListInitiator.cpp @@ -0,0 +1,189 @@ +/* + * 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 "ListInitiator.h" + +#include +#include +#include +#include +#include +#include +#include + +ListInitiator::ListInitiator(const sc_core::sc_module_name &name, MemoryManager &memoryManager) + : sc_core::sc_module(name), + iSocket("iSocket"), + peq(this, &ListInitiator::peqCallback), + memoryManager(memoryManager) +{ + iSocket.register_nb_transport_bw(this, &ListInitiator::nb_transport_bw); + SC_THREAD(process); +} + +void ListInitiator::process() +{ + for (auto &testTransactionData : testTransactionList) + { + wait(testTransactionData.startTime - sc_core::sc_time_stamp()); + + tlm::tlm_command command = + testTransactionData.command == TestTransactionData::Command::Write + ? tlm::TLM_WRITE_COMMAND + : tlm::TLM_READ_COMMAND; + + auto &trans = memoryManager.allocate(testTransactionData.dataLength); + trans.acquire(); + + TestExtension *ext = new TestExtension(testTransactionData); + trans.set_auto_extension(ext); + + trans.set_command(command); + trans.set_address(testTransactionData.address); + trans.set_data_length(testTransactionData.dataLength); + trans.set_streaming_width(testTransactionData.dataLength); + trans.set_byte_enable_ptr(nullptr); + trans.set_dmi_allowed(false); + trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + + if (trans.is_write()) + std::memcpy(trans.get_data_ptr(), &testTransactionData.data, testTransactionData.dataLength); + + if (requestInProgress != nullptr) + { + wait(endRequest); + } + + requestInProgress = &trans; + tlm::tlm_phase phase = tlm::BEGIN_REQ; + sc_core::sc_time delay = sc_core::SC_ZERO_TIME; + + std::cout << "\033[1;31m(" << name() << ")@" << std::setfill(' ') << std::setw(12) + << sc_core::sc_time_stamp() << ": " << std::setw(12) + << (command == tlm::TLM_WRITE_COMMAND ? "Write to " : "Read from ") + << "Addr = " << std::setfill('0') << std::setw(8) << std::dec + << testTransactionData.address << " Data = " + << "0x" << std::setfill('0') << std::setw(8) << std::hex + << testTransactionData.data << "(nb_transport) \033[0m" << std::endl; + + tlm::tlm_sync_enum status = iSocket->nb_transport_fw(trans, phase, delay); + + if (status == tlm::TLM_UPDATED) + { + peq.notify(trans, phase, delay); + } + else if (status == tlm::TLM_COMPLETED) + { + requestInProgress = nullptr; + checkTransaction(trans); + trans.release(); + } + } +} + +tlm::tlm_sync_enum ListInitiator::nb_transport_bw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &delay) +{ + peq.notify(trans, phase, delay); + return tlm::TLM_ACCEPTED; +} + +void ListInitiator::peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase) +{ + if (phase == tlm::END_REQ || (&trans == requestInProgress && phase == tlm::BEGIN_RESP)) + { + requestInProgress = nullptr; + endRequest.notify(); + } + else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP) + { + SC_REPORT_FATAL(name(), "Illegal transaction phase received"); + } + + if (phase == tlm::BEGIN_RESP) + { + checkTransaction(trans); + + tlm::tlm_phase fw_phase = tlm::END_RESP; + sc_core::sc_time delay = sc_core::sc_time(1, sc_core::SC_NS); + iSocket->nb_transport_fw(trans, fw_phase, delay); + + trans.release(); + } +} + +void ListInitiator::checkTransaction(tlm::tlm_generic_payload &trans) +{ + if (trans.is_response_error()) + { + SC_REPORT_ERROR(name(), "Transaction returned with error!"); + } + + tlm::tlm_command command = trans.get_command(); + + uint64_t transData{}; + + if (trans.get_data_length() == 1) + transData = *reinterpret_cast(trans.get_data_ptr()); + else if (trans.get_data_length() == 2) + transData = *reinterpret_cast(trans.get_data_ptr()); + else if (trans.get_data_length() == 4) + transData = *reinterpret_cast(trans.get_data_ptr()); + else if (trans.get_data_length() == 8) + transData = *reinterpret_cast(trans.get_data_ptr()); + + TestExtension *ext = nullptr; + trans.get_extension(ext); + TestTransactionData data = ext->getTestData(); + + std::cout << "\033[1;31m(" << name() << ")@" << std::setfill(' ') << std::setw(12) + << sc_core::sc_time_stamp() << ": " << std::setw(12) + << (command == tlm::TLM_WRITE_COMMAND ? "Check Write " : "Check Read ") + << "Addr = " << std::setfill('0') << std::setw(8) << std::dec << data.address + << " Data = " + << "0x" << std::setfill('0') << std::setw(8) << std::hex << transData << "\033[0m" + << std::endl; + + if (data.expectedEndTime != sc_core::sc_time_stamp()) + { + SC_REPORT_FATAL(name(), "NOT EXPECTED TIME"); + } + + if (trans.is_read() && data.data != transData) + { + SC_REPORT_FATAL(name(), "NOT EXPECTED DATA"); + } +} diff --git a/tests/tests_simulator/cache/ListInitiator.h b/tests/tests_simulator/cache/ListInitiator.h new file mode 100644 index 00000000..860975cd --- /dev/null +++ b/tests/tests_simulator/cache/ListInitiator.h @@ -0,0 +1,104 @@ +/* + * 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 "simulator/MemoryManager.h" + +#include +#include + +class ListInitiator : public sc_core::sc_module +{ +public: + tlm_utils::simple_initiator_socket iSocket; + + SC_HAS_PROCESS(ListInitiator); + ListInitiator(const sc_core::sc_module_name &name, MemoryManager &memoryManager); + + struct TestTransactionData + { + sc_core::sc_time startTime; + sc_core::sc_time expectedEndTime; + + enum class Command + { + Read, + Write, + } command; + + uint64_t address; + uint32_t dataLength; + uint64_t data; + }; + + void appendTestTransactionList(const std::vector &testTransactionList) + { + std::copy(testTransactionList.cbegin(), testTransactionList.cend(), std::back_inserter(this->testTransactionList)); + } + +private: + class TestExtension : public tlm::tlm_extension + { + public: + TestExtension(TestTransactionData data) : data(std::move(data)) {} + + tlm_extension_base *clone() const { return new TestExtension(data); } + + void copy_from(const tlm_extension_base &ext) + { + const TestExtension &cpyFrom = static_cast(ext); + data = cpyFrom.getTestData(); + } + + TestTransactionData getTestData() const { return data; } + + private: + TestTransactionData data; + }; + + void process(); + + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &delay); + void peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase); + void checkTransaction(tlm::tlm_generic_payload &trans); + + std::vector testTransactionList; + + sc_core::sc_event endRequest; + tlm_utils::peq_with_cb_and_phase peq; + tlm::tlm_generic_payload *requestInProgress = nullptr; + MemoryManager &memoryManager; +}; diff --git a/tests/tests_simulator/cache/TargetMemory.cpp b/tests/tests_simulator/cache/TargetMemory.cpp new file mode 100644 index 00000000..bc1524a6 --- /dev/null +++ b/tests/tests_simulator/cache/TargetMemory.cpp @@ -0,0 +1,231 @@ +/* + * 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 "TargetMemory.h" + +#include +#include +#include +#include + +DECLARE_EXTENDED_PHASE(INTERNAL); + +TargetMemory::TargetMemory(const sc_core::sc_module_name &name, + sc_core::sc_time acceptDelay, + sc_core::sc_time memoryLatency, + std::size_t bufferSize) + : sc_core::sc_module(name), + tSocket("tSocket"), + bufferSize(bufferSize), + peq(this, &TargetMemory::peqCallback), + acceptDelay(acceptDelay), + memoryLatency(memoryLatency) +{ + tSocket.register_nb_transport_fw(this, &TargetMemory::nb_transport_fw); + + memory.reserve(SIZE); + std::fill(memory.begin(), memory.end(), 0); +} + +tlm::tlm_sync_enum TargetMemory::nb_transport_fw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &delay) +{ + peq.notify(trans, phase, delay); + return tlm::TLM_ACCEPTED; +} + +void TargetMemory::printBuffer(int max, int n) +{ + std::cout << "\033[1;35m(" << name() << ")@" << std::setfill(' ') << std::setw(12) + << sc_core::sc_time_stamp() << " Target Buffer: " + << "["; + for (int i = 0; i < n; i++) + { + std::cout << "█"; + } + for (int i = 0; i < max - n; i++) + { + std::cout << " "; + } + std::cout << "]" + << " (Max:" << max << ") " + << "\033[0m" << std::endl; + std::cout.flush(); +} + +void TargetMemory::peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase) +{ + sc_core::sc_time delay; + + if (phase == tlm::BEGIN_REQ) + { + trans.acquire(); + + if (currentTransactions < bufferSize) + { + sendEndRequest(trans); + } + else + { + endRequestPending = &trans; + } + } + else if (phase == tlm::END_RESP) + { + if (!responseInProgress) + { + SC_REPORT_FATAL(name(), "Illegal transaction phase END_RESP received by target"); + } + + currentTransactions--; + printBuffer(bufferSize, currentTransactions); + + responseInProgress = false; + if (!responseQueue.empty()) + { + tlm::tlm_generic_payload *next = responseQueue.front(); + responseQueue.pop(); + sendResponse(*next); + } + + if (endRequestPending != nullptr) + { + sendEndRequest(*endRequestPending); + endRequestPending = nullptr; + } + } + else if (phase == INTERNAL) + { + executeTransaction(trans); + + if (responseInProgress) + { + responseQueue.push(&trans); + } + else + { + sendResponse(trans); + } + } + else // tlm::END_REQ or tlm::BEGIN_RESP + { + SC_REPORT_FATAL(name(), "Illegal transaction phase received"); + } +} + +void TargetMemory::sendEndRequest(tlm::tlm_generic_payload &trans) +{ + tlm::tlm_phase bw_phase; + sc_core::sc_time delay; + + // Queue the acceptance and the response with the appropriate latency + bw_phase = tlm::END_REQ; + delay = acceptDelay; + + tlm::tlm_sync_enum status = tSocket->nb_transport_bw(trans, bw_phase, delay); + + // Queue internal event to mark beginning of response + delay = delay + memoryLatency; // MEMORY Latency + peq.notify(trans, INTERNAL, delay); + + currentTransactions++; + printBuffer(bufferSize, currentTransactions); +} + +void TargetMemory::sendResponse(tlm::tlm_generic_payload &trans) +{ + sc_assert(responseInProgress == false); + + responseInProgress = true; + tlm::tlm_phase bw_phase = tlm::BEGIN_RESP; + sc_core::sc_time delay = sc_core::SC_ZERO_TIME; + tlm::tlm_sync_enum status = tSocket->nb_transport_bw(trans, bw_phase, delay); + + if (status == tlm::TLM_UPDATED) + { + peq.notify(trans, bw_phase, delay); + } + else if (status == tlm::TLM_COMPLETED) + { + SC_REPORT_FATAL(name(), "This transition is deprecated since TLM2.0.1"); + } + + trans.release(); +} + +void TargetMemory::executeTransaction(tlm::tlm_generic_payload &trans) +{ + tlm::tlm_command command = trans.get_command(); + sc_dt::uint64 address = trans.get_address(); + unsigned char *data_ptr = trans.get_data_ptr(); + unsigned int data_length = trans.get_data_length(); + unsigned char *byte_enable_ptr = trans.get_byte_enable_ptr(); + unsigned int streaming_width = trans.get_streaming_width(); + + if (address >= SIZE - 64) + { + trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); + return; + } + if (byte_enable_ptr != nullptr) + { + trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE); + return; + } + if (data_length > 64 || streaming_width < data_length) + { + trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE); + return; + } + + if (command == tlm::TLM_READ_COMMAND) + { + std::memcpy(trans.get_data_ptr(), &memory[trans.get_address()], trans.get_data_length()); + } + else if (command == tlm::TLM_WRITE_COMMAND) + { + memcpy(&memory[trans.get_address()], trans.get_data_ptr(), trans.get_data_length()); + } + + std::cout << "\033[1;32m(" << name() << ")@" << std::setfill(' ') << std::setw(12) + << sc_core::sc_time_stamp() << ": " << std::setw(12) + << (command == tlm::TLM_WRITE_COMMAND ? "Exec. Write " : "Exec. Read ") + << "Addr = " << std::setfill('0') << std::setw(8) << std::dec << address << " Data = " + << "0x" << std::setfill('0') << std::setw(8) << std::hex + << *reinterpret_cast(data_ptr) << "\033[0m" << std::endl; + + trans.set_response_status(tlm::TLM_OK_RESPONSE); +} diff --git a/tests/tests_simulator/cache/TargetMemory.h b/tests/tests_simulator/cache/TargetMemory.h new file mode 100644 index 00000000..5ec280d5 --- /dev/null +++ b/tests/tests_simulator/cache/TargetMemory.h @@ -0,0 +1,83 @@ +/* + * 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 + */ + +#pragma once + +#include +#include +#include +#include + +#include + +class TargetMemory : public sc_core::sc_module +{ +public: + tlm_utils::simple_target_socket tSocket; + SC_HAS_PROCESS(TargetMemory); + TargetMemory(const sc_core::sc_module_name &name, + sc_core::sc_time acceptDelay, + sc_core::sc_time memoryLatency, + std::size_t bufferSize = DEFAULT_BUFFER_SIZE); + +private: + tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &delay); + + void peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase); + + void sendEndRequest(tlm::tlm_generic_payload &trans); + void sendResponse(tlm::tlm_generic_payload &trans); + void executeTransaction(tlm::tlm_generic_payload &trans); + + void printBuffer(int max, int n); + + static constexpr std::size_t SIZE = static_cast(64 * 1024); + static constexpr std::size_t DEFAULT_BUFFER_SIZE = 8; + const std::size_t bufferSize; + + const sc_core::sc_time acceptDelay; + const sc_core::sc_time memoryLatency; + + std::vector memory; + + unsigned int currentTransactions = 0; + bool responseInProgress = false; + tlm::tlm_generic_payload *endRequestPending = nullptr; + + tlm_utils::peq_with_cb_and_phase peq; + std::queue responseQueue; +}; diff --git a/tests/tests_simulator/cache/tests_cache.cpp b/tests/tests_simulator/cache/tests_cache.cpp new file mode 100644 index 00000000..c8da5576 --- /dev/null +++ b/tests/tests_simulator/cache/tests_cache.cpp @@ -0,0 +1,93 @@ +/* + * 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 "ListInitiator.h" +#include "TargetMemory.h" + +#include +#include + +#include + +class SystemCTest : public testing::Test +{ +public: + ~SystemCTest() override { sc_core::sc_get_curr_simcontext()->reset(); } +}; + +class DirectMappedCache : public SystemCTest +{ +protected: + DirectMappedCache() + : memoryManager(true), + initiator("ListInitiator", memoryManager), + target("TargetMemory", + sc_core::sc_time(1, sc_core::SC_NS), + sc_core::sc_time(10, sc_core::SC_NS)), + cache("Cache", + 32768, + 1, + 32, + 8, + 8, + 8, + true, + sc_core::sc_time(1, sc_core::SC_NS), + 5, + memoryManager) + { + initiator.iSocket.bind(cache.tSocket); + cache.iSocket.bind(target.tSocket); + } + + MemoryManager memoryManager; + ListInitiator initiator; + TargetMemory target; + Cache cache; +}; + +TEST_F(DirectMappedCache, Hello) +{ + std::vector list{ + {sc_core::sc_time(1000, sc_core::SC_NS), + sc_core::sc_time(1017, sc_core::SC_NS), + ListInitiator::TestTransactionData::Command::Read, + 0x0, + 4, + 0x0}}; + + initiator.appendTestTransactionList(list); + sc_core::sc_start(); +} diff --git a/tests/tests_simulator/main.cpp b/tests/tests_simulator/main.cpp new file mode 100644 index 00000000..1c92c82d --- /dev/null +++ b/tests/tests_simulator/main.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019, 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: + * Lukas Steiner + */ + +#include +#include + +int sc_main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}