嵌入式系统是硬件和软件紧密一体化构成的,本文讨论硬件/软件协同验证技术及其工作过程,并探讨何种硬件和软件适用于此类验证,以及要避免什么问题。
传统的嵌入式系统中,设计周期、硬件和软件的开发是分开进行的,并在硬件完成后才将系统集成在一起。嵌入式系统是硬件和软件紧密一体化构成的,所以对初装的硬件和软件常常不能正常工作,我们就不必大惊小怪了。很多情况下,硬件完成后才开始进行实时软件和整体调试。
硬件/软件协同验证是一种在物理原型可用前,能尽早开始调试程序的技术。本文讨论硬件/软件协同验证技术及其工作过程,并探讨何种硬件和软件适用于此类验证,以及要避免什么问题。
协同验证的优点
严格地讲,硬件/软件协同验证是一种验证嵌入式系统中硬件和软件是否正确工作的技术。对于待建的每一个嵌入式系统,在系统研发期间都有一个对硬件和软件一起测试的阶段。当然,要进行这种测试,开销最昂贵的方法是把产品寄给你的客户,让客户去发现问题。现在,绝大部分设计工程师只在硬件被研制完成后才开始进行这种验证测试,研究过程发现问题越早,解决这些问题的成本就越少。硬件/软件协同验证是在硬件这一物理实体创建好之前就开始进行验证的技术(图1)。
或许每个编写嵌入式编码的人都会在他们职业生涯的某一点上编写“短测试编码(stub code)”。短测试编码是一种回送数值或进行一次由硬件执行的操作的功能,这样做以便于在不存在硬件的情况下对软件进行验证。从某些方面讲,这也是一种协同验证,它仅适用于硬件模型相当简单的情况。今天很多商业工具可从大量的主要EDA卖家那里获得,这些工具可令你具备运行“虚拟原型”的能力,使硬件和软件两者的执行环境都结合在一起,这些硬件和软件模拟在建的嵌入式系统的行为,也能为硬件及软件环境提供除错能力。
在探讨硬件/软件协同验证技术的细节问题之前,要弄清楚为什么在嵌入式设计中要采用该技术。较之于其它方法,协同验证技术有可能使软件设计工程师在设计早期着手调试,而采用传统的方法,设计工程师直到硬件设计完成才能进行除错处理。有些软件可在没有硬件支持的情况下完成任务的编码,如不涉及到硬件的算法。与硬件相互作用的编码在获得硬件之前编写,但只有在硬件上运行后,才能真正对编码进行调试。通过采用协同验证技术,可在设计早期开始这一设计调试过程。由于软件的开发通常在系统开发的后段完成,在设计周期中较早的开始调试有可能将使这一项目提早完成,该技术会降低首次将硬件和软件连接在一起时出现意外而致使项目延期完成所造成的风险。
在取得物理原型前,采用协同验证技术对硬件和软件之间的接口进行验证,将使你不会花太多的时间在系统集成实验室里。当你确实拿到原型开始在上面跑软件的时候,你会发现经过测试的软件部分将会正常工作,那么,至少要对所有的编码进行测试,包括执行复位到OS启动或某些板上除错程序,这将确保您在给原型上电的时候不以空白屏幕启动,这会节省项目后期的大量时间及努力。
当然,在协同验证环境中,进行测试的次数越多,你在系统集成实验室里进行测试的次数就会越少。协同验证系统通常会提供一种比采用物理原型所获得的更好的对硬件和软件的可见性。对于集成度很高的SoC和ASIC系统设计,传统的原型调试工具无法调试大部分设计。尽管有除错设备用于这些设计,但这些设计仍受到所能收集到的数据种类的限制,片上缓冲器就受限于所能收集到的数据数量。一部分这些调式设备会改变系统的实时状况,只有当调试监视器关闭时才能发现程序潜在的程序错误,而这些又是一些最难发现的程序错误。采用协同验证技术,你就会完全控制正在被调试的系统以及具有对硬件和软件的完全可见性。另一个优点是系统的软件模型不含有任何制造缺陷,因为当检验物理原型的编码时,你常常会在调试硬件和制造问题时,还要花时间调试编码。
无论什么时候,软件在硬件上运行都不可能发现所有硬件问题。协同验证技术为硬件设计工程师提供了一整套非常现实的激励集,硬件设计工程师将创建出力图使软件对硬件的影响最小化的测试,同时,硬件设计工程师要将这些激励与软件的相关性降低到尽可能小。硬件设计工程师对软件将要执行的任务理解不完全甚至有时是不准确的,理解上的局限性会反映在他们所设计的硬件之中,反映在硬件测试上就是这些测试将无法发现对系统不正确的假定所导致的问题,只有当把真实软件与该硬件连接在一起运行时,才会发现上述问题。不只是硬件设计工程师如此,软件设计工程师对硬件的功能也存在理解上的局限性,在编写测试代码时,测试也同样存在局限性。协同验证系统促进了硬件与软件团队之间的交流,使设计工程师能够根据所要实现的系统功能来测试他们对系统运行过程的理解。
由于这种协同验证是在硬件尚未被确认流片前进行的,如果问题发现硬件有问题,可通过改变硬件设计加以解决,而不是在软件中解决有关硬件的问题。如果硬件是SoC或 ASIC,在原型建好后改变硬件设计的成本很高,项目就可能被迫延误。采用90nm技术的ASIC掩膜造价高达1百万美元,从再次流片开始到获得新样品可能花两个月的时间,这就是说第一时间确保硬件合格至关重要。有时,ASIC内的一些问题可通过在软件内执行某个固件加以解决,但这种做法通常会导致嵌入式系统的性能下降。
协同验证工具的某些配置可提供整个嵌入式系统的精确定时模型,在这种情况下,可使用系统仿真来验证性能。如果你能测试软件关键部分的性能并确保这些性能符合系统要求,那么就能够检测到在各种中断服务程序所花的时间长短,并验证系统的吞吐量及响应时间,这些数据可用于确定系统的瓶颈所在。
采用协同验证技术使得设计小组有能力改进系统的整体设计。在硬件尚未流片之前,改变硬件设计是有可能的,但这种设计变更有时比较困难,特别是在项目后期,改变设计可能因为过于复杂而无法实现。与其如此,不如在可能的情况下,让设计小组提供更好的设计。获得系统的精确定时模型,就可开发系统的性能并加以完善。例如可采用大小不同的高速缓冲存储器测量系统性能,而通过物理原型却不能完成这一类型的设计开发和优化。
硬件/软件协同验证
协同验证系统由一个硬件执行环境和一个软件执行环境组成,有一些机制用于通过事件和命令,并在这两个环境间进行控制。通常在硬件和软件之间有某种类型的除错和控制界面。软件通过一系列由处理器启动的总线周期与硬件的交互作用,绝大部分总线周期与硬件没有相关性。通常协同验证系统能识别哪个总线周期与硬件具有相关性,哪些不具相关性。由于通过协同验证工具,在硬件和软件之间的界面通常有一些开销,屏蔽或隐藏硬件不需要的事件将会改进整体性能。
软件的执行环境用于产生总线周期的序列,只要软件执行需要捕获的事件,协同验证工具把这些事件传递到硬件环境中,在这一环境中这些事件从总线周期转换到许多信号事件集。协同验证工具需要驱动这些信号事件进入硬件执行环境,然后为总线周期响应进行硬件环境取样,这一响应又被传送回软件环境。必须保持硬件及软件环境间的同步以便硬件或软件环境都可发现由于错失响应而导致有误的情形(图2)。
硬件和软件建模
硬件和软件建模和执行的方式有若干种,下面将探讨每一种技术的折衷。尽管特定的验证需要确定应采用何种技术,你应力求使用作为嵌入式系统的一部分而开发的组件,而不要编写新组件。开发仅用于验证系统的新硬件或软件组件的效率低下而且方向是错误的。
硬件/软件协同验证系统中的硬件可以几种方式进行建模(图3),绝大部分验证系统至少有一种建模方法,许多通用的硬件可通过如下方式建模:1.采用FPGA原型或模拟系统;2. 采用HDL(硬件描述语言)及逻辑仿真器;3. 采用类似高级程序语言C或Java的HDL预言编写的行为模型;4. 采用UML之类的建模语言。软件也可通过几种方式执行:1. 采用ISS(指令集仿真器)在物理CPU上运行;2.通过编译在运行仿真程序的主机上运行。
以协同验证技术对硬件进行建模的方法之一在FPGA上运行硬件。有各种商业系统将FPGA和称为模拟器的原型设计系统内的可编程互连集成在一起。模拟器可以用于1-2个FPGA无法容纳的较大系统的设计。对FPGA中的硬件建模能够生成非常精确及快速的表述。硬件除错可见性受到一定的限制,尤其是不采用商用模拟系统的时候。设定特定硬件事件的断点或观察任意信号是困难的,商用模拟系统成本很高,耗资超过一百万美元。以这种方式对硬件建模要求硬件在FPGA上设计或在模拟系统上进行设计,对于复杂而庞大的设计而言,这种方式要花费很大的努力。这种方法要求对设计中涉及的所有元件,包括板级元器件建立RTL(寄存器传输级)描述。用FPGA原型实现的设计并不能总以实时速度运行,这就是说FPGA原型不能总能被挂在物理器件上用于产生输入/输出。
另一种硬件建模的方法是利用HDL语言编写RTL描述,这种描述可在逻辑仿真器中运行。现在所使用的最流行的HDL语言是VHDL和Verilog。硬件的HDL描述提供了一种精确到时钟周期的模型,对延迟的建模可以精确到几分之一纳秒。如果硬件设计是一种ASIC或复杂的FPGA,,硬件小组已在设计过程中创建HDL描述,那么就没有必要用这种方法建模。然而,工程师或许只是正在给ASIC 或FPGA建模,这就要创建外围设备的模型,以便软件正确运行。与实时运行相比,硬件的HDL描述运行速度很慢。
对硬件设计建模的最后一个方法是采用行为模型。这种方法比RTL模型更抽象,因而运行的更快,模型的创建很容易。如果模型以程序语言编写,就很容易也很自然地被链接到在主处理器中执行的嵌入式应用上。然而,由于这种方法更为抽象,不可能有精确的时钟周期。现在,这些抽象模型不再作为硬件设计过程一部分加以创建,有时作为系统级设计过程的一部分进行创建。我们无法确知这种模型是否与正在执行的硬件行为相匹配,其价值在于用软件验证哪些硬件模型与真实设计不匹配。你可能可以证实:具有这种抽象模型的软件能够工作只是为了发现在真实设计中它不能工作。这种方法对小型、简单或者设计中的一部分建模很管用。对于大型及复杂的设计,这种方法值得商榷。
一些硬件设计工程师已开始采用程序语言抽象地描述硬件,并采用行为综合来创建硬件实现的RTL描述。System C和 System Verilog两种语言能够储存大量重要信息。原始的HDL语言并没有C语言那样的软件编程语言的高级架构。尽管在更抽象层次运行硬件的仿真会得到更好的性能,但今天一般是无法知道抽象仿真结果是否与要实现的硬件相匹配。由于在RTL和行为模型之间出现了行为综合和形式验证,这些抽象模型的正确性得到证明,因而是一种有效的建模方法。此前针对这类模型进行大量的验证,即使最好的情况下其结果仍令人质疑。
创建硬件模型要理解硬件,否则此后的软件小组就会面对大量问题。如早先所提到的,软件小组有关硬件的假定会对软件的设计构成影响,如果这些假定是错误的,将会在协同验证中发现。如果硬件模型由软件设计小组创建,最终正确或不正确的假设都将对硬件及软件的模型构成影响。在这种情况下,软件未经硬件设计工程师从系统角度进行的确认,意见分歧可能导致大量接口问题。为了将协同验证的益处最大化,我们就必须确保设计模式与硬件设计小组的设计成果相一致。
执行软件的方法
可用于执行软件的方法之一称为ISS(指令设置仿真器)。ISS是一种仿真CPU行为的程序,操作于正在运行的程序的可执行镜像上。由于它通过目标编码操作,该程序可用于所有正在运行的包括第三方库在内的没有源代码的模块。如果ISS包含与处理器的内置高速缓冲存储器、管线结构和写入缓冲器的详细资料,ISS可能提供软件执行的时钟周期精细模型。由于包括这些详细资料,ISS的性能会变差,但仿真的精确性增加了。可对ISS编程以收集其中断程序的总线周期信息。ISS的不足之处在于其运行速度远比实时慢得多。
执行软件的另一种方法是对它进行编译,以使其在运行中仿真的主机上运行。采用这种方法提供一种更快的模型-常常比正在运行的目标系统还要快。然而,只有当你具有所有的软件源,并且该种方法是以一种存在于主机中的编译器的语言编写时才是可行的,它通常不包括汇编语言。
执行软件的最后一个方法是采用实际处理器,这种方法需要有一个支持板或硬件来运行芯片并提供除错及控制的设备。如果硬件可攫取到这一信息,这种运行软件的方法将精确到十亿分之一秒,它将以接近实时的速度非常快速的运行。这种方法唯一的重要缺陷是设计支持硬件很困难,成本很高,该硬件要运行CPU能与逻辑仿真接口连接。在这个领域,商用解决方案一直就很少。
目前,ISS和RTL HDL描述相结合在协同验证中获得了广泛的应用,这种结合采用设计过程中创建的一部分元件,不需要另外创建和维护用于验证的仿真模型,从而使得硬件及软件设计工程师可使用与他们目前正用于设计过程的相同的工具,从而可以利用现有的经验。当硬件设计工程师开始创建并使用更抽象的硬件模型,并且硬件设计流程支持这种类型的设计时,如果他们知道与在建的硬件相匹配,它们即可用于协同验证。
作者: Russell Klein
Mentor Graphics公司