如何在硅芯片制作完成前进行软件开发
扫描二维码
随时随地手机看文章
片上系统(SoC)开发不再仅仅是简单的硅芯片开发过程。现代设备大量使用了各种软件,包括软件栈、中间件、启动代码和驱动程序。你大可悠然自若地等到硅芯片开发完成后,再将其放在电路板上开始进行软件的开发。然而在激烈的市场竞争中,时间就是生命。开发进度日益紧迫,若能在硅芯片制作完成前便着手进行软件开发,将成为一个巨大的竞争优势。要做到这一点,需要满足以下三个要求:首先,需要一套可供寄存器传输级(RTL)设计高速运行、且在硅芯片或开发板准备就绪前就能在上面正常运行软件的仿真系统;此外,还需要一个高速、基于事务的协同建模通道将仿真器与基于工作站的软件调试工具进行连接;最后,还需要提供符合软件开发者需求的软件调试环境。
为一种硬件还没有成型的产品开发软件时,首先需要一个能运行代码的环境。通常有两种选择:物理环境或虚拟环境。大多数项目都是基于某个现有设计,即在原有版本中添加某些功能,使原有版本功能更强、速度更快、性能更好。这种情况下,有可能从接手项目的原有设计版本中直接获取现成的电路板,或者能取得该电路板的软件环境以进行软件开发,用自己的调试环境来对其进行验证。到目前为止,最简单的做法就是在现成的电路板上运行。如果是开发一个全新的软件,你可以使用一块开发板,运气好的话,或许还能找到类似的开发板。还有一种可行的方法,即在一个虚拟电路板上运行,如虚拟机(QEMU)。QEMU是一个开源系统仿真器,可随意模拟各种ARM板。ARM公司也提供一个虚拟平台,称作“基础模型”(可在其网站上免费获得),类似于QEMU,可运行ARM代码。二者都有引入调试器的工具。
图1:Mentor公司验证平台将先进的仿真器解决方案、硬件加速器平台以及强大的调试环境整合在一个全球共享的高性能数据处理中心资源里。
有了可运行和调试代码的环境,就可以开始编程了。某些情况下,你将需要访问一些还未成型的全新外围设备,应对此问题的一个解决方案是创建一个模型。我们先从一个非常简单的例子入手:读取这个新外围设备的ID寄存器。许多外围设备都有ID寄存器,这是一个只读寄存器,读取时返回固定的已知数值。这就好像让驱动程序多了些许自信,让其意识到设备在与正确的外围设备通信。很早以前,在驱动程序初始化时,读取寄存器并将其与预期进行比较就是一件较为敏感的事情。以下是一个ARM pl011串口驱动程序的例子:
图2:校验一个新外围设备的ID寄存器
驱动程序代码使用宏readl和writel对寄存器进行读写。这些在linux内核中定义的驱动程序被作为一种访问硬件的方式。但假如启动了一个新的驱动程序,你就可以在本地进行重新定义,以得到所需的响应。例如:
你无需访问实际硬件,便能开始进行软件开发。当然,你也可以采取极端的做法,使用这种方法来建模一个完整的外围设备,但无论如何请不要尝试最简单的外围设备,因为那样很容易产生故障。一旦出现握手失败而采样仍然在进行,系统可能会丢失某些返回值。
假如处于虚拟环境,如QEMU或ARM快速模型(AFM)—基础模型的付费版本,你可以引进更加复杂的模型。AFM连接了System-C,相比于存根代码(stub-code),这是一种更适宜于建模硬件行为的环境。QEMU也可以扩展模型,但经验不是凭空而来的,需要经过多次实践。与许多开源项目一样,代码即是文档。若使用了QEMU,但又不想在一团糟的C代码中苦苦挣扎并尝试理出头绪,那么一旦你需要超越存根代码,你可能想要跳过这个阶段。
很多情况下,无法使用存根代码进行验证,甚至连你为软件运行所创建的更复杂的System-C模型也无能为力。例如,你无从得知硬件团队和软件团队在设备中使用的是否为同一个寄存器映射。通过一个不会做出任何意料之外的反应的寄存器,你根本无从验证其设置是否正确。如果你同时编写驱动程序和相应的外围设备模型,那么也只能证明你对二者的理解是相吻合的。
虚拟样机系统,如Mentor Graphics的Vista,可用于创建你所需的更复杂化的模型。一般情况下,这些模型的处理速度非常快,软件运行也很顺畅。如果硬件团队创建了虚拟样机模型,那么在该模型上运行软件时,便能验证软硬件团队的设计观点是否相符。通常情况下,二者的设计观点是存在差异的。若能尽早发现这些差异,则在设计周期的后期可避免不少麻烦,让你不至于抓狂。在一个软硬件都很容易调试的工具中,要实现这一点其实并不难。
虚拟样机有一个你所开发的软件外围设备的完整功能模型。你将能以创建终极目标系统同样的方式来创建自己的软件,还能访问外设的寄存器,就像在真实的硬件上运行一样。此外,通过虚拟样机可以直接查看这些外设寄存器,在无任何干扰的情况下,调试过程变得更容易。你将能充分地编写驱动程序并验证其运行是否正常。你甚至还可以粗略计算出总共所需要的时间。然而,精确的验证时间的计算,还需等到与硬件更匹配的软件问世。
需要记住的是,虚拟样机并不是真正的硬件,而只是一个模型。模型(以程序的形式)需要由设计师来编写,但设计师所编写的程序偶尔会出现错误。还需要注意的是,硬件在一个很抽象的层面上建模,这可以引发实际硬件的微妙、却又至关重要的差异。因此,即使驱动程序完全验证了虚拟样机,你的工作仍然没有结束,还需要在更详细的硬件环境中进行验证。
硬件团队已经创建了可执行的硬件模型,作为正常开发周期的一部分。他们在寄存器传输级(RTL)使用一种硬件描述语言(HDL)来描述自己的设计。最终,通过一系列运行编译器和分析器来运行该设计的HDL描述,创建掩模组以用于制造硅芯片。HDL可在仿真软件上运行,并提供待生产硬件的时钟周期的准确运行状态。唯一的问题是,大部分以HDL描述的实体设计模拟器只能以几十或几百赫兹的频率运行,无法达到兆赫,甚至连千赫都很困难,对于软件程序员来说,这种频率低得几乎毫无用处。同样的HDL可用于编写可编程逻辑器(FPGA)或硬件加速器,如Mentor Graphics的Veloce.FPGA和硬件加速器可实现HDL所描述的行为,但它们的运行速度是兆赫级的。对于软件工程师来说,这一速度仍然不够,但是至少是可用的。
一旦你已经使用了存根代码和虚拟样机的全部功能,假如有一个是可用的,那么下一步就是在一个更加精确的硬件模型上验证你编写的代码,具体来说,就是RTL.开始这一步骤的最佳方法是将虚拟机(QEMU或AFM)与硬件的RTL模型结合起来,在软降仿真器或硬件加速器中运行。Mentor Graphics的产品Warpcore使这种方法成为可能。它将虚拟机与RTL执行环境进行了结合,仅在RTL被访问时才运行RTL仿真器。将虚拟机与仿真环境相结合,以几百赫兹的频率运行,看似疯狂,但是在不过度运行硬件的情况下,这种做法是可行的。如果硬件只运行一百万个时钟左右,执行效果会很好。通常情况下,仿真器更易于建立、访问和调试。一旦你需要使硬件运行超过一百万个时钟周期,则需要使用硬件加速器以实现更优良的性能。[!--empirenews.page--]
运行虚拟机和硬件加速器的组合,或一些供应商所谓的“混合仿真(hybrid-emulation)”,可在精确硬件模型的一个时钟周期中快捷、简便地运行软件。一般这种配置的性能为100 MHz,这并不是实时的,但是其速度足以运行和调试完整的软件堆栈。
可对外围设备进行一些简单的测试,但要对驱动程序进行彻底的验证,外围设备只进行“环回(loop-back)”,还远远不够。这意味着将其与外部世界相连接,无论是通过硬件加速器上的I/O电缆,还是虚拟模型或硬件加速器相连的主机的接口。Mentor的硬件加速器系统中,将其称为co-model主机。co-model主机和硬件加速器之间快速有效的连接对于维持高水平的性能是至关重要的。
图3:重新为新驱动程序定义读/写宏指令
需要注意的是,在这个配置中完整的设计不是在RTL中。这意味着系统将正常工作,但不会表现出与最终产品相同的性能特征。从这个配置中你能看出某些方面的性能,如某些组件之间转换的流量。但是详细的性能分析则需要对系统进行更准确的表达。
当RTL代表整个设计时,你将得到整个系统一个时钟周期的准确模型。这可以用来进行详细的时间分析并得出吞吐量、延迟以及响应时间的具体数据。要使系统有效运行,你需要将其放在一个硬件加速器或FPGA原型中。一个包括实际软件的完整系统,实际上是不可能基于软件仿真进行建模的。甚至在硬件加速器平台上也只能运行于一兆赫兹。这远远超过了基于软件的仿真速度,但与实际时间相比,还是要慢得多。
在硬件加速器上运行设计时,需要在嵌入式处理器中调试软件。一般这种调试会使用系统可用的硬件接口(例如JTAG接口)连接硬件调试探针来完成。但是有一个问题:尽管JTAG很适合调试功能问题,但很难用它来调试性能和时序问题。因为“混合”虚拟机和仿真的性能更高一筹,你会想在这上面调试所有的功能问题。因此,仅存的问题就是时序和性能相关的问题了。
JTAG和类似的调试技术使处理器进入调试模式,然后使用各种技术来从处理器和外围寄存器中检索数据。即使在最优情况下,这些操作也至少需要耗费成千上万个时钟-通常是数以百万计的时钟。而且这些调试时钟通常只是处理器时钟的一小部分。由于在调试时间点前后调试工具引入了数以百万计的操作时钟的延迟,因此,调试性能和时序问题变得极为困难。开发人员一般通过处理器跟踪来回溯调试,以避免延迟。但即使收集处理器跟踪数据也会影响到你正在观察的系统的运行。
Mentor Graphics有一款产品叫“Codelink”,通过它能收集在仿真中运行设计时的回溯数据,利用这些数据就能驱动传统的软件调试。本质上说,你可以获得传统软件调试中的所有功能-代码单步执行、设立断点,查看内存和变量。这样做保留了仿真系统的时钟周期的精确性,没有任何副作用。你还具有完全的并行多核可见性和运行与回退的能力。但许多性能问题很难在源代码层面调试,通常还需要一幅对比硬件动作的、在设计中运行的处理器的动作时间轴视图。Codelink收集这些跟踪数据,并导入Mentor的系统分析工具,便能对照显示性能数据和硬件数据。要在这一开发阶段对整个设计进行诊断,那么这可能是可视化性能问题和时序问题的最佳解决办法。
FPGA原型通常会比硬件加速器运行得更快,因而更长的软件运行时间是可以实现的,还可能会发现更多设计上的问题。软件调试通常采用JTAG或者类似的技术来实现,但都存在上述的各种问题。在硬件调试中,FPGA历来都存在可视性有限的缺点。FPGA供应商提供的嵌入式逻辑分析仪只能提供有限的跟踪幅度和较浅的跟踪深度以及频繁的重新测量,最终导致漫长、且经常是突然的(“回到原点”)重新编译(综合的和P&R)。这使得在FPGA中调试变得痛苦万分,枯燥不已。幸运的是, 新的技术面市了,不仅能提供成千上万种信号的可见视图,并具备深入跟踪芯片及系统级动作的能力,还能提供前所未有的易用性和强大的运行时可配置性,通过消除大多数重新测量和回头迭代的需求,能极大地提高调试效率。经过改进的调试将对使用FPGA原型的体验和效率产生积极的影响。
图4:硬件加速器正变得不仅仅只是加速仿真。
从简单的存根代码开始,通过一系列依次更详细和完整的硬件模型来推进,可以在得到实际硬件芯片之前对软件进行验证。你可以长时间保持最高性能能和最易用的调试环境,必要时使用详细的模型验证系统的各个方面。你将需要一个通用的环境来生成、运行和调试,以便和其他环境进行无缝转换。而且这也将扩展到最终的芯片中,因为你会需要对实际产品做一个最终的测试。这意味着一旦你拿到了实体原型,需要做的就仅仅是确认所有功能都正常运行了。针对硬件的抽象模型和后期具有精确时钟周期的RTL硬件模型,最难的软硬件交互问题将在设计阶段就能得以解决。一旦实体样机就绪,就能大大减少软件开发的时间。