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

这里是解决方案:

#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;  // finish event
int workingFlag = 0;  // maybe dnot need a lock

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() {   //extra forever thread to avoid simulation exit
            while (true) {
                usleep(0.05*1000*1000);  // check if there is any instruction every one sec.
                wait(SC_ZERO_TIME);
                if(workingFlag){    // check working
                    wait(workingFinishEvent);  // wait the working finish 
                }
                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);  // advance simulation time
                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.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/556118.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DevOps(七)Jenkins发布第一个流水线任务

Jenkins的流水线&#xff08;Pipeline&#xff09;是一种强大的工具&#xff0c;用于定义和管理持续集成和持续交付&#xff08;CI/CD&#xff09;过程。它允许你以代码的形式&#xff08;即"Pipeline as Code"&#xff09;定义整个构建、测试和部署流程&#xff0c;…

UE4 拍摄、保存并浏览相册

效果&#xff1a; 1.新建CameraActor类 2.修改截图保存路径 3.编写BP_Camera蓝图 注意路径 Save Image函数要在执行拍照和BeginPlay事件执行一次 按钮执行拍摄事件 3.编写UMG蓝图 技巧&#xff1a;让Index加1、减1循环赋值 4.把BP_Camera挂在玩家上

《QT实用小工具·三十》基于QT开发的访客管理平台demo

1、概述 源码放在文章末尾 该项目为访客管理平台demo&#xff0c;包含主界面、系统设置、警情查询、调试帮助、用户退出功能。 项目部分代码如下&#xff1a; #ifndef QTHELPER_H #define QTHELPER_H#include "head.h"class QtHelper { public://获取所有屏幕区域…

从Linux角度具体理解程序翻译过程-----预处理、编译、汇编、链接

前言&#xff1a; 在C语言中&#xff0c;我们知道程序从我们所写的代码到可执行执行的过程中经历了以下过程 1.预处理 2.编译 3.汇编 4.链接 可以通过下图来理解 翻译过程 1.预处理 该过程主要进行以下操作&#xff1a; (1)头文件的包含 (2)define定义符号的替换&#xff…

怎样实现opc采集数据后传给web后端

现在很多老工厂要进行数字化改造&#xff0c;现场生产的各种数据需要传到web后端&#xff0c;很多工厂现场原有的自动监控系统已经采集了现场的各种数据&#xff0c;只是没有形成联网。如果前端自动化系统全部废除&#xff0c;重新做数字化控制系统&#xff0c;成本投入太大&am…

docker服务无法启动

背景&#xff1a;断电重启经常会导致磁盘io错误&#xff0c;甚至出现磁盘坏块 这时可以使用xfs_repair来修复磁盘&#xff0c;但是修复过程可能会导致部分数据丢失 xfs_repair -f -L /dev/sdc问题一&#xff1a; Apr 15 19:27:15 Centos7.6 systemd[1]: Unit docker.service e…

Java入门(JDK安装)

安装 JDK 下载 Java Downloads | Oracle 安装 下一步直接安装安装过程中&#xff0c;需要确定自己的安装位置 参考&#xff1a;D:\Java\jdk1.8.0_281_x64 演示位置 校验 终端输入 java -version 配置 1&#xff09;删除默认 javapath 默认情况下&#xff0c;可以在cm…

【C++题解】1607. 两位数运算

问题&#xff1a;1607. 两位数运算 类型&#xff1a;基本运算、拆位求解 题目描述&#xff1a; 小丽在编程课上学会了拆位运算&#xff0c;她已经可以拆出一个两位整数的十位和个位了&#xff0c;她想知道这个整数的十位 / 个位的结果是多少&#xff0c;请编程帮她实现&#…

VulnHub靶机 DC-5 打靶 渗透测试详情过程

VulnHub靶机 DC-5 打靶 详细渗透测试过程 目录 VulnHub靶机 DC-5 打靶 详细渗透测试过程一、将靶机导入到虚拟机当中二、渗透流程主机发现端口扫描目录爆破文件包含getshell反弹shell提权 一、将靶机导入到虚拟机当中 靶机地址&#xff1a; https://download.vulnhub.com/dc/…

【论文阅读】YOLO-World | 开集目标检测

Date&#xff1a;2024.02.22&#xff0c;Tencent AI Lab&#xff0c;华中科技大学Paper&#xff1a;https://arxiv.org/pdf/2401.17270.pdfGithub&#xff1a;https://github.com/AILab-CVC/YOLO-World 论文解决的问题&#xff1a; 通过视觉语言建模和大规模数据集上的预训练来…

HTTP/HTTPS详解

HTTP/HTTPS详解 1. HTTP1.1 HTTP基础知识1.2 HTTP建立和断开连接 2. HTTPS 1. HTTP 1.1 HTTP基础知识 HTTP是互联网上应用最为广泛的一种网络协议&#xff0c;是一个客户端和服务器端请求和应答的标准&#xff08;TCP&#xff09;&#xff0c;用 于从WWW服务器传输超文本到本…

学习一下选择排序,快速排序

1.选择排序 我们可以根据这动图看到&#xff0c;就是在这个数组里面我们选出最小的放进第一个位置&#xff0c;然后再选除了第一个位置最小的&#xff0c;剩下的数里面最小的放到第二个位置&#xff0c;是不是非常简单呢。 void SelectSort2(int* arr, int n) {int begin 0;…

Stable Diffusion 3 API 发布!超越Midjourney v6和DALL-E 3

Stable Diffusion 3 于 2 月首次宣布作为预览版发布。而今天&#xff0c;StabilityAI 正式推出了 Stable Diffusion 3 和 Stable Diffusion 3 Turbo API 的API接口服务。 Stability AI 称仍在持续改进该模型&#xff0c;并没有说明发布日期。模型还没发布&#xff0c;但API先来…

安装importlib_resources库的方法最终解答!_Python库

安装Python库importlib_resources 我的环境&#xff1a;Window10&#xff0c;Python3.7&#xff0c;Anaconda3&#xff0c;Pycharm2023.1.3 importlib_resources importlib_resources是一个用于访问Python包中非代码资源&#xff08;如文本、图片等&#xff09;的库&#xff…

neo4j使用详解(终章、neo4j的java driver使用模板及工具类——<可用于生产>)

Neo4j系列导航: neo4j安装及简单实践 cypher语法基础 cypher插入语法 cypher插入语法 cypher查询语法 cypher通用语法 cypher函数语法 neo4j索引及调优 neo4j java Driver等更多 1. 简介 本文主要是java使用neo4j driver操作neo4j的模板项目及非常有用的工具类,主要包括: 图…

yolov7模型输出层预测方法解读

本文从代码的角度分析模型训练阶段输出层的预测包括以下几个方面&#xff1a; 标注数据&#xff08;下文统称targets&#xff09;的正样本分配策略&#xff0c;代码实现位于find_3_positive。候选框的生成&#xff0c;会介绍输出层的预测值、GT、grid、 anchor之间的联系损失函…

【原创】springboot+mysql疫苗预约管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

《Kubernetes部署篇:基于Kylin V10+ARM架构CPU+外部etcd使用containerd部署K8S 1.26.15容器版集群(多主多从)》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;企业级K8s集群运维实战 1、在当前实验环境中安装K8S1.25.14版本&#xff0c;出现了一个问题&#xff0c;就是在pod中访问百度网站&#xff0c;大…

ollama大语言模型

查看已经安装的大语言模型 ollama list运行大语言模型 ollama run llama2:latest

【EI会议征稿通知】2024年图像处理、机器学习与模式识别国际学术会议(IPMLP 2024)

2024年图像处理、机器学习与模式识别国际学术会议&#xff08;IPMLP 2024) 2024 International Conference on Image Processing, Machine Learning and Pattern Recognition 重要信息 大会官网&#xff1a;www.ipmlp.net&#xff08;点击参会/投稿/了解会议详情&#xff09;…
最新文章