>
摘要:系统级建模是大规模集成电路设计的一个重要阶段,它实现了设计从文本规范向功能实现的过渡,传统方法中一直使用硬件描述语言(HDL) 来完成系统级建模,其弊端在于建模的效率低不适应如今SoC 设计的要求。SystemC 作为一种基于C+ + 语言的新型硬件设计语言较已有的HDL 语言在系统级建模、软硬件协调设计方面更具优势,因此也更适用于SoC 的设计建模,该文介绍了SystemC 的最新版本SystemC2. 0 的使用特点以及如何利用其进行SoC 顶层设计的方法,并通过对一个短消息平台的建模实例说明如何具体使用SystemC2. 0 ,通过与传统方法的比较可以得出结论,SystemC 可以迅速有效地实现SoC系统级的建模。
关键词:集成电路;片上系统;协同建模;硬件描述语言
引言
近年来,集成电路的设计规模随着半导体工艺的不断进步而变得越来越大,片上系统(System on Chip ,SoC) 的时代已经到来,SoC 的设计思想被越来越多的设计者(designer) 所接受。
然而,随着设计规模的增加,传统的使用硬件描述语言(HDL) 建模的方法突显出其效率低、调试和仿真时间长等缺点,如何有效进行系统建模和验证开始成为广大设计人员注重的焦点。一般的系统设计中,常采用C/ C + + 等高级编程语言来建立系统模型,但是,由于这些高级语言本身不与硬件描述语言(HDL) 兼容,同时无法有效表述一些硬件系统特有的数据类型和时序信息,因此这种设计方法也不适于完成硬件系统的建模需求。
SystemC是一种新型系统建模语言,其产生目的是为系统级设计提供一种单一的语言,提供一个公共平台来更好的进行软硬件协同设计和验证。自从1999 年的9 月SystemC的0. 9 版本推出以来,作为一种基于C + + 语言的硬件设计语言,SystemC 凭借其高效、便捷的特性得以迅速推广,业界的舰旗公司均对SystemC 进行支持,这也就不难理解,为什么2003 年的年初ARM公司推出了ABMA 的SystemC模型。
SystemC 的设计流程
传统设计流程
传统的设计流程如图1 所示,其中“代码转换”的过程是人工完成的。传统的设计流程存在着下列问题:
1) 在对系统模型建立使用的语言到HDL 人工转换中,容易出现错误。
2) 系统模型与HDL 模块的彼此独立,会造成设计修改的不同步行为。当完成从系统模型到HDL 模块的转换,HDL
模块成为设计修改的重点,这时原有的系统模型的维护与修改往往会被忽略。
3) 由于系统模型使用的语言与HDL 语言不兼容,所以针对系统模型使用的测试集也需要重新转换,进而需要将原来完成的系统环境重新转换成为HDL 环境。
图1 所示的设计流程是SoC 设计中被普遍使用的,之所以使用C 等高级语言参与顶层建模设计,是因为用C 等高级语言建立的模型可以在算法级上首先对模块进行设计,同时验证模块的正确性,这不仅有利于此后开始的硬件描述语言的编程工作的理解与验证,同时为进行与硬件相关的软件设计工作提供了可以依据的环境。此外,C 模型还具有仿真速度快,便于修改调试等优点。各大EDA 供应商对于Verilog仿真器增加了PLI (Programming Language Interface) 功能,对于VHDL 增加了FLI(Foreign Language Interface) 功能,这些举措为C等高级语言进入顶层设计环节提供了方便之门。使用C语言进行抽象设计,然后使用PLI 或FLI 为设计好的C 模型进行“打包”(wrap) , 使设计的C 模型作为一个功能函数(Function) 引入已有的HDL 的设计中,从而可以与HDL 模块共同仿真。
SystemC的设计流程
图2 所示的是SystemC 的设计流程,显然, SystemC 所希望的设计流程可以避免从C 等系统建模使用的高级语言到HDL 代码的转换过程,这样,由于使用单一的设计语言,系统的修改与优化效果都会得到提高。但在目前,这种使用SystemC实现前端一体化的无缝设计还不能做到, 尽管出现了SystemC的综合工具(如Synopsys 的CoCentric) ,但是由于这方面的技术尚不完善,所以SystemC还无法真正做到省去“代码转换”这一步。很多EDA 供应商在致力于相关产品的开发,而且取得了长足的进步,相信在不久之后,如图2 所示的实现前端无缝设计就会实现。简单来说,SystemC语言具有以下特点:
●SystemC是基于C + + 库开发的,因此在系统设计时可以兼容C/ C + + 算法。
●SystemC在C/ C + + 的基础上扩展了可用于硬件设计的基本功能。比如具有并行性过程语句、可描述时间的时钟、硬件的数据类型等等。
●SystemC有一个精简的仿真内核,可实现系统级和电路级设计的融合,因此也可以实现系统的软硬件协同设计。
●SystemC是开放性的,可以从SystemC 的官方网站下载最新的版本。
当然,SystemC也有不足,比如目前SystemC 对于模拟和射频系统的设计还不是很有效,这是SystemC 需要进一步改进的方面。
SystemC2. 0 中的通道
在SystemC2. 0 较SystemC1. 0 新增的特性中,除了对SystemC1. 0 原有的一些功能指令的增强之外,SystemC2. 0 更便于实现系统建模是其最重要的方面,其中自行通道(channel) 设计的提出不仅为SoC 设计提供了极大的灵活性,也是SystemC2. 0 实现系统建模的关键技术。
与通道概念紧密相关的还有界面( interface) 和端口(ports) ,可以说,这三者的合理使用就构成了SystemC 的设计。
所谓界面(interface) ,就是通道可以实现的方法的集合。以读写界面为例来说明界面的声明,其方法如下。
class read if :virtual public sc inerface
{
public :
virtual void read(char &) = 0 ;
} ;
class write if :virtual public sc interface
{
public :
virtua void write(char) = 0 ;
virtual void reset () = 0 ;
} ;
界面的使用是为了声明将要实现的功能,但在界面声明中并不具体实现这些功能,从上面的实例中也能看出,界面中只包括纯虚函数。
界面声明的函数由通道具体实现,也就是说,通道是对界面的一个具体实现,通道的实现方法如下:
class channel :public sc channel ,public write if ,public read if
{
public :
void writ (char c) {
write 函数的具体实现过程
}
void read(char &c) {
read 函数的具体实现过程
}
void read() {
write 函数的具体实现过程
}
} ;
当界面与通道都声明完毕,就可以使用端口来调用声明好的界面了,以上面声明的界面和通道为例,其声明如下:
class gen :public sc module
{
public :
sc port
SC HAS PROCESS(gen) ;
gen(sc module name name) :sc module (name)
{
SC THREAD(excute) ;
}
} ;
这里声明了一个新的函数gen ,它调用了界面write if 。对于新函数gen 来说,当它声明了调用界面write if ,同时意味着将使用通道中声明的关于write if 的函数write ( ) 。可见,这样的声明方法具有层次分明,修改简单的特点,同时借助C + + 的继承方法,可以不断为已有的类型或函数增加新的功能。
下面将通过对一个消息发送、传送和接收平台的设计来具体说明使用SystemC2. 0 建模的方法。
消息发送和接收平台
消息发送和接收平台包括一个消息产生器,一个消息接收器,以及一系列的消息传送器用来对消息进行传播。消息发生器用来产生消息,消息经由传送器,最终送达消息接收器。显然,消息发生器,消息传送器,消息接收器彼此之间需要相互通讯来完成这一过程。根据上面的描述,可以得到消息发送、接收平台的设计示意图,见图3。
该消息发送和接受平台的一个简单目的就是,从消息产生器发出十进制的整数,经由消息传送器转成二进制数,最终送达消息接收器。
由图3 可以看到,各个模块之间的界面包括发送和接收两种,因此有两个基本界面声明,一个是发送界面“send if .h”,一个是接收界面“receive if . h”。发送界面和接收界面的代码描述如下:
/ / send if . h
# include < systenc. h >
template < class I >
class send if :virtual public sc interface
{
public :
virtual void send( I) - 0 ;
virtual bool probe() - 0 ;
virtual void reset () - 0 ;
} ;
/ / recive if . h
# include < systemc. h >
template < class I >
class receive if :virtual public sc interface
{
public :
virtual void receive( I &) - 0 ;
virtual bool probe() - 0 ;
} ;
为了完成界面之间的通讯,需要建立通道文件“channel.h”和“channel. cpp”具体实现界面要实现的功能。由于“channel. h”和“channel. cpp”程序较大,这里只给出其设计的基本内容。
/ / channel. h
# include < systenc. h >
# include“send if . h”
# include“receive if . h”
template < class I >
class channel :
public sc channel ,
public send if < I > ,
public receive if < I >
{
public :
声明界面的功能函数
sc HAS PROCESS(channel) ;
channel (sc module name name) :sc channel (name)
{
channel 的构造函数
}
} ;
除界面和通道文件之外,还需为消息产生器和接收器建立文件,与上面的文件实现相似,可以设计消息产生器和接收器模块。为了不失一般性,这里使用3 个消息传送器来完成消息的传送过程。上述所有文件就是构成了整个设计的基本设计单元。
该设计的过程是这样的,首先完成界面和通道的设计,产生基本的类,利用这些新生成的类,设计完成消息产生器,消息传送器和消息接收器。最后,将生成的各个单元模块整合成为一个顶层模块,进行仿真,其设计流程如图4 所示。
仿真结果
为了便于设计人员检查结果,SystemC提供了sc createvcd trace file 函数来生成vcd 波形文件的函数,这对于仿真结果的查看非常方便。
使用SystemC生成的波形函数可以与后期使用HDL 语言编写的仿真模型生成的波形比较,进而判断后期实现的结果是否与系统建模的要求一致,这种方法对于实际的集成电路设计十分必要。
图5 所示就是使用Modelsim 波形观察器打开的该消息平台的SystemC仿真波形结果。
结论
本文介绍使用SystemC2. 0 进行SoC 设计建模的方法,并使用SystemC建模的方法对一个消息发送、传送和接收平台进行了设计和仿真。通过这个消息平台的建模可以得出这样的结论,SystemC2. 0 在SoC 设计的建模过程中具有高效,快速,准确的特点,是今后SoC 建模设计的发展方向。