• SystemC 等待异步事件解决方案


    本文为实现 SystemC 响应异步事件 解决方案。

    应用场景:

    SystemC是一个支持系统事务级、行为级建模的开源的C++ library;

    我们将SystemC仿真的模拟叫做模拟器。在很多场景下,模拟器要保持alive,等待异步async事件,做出对应的处理。例如设计一个SystemC消费者模拟器,而生产者程序不属于SystemC仿真范畴,消费者模拟器需要一直保持等待,并在出现数据后进行处理。

             世界上没有东西是完美的啊,倒不如说,同时拥有光明和阴影才是完美的,这样的你才是真正的你。。

                                                                                           ------ 大家好啊 我是 暮冬Z羡慕

    以上应用场景应当很常见,但是无论中文网站搜索、SystemC社区、谷歌搜索、Stack Overflow等,都没有合适的解决方案。笔者在综合了解相关问题及做了不少尝试后,给出了较为合适的解决方案。感兴趣的伙伴可以查看以下相关帖子:

    Example of main thread controlling sub_thread(systemc module) to complete instructions - SystemC Language - Accellera Systems Initiative Forums

    How to make a "single-only" sc_thread wait for a notify() from external host thread - SystemC Language - Accellera Systems Initiative Forums

    https://workspace.accellera.org/document/dl/10932

    async_request_update example - SystemC Language - Accellera Systems Initiative Forums

    c++ - async_request_update() example in SystemC - Stack Overflow

    这里是解决方案:

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. class ThreadSafeEventIf : public sc_interface {
    6. virtual void notify(sc_time delay = SC_ZERO_TIME) = 0;
    7. virtual const sc_event &default_event(void) const = 0;
    8. protected:
    9. virtual void update(void) = 0;
    10. };
    11. class ThreadSafeEvent : public sc_prim_channel, public ThreadSafeEventIf {
    12. public:
    13. ThreadSafeEvent(const char *name = ""): event(name) {}
    14. void notify(sc_time delay = SC_ZERO_TIME) {
    15. this->delay = delay;
    16. async_request_update();
    17. }
    18. const sc_event &default_event(void) const {
    19. return event;
    20. }
    21. protected:
    22. virtual void update(void) {
    23. event.notify(delay);
    24. }
    25. sc_event event;
    26. sc_time delay;
    27. };
    28. sc_event GenScEvent;
    29. sc_event workingFinishEvent; // finish event
    30. int workingFlag = 0; // maybe dnot need a lock
    31. SC_MODULE(Foo) {
    32. public:
    33. SC_CTOR(Foo) {
    34. SC_THREAD(main);
    35. SC_METHOD(eventTriggered);
    36. sensitive << threadSafeEvent;
    37. dont_initialize();
    38. SC_METHOD(stopTriggered);
    39. sensitive << threadStopEvent;
    40. dont_initialize();
    41. }
    42. private:
    43. void main() { //extra forever thread to avoid simulation exit
    44. while (true) {
    45. usleep(0.05*1000*1000); // check if there is any instruction every one sec.
    46. wait(SC_ZERO_TIME);
    47. if(workingFlag){ // check working
    48. wait(workingFinishEvent); // wait the working finish
    49. }
    50. usleep(0.05*1000*1000);
    51. }
    52. }
    53. void eventTriggered() {
    54. GenScEvent.notify();
    55. }
    56. void stopTriggered(){
    57. sc_stop();
    58. }
    59. public:
    60. ThreadSafeEvent threadSafeEvent;
    61. ThreadSafeEvent threadStopEvent;
    62. };
    63. void* PollingThread(void* arg) {
    64. int cnt = 0;
    65. Foo *foo = (Foo*)(arg);
    66. while (cnt<3) {
    67. cnt++;
    68. printf("[POLL]: %d: Before generating event from PollingThread \n", cnt);
    69. usleep(3*1000*1000);
    70. foo->threadSafeEvent.notify();
    71. printf("[POLL]: %d: Event notified from PollingThread \n", cnt);
    72. }
    73. usleep(5*1000*1000);
    74. foo->threadStopEvent.notify();
    75. };
    76. class sc_top : public sc_module {
    77. private:
    78. SC_HAS_PROCESS(sc_top);
    79. public:
    80. sc_top(sc_module_name name="SCTOP"): sc_module(name) {
    81. SC_THREAD(processing_thread);
    82. }
    83. void processing_thread(){
    84. int cnt =0;
    85. while (true) {
    86. printf("[PROC]: processing_thread called \n");
    87. cout << "[PROC]: Wait GenScEvent time: " << sc_time_stamp();
    88. wait(GenScEvent);
    89. workingFlag = 1;
    90. cnt++;
    91. wait(10, SC_SEC); // advance simulation time
    92. cout << "[PROC]: Process and Finish "<" GenScEvent time: " << sc_time_stamp();
    93. workingFinishEvent.notify();
    94. workingFlag = 0;
    95. }
    96. }
    97. };
    98. int sc_main(int argc, char *argv[]) {
    99. Foo foo("foo");
    100. sc_top u_sc_top("u_sc_top");
    101. pthread_t thread;
    102. pthread_create(&thread, NULL, PollingThread, &foo);
    103. sc_start();
    104. return 0;
    105. }

    CMakeLists.txt

    1. cmake_minimum_required (VERSION 3.5)
    2. project (demo)
    3. include_directories (${PROJECT_SOURCE_DIR}/include)
    4. find_library(SystemC_LIB systemc HINTS ${PROJECT_SOURCE_DIR}/lib)
    5. set (syc_LIST ${PROJECT_SOURCE_DIR}/src/syc.cpp)
    6. add_executable (syc ${syc_LIST})
    7. find_package(Threads REQUIRED)
    8. target_link_libraries (syc ${SystemC_LIB} Threads::Threads)

    以上代码实现了 :

    1.主线程中运行 SystemC仿真模型,子线程中运行异步触发程序 (也可以根据自己的需要反过来,子线程中运行SystemC仿真模型,主线程运行触发程序。)

    2.子线程每隔3秒触发一次SystemC仿真模型,主线程中的SystemC进行响应。

    3.子线程主动触发三次之后,睡眠5秒,告知SystemC仿真结束。

    结果:

    1. SystemC 2.3.3-Accellera --- Mar 12 2024 15:33:04
    2. Copyright (c) 1996-2018 by all Contributors,
    3. ALL RIGHTS RESERVED
    4. [POLL]: 1: Before generating event from PollingThread
    5. [PROC]: processing_thread called
    6. [PROC]: Wait GenScEvent time: 0 s[POLL]: 1: Event notified from PollingThread
    7. [POLL]: 2: Before generating event from PollingThread
    8. [PROC]: Process and Finish 1 GenScEvent time: 10 s[PROC]: processing_thread called
    9. [PROC]: Wait GenScEvent time: 10 s[POLL]: 2: Event notified from PollingThread
    10. [POLL]: 3: Before generating event from PollingThread
    11. [PROC]: Process and Finish 2 GenScEvent time: 20 s[PROC]: processing_thread called
    12. [PROC]: Wait GenScEvent time: 20 s[POLL]: 3: Event notified from PollingThread
    13. [PROC]: Process and Finish 3 GenScEvent time: 30 s[PROC]: processing_thread called
    14. [PROC]: Wait GenScEvent time: 30 s
    15. Info: /OSCI/SystemC: Simulation stopped by user.

  • 相关阅读:
    通过 Docker 灵活部署 Neo4j 图数据库
    HTML期末学生大作业:中华传统文化【苏绣手工艺】带psd设计图(15页)
    基于SSM+Vue的网上花店系统
    【无功优化】“碳中和”目标下电气互联系统有功-无功协同优化模型(Matlab代码实现)
    JVM加载class文件的原理简介说明
    Mac平台M1PRO芯片MiniCPM-V-2.6网页部署跑通
    桥接模式学习
    spring aop
    JSON数据
    Apache Shiro 漏洞复现
  • 原文地址:https://blog.csdn.net/whscheetah/article/details/137939927