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

推荐订阅源

F
Full Disclosure
博客园 - 聂微东
博客园_首页
人人都是产品经理
人人都是产品经理
N
News | PayPal Newsroom
云风的 BLOG
云风的 BLOG
U
Unit 42
T
Tailwind CSS Blog
Recent Announcements
Recent Announcements
Security Archives - TechRepublic
Security Archives - TechRepublic
T
The Blog of Author Tim Ferriss
Stack Overflow Blog
Stack Overflow Blog
The Register - Security
The Register - Security
The Hacker News
The Hacker News
博客园 - Franky
Engineering at Meta
Engineering at Meta
Jina AI
Jina AI
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
F
Fortinet All Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Check Point Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
有赞技术团队
有赞技术团队
TaoSecurity Blog
TaoSecurity Blog
博客园 - 司徒正美
GbyAI
GbyAI
G
Google Developers Blog
B
Blog
G
GRAHAM CLULEY
Y
Y Combinator Blog
雷峰网
雷峰网
爱范儿
爱范儿
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
V
V2EX
罗磊的独立博客
Know Your Adversary
Know Your Adversary
AWS News Blog
AWS News Blog
T
Troy Hunt's Blog
S
SegmentFault 最新的问题
P
Privacy & Cybersecurity Law Blog
T
Threat Research - Cisco Blogs
H
Help Net Security
N
Netflix TechBlog - Medium
Help Net Security
Help Net Security
L
LangChain Blog
D
Docker

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

【琐记】烟火与尘埃 【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 【AI编译】张量生命周期管理 SystemC 用寄存器同步建模方法 【脉动阵列】脉动阵列类型 【im2col】AScend conv accelerate 【感想】写作进度报告4 【BYOC】TVM添加自定义编译器 ccompiler 【感想】写作进度报告3 【Tengine】推理流程脑图【2】 【Tengine】推理流程脑图【1】 【NCNN】学习ncnn模型转换 【编译器】使用llvm编译自定义语言【3】编译 object 【编译器】使用llvm编译自定义语言【2】转llvm IR 【编译器】使用llvm编译自定义语言【1】构建AST 【AI编译】如何进行内存分配 【感想】写作进度报告2 【AI编译】layer-group之后如何tiling 【AI编译】如何进行layer-group 【量化】连续卷积层首尾量化的可行性 【Gemm】内存对齐 【gemm】Gemm计算加速 【TVM】通过代码学习编译流程【5】FuseOps 【TVM】通过代码学习编译流程【6】CodeGen 【TVM】通过代码学习类【3.5】Pass 【TVM】通过代码学习编译流程【4】BuildRelay 【AI编译】Tiling操作能优化什么时间 【TVM】通过代码学习编译流程【3】模型编译 【TVM】通过代码学习编译流程【2】模型转换 【TVM】通过代码学习编译流程【1】必要知识 【感想】写作进度报告1 【Winograd】卷积加速算法原理及实现 【TVM】Python脚本实现模型编译和保存 【推理引擎】常见AI推理框架 【3D建模】T110E3卡迪夫蓝调皮肤模型 【TVM】C++部署运行TVM 【推理引擎】NCNN和Tengine量化推理逻辑对比 【3D建模】IS-7攻城锤流纹岩皮肤展示 【TVM】根据例子走通代码库 博客汇总目录 【Im2Col】卷积加速算法【2】NHWC 【Im2Col】卷积加速算法【1】 NCHW openBlas库的安装与简单使用 C语言工程调用Cpp库解决方案 foo Hello World
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,并指明哪一篇博客,我看到一定及时回复!