嵌入式学习小组
直播中

李伟

8年用户 210经验值
私信 关注

浅谈可移植激励规范复用策略介绍

  当今硬件设计变得愈加复杂,如何创建出足够的测试来保证设计的正确性是每个硬件工程师需要面对的问题。Accellera的可移植激励测试规范(PSS、又称便携激励标准)[1]旨在希望能够提供一个独立的测试来源,从而实现跨层级的验证复用,即无论是IP级别、子系统、还是SoC级都使用同样的测试来源,他们也希望提供一系列功能来解决不同级别对于验证测试的不同要求,从而达到真正意义上的复用。然而,即使是像Java和C++这样拥有强大的面向对象特性的编程语言,都不能直接保证我们能得到高质量的可复用的代码,PSS本身的语言特性也同样需要工程师按照一定规范使用才能达到高效复用的目的。如果我们正确的使用这些特性,实现设计IP和测试目的的复用,能够显著减少其所消耗的时间成本。这篇文章就是讨论了如何通过前期的计划,针对自身公司的规模和设计需求使用PSS更加正确、有效的通过复用来加速验证过程。

回帖(5)

张倩

2020-12-18 16:25:38
  剖析可移植激励
  可移植激励(下文简称PSS)语言在设计初期就考虑到了测试意图和自动化创建测试的要求。下图一就很好的展示了PSS是如何通过对于测试意图和测试实例的清晰区分,来达到对于测试意图的平台复用的。在PSS描述文件中,测试意图主要抽象定义了一个测试需要执行什么行为,是通过声明的形式来实现的。就如同在SystemVerilog语言中声明式的约束一样,我们可以通过这种方式得到比较好的复用性。
  
  图一 – PSS描述文件结构详解
  通过这种声明式的语言特性,PSS很好地满足了复用和自动化的需求。通过这种特性,定义了合法空间中可以发生的行为,我们能够直接编写程序定义其行为内容而不是如何执行这种行为。如果有读者使用过SystemVerilog的约束特性,就能够明白约束定义的是合法激励数据范围。PSS语言正是将这种特性从数据定义扩展到测试场景的使用上,提供了一种新的元素-动作(action)。
  然而支持这种声明式的语言特性并不够,因为测试本质上是需要和设计单元进行底层的互动,如修改寄存器或者中断等等来达到验证的目的。所以测试代码不仅仅是要定义抽象的测试场景,也需要能够定义底部的设计细节。另外绝大部分的验证环境已经拥有大量的测试代码供工程师使用,所以大多数情况下,工程师们会使用他们熟悉的编程语言如SystemVerilog、C++或C来实现所需要的可移植激励测试。
  当然,我们使用PSS的最终目的是为了生成更多的测试用例,下图二就向我们展示了一个典型的PSS使用流程。在这种情况下,PSS文件一般会在测试生成过程中被执行。比如说,我们可以使用PSS来提供约束生成仲裁功能。在SoC环境下,我们会系统的处理器执行测试,此时我们可以提前使用PSS生成一些简单的测试用例来让处理器更高效快速的运行。
  在这两种使用环境下,PSS都会将抽象的测试场景定义和测试生成两部分完全分离出来。
  
  图二 – PSS流程详解
举报

王一凡

2020-12-18 16:26:10
  详解可移植的含义
  在详细讨论可移植激励应用设计策略之前,有必要花时间了解“可移植”本身的含义。接下来我们将从三个方面讨论如何更好地实施相应设计策略。
  在讨论可移植测试特性时,我们经常会涉及到垂直复用这一术语。这个概念通常是指从项目早期 – 一般是指在IP层级 – 就开发出相应测试意图,以便在之后的验证流程中重复使用,比如子系统和系统层级。对于测试意图在各个层级上的垂直复用,能够提供一个全面健壮的测试库,有效帮助我们更快的搭建测试环境,同时进一步减少在开发过程中带来的程序错误。当然尽管垂直测试的好处多多,但是开发这种测试需要各个团队协作共同努力,比如我们需要IP层级的团队同时支持系统级和子系统级别的测试开发,另外也需要对已存在的IP开发相应的可移植激励描述文件。
  水平复用则可以让测试意图文件在不同项目中工作,当然设计本身会有一些参数上的变化。但是可移植激励标准本身声明式的语言特性,能够有效降低对于参数调整带来的工作量。我们只需要调整测试规则即可,而不需要对测试意图本身进行更新。
  
  图三 – 垂直复用实例
  如图三的实例,不同的SoC设计中可能包含不同数目的DMA引擎。如果使用直接测试的方式,我们需要检查所有测试文件,以确保他们检查SoC时使用正确的DMA引擎数目。但是使用可移植激励规范时,我们只需要调整DMA参数,即可以重新生成正确的测试文件。
  最后一项可能比较难以理解 – 测试技术的可移植性。例如SystemVerilog的受约束随机特性,虽然可以有效帮助我们提升验证效率和速度,但是这种特性只能使用在模拟测试环境当中,无法使用在以C++为主的高级综合环境(HLS)中,也并不能使用在嵌入式软件测试中,因为一般来说,嵌入式系统的硬件资源有限,没有办法运行一个完整的SystemVerilog模拟器。
  但是可移植激励规范的出现,让这些测试技术,比如自动化的受约束随机测试,能够在不同的测试环境中得以应用。这一益处本身也许就足够可以说服团队采用可移植激励规范。
  在一个项目初期,团队就需要从以上三方面来考虑如何设计PSS策略,比如哪方面的复用更为重要,需要团队投入更多的资源进行开发。从而让整个项目能够最大化利用可移植激励带来的好处。
举报

孟薇

2020-12-18 16:26:23
  实例详解
  我们接下来将用一个非常简单的实例来探讨PSS的实际应用,我们将继续使用图三展示的SoC设计框架,其中包含一个四核RISC-V处理器、一个外围设备子系统以及一些其他控制器组件。
  接下来我们也会从组件层级讨论DMA IP。如下图四,我们可以看到一个组件级别的验证环境框架图。另外如图五所示,我们也会探讨一下如何从子系统级别嵌入一个DMA引擎、一个UART控制器和一个中断控制器。
  
  图四 – DMA引擎模块级环境
  
  图五 – 外围子系统验证环境
举报

马占云

2020-12-18 16:26:39
现有测试用例的复用
当我们完成文档的编写,接下来就是对代码库进行分析,来确定哪一些可以进行复用。我们可以利用这段时间来评估一下有多少现有代码可以继续用于当前项目。另外如果时机允许也可以借此来评估对整个组织内的相关代码,通过整合资源可以更好的提升开发效率。
约束
PSS描述文件绝大部分基于约束语句,这是由其声明特性所决定的。所以现有的一些约束文件也可以很轻易的转换成PSS格式进一步节省开发时间

SystemVerilog的约束文件由于其声明特性,通常可以作为PSS描述文件二次再开发的来源。另外其本身语法特性与PSS非常相似,我们甚至可以直接拷贝复制进PSS文件直接进行使用。这种情况的使用案例是一些IP或者子系统的配置对象代码,可以这样复用在PSS文件当中。

通常约束文件可读性比较低,比如SoC的内存映射文件。但是通过一点点改动,我们就能将其改写成PSS约束,来专门定义不同内存空间的读取权限
测试案例实现细节
团队现存的测试环境通常是一个非常好的实现基础,当然这其中需要花时间将其按照PSS的语法进行改动。

UVM环境中,我们会使用utility sequence来对IP模块进行简单的操作,比如初始化设置,命令其进行数据计算等等。这些序列在定义时通常有一些随机约束和变量。其他情况下,我们会通过输入参数来控制其工作模式。无论如何,我们都可以通过一些方法将其转换成PSS描述文件。
task init_single_transfer(  int unsigned        channel,  int unsigned        src,  int unsigned        inc_src,  int unsigned        dst,  int unsigned        inc_dst,  int unsigned        sz);  wb_dma_ch ch = m_regs.ch[channel];  uvm_status_e status;  uvm_reg_data_t value;    // Disable the channel  ch.CSR.read(status, value);  value[0] = 0;  ch.CSR.write(status, value);   // These registers are volatile. Read-back the content  // so the register model knows to re-write them  ch.A0.read(status, value);  ch.A1.read(status, value);图六 – SystemVerilog测试复用实例

图六截取了一段SystemVerilog代码,其中我们定义了一个virtual sequence的task,来设计DMA引擎在一条特定的数据通路上传输数据。这段代码就可以通过简单改写将其使用在测试DMA引擎的PSS模型中。需要注意的是,因为我们本身的代码使用了UVM,所以底层是使用了UVM寄存器模型来读取DMA引擎的相关寄存器。

void wb_dma_drv_init_single_xfer(  wb_dma_drv_t                *drv,  uint32_t                ch,  uint32_t                src,  uint32_t                inc_src,  uint32_t                dst,  uint32_t                inc_dst,  uint32_t                sz  ) {  uint32_t sz_v, csr;   csr = WB_DMA_READ_CH_CSR(drv, ch);   csr |= (1 << 18); // interrupt on done  csr |= (1 << 17); // interrupt on error  if (inc_src) {    csr |= (1 << 4); // increment source  } else {    csr &= ~(1 << 4);  }  if (inc_dst) {    csr |= (1 << 3); // increment destination  } else {    csr &= ~(1 << 3); // increment destination  }  csr |= (1 << 2); // use interface 0 for source  csr |= (1 << 1); // use interface 1 for destination   csr |= (1 << 0); // enable channel   // Setup source and destination addresses  WB_DMA_WRITE_CH_A0(drv, ch, src);  WB_DMA_WRITE_CH_A1(drv, ch, dst);   sz_v = WB_DMA_READ_CH_SZ(drv, ch);  sz_v &= ~(0xFFF); // Clear tot_sz  sz_v |= (sz & 0xFFF);  WB_DMA_WRITE_CH_SZ(drv, ch, sz_v);   // Start the transfer  WB_DMA_WRITE_CH_CSR(drv, ch, csr);   drv->status[ch] = 1;}图七 – 相关测试的C代码复用

上图是一个相似功能的C代码实现。我们同样也可以将其转换用在PSS测试中。

当然需要注意的是虽然两种代码实现的测试目的相似,但我们会讨论哪一种更适合用在PSS文件中
举报

更多回帖

发帖
×
20
完善资料,
赚取积分