中文 英语
18.luck新利
的意见

基于arm的soc上调试SW工作负载的两种方法

在前置硅设计中使用实际软件工作负载的替代方案。

受欢迎程度

Andy Meier和Tomasz Piekarz著

在典型的片上系统(SoC)开发项目中,芯片架构师会在芯片问世前数年就将给定SoC的初始规格提供给设计团队。随着需求的变化,他们将修改硬件和软件规范。通常,软件开发的很大一部分发生在开发程序的后面。

SoC验证和验证团队面临的一个主要挑战是在软件开发之前确保正确的系统运行。一些新兴技术解决了这个问题,包括在全功能的前硅设计上运行实际软件。这种方法之所以特别吸引人,仅仅是因为硬件辅助验证平台的技术进步;验证工程师可以让设计通过一组实际的工作负载,并模拟设计最终的日常使用。

然而,使用实际的软件工作负载也不是没有问题,因为有限的可见性和可调试性是设计人员可能面临的障碍之一。

在本文中,我们将研究用于在寄存器传输级(RTL)调试基于arm的soc的两种不同技术,包括向硬件验证环境添加增强的软件调试器。我们在本文中使用的例子是基于Arm 926的设计。

在嵌入式处理器设计的典型流程中,IP供应商基于设计的架构(如Arm、RISC-V等)以预编译的加密设计仿真模型(DSM)或Verilog模型的形式提供处理器模型。然后将这个CPU模型连接到总线结构和RTL设计的其余部分,并使用逻辑模拟器或模拟器执行设计。一旦基本的嵌入式设计可用,下一步涉及构建和划分嵌入式软件,并将其加载到设计的(基于rtl的)程序内存中。虽然理解了该过程的大致轮廓,但设计人员和设计验证工程师在调试CPU子系统设计时经常面临挑战。由于模型不是为调试而设计的(也就是说,它们没有提供一个API来连接到显示实际软件执行、变量值或内存内容的调试器),因此显示的值通常与PC执行不一致。这是因为调试处于管道的不同阶段,创建了不一致的视图。考虑一个场景,两个连续的指令更新同一个寄存器。由于CPU管道通常与整体执行不一致,因此只有最后一个更改是可见的。

手动调试:不适合胆小的人

让我们来看看手动调试在CPU上运行的嵌入式软件所涉及的内容。考虑相对常见的故障,即CPU执行代码,然后在某个点进入“平线”模式,基本上停止执行进一步的指令。

要调试此故障,我们至少提出四个问题来查找CPU在故障前的状态:

问题1:在模拟中最后执行的是哪行代码?

要回答这个问题,必须确定最后执行的指令。在这里可以找到isis .log。isis .log文件,也称为tarmac文件,由Arm内核在模拟过程中生成,由静态指令跟踪组成。根据文件,这里执行的最后一条指令是地址为0x118的LDRB指令。

接下来,我们必须识别源代码中的相关行。这可以在行表中找到,该行表指向demo_diag.c文件中的第135行。

问题2:执行停止时正在执行什么函数?

要回答这个问题,请转到符号表并查找地址0x118,该地址显示为属于send_to_dbg_port函数。

问题3:从哪里,在源行号和函数名方面,函数被调用?

要回答这个问题,必须查看反汇编文件,这里显示该函数是从main中从地址0x7e0调用的。该信息可以通过行表引用,行表显示该函数是从文件mine.c第411行调用的。

问题4:当模拟停止时,main()中的变量“p”的值是多少?

接下来,查看main.c文件中的main,看看“p”的值在哪里被改变了。请注意下面第400行中可能影响“p”值的三个条目。

现在,使用行表查找第400行(p++)上的第三条语句的地址,并使用反汇编视图查找“p”存储在哪里。事实证明,我们正在查找的地址是0x784,“p”存储在R7中。

现在回到波形并查看R7中的值,下面的值在函数调用周围为零。

增强调试技术

到目前为止一切顺利,但我们仍然不知道失败的原因。我们可以在逻辑模拟器记录文件中找到其他线索,该文件显示“X”传播到状态寄存器,后面跟着一个条件分支,但没有指出原因。

让我们说明一个显而易见的事实:手动调试是劳动密集型和乏味的。前面描述的示例涉及生成静态日志文件,搜索它们,然后尝试将收集到的数据与表示CPU中硬件模拟环境的波形中的正确时间关联起来。所有这些都是为了找到故障前的最后一个CPU状态,即调试过程的逻辑起点。

最重要的是,硬件验证环境非常适合于验证硬件,但在为硬件-软件环境带来更多可见性方面却有所欠缺。实现这种可见性的关键是将软件调试器链接到RTL模拟环境。现在让我们使用Siemens EDA的Veloce Codelink来回答相同的问题,以排除在模拟运行期间发生的故障。

Veloce Codelink不需要更改软件或硬件设计,同时允许记录和重放模拟。它支持多核和多cpu环境,并提供前进和后退的能力。

Veloce Codelink的一个关键特性是能够从模拟器和模拟器环境中脱机调试。这对于释放有价值的资源用于其他用途至关重要。

运行中最后执行的是哪行代码?

要找出这一点,在从示例运行中加载软件执行文件(rlf)之后,您可以将光标移动到最后执行的指令,并使用Veloce Codelink调试器查看源代码窗口。demo_diag.c文件中的行号是135。

从哪里,在源行号和函数名方面,函数被调用?

要回答这个问题,请在源代码窗口中向上滚动,以查看代码属于哪个函数。从那里,您可以单步后退到调用方。在这里,函数调用是send_to_dbg_port,调用方是main.c第411行。在这样的环境中,能够后退是非常重要的,因为很多RTL调试都发生在之前执行的运行上。

当模拟停止时,main()中的变量“p”的值是多少?

移动光标并将其悬停在“p”变量上会显示最新的值:在本例中为0。

将调试器连接到RTL处理器模型

将调试器连接到RTL CPU模型的最佳方法是将任务分成两部分:将实时模拟记录到数据库中,然后使用该数据库以模拟后模式打开调试器。这与硬件调试环境相匹配,在硬件调试环境中,通常进行批处理模拟,然后在后模拟模式下进行调试,以避免长时间的模拟时间。该设置对预先录制的数据进行操作,提供了向前和后退的能力。这允许验证工程师从故障点开始并追溯原因,这当然胜过另一种选择:每次通过模拟中感兴趣的位置时重新运行模拟。

结论

添加一个支持软件的验证环境来帮助调试在硬件验证环境中执行的SW工作负载,可以为设计人员带来许多好处。诸如Veloce Codelink之类的工具提供了所描述的功能。Veloce Codelink不需要更改软件或硬件设计,并允许记录和重放模拟。这个多面工具支持多核、多cpu环境,并提供前进和后退的能力。

在编写和调试软件时,将软件调试器添加到硬件验证环境可以提高工作效率。这有助于避免由于缺乏执行可见性而过度简化用于嵌入式CPU验证的软件的倾向。有了这种额外的可见性和调试功能,现在就能够从简单的C和c++程序扩展到复杂的启动软件和在CPU上运行的完整Linux执行,从而在真实的工作负载条件下完全验证设计。

Andy Meier是西门子EDA可扩展验证解决方案部门的产品营销经理。

Tomasz Piekarz是西门子EDA可扩展验证解决方案部门的技术营销工程师。



留下回复


(注:此名称将公开显示)

Baidu