当前位置: 首页 > article >正文

IC验证基础知识系列随笔

一、断言 and 和 和 intersect 区别

  1. And 指的是两个序列具有相同的起始点,终点可以不同。

  2. Intersect 指的是两个序列具有相同的起始点和终点。

  3. Or 指的是两个序列只要满足一个就可以

  4. Throughout 指的是满足前面要求才能执行后面的序列

二、Break;continue;return的含义,return之后,function里剩下的语句会执行吗

  1. break 语句结束整个循环。

  2. continue 立即结束本次循环,继续执行下一次循环。

  3. return语句会终止函数的执行并返回函数的值(如果有返回值的话)。

  4. return之后,function里剩下的语句不能执行,其是终止函数的执行,并返回函数的值。

三、组件之间的通信机制,analysis port和其它的区别

  1. 通信分为,单向通信,双向通信和多向通信

  • 单向通信:指的是从initiatortarget之间的数据流向是单一方向的

  • 双向通信:双向通信的两端也分为initiatortarget,但是数据流向在端对端之间是双向的

  • 多向通信:仍然是两个组件之间的通信,是指initiatortarget之间的相同TLM端口数目超过一个时的处理解决办法。

  1. blocking阻塞传输的方法包含:

  • Put():initiator先生成数据Tt,同时将该数据传送至target

  • Get():initiatortarget获取数据Tt,而target中的该数据Tt则应消耗。

  • Peek(): initiatortarget获取数据Tt,而target中的该数据Tt还应保留。

  1. 通信管道:

  • TLM FIFO:可以进行数据缓存,功能类似于mailbox,不同的地方在于uvm_tlm_fifo提供了各种端口(put、get、peek)供用户使用

  • analysis port:一端对多端,用于多个组件同时对一个数据进行处理,如果这个数据是从同一个源的TLM端口发出到达不同组件,则要求该端口能够满足一端到多端,如果数据源端发生变化需要通知跟它关联的多个组件时,我们可以利用软件的设计模式之一观察者模式实现,即广播模式

  • analysis TLM FIFO

a. 由于analysis端口提出实现了一端到多端的TLM数据传输,而一个新的数据缓存组件类uvm_tlm_analysis_fifo为用户们提供了可以搭配uvm_analysis_port端口uvm_analysis_imp端口和write()函数。

b.uvm_tlm_analysis_fifo类继承于uvm_tlm_fifo,这表明它本身具有面向单一TLM端口的数据缓存特性,而同时该类又有一个uvm_analysis_imp端口analysis_export并且实现了write()函数:

  • request & response通信管道 双向通信端口transport,即通过在target端实现transport()方法可以在一次传输中既发送request又可以接收response

四、类的public、protected和local的区别

  1. 如果没有指明访问类型,那么成员的默认类型是public,子类和外部均可以访问成员。

  2. 如果指明了访问类型是protected,那么只有该类或者子类可以访问成员,而外部无法访问。

  3. 如果指明了访问类型是local,那么只有该类可以访问成员,子类和外部均无法访问。

五、Uvm_component_utils有什么作用

UVM(Universal Verification Methodology)是一种用于验证集成电路设计的标准方法学,它提供了一套面向对象的验证框架和工具库,简化了验证环境的搭建和管理。UVM_component_utils是UVM中的一个宏定义,它的作用是简化UVM组件(component)的声明和注册流程。

在UVM中,组件是验证环境中的基本单元,可以是顶层环境、测试用例、序列等。UVM_component_utils宏定义了一个名为"uvm_component_registry"的类静态成员,该类用于将组件自动注册到验证环境中。通过在组件的定义中使用UVM_component_utils宏,可以省略手动编写的注册代码,提高验证环境代码的简洁性和可读性。

使用UVM_component_utils宏的示例代码如下:

class my_component extends uvm_component;
  // 组件定义
  
  // 使用UVM_component_utils宏进行组件注册
  `uvm_component_utils(my_component)
  
  // 其他组件代码
endclass

上述代码中,my_component继承自uvm_component类,并使用了UVM_component_utils宏来注册my_component类到验证环境中。

通过使用UVM_component_utils宏,验证工程师可以更方便地声明和管理UVM组件,提高了代码的可重用性和可维护性,进而提高了验证环境的开发效率。

五、为什么要配置is_active呢?


比如你在模块级做验证时,拿验APB接口为例,你需要用一个APB VIP,包含master agent和 slave agent。master通过APB的接口进行读写操作,slave是通过APB接口去响应操作,所以需要 master agent和slave agent里面都要有driver,maser_driver来模拟从APB总线上发起读或写的操作(控制paddr、pwrite和pwdata等),slave_driver模拟从APB总线上做响应,返回predata,pready和pslverr信号。
但是当你这个APB接口的模块验证环境被集成到一个更大的模块时,有真正的master模块设计连接着APB总线,设计里面自己会去对总线做操作,也有slave模块通过APB总线做响应。那这个时候,我就不需要你APB VIP里面的master agent 里面的 driver 和 sequencer 来模拟master去发送激励了,因为这个时候我有真正的master连在总线上。同样,我也有真正的slave模块来响应。但这个时候,我们仍然想监测APB总线上数据的来来回回,但又不需要发送激励,这时候我们就可以通过对APB VIP的 master agent 和 slave agent 配置UVM_PASSIVE,也就是不例化 driver 和 sequencer ,只例化monitor,实现了模块级环境复用到更高级别的环境中

六、在数字验证工作中,常见的一些bug包括:

  1. 时序问题:时钟和时序路径错误,导致数据传输不完整或乱序。
  2. 数据不匹配:期望值与实际值不匹配,可能是因为设计问题或验证环境问题。
  3. 边界条件错误:未正确处理各种边界条件,导致错误情况未覆盖或处理不正确。
  4. 接口问题:接口配置错误或接口信号连接错误,导致数据无法正确传输。
  5. 错误的时序约束:时序约束设置错误,导致无法满足设计的时序要求。
  6. 数据溢出或截断:数据宽度错误导致数据溢出或截断,结果不正确。
  7. 波形形状错误:波形形状错误或时序不一致,导致验证失败。
  8. 任务或进程协作错误:任务或进程之间的通信或同步问题导致错误的行为。
  9. 配置错误:配置参数或寄存器设置错误,导致不正确的配置行为。
  10. 仿真工具或工作流问题:仿真工具或工作流本身的问题导致错误结果。

这些是数字验证工作中常见的一些bug,当进行验证时需要注意并仔细排查以确保验证正确性。

七、你在做验证时的流程是怎么样的,你是怎么做的。

对于流程的话

  1. 第一步先去查看spec文档,将模块的功能和接口总线时序搞明白,尤其是工作的时序,这对于后续写TB非常重要; 这一步一般和designer一起,可以加快理解,如果有分歧可以找有经验的同事一起review。

  2. 第二步我会根据功能点去划分我的TB应该怎么搭建,我的case大致会有哪些,这些功能点我应该如何去覆盖,时序应该如何去检查,总结列出这样的一个清单;此时进行testplan和verification plan的编写,并同designer一起review,检查功能点是否全部考虑到,确保验证计划的完备。

  3. 第三步开始去搭建我们的TB,包括各种组件和VIP(例化VIP接口,集成到环境中,确保后面可以正常工作),和一些基础的 sequence还有test,暂时先就写一两个基础的sequence,然后还有一些环境配置参数的确定等,最后能够将TB正常运行,保证无误;

  4. 第四步就是根据清单去编写sequence和 case,然后去仿真,保证仿真正确性,收集覆盖率;验证工程师大部分时间在反复调试测试用例,发现RTL的bug,report给designer并协助designer去debug。

  5. 第五步就是分析收集的覆盖率,然后查看覆盖率报告去分析还有哪些没有被覆盖,去写一些定向case,和更换不同的seed去仿真;在收集覆盖率前,一般要根据设计功能去编写func coverage,然后通过regression收集code coverage 和func coverage。

  6. 第六步就是回归测试regression,通过不同的 seed去跑,收集覆盖率和检测是否有其它bug;

  7. 第七步就是review验证工作,找有经验的工程师前辈,一起查看验证tb和testcase,一方面查看是否有验证遗漏,另一方面可以借鉴前辈的经验优化验证环境。

八、在寄存器模型中加入后门访问

        在IP验证工作中,我们通常会引入寄存器模型,针对寄存器模型的功能是否正确,我们会有专门的case进行测试,通常测试寄存器的读写功能,采用寄存器前门访问先写后读的方式,但是有些寄存器的偏移地址错误的情况,这种先写后读的方式并不能检查出来,此时需要换一种方式,比如采用前门写入,后门读出,进行检查。为此我们需要在寄存器模型中加入后门访问路径:

在寄存器模型中加入后门访问的一种常见方式是通过添加特殊的控制寄存器或位来实现。后门访问可以是一种特权访问,可以用于调试、测试或特殊操作。

以下是一种可能的实现方式:

  1. 定义一个特殊的控制寄存器或位,用于表示后门访问的使能或状态。
  2. 修改寄存器模型的访问逻辑,使用这个特殊的控制寄存器或位来判断是否允许后门访问。
  3. 在访问寄存器的逻辑中添加额外的逻辑判断,以便在后门访问使能时执行相应的操作。
  4. 根据后门访问的需求,可能需要在寄存器模型中添加一些特殊的操作,例如读取或写入特定的寄存器值,执行特殊的操作序列等。

需要注意的是,后门访问是一种特权操作,需要根据设计要求和安全考虑来谨慎使用。同时,在寄存器模型中加入后门访问时,需要确保相关的验证和仿真工作也能正确处理后门访问的逻辑。

        假设我们有一个简单的寄存器模型,其中包含一个32位的控制寄存器 control_reg,我们希望为管理员用户添加后门访问权限。

        首先,我们可以在寄存器模型的寄存器类中添加一个额外的配置字段 admin_access,用于标识是否具有管理员访问权限。这可以通过修改寄存器类的定义来实现:

class my_register extends uvm_reg;
  bit admin_access;

  function new(string name = "my_register");
    super.new(name, 32, UVM_NO_COVERAGE);
  endfunction

  virtual function bit can_read(uvm_reg_map map = null, uvm_reg_item item = null);
    if (admin_access && !uvm_reg::default_map.has_write_access(UVM_BACKDOOR))
      return 0;
    return 1;
  endfunction

  virtual function bit can_write(uvm_reg_map map = null, uvm_reg_item item = null);
    if (admin_access && !uvm_reg::default_map.has_write_access(UVM_BACKDOOR))
      return 0;
    return 1;
  endfunction

endclass
 

在上面的示例中,我们重写了 can_read() 和 can_write() 函数,以检查是否具有管理员访问权限,并且不仅检查默认映射的访问权限,还检查是否具有后门访问权限。

然后,在使用寄存器模型的环境中,我们可以根据需要设置 admin_access 字段,为管理员用户启用后门访问权限。示例代码如下:

my_register my_reg;

initial begin
  // 创建寄存器模型实例
  my_reg = new();

  // 模拟环境中启用管理员后门访问权限
  my_reg.admin_access = 1;

  // 环境中的其他代码...
end

在上面的示例中,我们创建了 my_register 的实例 my_reg 并将 admin_access 字段设置为 1,从而启用了管理员用户的后门访问权限。

这只是一个简单的示例,实际情况中可能涉及更复杂的权限控制和访问策略。根据具体需求,可以根据寄存器模型的设计灵活地实现后门访问机制。


http://www.kler.cn/a/430403.html

相关文章:

  • STM32——系统滴答定时器(SysTick寄存器详解)
  • excel如何将小数转换为百分比
  • JAVA创建绘图板JAVA构建主窗口鼠标拖动来绘制线条
  • 『SQLite』表的创建、修改和删除
  • 【LC】2469. 温度转换
  • 资源分享:gpts、kaggle、paperswithcode
  • UiPath API接口说明
  • Next.js优化教程:优化脚本加载
  • Unity3D 为什么要避免使用SetActive详解
  • windows将文件推给Android真机/实机
  • Docker魔法:用docker run -p轻松开通容器服务大门
  • 双向链表的模拟实现 —— LinkedList
  • java全栈day12-后端Web实战(IOC+DI)
  • 在商业智能BI系统中,如何配置高级感的数据可视化折线图?
  • vue 封装全局过滤器
  • Leecode刷题C语言之判断国际象棋棋盘中一个格子的颜色
  • 子网划分实例
  • 数据结构第一弹-图
  • sql中的运算符
  • 数据结构题库11
  • 网络安全法-法律责任
  • 酷柚易汛进销存系统PHP+Uniapp
  • 上下料机器人,CNC 加工行业的变革性力量
  • 电动车多动力源的扭矩协调:提升能源效率与车辆性能的关键
  • 如何优化 JavaScript 中的 DOM 操作?
  • Linux: docker: 怎么修改 proc下的文件内容?