新闻中心

EEPW首页 > EDA/PCB > 设计应用 > SoC系统描述与SystemC

SoC系统描述与SystemC

作者:■ 东北微电子研究所 苏舟时间:2005-05-06来源:电子设计应用收藏

摘    要:随着VLSI工艺技术的发展,为了缩短开发周期,提高设计的可预见性,设计已经成为迫切需求。本文将比较C++、VHDL和,说明是一种非常好的系统描述语言。同时利用C++和VHDL的语法来深入介绍的语法。

引言
在早期的集成电路设计过程中,由于低抽象层次的设计问题比高抽象层次的设计问题手工处理更难,这迫使研究者首先把注意力集中到低层次设计问题上。例如:电路仿真、布局、布线和布局规划。随着低层次设计问题变得易于处理,逻辑仿真与综合取得了成功的发展,并引进到设计过程中。随着现代系统复杂性的日益增加和紧迫的上市时间的压力,特别是技术的发展,利用上面的工具和设计方法已遇到了巨大的挑战。工业界和学术界开始把注意力集中到系统设计。因为在系统级可以大大减少设计者需要考虑的对象的数目,这样就可以在短时间内完成复杂系统的设计。
用自然语言来描述一个系统,通常是模糊和不完备的,缺乏详细说明任务的能力。因此,设计者需要用一些精确的语言来描述系统的功能。随着与有关的设计复杂性的增加,设计者非常渴望有一个可执行的系统描述语言,能在综合执行之前就能表示和验证系统的中间实现。但是目前出现的很多语言都不能作为系统描述语言,因为每一种语言只能描述系统的一部分特性,不具备描述全部系统特性的能力。本文介绍的系统描述语言SystemC则较好地解决了上述问题。

系统特性
随着功能需求的增加,现在的系统越来越复杂,并且具有许多特性。
并发性:任何系统都可分解成许多称为行为的功能块。每一个功能块通常可以用进程、子程序或状态机的形式来描述。大部分情况下,系统的功能都能很容易地概述成并发行为的集合。因为用顺序结构来描述将产生复杂的、难于理解的描述。
层次性:在面对大的系统时,一个突出的问题就是系统太复杂而不能以整体来考虑。在这种情况下,人们只能以层次模型来分析。首先,层次模型允许系统概述成更小子系统的集合。这种分解系统的建模方式可以大大简化系统的开发。而且,一旦得到了系统的概念概述,层次模型将大大促进设计者对系统功能的理解。
时序:在系统说明中必须详细说明时序关系。当一个部件在指定的时间范围收到或产生一个事件时,必须能以实际的时间单位来测量。协议通常可用时序图表来表示。时序信息对实时系统非常重要,它的性能通常根据实现满足时序限制的程度来度量。
通信:系统由一些相互作用的行为组成。这些行为必须与它们相互协作的行为进行通信。这样一个通信模型对系统描述是必需的。
进程同步:在一个可以概述为一些并发进程的系统中,进程很少完全与其它进程相互独立。每个进程通常产生被其它进程考虑的数据和事件。当进程需要交换数据或者当某个操作同时要被不同的进程执行时,必须采取某种方式来使进程同步。
当然,现代系统还有许多特性,如异常处理、行为完备性、编程结构等。
传统语言的缺陷
传统的C++语言是顺序语言,不能处理硬件系统固有的并发性。它也缺少时间概念,不能描述时间顺序,但是硬件系统必须以时间顺序来进行操作。同时它缺少硬件类型的通信,缺少重启机制,不支持各种硬件数据类型:例如Bit类型、多值逻辑类型、定点数据类型等。
传统的VHDL语言是专用的硬件描述语言,缺少描述各种机制的支持,因此不能作为系统描述语言。
怎样才能得到系统描述语言呢?目前有两种方案,一种方案是以硬件描述语言为基础,增加类C语言的结构来描述系统,如ICL Design Automation的VHDL+、Co-Design的Superlog;另一种方案是以软件语言C++为基础,增加对硬件特性的描述类库,如Synopsys、Co-Ware等提出的SystemC语言。SystemC采用了源码公开的形式,得到了很多设计公司和用户的支持。

SystemC语言
SystemC使用C++面向对象的编程特点, 在没有对C++增加新的语言构件的基础上,利用类的概念对C++进行了扩充,加入了一个类库和仿真核,用以支持硬件的建模和仿真概念。设计者能利用它有效地创建软件算法、硬件结构、SoC接口和系统设计模型。可以用SystemC和标准的C++开发工具来创建一个系统级模型,通过快速地仿真来验证和优化设计,探索各种各样的算法,并且提供给软硬件开发队伍一个可执行的系统说明。一个可执行的说明本质上是一个C++程序,能展示与系统相同的行为。
SystemC支持协同设计和由软硬件部件组成的复杂系统的结构描述。在C++环境中,它支持软件、硬件和接口描述。
模块
模块是SystemC中用来划分设计的基本块。模块允许设计者把复杂的系统划分成更小的、可以管理的块。模块能在一个设计队伍中划分复杂的系统,允许设计者隐藏内部数据和算法,迫使设计者采用公开接口与其它模块进行通信,并且整个系统更容易测试和维护。
模块用SystemC的关键字:SC_MODULE来声明。
SC_MODULE(transmit)
{......}
这个模块的名字为transmit。一个模块可以包含端口(Ports)、局部信号(Local Signals)、局部数据(Local Data)、其它模块、进程(Processes)和构造函数(Constructors)。这些元素实现了模块要求的功能。
模块的端口用来传递模块进程的数据。端口的模式有:sc_in、sc_out、sc_inout。端口的数据类型可以是C++的数据类型、SystemC的数据类型或者用户定义的数据类型。端口的模式已经预定义在SystemC的类库中。
SystemC的模块对应C++语言的类。模块中的端口、局部信号、局部数据、其它模块对应C++类的成员变量,模块中的进程对应类的成员函数。
SystemC的模块也对应VHDL中的设计实体。模块的端口、局部信号、局部数据部分对应实体说明。端口模式对应实体说明部分中的类属和端口说明。模块的进程对应设计实体的结构体。
进程
进程是SystemC中基本的运行单元,调用进程可以仿真目标设备或系统的行为。SystemC的进程有三种类型可以使用:method process、thread process、clocked thread process。有些进程的行为与函数相似,进程调用时开始运行,完成之后把结果返回到调用机制。其它的进程仅仅在仿真开始时调用一次,然后或者运行,或者挂起,等待一个条件变成真。进程不是层次的,因此进程不能直接调用其它进程,进程可以调用不是进程的方法或函数。
进程有敏感列表,也就是能激活进程的信号列表。一个进程被触发,进程的列表肯定有事件发生。
方法进程(Method Process):当一个进程的敏感信号上发生事件时,进程就要被执行。一个方法执行并且把控制返回到仿真核中。方法进程不能被挂起或包含无穷循环,当一个方法进程被激活,它将一直执行直到结束。
线程(Thread process):它能被挂起或重新激活,包含wait()函数。一个时间将重新激活线程,从上次挂起时的语句开始,继续执行直到下一个wait()函数。敏感列表是在模块的构造函数中说明。线程是最一般的进程,几乎可以用来建模一切事物。一个方法进程用来建模同样的设计,但要求更多的语句,并且难于理解和维护。
线程是作为co-routines来实现的。这种实现比方法进程慢。如果提高仿真速度是当前的主要目的,那么应该限制线程的使用,而去维护最高的仿真速度。
时钟线程(Clocked thread process):它是线程中的一个特殊情形,它能更好地综合结果,帮助设计者描述他们的设计。时钟线程仅仅能被一个时钟的边沿所触发,这与硬件用综合工具实现的方式匹配。时钟线程能用来创建隐式状态机。这种设计所以创建的形式简单且容易理解。一个显式状态机将在声明中定义状态机,并且用case语句从一个状态移到另一个状态。
时钟线程与线程在许多方面不同。首先,时钟线程说明了一个时钟对象,它不能与其它进程一样有分开的敏感列表。敏感列表仅仅是特定的时钟边沿。无论什么时候到达了特定的时钟边沿,时钟线程都会被激活。
Wait Until
在一个时钟线程中,wait until()能用来控制进程的执行。wait until()将停止进程的执行,直到一个特定的事件发生。这个特定的事件是被wait until()的表达式所指定的。wait until()函数仅仅与sc_signal<bool>类型的表达式一起工作。
Watching
线程与时钟线程中有无穷循环。一个典型设计需要某些方式来初始化循环行为,或者当某个条件发生时跳出循环。这些通过watching construct的使用来完成。watching construct将监控一个特定的条件。当这个条件发生时,控制从当前的执行点转移到进程的开始点。那里需要处理watched condition,被watch的对象必须是布尔类型。
Local Watching允许精确地说明进程的哪一个部分正观察哪一个信号和事件处理者所定位的位置。它的功能用四个特定的宏来定义。
W_BEGIN        // put the watching declarations here.
      watching (......);
      watching (......);
W_DO           // This is where the process functionality goes.
      ..................;
W_ESCAPE      // This is where the handler for the watched events go.
      if (...)  {.............};
W_END
W_BEGIN宏标记Local watching块的开始。在W_BEGIN与W_DO宏之间放所有的watching声明。这些声明与全局watching事件看起来一样。在W_DO与W_ESCAPE之间放入进程的功能,只要没有watching事件发生,就会执行这些代码。在W_ESCAPE与W_END之间放事件处理者。事件处理者将确保相关事件已发生,然后去执行这个事件的必要行动。W_END结束local watching块。
对于local watching,下面的情形需要注意:
在声明块中,所有事件有相同的优先级。如果需要不同的优先级,Local watching块将需要被嵌套(nested)。
Local watching仅仅在时钟线程中工作。
在watching表达式中的信号仅仅在进程的活动边沿取样。在时钟线程中,这仅仅意味着进程敏感块什么时候改变。全局watched事件比局部watched 事件有更高的优先级。
时钟(Clocks)
时钟对象是SystemC中的特别对象,它产生时间信号,用来同步仿真中的事件。时钟按时间顺序排列,以致硬件上并行的时间能在顺序计算机上适当地被仿真器建模。时钟对象有许多数据成员来存储时钟环境和执行时钟动作的方法。
举个例子:sc_clock  clock1(“clock1”,20,0.5,2,true)。这个声明将创建一个名字为clock1的时钟对象,它的周期为20个时间单位,占空比为50%,第一条时钟边沿在第二个时间单位,第一个值为真。除了时钟的名字,所有的变量都有缺省值:周期为1,占空比为0.5,第一条时钟边沿为0,第一个值为真。
事件(Events)
事件类型sc_event是SystemC中基本的同步对象。一个进程能通知一个事件,也就是说导致一个事件发生,以致所有等待这个事件的进程将被激活。一个事件对象通常在模块中声明,并且被模块中的进程使用。为了实现模块重用,通过模块的端口,应该总是能访问一个外部时间对象。
sc_event类型提供下列功能:
构造函数:sc_event  mu_event。
通知:my_event.notify(0);sc_time  t(10,sc_ps);my_event.notify(t)。
Wait()方法
wait()函数接收它等待的事件参数列表,能有多个wait()语句。它们有不同的参数。这意味着进程的敏感性能可以动态地改变。wait()方法能在线程执行的任何地方被调用。当它被调用时,指定的事件临时覆盖线程的静态敏感列表。当一个或所有的时间被通知时,等待的线程被重新开始,调用的线程再一次对静态敏感列表敏感。当wait()没有参数时,这与以前一样:当事件发生在线程的静态敏感列表上时,wait()被激醒。
主从通信库
主从通信库的目标是利用主从总线通信协议的系统。由一个或多个CPU核、DSP、外围设备和通过总线集进行通信的定制组成的系统特别适合这个库。这个库提供了一个从功能级可执行说明到RTL级的路径,并且可以使用通信综合的界面综合工具。这个库介绍了一个顺序执行和进程之间的通信协议。这非常好地适合顺序软件-软件通信的抽象功能级建模、硬件-软件的界面和硬件-硬件的界面。
利用这个库,复杂的系统模型能被建模。作为一个顺序通信功能块的相互连接体,它允许快速模型开发、软硬件划分的权衡分析和资源分配决定。在设计过程的后期,功能通信被精炼到循环精确总线协议通信,然后通过在块内的功能行为通信,到循环精确可综合的形式。这个模型的一个重要特性是:功能级抽象通信能被精炼到循环精确总线协议通信,而保持顺序通信和功能级的执行顺序。这个特性是界面综合工具的一个关键因素。这个库也允许把模块的通信从它的内部行为分开到一个大的程序,当然完全的分开是不可能的。

结语
系统描述是一个非常复杂的过程。为了能有效地描述一个系统,合适的系统描述语言是必不可少的。SystemC利用流行的C++编译器,通过扩展类库的方法,实现了硬件的高级语言描述。利用流行的C++编译器,保证SystemC在语法上完全兼容标准C++,为系统开发者提供了统一的开发平台。扩展类库是SystemC的核心。它实现了硬件描述的并发性和模块化的本质特点。通过使用面向对象的方法,可以方便地实现硬件的描述和IP核的复用。随着芯片系统规模日益扩大,软件工程的思想日益渗透到芯片的设计过程中,使用成熟的软件工程方法,可以有力地支持芯片系统的设计。采用高级语言的芯片系统设计,将是未来的发展方向。■



关键词: SystemC SoC ASIC

评论


相关推荐

技术专区

关闭