惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
About on SuperTechFans
小众软件
小众软件
WordPress大学
WordPress大学
Microsoft Azure Blog
Microsoft Azure Blog
Recent Announcements
Recent Announcements
博客园 - 三生石上(FineUI控件)
博客园_首页
N
Netflix TechBlog - Medium
IT之家
IT之家
H
Help Net Security
博客园 - 聂微东
Google DeepMind News
Google DeepMind News
罗磊的独立博客
T
Tailwind CSS Blog
F
Fortinet All Blogs
Hugging Face - Blog
Hugging Face - Blog
MongoDB | Blog
MongoDB | Blog
V
V2EX
量子位
云风的 BLOG
云风的 BLOG
爱范儿
爱范儿
博客园 - 司徒正美
The Cloudflare Blog
Engineering at Meta
Engineering at Meta

Пусть этот камень будет более крепким, чем человек

【MLIR】Transform Dialect【0】保持计算结构 【MLIR】跟着Toy语言学习MLIR【6】支持复合结构类型 【MLIR】跟着Toy语言学习MLIR【5】降级到LLVM及CodeGen 【MLIR】跟着Toy语言学习MLIR【4】部分降级到低层方言 【MLIR】跟着Toy语言学习MLIR【3】通过接口实现通用转换 【MLIR】跟着Toy语言学习MLIR【2】pattern匹配和重写 【MLIR】跟着Toy语言学习MLIR【1】Toy语言和 Toy Dialect 【琐记】你的爱好能坚持多少年 【琐记】烟火与尘埃 【Triton】Triton实现矩阵乘 【LLM推理加速】FlashAttention 【LLM推理加速】PagedAttention 【LLM推理加速】Online Softmax LLM基础知识【1】 Transformer模型 【AI编译】LayerGroup Tiling Tile的疑惑和思考 【AI编译】深度优先的Tile调度,万事大吉? 【AI编译】多级流水线Tile调度策略 【CUDA C++】GPU内存使用【3】 【AI编译】Cache缓存地址映射 【CUDA C++】GPU存储【2】 【CUDA C++】GPU基本介绍【1】 【00】0序章-不受欢迎的来客 【转载】我来了——持续低熵 【Halide】调度优化【2】 【感想】写作进度报告5 【Halide】调度优化【1】 【转载】北大中文男足战报2 【BYOC】TVM切分子图 【转载】北大中文男足战报1
SystemC 等待异步事件解决方案
Post author: XianMu@Пусть этот камень будет более крепким, чем ч · 2024-07-05 · via Пусть этот камень будет более крепким, чем человек

# 介绍

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

应用场景:

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

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

世界上没有东西是完美的啊,倒不如说,同时拥有光明和阴影才是完美的,这样的你才是真正的你。
------ 大家好啊 我是 暮冬 Z 羡慕

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

https://forums.accellera.org/topic/7791-example-of-main-thread-controlling-sub_threadsystemc-module-to-complete-instructions/

https://forums.accellera.org/topic/7609-how-to-make-a-single-only-sc_thread-wait-for-a-notify-from-external-host-thread/

https://workspace.accellera.org/document/dl/10932
https://forums.accellera.org/topic/29-async_request_update-example/

https://stackoverflow.com/questions/49814756/async-request-update-example-in-systemc

# 解决方案:

#include <systemc.h>
#include <pthread.h>
#include <unistd.h>
using namespace std;
class ThreadSafeEventIf : public sc_interface {
        virtual void notify(sc_time delay = SC_ZERO_TIME) = 0;
        virtual const sc_event &default_event(void) const = 0;
    protected:
        virtual void update(void) = 0;
};
class ThreadSafeEvent : public sc_prim_channel, public ThreadSafeEventIf {
    public:
        ThreadSafeEvent(const char *name = ""): event(name) {}
        void notify(sc_time delay = SC_ZERO_TIME) {
            this->delay = delay;
            async_request_update();
        }
        const sc_event &default_event(void) const {
            return event;
        }
    protected:
        virtual void update(void) {
            event.notify(delay);
        }
        sc_event event;
        sc_time delay;
};
sc_event GenScEvent;
sc_event workingFinishEvent;  
int workingFlag = 0;  
SC_MODULE(Foo) {
    public:
        SC_CTOR(Foo) {
            SC_THREAD(main);
            SC_METHOD(eventTriggered);
            sensitive << threadSafeEvent;
            dont_initialize();
            SC_METHOD(stopTriggered);
            sensitive << threadStopEvent;
            dont_initialize();
        }
    private:
        void main() {   
            while (true) {
                usleep(0.05*1000*1000);  
                wait(SC_ZERO_TIME);
                if(workingFlag){    
                    wait(workingFinishEvent);  
                }
                usleep(0.05*1000*1000);
            }
        }
        void eventTriggered() {
            GenScEvent.notify();
        }
        void stopTriggered(){
            sc_stop();
        }
    public:
        ThreadSafeEvent threadSafeEvent;
        ThreadSafeEvent threadStopEvent;
};
void* PollingThread(void* arg) {
    int cnt = 0;
    Foo *foo = (Foo*)(arg);
    while (cnt<3) {
        cnt++;
        printf("[POLL]: %d: Before generating event from PollingThread \n", cnt);
        usleep(3*1000*1000);
        foo->threadSafeEvent.notify();
        printf("[POLL]: %d: Event notified from PollingThread \n", cnt);
    }
    usleep(5*1000*1000);
    foo->threadStopEvent.notify();
};
class sc_top : public sc_module {
    private:
        SC_HAS_PROCESS(sc_top);
    public:
        sc_top(sc_module_name name="SCTOP"): sc_module(name) {
            SC_THREAD(processing_thread);
        }
        void processing_thread(){
            int cnt =0;
            while (true) {
                printf("[PROC]: processing_thread called \n");
                cout << "[PROC]: Wait GenScEvent  time: " << sc_time_stamp();
                wait(GenScEvent);
                workingFlag = 1;
                cnt++;
                wait(10, SC_SEC);  
                cout << "[PROC]: Process and Finish "<<cnt << " GenScEvent   time: " << sc_time_stamp();
                workingFinishEvent.notify();
                workingFlag = 0;
            }
        }
};
int sc_main(int argc, char *argv[]) {
    Foo foo("foo");
    sc_top u_sc_top("u_sc_top");
    pthread_t thread;
    pthread_create(&thread, NULL, PollingThread, &foo); 
    sc_start();
    return 0;
}

对应的 CMakeLists.txt

cmake_minimum_required (VERSION 3.5)
project (demo)
include_directories (${PROJECT_SOURCE_DIR}/include)
find_library(SystemC_LIB systemc HINTS ${PROJECT_SOURCE_DIR}/lib)
set (syc_LIST ${PROJECT_SOURCE_DIR}/src/syc.cpp)
add_executable (syc ${syc_LIST})
find_package(Threads REQUIRED)
target_link_libraries (syc ${SystemC_LIB} Threads::Threads)

以上代码实现了 :

  • 1. 主线程中运行 SystemC 仿真模型,子线程中运行异步触发程序 (也可以根据自己的需要反过来,子线程中运行 SystemC 仿真模型,主线程运行触发程序。)
  • 2. 子线程每隔 3 秒触发一次 SystemC 仿真模型,主线程中的 SystemC 进行响应。
  • 3. 子线程主动触发三次之后,睡眠 5 秒,告知 SystemC 仿真结束。

# 结果


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

# 后记

本博客目前以及可预期的将来都不会支持评论功能。各位大侠如若有指教和问题,可以在我的 github 项目 或随便一个项目下提出 issue,并指明哪一篇博客,我看到一定及时回复!