验证平台,SV 和UVM

验证是确保设计和预定的设计期望一致的过程。

验证平台:被用来应用一个或多个测试激励,并将激励发送到设计的输入中,激励可通过验证平台产生,或者通过手动创建。最后,输出进行比较,看结果是否正确。结果检查可通过验证平台、脚本或者手工来实现。

验证平台的主要功能:产生激励、把激励应用到被测设计DUT中,检查结果和验证测试是否通过,也就是确保被测设计的输出和期望一致。

验证的难点:如何产生全部的激励,如何检查结果的正确性。

功能验证流程:制定验证策略(定义测试用例,验证平台抽象层次,激励产生方案,结果检查方案)和验证计划(搭建验证平台,创建测试用例、运行和调试)、 覆盖率分析和回归测试。

验证流程:1、仔细阅读设计文档,并理解分析。2、指定验证计划,包括验证功能点的提取,规划tests,TB的架构,用什么方法学,功能覆盖率的提取以及检查机制。3、搭建验证环境,码代码,测试用例编写以及调试debug。4、回归测试。5、覆盖率包括代码代码覆盖率和功能覆盖率,增加一些tests。6、撰写验证报告,主要是覆盖率的分析。

验证手段:黑盒验证:只通过其边界信号来验证一个模块或者设计的功能。通过这种方法,激励可以被应用到设计和参考模型中,在某个抽象层次,通过被测设计和参考模型的输出被校对,黑盒验证存在下列主要的缺点:很难验证和设计相关的特点、很难调试、要求一个精确的参考模型。白盒验证:可以不需要参考模型,通过在设计内部或外部输出信号放置监控器和断言来保证设计操作的正确性。灰盒验证:综合了白盒和黑盒的一个阶段,也就是在设计内部添加监控器和断言来减少对参考模型的精确要求,在错误发现的时候也减少调试的压力。

验证可能出现的错误:从来没有被激发过的错误,被激发的错误没有被传递出来,多个潜在的错误掩盖了其他错误。

代码覆盖率:行覆盖率、状态机覆盖、翻转覆盖、判定覆盖、条件覆盖、路径覆盖。

功能覆盖率:代表设计要求的功能中有多少被验证了。功能覆盖率包括3个概念:覆盖点、交叉覆盖率、传输覆盖率。覆盖点是单个标量值或者表达式的抽样。目的是确保所有感兴趣的和相关的值都可以在已抽样的值或表达式中被观测到。交叉覆盖率是度量同一点多个标量值的结合,可以设计两种或者多种覆盖点的结合,只能用于同一类的覆盖组。传输覆盖率是度量一系列值的存在和发生,可以包括统一覆盖点上超过两个的连续不断的值。

功能覆盖率高、代码覆盖率低:验证计划不充分,需要增加佛南功能覆盖点。

代码覆盖率高,功能覆盖率低:设计没有实现指定的功能。

覆盖率驱动验证:最重要的特点是基于随机激励产生。随机激励生成是提高效率的最主要的原动力,覆盖率验证驱动是将事务级验证、约束随机激励产生、自动化结果比较、覆盖率统计分析和直接测试。事务级验证允许在一个更高的抽象层次来创建验证场景。约束随机激励产生可以获取更高的效率,为生成验证场景和自动化结果比较提供了充分的保证,设计能够在各种随机的情况下被验证。覆盖率统计是必须的,若没有覆盖率统计,就没有办法清晰的分析哪个场景被随机生成过。直接测试也是必须的,因为最终不可能全部的场景都能够随机生成。覆盖率驱动验证方法学要求指定一个可以数量化衡量完备性,可追踪、有组织的验证计划,这对于验证计划的严格要求可以暴露出可能被遗漏的相关场景。

验证存在的挑战,一个有效的验证方案必须解决验证完备性、验证可重用性、验证可靠性、验证效率、验证的性能。验证完备性是如何最大限度地验证被测设计的行为,难点在于如何获取所有必须被验证的场景,可采用覆盖率驱动的验证方法学。覆盖率驱动验证方法学要求指定一个可以数量化衡量完备性,可追踪、有组织的验证计划,这对于验证计划的严格要求可以暴露出可能被遗漏的相关场景。验证可重用性是优化验证环境的架构,使之可以在不同的场合重用。重用可以通过模块化验证组件、采用标准接口、将激励产生机制和验证架构分离等方式实现。一个项目中,深层次的重用是如何实现一个验证平台可以供多个测试用例使用。验证可靠性在于如何减少在完成一个验证项目中的手工操作,手工操作可能存在错误、冗长和耗时很大的问题。有一个很好的方法是约束随机验证,是通过搭建一个自动化的系统来产生激励和自动比较,进而提高验证的可靠性。验证的效率可以通过提高验证平台的抽象层次和采用重用。验证性能是在运行回归测试时候,迭代周期主要为验证平台运作的有效性来决定,验证程序的性能成为这个阶段的主要因素。

数字ic设计流程:确定项目需求,指定芯片的具体指标,系统级设计,用系统建模语言对各个模块描述。前端设计,RTL设计,仿真,硬件原型验证,电路综合,后端设计,版图设计,物理验证,后仿真。

数字ic设计具体指标:物理指标(制作工艺)、性能指标(速度、功耗)、功能指标(功能描述、接口定义)

集成电路产业链:集成电路设计、晶圆、封装测试、组装、成品整机。

soc芯片最重要的是cpu

总线连接,总线直接桥接,AHB-bridge-APB总线协议。

system controller产生系统的时钟和复位信号。

soc芯片主要无线通信和数据存储功能,主要应用场景是数码相机的存储片。

无线通信功能是通过apb总线上的spi接口外挂wifi芯片。

sv基本语法:2值逻辑(0,1)和4值逻辑(0,1,x,z,reg类型,verilog中用),有符号数(整型)与无符号数(bit),合并数据(内存空间更紧凑)与非合并数据(每个元素占用32bit内存空间),动态数据(数组大小不确定)和队列,关联数据(不需要连续空间,可以整数、字符串等),数组的方法。

多线程:join(三个子线程都执行完后,才可以执行主线程),fork_join_any(任何一个子线程执行完后,便可以执行主线程),fork_join_none(子线程不会阻塞主线程、先执行主线程,三个子线程才会并行执行。)

function是没有时间的,task是有时间的。void function是没有返回值。

static:module和program子程序默认是静态存储。

automatic:自动存储模式,函数和任务的重入成为可能。

random()产生有符号的随机数,urandom()产生无符号的随机数,randomc产生平均分布的平均数。

sv预定义随机化方法:randomize,pre_randomize, post_randomize.调用randomize之前调用pre,之后调动post

用super.task_name()调用一个定义在父类的task

this是指向当前class

local和protected都是保护变量,外部不可以访问,子类不能访问父类的local变量。子类可以访问父类的protected变量。

把代码打包,使用package,解决类命名冲突等问题

dut是module,TB是program,不同代码运行在不同区域,program与module运行的时间域是不同的,这样会避免竞争和冒险。

virtual interface : virtual interface的本质是指向interface的指针,因此其并不是一个真实存在的实体,而interface是一个真实存在的实体。

静态cast是数据类型的转化。动态cast类的向下转换(当父类句柄指向的对象是真正的子类对象,可使用),或者是枚举的转换。

类的三大属性:封装性、继承性、多态性。

多态:虚方法与重写的实现。当一个类派生出子类的时候,基类中的一些方法(定义为virtual)可能需要被重写(在派生类),对象中的类型来决定调用方法的实现方式,通常这是一个动态的过程,动态的选择方法的实现方式叫多态。如果想要重写某个方法,在父类中声明中为虚方法,后续继承过程中永远是一个虚方法,不再注意是否virtual。

封装性:通过访问控制来实现的。高内聚、低耦合,类的内部数据操作细节自己完成,不允许外部干涉,仅暴露少量的方法给外部使用。通常是禁止直接访问一个对象中数据的实际表示,应该通过操作接口来访问,称为信息隐藏。封装可以提高程序安全性,保护数据,隐藏代码实现细节,统一接口,更加具有规范性,增加系统可维护性。

继承:对某一批类的抽象,从而实现对显示世界更好的建模。

UVM:分层的验证环境,组件(test、env、agent、sequencer、driver、monitor、scoreboard)、每个类的激励,如何通信,如何连接(port)、如何启动、如何结束、如何打印信息、数据(uvm_sequence_item)。

uvm平台的开启和结束:启动:在run-test函数里面调用用例名字,仿真用UVM_TESTNAME, 结束:正常结束(drops objection+check)异常结束(错误而挂起 / timeouts)

UVM 的PHASE:build phase总体目的是构建、配置和连接测试台组件层次结构,所有的build phases方法都是functions,在0仿真时间执行完成。一旦构建了UVM testbench根节点组件,build phase 就开始执行。是从上到下地构建testbench组件层次结构。connect phases用于在组件之间建立TLM连接,或者向testbench资源池分配对象句柄。connect phase 在build phases方法之后自底向上地执行。run phase(reset、configure、main、shutdown 共12个)发生在start_of_simulation阶段之后,用于激励的产生和testbench的监测和检查。run phase 作为一个task实现,所有uvm_component 的run phase 都并行执行。

PHASE同步用同步机制。build phase和finel phase是自顶向下的。其他的是自下向上的。run phase是task,其他的phase均是function。run phase 和run-time tasks是消耗时间的。一个phase执行完后才会执行下一个phase

new是产生一个对象,build_phase是产生组件,create调用UVM factory 产生一个对象 ,会用到一个registry注册表。

uvm_info才有打印等级,最高是uvm_debug, 最低是uvm_medium, fatal、error、warning无打印等级.

sequence机制,控制并产生一系列的事物,并通过某种方法将事物发送给driver的机制。具有控制何时产生事物,产生事物,并将事物发送给driver的功能。sequence是一个产生和发送数据的过程,会消耗仿真时间。只有在task_phase中才会启动。

事物产生和发送流程:1、当进入某个task_phase之后,sequence被启动产生事物,并将事物发送给sequencer。2、当driver需要驱动事物发送给DUT时,首先向sequencer发送事物请求,sequencer再将产生好的事物发送给driver。3、driver处理完事物,会发送完成响应,并发送给sequencer,在转发给sequence。sequence收到响应会产生下一个事物。

sequence机制有五个uvm class,uvm_sequence, uvm_sequence_item, uvm_sequencer, uvm_driver, uvm_agent, 主要涉及到三个组件sequence、sequencer和driver。

sequence:当sequence的start的函数启动,sequence会执行body方法,产生事物,并将事物发送给sequencer放入FIFO中储存。sequence会等待一个driver的完成响应,得到之后会退出该次事物的产生。

sequencer: 当sequencer启动时,首先会检查自身的default_sequence是否配置,如果配置了会创建实力,设置该sequence的starting_phase并随机化该sequence。最后调用sequence的start()函数启动该sequence。

driver:首先向sequencer发送一个事物请求,然后等待事物,sequencer会将产生好的事物发送给driver,driver在处理完该事物后,返回一个完成响应。

sequence机制的实现流程:传入句柄是sequence_item类型时,调用start_item函数,随机化item,最后调用finish_item函数。如果句柄是sequence类型,则调用该对象的start().

UVM callback (回调函数)机制: 最大用处就是为了提高验证平台的可重用性,在不创建复杂的OOP层次结构前提下,针对组件中的某些行为,在其之前之后,内置一些函数,增加或者修改UVM组件的操作,增加新的功能,从而实现一个环境多个用例,还可以通过callback机制构建异常的测试用例。回调函数的使用步骤:1、在UVM组件中内嵌回调函数或者任务。2、声明一个UVM回调空壳类。3、从UVM回调空壳类中扩展UVM callback类。4、在验证环境中创建并登记UVM callback 实例。UVM——Callback机制(作用、使用步骤实例)_簡時光℃的博客-CSDN博客_uvm中callback

 UVM configure机制:可以传递值、可以传递对象、可以传递interface(virtual)。作为半个全局变量,为避免全局变量带来的风险,高层次组件可以通过该机制实现不改变代码的机制下更改它所含子组件的变量,各个层次都可使用,支持通配符和正则表达式,支持用户自定义的数据类型,可以在仿真运行的过程中进行配置。configuration机制使用的是set函数和get函数的过程。

interface使用configure机制:首先根据DUT构建interface,为driver添加virtual interface和驱动DUT,将事物信息分解为pin级信号驱动给DUT,新建top.sv文件,将其他平台组件include,建立顶层module,进行各种连接,将实例化interface配置给virtual interface。

使用uvm_config_db的优势在于:
1.与SV的层次化索引不同,可以在顶层对任意层次进行配置,也可以在硬件域对软件域的接口进行配置,操作更方便
2.验证组件更独立,水平复用和垂直的移植都更加方便
3.即使在顶层没有配置,底层也不会报错,一方面提高了复用性,另一方面增加了隐患,所以最好在配置时设置调试语句,在配置失败时报错,以便于调试。

UVM资源池由两部分组成,分别是添加配置资源和获取配置资源。

UVM的验证环境构成可分为两个部分,一部分构成了环境的层次,这部分代码是通过uvm_component类完成,另一部分构成了环境的属性和数据传输,这部分是通过uvm_object类完成。

UVM factory:为了更方便替换验证环境中的实例或注册了的类型,同时工厂的注册机制也带来了配置的灵活性。1、注册,使用factory机制的第一步是将类注册到工厂,这个factory是整个全局仿真中存在且唯一的机构,所有被注册的类才能使用factory机制。2、创建,创建就是实例化对象,所有注册到factory的类均可通过factory独特的方式实例化对象。但factory的独特方式,实际上是调用了new函数,也是先创建了句柄再赋予对象。3、创建函数的重载,重载也就是覆盖、替换,对于UVM中的factory机制,可实现factory机制中创建函数的重载,即将父类的创建函数重载为子类的创建函数,也就是说,重载之后,父类的句柄指向的是子类的实例。

从流程上,如何保证芯片验证的质量,验证代码覆盖率与功能覆盖率如何相互保证验证质量?

从流程上看,要保证验证的独立性、完备性和正确性。还需要采用各类先进的验证方法和策略,比如覆盖率驱动的验证策略,随机化验证策略,基于断言的验证策略,还需要维护回归测试的流程。

覆盖率包含了功能覆盖率和代码覆盖率,当两者都达到100%时,就可以去流片,其中功能覆盖率为主,需要工程师根据需求和经验,设计功能覆盖率模型,代码覆盖率为辅,可以通过EDA获取客观数据。当又一个覆盖率较低的时候需要分析。

功能覆盖率高、代码覆盖率低:验证计划不充分,需要增加佛南功能覆盖点。

代码覆盖率高,功能覆盖率低:设计没有实现指定的功能。

SRAMC控制器用一组总线实现了8个SRAM块,每个SRAM是8k,SRAM做片选时,是怎么验的,回答:通过看sram_csn片选信号。32位,4个byte是0,4,8,c。2个byte是0,2,4,6,8。1个byte是0,1,2,3,4。

stam控制器的低功耗设计与时钟门控没有关系,跟sram选片有关系。因为通过阅读sram的数据手册,发现当不选中sram时的功耗只有选中sram的千分之一,因此设计了8*8k的多片SRAM。而且支持8/16/32位的数据操作,就是通过片选信号实现低功耗。

低功耗设计跟三态门也没有关系,sram控制器项目中没有三态门,

你可能感兴趣的:(测试用例,1024程序员节)