SystemC From The Ground Up学习笔记中文Word文档下载推荐.docx
- 文档编号:8185178
- 上传时间:2023-05-10
- 格式:DOCX
- 页数:29
- 大小:2.52MB
SystemC From The Ground Up学习笔记中文Word文档下载推荐.docx
《SystemC From The Ground Up学习笔记中文Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《SystemC From The Ground Up学习笔记中文Word文档下载推荐.docx(29页珍藏版)》请在冰点文库上搜索。
交易可以理解为系统模型中两个组件之间的一次数据交换。
这个交换与所采用的协议无关,因为交易级的模型通常不牵扯到具体的总线时序等细节。
一个数据交易可能是在系统组件之间传输的单个的字,多个字或者整个数据结构。
例如:
一次DMA,一次存储器读或者写、一次寄存器读或者写都可以看成是一个交易。
4、交易级建模提供的一个非常重要的用途就是可以在整个设计的比较早的阶段就开始进行嵌入式软件的开发。
好处是:
并行开发、仿真速度快、协同设计与验证
更早进行软件开发
更早更好的硬件功能验证测试
建立一个从客户需求到详细软硬件规范的完整清晰路径
5、交易级建模与SystemC的通信机制
SystemC的通信机制有两个特点特别适合TLM建模:
功能与通信分离。
也就是实现具体算法的部分与实现数据和事件传输的部分分离。
功能由SystemC的模块(sc_module)来实现,而通信由通道(channel)来实现。
接口方法调用(InterfaceMethodCall,IMC)。
一组给定的通信方法(method)被称为接口(interface),包括数据接口和控制接口。
通道(channel)是由一个或者多个接口来实现。
模块能够使用它的端口(port)调用实现了相应接口并关联到该端口的通道实例方法。
(三)SystemC概述
1、主要组件
2、SystemCCompilationFlow
3、面向硬件的特征
Themajorhardware-orientedfeaturesimplementedwithinSystemC:
Timemodel(sc_time、sc_clock)
Hardwaredatatypes
Modulehierarchytomanagestructureandconnectivity
Communicationsmanagementbetweenconcurrentunitsofexecution(通道)
Concurrencymodel(SC_METHOD、SC_THREAD、SC_CTHREAD)
4、SystemCComponents
5、SystemCSimulationKernel
(4)数据类型
数据类型的选择依赖于值的范围,要求的精度,要求的操作,数据类型的选择影响仿真的速度、合成器和综合的结果。
4.1NumericRepresentation
字符串表示:
4.2NativeDataTypes
SystemC支持所有的C++内建数据类型,包括int、longint、shortint、unsignedint、unsignedlongint、unsignedshortint、double、float、char、bool,以及C++的string类型。
在任何情况下,C++内建数据类型在仿真速度和内存使用上是最有效的。
4.3ArithmeticDataTypes算术数据类型
提供两类算术数据类型,一类是位宽1到64,另一类位宽大于64位
1.sc_intandsc_uint
对应于C++内建的int和unsignedint,不同点是可以指定数据的位宽(1到64位),使用格式为:
sc_int<
LENGTH>
NAME...;
sc_uint<
由于仿真SystemC的数据类型会比仿真C++的数据类型慢
2.sc_bigintandsc_biguint
可支持大于64位的数据。
sc_bigint<
BITWIDTH>
sc_biguint<
4.4BooleanandMulti-ValueDataTypes布尔及多值数据类型
1、sc_bit和sc_bv:
sc_bitNAME...;
(表示0、1)
sc_bv<
(位向量,长度大于1的0、1序列)
在SystemC中,SC_LOGIC_1和SC_LOGIC_0是分别表示1和0的数据常量。
sc_bit和sc_bv支持与(&
)、或(|)、异或(^)操作,以及位选择([])和范围选择操作(range())。
2、sc_logic和sc_lv:
sc_logicNAME[,NAME]...;
(表示1、0、X、Z四种逻辑)
sc_lv<
BITNIDTH>
NAME[,NAME]...;
(logicvector)
SC_LOGIC_X和SC_LOGIC_Z分别表示不确定状态和高阻态
4.5Fixed-PointDataTypes定点数据类型
SystemC提供sc_fixed、sc_ufixed、sc_fix、sc_ufix以及它们的_fast后缀变种,来表示定点数据类型。
要使用这些数据类型,必须在头文件包含语句#incluede<
systemc.h>
前面加上#defineSC_INCLUDE_FX。
WL表示字长度、IWL表示整数字长度,例如:
(i:
整数位;
f:
分数位;
s:
符号位)
sc_fixed<
5,5>
表示
iiiii.
5,3>
iii.ff
5,0>
.fffff
5,7>
iiiii.00
5,-2>
表示.ssfffff
fix和fixed的区别是fixed的定点数据类型在编译后便不能再改变。
_fast后缀的类型在仿真时更快,因为它们的精度被限制为53位。
4.6SystemC数据类型的操作符
(5)模块SC_MODULE
5.1程序起始点:
sc_main
所有程序都有一个起始点。
在C/C++中,这个起始点叫做main,例如:
intmain(intargc,char*argv[]){
BODY_OF_PROGRAM
return0;
}
在SystemC中,这个起始点被叫做sc_main。
intsc_main(intargc,char*argv[]){
ElABORATION
sc_start();
//<
--Simulatioinbegins&
endsinthisfunction!
[POST-PROCESSING]
returnEXIT-CODE;
//Zeroindicatessuccess
在sc_main中,代码执行分三个阶段:
Elaboration、Simulation和Post-processing。
Elaboration阶段描述系统的结构和相互连接关系,包括时钟、设计模块和通道的例化等;
Simulation阶段完成整个仿真行为;
从第一次遇到sc_start()开始到预先设定的仿真时间结束或者遇到sc_stop()。
Post-processing阶段是可选的,取决于设计者是否需要在完成仿真后还要进行其他处理。
5.2设计的基本单元:
SC_MODULE
复杂系统都是由许多独立的的功能模块组成的,这些模块代表硬件、软件或者物理实体,它们可大可小。
在SystemC中用SC_MODULE来表示这些模块。
的语法如下:
#include<
SC_MODULE(module_name)
{
MODULE_BODY
};
SC_MODULE实际上一个C++宏:
#defineSC_MODULE(module_name)\
structmodule_name:
publicsc_module
MODULE_BODY可由以下元素构成:
Ports端口
Memberchannelinstances成员通道的例化
Memberdatainstances成员数据的例化
Membermoduleinstances(sub-designs)成员模块的例化
Constructor构造函数(必须的)
Destructor析构函数
Processmemberfunctions(processes)成员过程
Helperfunctions
5.3SC_MODULE的构造函数:
SC_CTOR
SC_MODULE的构造函数SC_CTOR主要完成以下任务:
Initializing/allocatingsub-designs初始化和分配子设计
Connectingsub-designs连接子设计
RegisteringprocesseswiththeSystemCkernel注册过程
Providingstaticsensitivity提供静态敏感表
Miscellaneoususer-definedsetup其他用户定义的设置。
SC_CTOR的语法如下:
5.4执行的基本单元:
SystemCProcess
过程是SystemC的基本执行单元。
其语法如下:
voidPROCESS_NAME(void);
SystemC过程没有参数,也没有返回值。
最简单的过程是SC_THREAD,它和软件概念上的thread很相似。
SC_THREAD只被调用一次便结束。
5.5注册最简单的过程:
SC_THREAD
一旦定义了过程,就必须要让仿真内核识别和注册它。
过程的注册是在构造函数SC_CTOR中进行的。
注册SC_THREAD过程的语法如下:
SC_THREAD(process_name);
//MustbeINSIDEconstructor
下面是一个简单的例子:
SC_MODULE(simple_process_ex)
SC_CTOR(simple_process_ex)
SC_THREAD(my_thread_process);
}
voidmy_thread_process(void);
5.6完成一个简单的设计:
main.cpp
在my_instance中用了"
my_instance"
做参数,这么做的目的是为了将实例的名字存储在其内部,以便在debug时调用。
sc_module的成员函数name()可用来获取当前实例的名称。
5.7另一种构造函数:
SC_HAS_PROCESS
可以在两种情况下使用该宏:
当需要将实例名称以外的参数传给构造函数;
希望将构造函数的实现放到另一个cpp文件中。
例如,一个存储设计可以允许通过参数进行不同大小的存储选择:
My_memoryinstance("
instance"
1024);
(6)时间概念
6.1sc_time
SystemC提供sc_time数据类型来衡量时间。
时间由两部分构成:
长度(magnitude)和单位(unit)。
时间数据类型语法如下:
时间单位有以下几种:
SystemC允许对sc_time对象进行加、减以及比例缩放等操作。
一个特殊的常量SC_ZERO_TIME,即代表sc_time(0,SC_SEC)。
6.2sc_start()
sc_start()用于启动仿真阶段。
sc_start()提供了一个sc_time类型的可选参数,用来指定最大仿真时间。
如:
sc_start(60.0,SC_SEC);
6.3sc_time_stamp()andTimeDisplay
在SystemC中可以通过sc_time_stamp()来获得当前仿真时间。
cout<
<
sc_time_stamp()<
endl;
6.4wait(sc_time)
wait()被用在SC_THREAD过程中完成延迟功能。
当遇到wait(),SC_THREAD过程被阻塞,并且在指定的时间返回继续执行。
wait(delay_sc_time);
//waitspecifiedamountoftime
6.5sc_simulation_time(),时间分辨率和单位
有时想要用C++内建数据类型操作时间,sc_simulation_time()将以当前缺省单位返回double类型的时间。
修改缺省时间单位:
sc_set_default_time_unit().缺省时间单位必须是10的幂,必须大于等于时间分辨率,只能设置一次,只能在仿真开始之前设置。
指定时间分辨率:
sc_set_time_resolution().时间分辨率必须是10的幂,只能在仿真开始之前设置,且只设置1次,必须在任何的非零的sc_time声明之前设置。
(7)并发Processes&
Events
实时系统中的很多活动都是同时发生的,SystemC用processes模拟并发。
SystemC提供了两个主要的process类型:
SC_THREAD,SC_METHOD,还有第三种类型,SC_CTHREAD,是SC_THREAD的变型。
7.1sc_event
事件就是在某个特定时间点发生的事情。
一个时间没有取值,也没有持续时间。
事件本身没有并不做任何可以被观察到的事情,它只是激发对它敏感的过程,从而表现出作用。
SystemC中的process通过动态或者静态敏感表来等待一个事件的发生。
声明一个事件的语法如下:
由于sc_event没有取值,只能对它采取两种动作:
等待或导致它发生。
7.2SimplifiedSimulationEngine
需要理解事件驱动模拟是怎样工作的。
见5页SystemCSimulationKernel.
7.3SC_THREAD
过程SC_THREAD被且只被仿真器启动一次。
SC_THREAD一旦被执行,就完全控制仿真过程,直到其自己将控制返回给仿真器。
SC_THREAD有两种返回控制给仿真器的方法,一种是简单退出(如return),这意味着永远结束该过程。
因此,常常在SC_THREAD中使用含有至少一条wait语句的无限循环。
另一种返回控制的方法是调用wait方法,wait挂起sc_thread进程。
有时候wait并不是被直接使用的,比如sc_fifo的阻塞读或写在FIFO分别为空或满的时候将隐式的激活wait。
7.4SC_THREAD:
:
wait()的动态敏感表
SC_THREAD依靠wait来挂起自身。
当wait被执行时,当前SC_THREAD进程的状态将被保存,同时仿真内核得到控制权,启动另一个准备好的进程。
当被挂起的过程重新被启动时,它将从wait后的语句开始执行。
wait的语法如下:
当使用timeout时,在wait后立即调用布尔函数timed_out()来检测是否是timeout导致进程返回。
7.6启动事件:
.notify()
事件通过使用notify()来显式的发生。
面向对象的语法风格:
调用.notify()会使任何等待该事件的进程立即由等待转为就绪。
.notify(SC_ZERO_TIME)会在当前等待被执行的所有过程完成后,才将等待该事件的过程转为等待被执行(所谓的下一个delta-cycle)。
对于.notify(time)来说,如果有多个notification,那么只有时间最近的那个是有效的。
我们可以用.cancel()来取消所有notification。
7.7SC_METHOD
SC_METHOD从不在其内部被挂起(不能直接或间接的使用wait(),否则会报runtimeerror的错误),SC_METHOD一旦运行便会运行到底,然后返回。
仿真引擎根据动态或静态敏感表不断的调用SC_METHOD。
语法如下:
SC_METHOD(process_name);
//Locatedinsideconstructor
在SC_THREAD中变量分配是永久的,即变量是永远存在的。
在SC_METHOD中,每次被调用时变量都要被声明和初始化,如果希望保存SC_METHOD中的值,那么就需要使用SC_MODULE中定义的局部变量。
7.8SC_METHOD:
next_trigger()的动态敏感表
SC_METHODprocesses使用next_trigger()动态的指定它们的敏感性。
next_trigger不会阻碍当前SC_METHOD的执行,它会改变下一次调用该SC_METHOD的敏感表。
如果没有静态敏感表,那么SC_METHOD的所有执行分支都应当有next_trigger,否则可能导致该SC_METHOD不再被调用。
7.9进程的静态敏感表
动态敏感表示在仿真阶段的建立的,并且可以在仿真中被改变。
静态敏感表是在elaboration阶段(仿真前)建立的,静态敏感表一旦建立就不能再改变。
静态敏感表只应用于最近的进程注册。
建议选择类似于C++流的第一种语法风格。
7.10dont_initialize
SystemC的仿真引擎将在开始时初始化执行所有的进程,然后有时候某些进程不需要在一开始就执行。
SystemC提供了dont_initialize()来阻止初始化
//IMPORTANT:
Mustfollowprocessregistration
dont_initialize();
使用dont_initialize需要一个静态敏感表,否则将没法启动进程。
7.11sc_event_queue
sc_event只能被安排一次(如果多个notification只有时间最近的那个会被执行),sc_event_queue可以使一个事件被安排多次甚至是在同一时间。
(8)基本通道
并发过程之间的通讯可以使用事件和模块成员数据。
由于没法保证下一个从就绪态执行的是哪个进程,在共享数据是必须十分小心使用这两种方法。
SystemC提供一种“握手(handshake)”变量来实现过程间的通讯,称作通道(channel)。
通道有primitive和hierarchical两种。
8.1PrimitiveChannels基本通道
基本通道不包含任何进程,也不对外展现出任何可见结构,它们也不能够直接的或者间接的调用其它基本通道。
所有的primitivechannel都是从sc_prim_channel基类继承而来。
下面介绍最简单的三种primitivechannel:
sc_mutex、sc_semaphore、sc_fifo。
8.2sc_mutex
在elaboration阶段,mutex被创建(有唯一的名字),之后任何需要该资源的进程必须lock该mutex以阻止其他进程使用该共享资源,当进程不再使用互斥资源时需要unlock该mutex,如果另一个进程试图使用一个锁定的资源,该进程将被阻止直到资源解锁。
SystemC通过sc_mutex通道实现mutex。
sc_mutex包含许多访问函数,包括阻塞和非阻塞两种风格。
阻塞风格的函数只能在SC_THREAD过程中使用。
在电子设计中,可以用sc_mutex作为共享总线的仲裁。
当仲裁器设计好后再替换该sc_mutex。
8.3sc_semaphore
有些资源可以有多个copy或owner,SystemC提供sc_semaphore来管理这种资源。
当建立信号量对象时,指定有多少可用是必须的。
其实mutex是只有一个计数值的信号量。
信号量代表可用资源实体的数量,所以可以认为信号量就是一个资源计数器,它限制的是同时使用某共享资源(也称为临界资源)的进程的数量。
信号量计数的值代表的就是当前仍然可用的共享资源的数量。
sc_semaphore的语法如下:
sc_semaphore实现的是sc_semaphore_if接口。
其中,wait()方法获得一个信号量,其作用效果是获得一份资源的使用权,使信号量计数减一,如下面的实现代码。
intsc_semaphore:
wait(){
while(in_use()){sc_prim_channel:
wait(m_free);
--m_value;
8.4sc_fifo
FIFO是用来管理数据流的最常用的数据结构。
SystemC提供sc_fifo来实现FIFO。
sc_fifo<
>
在默认情况下深度是16,另外还需要指定元素的数据类型。
sc_fifo的语法如下:
T>
是SystemC核心语言库中已经实现了的FIFO通道。
write(&
T)代表写FIFO的方法。
read()是读FIFO的方法,它返回队头单元的数据。
num_free()用于查询FIFO还有多少空单元。
num_available()查询FIFO还有多少个数据可以读。
Size代表FIFO的总单元数,对于sc_fifo,Size的默认值为16。
对于复杂数据类型的元素,将指针传给sc_fifo将会更加高效。
(9)EVALUATE-UPDATECHANNELS
通常,电子信号有单一的来源,但是多个接收器。
使所有的sinks能在同一时间检测到信号更新是很重要的。
9.1CompletedSimulationEngine
信号通道使用这个更新状态作为数据同步点。
为了达到同步,每个通道有两个存储区域
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SystemC From The Ground Up学习笔记中文 Up 学习 笔记 中文