Skip to content

Commit

Permalink
Adding peq wip
Browse files Browse the repository at this point in the history
  • Loading branch information
janweinstock committed Dec 6, 2023
1 parent ca70b3d commit d1e2b7b
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/vcml.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "vcml/core/thctl.h"
#include "vcml/core/systemc.h"
#include "vcml/core/range.h"
// #include "vcml/core/peq.h"
#include "vcml/core/command.h"
#include "vcml/core/module.h"
#include "vcml/core/component.h"
Expand Down
89 changes: 89 additions & 0 deletions include/vcml/core/peq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/******************************************************************************
* *
* Copyright (C) 2023 MachineWare GmbH *
* All Rights Reserved *
* *
* This is work is licensed under the terms described in the LICENSE file *
* found in the root directory of this source tree. *
* *
******************************************************************************/

#ifndef VCML_PEQ_H
#define VCML_PEQ_H

#include "vcml/core/types.h"
#include "vcml/core/systemc.h"

namespace vcml {

template <typename T>
class peq : public sc_object
{
private:
sc_event m_event;
std::multimap<sc_time, T> m_schedule;

public:
// Constructor
peq(const char* nm):
sc_object(nm),
m_event(mkstr("%s_event", basename()).c_str()),
m_schedule() {}
virtual ~peq() = default;
VCML_KIND(peq);

void notify(T payload, double t, sc_time_unit tu);
void notify(T payload, const sc_time& delta);
void cancel(T obj);
bool pop(T& obj);

sc_event& event() { return m_event; }
};

template <typename T>
inline void peq<T>::notify(T payload, double t, sc_time_unit tu) {
notify(payload, sc_time(t, tu));
}

template <typename T>
inline void peq<T>::notify(T payload, const sc_time& delta) {
sc_time t = sc_time_stamp() + delta;
m_schedule.emplace(t, payload);
m_event.notify(m_schedule.begin()->first - sc_time_stamp());
}

template <typename T>
inline void peq<T>::cancel(T obj) {
if (m_schedule.empty())
return;

sc_time curr = m_schedule.begin()->first;
mwr::stl_remove(m_schedule, curr);

if (m_schedule.empty()) {
m_event.cancel();
return;
}

sc_time next = m_schedule.begin()->first;
if (next == curr)
return;

m_event.cancel();
m_event.notify(next - sc_time_stamp());
}

template <typename T>
inline bool peq<T>::pop(T& obj) {
auto it = m_schedule.find(sc_time_stamp());
if (it == m_schedule.end())
return false;

obj = it->second;
m_schedule.erase(it);
return true;
}

} // namespace vcml

#endif
1 change: 1 addition & 0 deletions test/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ core_test("memory")
core_test("disk")
core_test("model")
core_test("system")
core_test("peq")

if(LUA_FOUND)
core_test("lua")
Expand Down
63 changes: 63 additions & 0 deletions test/core/peq.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/******************************************************************************
* *
* Copyright (C) 2023 MachineWare GmbH *
* All Rights Reserved *
* *
* This is work is licensed under the terms described in the LICENSE file *
* found in the root directory of this source tree. *
* *
******************************************************************************/

#include "testing.h"

#include "vcml/core/peq.h"

class peq_test : public test_base
{
public:
peq_test(const sc_module_name& nm): test_base(nm) {}
virtual ~peq_test() = default;

virtual void run_test() override {
int val;
peq<int> queue("peq");

EXPECT_STREQ(queue.name(), "test.run.peq");
EXPECT_STREQ(queue.event().name(), "test.run.peq_event");
EXPECT_STREQ(queue.kind(), "vcml::peq");

queue.notify(2, 2.0, SC_SEC);
queue.notify(1, 1.0, SC_SEC);
queue.notify(3, 3.0, SC_SEC);

wait(queue.event());

EXPECT_EQ(sc_time_stamp(), sc_time(1.0, SC_SEC));
EXPECT_TRUE(queue.pop(val));
EXPECT_EQ(val, 1);
EXPECT_FALSE(queue.pop(val));

queue.notify(4, 3.0, SC_SEC);

wait(queue.event());

EXPECT_EQ(sc_time_stamp(), sc_time(2.0, SC_SEC));
EXPECT_TRUE(queue.pop(val));
EXPECT_EQ(val, 2);
EXPECT_FALSE(queue.pop(val));

wait(queue.event());

EXPECT_EQ(sc_time_stamp(), sc_time(3.0, SC_SEC));
EXPECT_TRUE(queue.pop(val));
EXPECT_EQ(val, 3);
EXPECT_TRUE(queue.pop(val));
EXPECT_EQ(val, 4);
EXPECT_FALSE(queue.pop(val));
}
};

TEST(peq, test) {
peq_test test("test");
sc_core::sc_start();
}

0 comments on commit d1e2b7b

Please sign in to comment.