当前位置: 首页 > news >正文

SystemC的调度器

文章目录

    • 前言
    • 调度器
      • 初始化
      • evaluate
        • wait
      • update
        • notify
      • delta notification
      • time notification
      • 仿真结束

前言

SystemC是基于C++的库,主要用来对 IC 进行功能建模和性能建模。有时也被用来当做 RTL (register transfer level) 级的升级版 HLS(High Level synthesis) 直接用来表达设计,但是主流 EDA 对 SystemC 综合支持不够好,目前已经很少被用来当做设计语言搞了。有时候 SystemC 也会用来在 design verification 中当做 reference model 来使用,但是因为 SystemC module之间连接必须使用 channel,而 channel 在实现上是类似于 verilog reg 的一种方式,而没有对应的 verilog wire 类型的 channel ,所以在 module 划分时 SystemC module 和 verilog module 在实现上很难对应,使用 systemverilog 是一种更好的方式。

下面主要讨论 SystemC 的调度器,它在运行过程中是怎样控制我们的代码执行。其他比较基础的问题不在下面的讨论范畴中。

调度器

在 SystemC 中 sc_main 作为程序的入口,它类似于 C 语言中的 main,作为用户代码的入口,在他们前面还有一些库的代码作为整个程序的入口,这个请参考其他资料。

在 sc_main 中首先例化我们的 sc_module,连接各种模块,最后调用 sc_start 来开始仿真。在 sc_start 之前的阶段称为 Elaboration,类似于 verilog 中的 elaboration,将所有的 sc_module 都当做硬件摆放,并且检查 module 之间的连线关系。因为 sc_in/sc_out 都实现了sc_signal_in_if/sc_signal_out_if 接口,它的接口中实现访问连接它绑定的 channel 资源,通常是 sc_signal, 如果没有 bind,一旦操作它就会出现空指针的问题,所以在 sc module 连接时不允许接口悬空或者宽度不匹配,这个纯粹是 SystemC 库实现的问题,官方不支持我们也没办法。当所有 sc_module 的展开都没有问题时,整个系统的 hierarchy 就是固定了,可以启动整个硬件系统的。

在 sc_start 之后,它首先进行初始化,然后循环执行 evaluate-> update -> delta notification, time notification, 最后没有就绪的任务、超时或者主动结束(sc_stop)。 在仿真结束阶段进行

首先我们需要澄清两个时间:
仿真时间: 仿真程序中自己的时间精读,类似于一个虚拟世界中的世界。可能物理计算机已经跑了10分钟,但是虚拟世界中的时钟才跑了100us,我们分析仿真功能时一般使用仿真时间。
仿真程序运行时间: 仿真程序相对于真实世界运行的时间,例如这个程序运行了10s才结束,对于仿真内部是没有任何影响的,它只作为我们评判仿真程序性能的标准。

下面我们分别解释其中的几个 phase 或者称为 stage.

systemC phase

初始化

模拟内核识别所有模拟进程并将它们放置在可运行或等待进程集中。除那些请求“dont_initialize”的模拟进程(也包括 METHOD)外,所有模拟进程均处于可运行集中。

除此之外,我们的模拟工具还将为我们创建的任何变量分配初始值。这包括我们在模块内部声明的任何信号。从广义上讲,我们可以将初始化阶段视为大致相当于重置整个电路,所以有些设计省略了 reset 信号而是使用初始化赋值的方式来进行复位,这种方式只在仿真中可以使用。

在我们开始运行模拟之前,初始化阶段使我们的设计进入已知状态。

SystemC 是一个单线程、单进程的程序,虽然有SC_THREAD, 但是它是一种相当于协程任务的存在,所有的SC_THREAD/METHOD都是串行执行的。

evaluate

在 evaluate 阶段,模拟内核执行每个module 中的每个 thread/method。我们的thread/method 并非全部并行运行,模拟器一次只运行一个thread/method。下面我们将thread/method和其他所有的变种都称为任务。

模拟器运行每个进程,直到 return、执行任务中的最后一条语句或调用 wait()。 模拟器要么在到达 wait() 语句时挂起任务,要么在到达任务末尾或 return 语句时终止它们。

任务被挂起或终止后,调度程序将开始执行我们设计中的下一个任务。

调度程序重复此操作,直到我们设计中的所有进程都以这种方式执行。

此时,调度程序进入 update 阶段。

wait

wait 方法是 evaluate 阶段的重要组成部分,因为它确定 task 何时被挂起然后进入 update 阶段。

wait() 是在等待事件,事件在 SystemC 中有几种方式指定: 静态敏感列表 和 动态敏感列表,下表中列出了wait 使用不同的参数时的用法。

SyntaxFunction
wait()Suspend the thread until an event occurs on one of the signals in the sensitivity list (static sensitivity).
wait(n)Suspend the thread until events occur on one of the signals in the sensitivity list
wait(e1)Suspend the thread until the event e1 is active.
wait(n, SC_NS)Suspend the thread for ns. We can also pass a time object to the method to make it wait for a given period.
wait(n, SC_NS, e1)Suspend the thread either until event e1 is active or for ns, whichever is the shortest.
// Wait for a single event
wait()// Wait for 2 events
wait(2);// Wait for event e1 (this is generated in event_schedule)
wait(e1);// Wait for 10ns
wait(10, SC_NS);// Wait for 20ns (using time object)
sc_time t_20ns(20, SC_NS);
wait(t_20ns);
wait(20, SC_NS);// Wait for event e2 or 50ns
wait(50, SC_NS, e2);

update

一旦 evaluate 阶段完成执行,调度程序就会进入更新阶段。

为了正确模拟数字电路的行为,SystemC 模拟器在 evaluate 阶段创建更新请求。

每当模拟器在运行 evaluate 阶段时遇到信号赋值时,它就会标记创建这些更新请求。

此时,模拟器不会为我们的信号分配新值。 相反,我们的模拟器使用信号的原始值执行 evaluate 阶段的其余部分。

完成 evaluate 阶段后,调度程序将进入update 阶段,在该阶段它将处理所有更新请求。

结果,所有被分配值的信号在更新阶段而不是在evaluate阶段被更新为该新值。

在实现所有更新请求后,更新阶段完成,然后模拟器进入 delta notification 状态。

为了了解更新请求的工作原理,让我们看一个简单的示例。

对于这个例子,让我们看一下简单的扭曲环形计数器电路,如下所示。

一个简单的扭环式计数器电路
twisted ring counter

下面的代码片段显示了我们如何在 SystemC 中对该电路进行建模。

dff1.write( ~dff2.read() );
dff2.write( dff1.read() );

首先,让我们看看信号在分配后立即更新时的行为。 这是我们在传统编程语言中所期望的行为。

假设时钟边沿出现时两个触发器的输出均为 0。 由于上面代码中第 1 行的结果,DFF1 的输出更改为 1。然后我们可以看到下一行代码会将 DFF2 的输出设置为 1。

这显然不是我们正在建模的电路的预期行为。 相反,我们预计 DFF2 保持为 0,DFF1 更改为 1。

现在让我们考虑一下使用更新请求后模型的行为如何。

模拟器首先执行更新DFF1的语句并为此信号创建更新请求。 调度程序创建此更新请求的方式是将 DFF1 的输出更新为 1b。

然后,模拟器使用 DFF1 触发器的原始值运行第二行代码,并为 DFF2 的输出创建更新请求。 由于此时 DFF1 仍设置为 0b,因此调度程序创建一个更新请求,将 DFF2 的输出更新为 0b。

由于此设计中只有两个语句,因此评估阶段现已完成,调度程序进入更新阶段。

在更新阶段,模拟器执行它在评估阶段创建的 2 个更新请求。 执行更新请求后,DFF1 的值为 1b,DFF2 的值为 0b。

notify

在更新阶段,我们使用通知方法告诉模拟器信号值已更改。

这意味着通知方法对于控制我们设计中的信号如何更新非常重要。

在大多数情况下,我们实际上不需要在设计中直接调用notify方法。

原因是我们在 SystemC 中使用的许多数据类型和信号都是作为类实现的。 大多数情况下,这些类会在需要时自动为我们调用notify方法。

例如,当我们使用sc_fifo、sc_mutex或sc_signal时,所有这些类都为我们实现了notify方法。 因此,当我们想要更新任何使用这些类型的变量时,我们不需要手动调用通知方法。

然而,如果我们想在SystemC中编写自己的分层通道,那么我们可能需要在代码中手动调用notify方法。

我们实际上可以使用notify方法来创建三种不同类型的通知。 我们的调度程序将在不同阶段处理每个不同的通知。

下表总结了我们可以使用notify方法创建的三种不同类型的通知。

SyntaxFunction
notify()We use the notify method without any arguments to create an immediate notification. These are implemented in immediately.
notify(SC_ZERO_TIME)When we use the notify method together with the SC_ZERO_TIME constant we create a delta notification. These are implemented during the delta notification phase.
notify(n, SC_NS)
We create a time notification by passing a time argument to the notify method. We can also pass a time object to create a time notification. These are implemented during the time notification phase.
// Create an immediate notification
e1.notfy();// Create a delta notificatione1.notify(SC_ZERO_TIME);// Create a time notification (in this case 10ns)
e1.notify(10, SC_NS);

delta notification

一旦更新阶段完成为我们设计中的信号分配新值,调度程序就会进入增量通知阶段。

正如我们在更新阶段部分中讨论的那样,我们可以使用 notification() 方法来创建增量通知。

然后,增量通知阶段负责处理这些通知。

为此,我们的模拟器会计算出哪些进程受到增量通知的影响。

例如,假设我们正在对一个简单的电路进行建模,如下所示。
在这里插入图片描述

显示两个输入与门的电路图,其中与门的输出是 D 型触发器的输入
现在假设在评估阶段,与门的输出改变值。 由于此更改,模拟器会在更新阶段发出增量通知。

在增量通知阶段,模拟器确定哪些进程受到此值更改的影响。 在这种情况下,增量通知会影响对触发器进行建模的过程

一旦模拟器确定哪些进程受到增量通知的影响,它就会将这些进程标记为可运行。

调度程序以这种方式完成所有增量通知的处理后返回到评估阶段。

然后模拟器将再次执行它标记为可运行的所有进程。

如果没有需要处理的增量通知,SystemC 调度程序将直接进入时间通知阶段。

time notification

在执行给定时间步长的所有增量周期后,调度程序将进入时间通知阶段。

正如我们在更新阶段部分中讨论的那样,我们可以使用 notification() 方法来创建时间通知。

处理这些时间通知是时间通知阶段的责任。

为此,调度程序会分析该时间步期间发出的所有时间通知。

然后,调度程序根据请求的超时持续时间组织这些通知。

例如,如果我们有 3 个时间通知,分别为 1ms、5ns 和 10ns,那么调度程序会按照从最短到最长的顺序组织它们。 在这种情况下,我们的调度程序将按照 5ns、10ns 和 1ms 的顺序组织它们。

一旦调度程序以这种方式完成时间通知的组织,它就会将模拟时间提前到下一个最早的时间步长。

例如,如果我们有 3 个 5ns、10ns 和 1ms 的时间通知,那么调度程序会将模拟时间提前 5ns。

在调度程序以这种方式处理完所有时间通知后,调度程序返回到评估阶段。 然后,调度程序将在下一个时间步骤中再次运行整个周期。

仿真结束

仿真结束时,它会清理资源,例如关闭打开的文件,释放申请的内存,析构object等操作。这部分对于程序分析比较重要,例如仿真程序是否存在内存泄露问题影响稳定性,对于仿真功能已经没什么影响了。

另外 SystemC 提供给用户 callback 在这阶段实现一些自定义操作: end_of_simulation(), 一般可以用来报告仿真程序的统计信息。

相关文章:

SystemC的调度器

文章目录 前言调度器初始化evaluatewait updatenotify delta notificationtime notification仿真结束 前言 SystemC是基于C的库,主要用来对 IC 进行功能建模和性能建模。有时也被用来当做 RTL (register transfer level) 级的升级版 HLS(High Level synthesis) 直接…...

SpringBoot、SpringCloud 版本查看

1、SpringBoot 官网地址 https://spring.io/projects/spring-boot#learn spring-boot-starter-parent 版本列表可查看: https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent 2、SpringCloud 官网地址 https://spring.io/pro…...

AI Chat 设计模式:12. 享元模式

本文是该系列的第十二篇,采用问答式的方式展开,问题由我提出,答案由 Chat AI 作出,灰色背景的文字则主要是我的一些思考和补充。 问题列表 Q.1 给我介绍一下享元模式A.1Q.2 也就是说,其实共享的是对象的内部状态&…...

Spring mvc:SpringServletContainerInitializer

SpringServletContainerInitializer实现了Servlet3.0规范中定义的ServletContainerInitializer&#xff1a; public interface ServletContainerInitializer {void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException; }SpringServletCont…...

微信小程序中的全局数据共享(状态管理)使用介绍

开发工具&#xff1a;微信开发者工具Stable 1.06 一、状态管理简介 微信小程序全局状态是指可以在不同页面之间共享的数据或状态。 它可以存储用户的登录状态、个人信息、全局配置信息等。 二、安装MobX 1、安装NPM 在资源管理器的空白地方点右键&#xff0c;选择“在外部…...

LLM - LLama 模型读取报错 TypeError: not a string

一.引言 读取 LLama2 模型时报错 TypeError: not a string 看异常栈是 AutoTokenizer.from_pretrained 时候的异常。 二.问题解决 出现类似加载模型异常的问题&#xff0c;大致分两类&#xff1a; ◆ 模型地址异常 脚本里传的 pretrained_model Path 有问题&#xff0c;加 …...

2023年08月在线IDE流行度最新排名

点击查看最新在线IDE流行度最新排名&#xff08;每月更新&#xff09; 2023年08月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多&#xff0c;人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…...

k8s的架构

简介 一个 K8s 系统&#xff0c;通常称为一个 K8s 集群&#xff0c;集群主要包括两个部分 一个 Master 节点&#xff08;主节点&#xff09; 一群 Node 节点&#xff08;计算节点&#xff09; Master节点 Master 节点包括 API Server、Scheduler、Controller manager、etcd A…...

数据分析基础-Excel图表的美化操作(按照教程一步步操作)

一、原始数据 包含月份和对应的销量和产量。 时间销量产量1月60722月38673月28344月58685月67596月72357月61428月24319月556710月243511月122112月2645 二、原始的图表设计-采用Excel自带模板 三、优化思路 1、删除多余元素 2、弱化次要元素 对于可以弱化的元素&#xff0c…...

Mybatis嵌套查询(一对多)

一、返回数据Java类 Data public class PersonnelDetailsVO{/*** 主键*/Column(name "ID", length 36, precision 0)private String id;/*** 人员姓名*/Column(name "OPERATE_NAME", length 36, precision 0)private String operateName;/*** 单位i…...

web前端转正工作总结范文5篇

web前端转正工作总结&#xff08;篇1&#xff09; 来到__有限公司已经三个月了&#xff0c;目前的工作是前端开发&#xff0c;我是一名应届毕业生&#xff0c;之前没有过工作经验&#xff0c;在刚来到__这个大家庭的时候&#xff0c;我就被这里的工作气氛深深地吸引&#xff0…...

P1144 最短路计数

最短路计数 题目描述 给出一个 N N N 个顶点 M M M 条边的无向无权图&#xff0c;顶点编号为 1 ∼ N 1\sim N 1∼N。问从顶点 1 1 1 开始&#xff0c;到其他每个点的最短路有几条。 输入格式 第一行包含 2 2 2 个正整数 N , M N,M N,M&#xff0c;为图的顶点数与边数…...

Docker入门之命令

Docker命令学习方式 docker -h docker run --help # 这种形式参考 # 官方帮助 # https://docs.docker.com/reference/ Docker中命令是一等公民, 容器是为命令服务的,甚至启动容器都是为了执行一个命令 run docker run -i -t --name c1 centos:latest bash # 翻译: docker ru…...

Multimodal Learning with Transformer: A Survey

Transformer多模态学习 Abstract1 INTRODUCTION2 BACKGROUND2.1 Multimodal Learning (MML)2.2 Transformers: a Brief History and Milestones2.3 Multimodal Big Data 3 TRANSFORMERS: A GEOMETRICALLY TOPOLOGICAL PERSPECTIVE3.1 Vanilla Transformer3.1.1 Input Tokenizat…...

网工内推 | 实施、售后工程师,厂商认证优先

01 安井食品集团股份有限公司 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1.负责集团组网的网络规划、实施、维护工作&#xff1b; 2.负责公司局域网的网络规划、实施、维护工作&#xff1b; 3.负责公司企业安全系统规划、实施、维护工作&#xff1b; 4、负责公…...

小程序商品如何设置限购

限购是一种常用的小程序商品销售策略&#xff0c;可以帮助商家提高销售额、控制库存和增加用户的购买欲望。那么&#xff0c;小程序产品怎么设置限购呢&#xff1f;下面将为您详细介绍。 1. 设置限购数量 可以设置最低购买数量来鼓励用户批量购买或满足特定的销售需求。例如&…...

通信原理复习公式整理(自用/持续更新)

目录 符号表欧拉公式第一章平均信息量传信率(信息速率)传码率(码元速率) 第二章第三章第四章第五章第六章 数字信号的载波传输2ASK带宽余弦滚降基带信号-2ASK带宽2FSK带宽余弦滚降基带信号-2ASK带宽2PSK带宽匹配滤波器最大输出信噪比最佳线性滤波器传输特性ASK系统信号能量FSK系…...

TypeScript实战篇 - TS实战: 服务层开发 - 完整的聊天服务

目录 huatian-svc/src/main.ts huatian-svc/src/context/ChatContext.ts huatian-svc/src/ChatSession.ts huatian-svc/src/service/ChatIDService.ts huatian-svc/src/dao/DB.ts huatian-svc/src/dao/Dao.ts huatian-svc/src/dao/create_db.ts huatian-svc/src/main.ts…...

【雕爷学编程】MicroPython动手做(32)——物联网之MQTT

MQTT &#xff08;Message Queuing Telemetry Transport&#xff09;消息队列遥测传输协议&#xff0c;是一种基于发布/订阅&#xff08;publish/subscribe&#xff09;模式的"轻量级"通讯协议&#xff0c;该协议构建于TCP/IP协议上&#xff0c;由IBM在1999年发布。M…...

操作系统专栏4-网络专题from小林coding

网络专题 文件传输mmapwritesend file大文件传输过程 文件传输 传统的文件传输过程 在这个过程中发生了4次用户态与内核态之间的切换,4次数据拷贝分别是 read系统调用陷入内核,read完成返回write调用陷入内核,write返回 4次数据拷贝分别是 磁盘->内核缓冲区->用户缓冲…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...

Python爬虫实战:研究Restkit库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...

react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架

1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...

RabbitMQ 各类交换机

为什么要用交换机&#xff1f; 交换机用来路由消息。如果直发队列&#xff0c;这个消息就被处理消失了&#xff0c;那别的队列也需要这个消息怎么办&#xff1f;那就要用到交换机 交换机类型 1&#xff0c;fanout&#xff1a;广播 特点 广播所有消息​​&#xff1a;将消息…...

用js实现常见排序算法

以下是几种常见排序算法的 JS实现&#xff0c;包括选择排序、冒泡排序、插入排序、快速排序和归并排序&#xff0c;以及每种算法的特点和复杂度分析 1. 选择排序&#xff08;Selection Sort&#xff09; 核心思想&#xff1a;每次从未排序部分选择最小元素&#xff0c;与未排…...