IC验证秋招笔记

1、wire型和reg型的区别

        wire型数据常用来表示用以assign关键字指定的组合逻辑信号,reg型相当于储存器的基础上,可以看做是一个一个的寄存器,当触发条件达成时,寄存器的内容才发生改变,否则一直保持上一个状态。

wire型相当于是一根连线

reg型相当于是储存器

注:reg型常被用于always模块内,也可以在initial里。而always模块内被赋值的每一个信号必须被定义成reg型。

2、顺序和并行

        Verilog模块中所有的过程块(如initial块,always块)、连续赋值语句、实例引用都是并行的。对于过程块,在Verilog模块中是并行执行的,但在内部是顺序执行,如always内部顺序执行。

注:initial块只执行一次,而always块不断反复执行,直到仿真结束。

3、Verilog里为什么不用花括号{}而用begin...end?

        C语言中花括号{}的作用:就是把多个单条语句用花括号{}括起来组成一个结构上可以认为是一个复合语句。

       而Verilog里自上而下的程序性代码用begin...end类似于C语言里的{},但是却不能用{},但是在约束constraint以及coverpoint的内容要用{}围起来,因为这里是声明性代码(声明语言),是并行的。

         Verilog里面用begin...end关键字,用于多语句组成顺序块。Verilog 里{}还有两个基本作用,一个是拼接,一个是复制,如下

  • { }表示拼接,{第一位,第二位…};
  • {{ }}表示复制,{4{a}}等同于{a,a,a,a};
    所以{4{1‘b1}}就表示将6个1拼接起来,即4’b1111

4、描述一下 code coverage 和 function coverage 的区别,为什么需要这些 coverage?

        验证中,代码覆盖率是指衡量哪些设计代码在激活触发,而哪一些则一直处 于非激活状态的统计数据 ,而功能覆盖率指我们对设计所实现功能特性的收集  。

        即使我们可以达到 100%的代码覆盖率,但这并不意味着 100%的功能覆盖率。原因在于代码覆盖率并不是用来衡量设计内部的功能运转,或者模块之间的互动,或者功能时序的触发等。代码覆盖率可以通过仿真器完成自动收集

        类似地,我们即便达到了 100%功能覆盖率,也可能只达到了 90%的代码覆盖率。 原因可能在于我们疏漏了去测试某些功能,或者一些实现的功能并没有被描述。 功能覆盖率需要通过人为定义,与拆分的待测功能点做一一映射。

        从上述关于代码覆盖率和功能覆盖率简单的论述就可以证明, 没有任何一种单一的覆盖率可以完备地去衡量验证过程 ,如果想要得到全面的验证精度,我们就需要多个覆盖率种类的指标。

注:

代码覆盖率 100% 不代表功能没问题。

(1)功能覆盖率高但是代码覆盖率低

分析未覆盖到的代码,推断仿真是否有遗漏的功能点,代码是否为冗余或不可达代码;

(2)功能覆盖率低但是代码覆盖率高

仿真用例没有关注到一些功能点,需要修改测试用例

       

5、定宽数组、动态数组、关联数组、队列各自的特点和使用

        定宽数组:定宽,顾名思义就是一个确定的状态,是一个静态数组编译时就已经确定了大小。其可分为压缩数组和非压缩数组,压缩数组是定义在类型的后面,名字的前面,例如        Bit[7:0][3:0]name,而非压缩数组是定义在名字的后面,例如Bit[7:0]name[3:0]

        动态数组:与静态数组不一样,编译时还未确定大小,只有在其内存空间运行时才能确定大小,使用前需要new[]进行空间分配。

        关联数组:其主要针对超大空间但是又不全部需要所有数据时使用,这类似与Java里面的Hash,通过一个索引值的一个数组组成,且索引值必须唯一。例如bit [63:0] name[bit[63:0]]。

        队列:队列结合了数组和链表的特点,可以在一个队列的任何位置进行增加或者删除元素。其通过[$]这样的符号进行申明:int q[$]。

6、结构体和联合体的区别

        结构体 struct,其相比于其他数据结构,主要的特点就是可以由不同类型的数据类型变量组成,然后可以对这个结构体进行操作。Struct {bit [2:0] a,int c}name;

        联合体 union 是对同一个内存变量可以有不同类型,比如一个寄存器有时 候为整数,有时为小数。

7、简述在 TB 中使用 interface 和 clocking block 的好处

        Interface 是一组接口,用于对信号进行一个封装,捆扎起来。如果像 verilog 中对各个信号进行连接,每一层我们都需要对接口信号进行定义,若信号过多, 很容易出现人为错误,而且后期的可重用性不高。因此使用 interface 接口进行连 接,不仅可以简化代码,而且提高可重用性,除此之外,interface 内部提供了其他一些功能(引入delta_cycle)用于测试平台与 DUT 之间的同步和避免竞争。

        Clocking block:在 interface 内部我们可以定义 clocking 块,可以使得信号保持同步,对于接口的采样和驱动有详细的设置操作,从而避免 TB 与 DUT 的接口竞争,减少我们由于信号竞争导致的错误。采样提前,驱动落后,保证信号不 会出现竞争。

8、简单介绍一下 virtual methods,SV 中什么需求下必须使用 virtual methods。

          虚方法就是一个基本的多态结构,在父类中使用virtual定义的方法和函数,父类句柄在指向子类对象时,可以动态索引到子类重写的子类方法

理解:

        当需要决定调用哪个虚方法时,SV会根据对象的类型,而非句柄的类型决定调用什么方法。这句话的理解是:即,当父类A定义了一个virtual method(),子类B中重写了方法method()。子类B例化后有个句柄b指向子类对象,将子类句柄b赋值给父类句柄a,即 a = b 。此时父类句柄a指向子类对象,调用a.method(),SV中会有个动态查找的过程,当a句柄看到父类A中的method()是虚方法时,会查找子类中是不是重写了method(),如果子类中也有同名、同参的方法,会直接调用子类中的method(),实现子类对父类方法的继承。

        (1)在父类定义方法时,若该方法后面可能会被覆盖或者继承,则应该声明虚方法

        (2)虚方法如果定义,尽量定义在底层父类中

        (3)虚方法virtual一次声明即可,子类无需再次声明

        (4)虚方法的继承要和父类的参数和返回值类型相同

        (5)不能给成员变量添加virtual,不能用父类句柄找到子类中的成员变量。如果这个句柄,真正指向的是子类对象,那么就通过动态查找找到子类的方法,但不能找到变量。

  1.         
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值