diff --git a/src/libdramsys/DRAMSys/common/utils.cpp b/src/libdramsys/DRAMSys/common/utils.cpp index ab919c30..7eaf2ff6 100644 --- a/src/libdramsys/DRAMSys/common/utils.cpp +++ b/src/libdramsys/DRAMSys/common/utils.cpp @@ -86,4 +86,14 @@ void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank ra ArbiterExtension::setExtension(payload, Thread(UINT_MAX), Channel(0), 0, SC_ZERO_TIME); } +bool isFullCycle(sc_core::sc_time time, sc_core::sc_time cycleTime) +{ + return alignAtNext(time, cycleTime) == time; +} + +sc_time alignAtNext(sc_time time, sc_time alignment) +{ + return std::ceil(time / alignment) * alignment; +} + } // namespace DRAMSys diff --git a/src/libdramsys/DRAMSys/common/utils.h b/src/libdramsys/DRAMSys/common/utils.h index 47e3164e..a6f922be 100644 --- a/src/libdramsys/DRAMSys/common/utils.h +++ b/src/libdramsys/DRAMSys/common/utils.h @@ -69,6 +69,9 @@ std::string getPhaseName(const tlm::tlm_phase &phase); void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t channelPayloadID, Rank rank = Rank(0), BankGroup bankGroup = BankGroup(0), Bank bank = Bank(0)); +bool isFullCycle(sc_core::sc_time time, sc_core::sc_time cycleTime); +sc_core::sc_time alignAtNext(sc_core::sc_time time, sc_core::sc_time alignment); + } // namespace DRAMSys #endif // UTILS_H diff --git a/src/libdramsys/DRAMSys/controller/Controller.cpp b/src/libdramsys/DRAMSys/controller/Controller.cpp index c87a21df..2c40fa11 100644 --- a/src/libdramsys/DRAMSys/controller/Controller.cpp +++ b/src/libdramsys/DRAMSys/controller/Controller.cpp @@ -258,7 +258,7 @@ Controller::Controller(const sc_module_name& name, const Configuration& config, void Controller::controllerMethod() { - if (isFullCycle(sc_time_stamp())) + if (isFullCycle(sc_time_stamp(), memSpec.tCK)) { // (1) Finish last response (END_RESP) and start new response (BEGIN_RESP) manageResponses(); @@ -685,10 +685,4 @@ void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans) ParentExtension::setExtension(parentTrans, std::move(childTranses)); } -bool Controller::isFullCycle(const sc_core::sc_time& time) const -{ - sc_time alignedAtHalfCycle = std::floor((time * 2 / memSpec.tCK + 0.5)) / 2 * memSpec.tCK; - return sc_time::from_value(alignedAtHalfCycle.value() % memSpec.tCK.value()) == SC_ZERO_TIME; -} - } // namespace DRAMSys diff --git a/src/libdramsys/DRAMSys/controller/Controller.h b/src/libdramsys/DRAMSys/controller/Controller.h index 4c598f70..7fa929bf 100644 --- a/src/libdramsys/DRAMSys/controller/Controller.h +++ b/src/libdramsys/DRAMSys/controller/Controller.h @@ -106,8 +106,6 @@ private: void manageResponses(); void manageRequests(const sc_core::sc_time& delay); - bool isFullCycle(const sc_core::sc_time& time) const; - sc_core::sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent; const unsigned minBytesPerBurst; diff --git a/tests/tests_dramsys/test_utils.cpp b/tests/tests_dramsys/test_utils.cpp new file mode 100644 index 00000000..a2cddc04 --- /dev/null +++ b/tests/tests_dramsys/test_utils.cpp @@ -0,0 +1,42 @@ +#include + +#include + +using sc_core::sc_time; +using sc_core::SC_NS; +using sc_core::SC_US; + +TEST(AlignAtNext, FullCycle) +{ + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(5, SC_NS), sc_time(1, SC_NS)), sc_time(5, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(10, SC_NS), sc_time(2, SC_NS)), sc_time(10, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(10, SC_NS), sc_time(10, SC_NS)), sc_time(10, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(100, SC_NS), sc_time(10, SC_NS)), sc_time(100, SC_NS)); +} + +TEST(AlignAtNext, HalfCycle) +{ + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(0.5, SC_NS), sc_time(1, SC_NS)), sc_time(1, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(5, SC_NS), sc_time(10, SC_NS)), sc_time(10, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(22.5, SC_NS), sc_time(5, SC_NS)), sc_time(25, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(55, SC_NS), sc_time(5, SC_NS)), sc_time(55, SC_NS)); +} + +TEST(AlignAtNext, ArbitraryCycle) +{ + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(0.37, SC_NS), sc_time(1, SC_NS)), sc_time(1, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(5, SC_NS), sc_time(6.67, SC_NS)), sc_time(6.67, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(4.99, SC_NS), sc_time(5, SC_NS)), sc_time(5, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(0, SC_NS), sc_time(7.77, SC_NS)), sc_time(0, SC_NS)); + EXPECT_EQ(DRAMSys::alignAtNext(sc_time(4.49, SC_US), sc_time(500, SC_NS)), sc_time(4.5, SC_US)); +} + +TEST(IsFullCycle, IsFullCycle) +{ + EXPECT_TRUE(DRAMSys::isFullCycle(sc_time(0, SC_NS), sc_time(1, SC_NS))); + EXPECT_TRUE(DRAMSys::isFullCycle(sc_time(0, SC_NS), sc_time(1000, SC_US))); + EXPECT_TRUE(DRAMSys::isFullCycle(sc_time(5, SC_NS), sc_time(1, SC_NS))); + EXPECT_FALSE(DRAMSys::isFullCycle(sc_time(0.5, SC_NS), sc_time(1, SC_NS))); + EXPECT_TRUE(DRAMSys::isFullCycle(sc_time(67, SC_US), sc_time(1, SC_NS))); + EXPECT_FALSE(DRAMSys::isFullCycle(sc_time(67.05, SC_US), sc_time(100, SC_NS))); +}