仿真验证面试问题

1.Systemverilog相关

1.1Clocking block的作用

同步驱动和采样信号,声明信号相对TB的方向,并声明输入输出,(若不声明default input 1step output #0),防止竞争冒险;

1.2FIFO注意事项

(1)为啥使用virtual interface?
因为interface无法在class,program中实例化
(2)fork…join
1、fork join_any:只要有一个子线程优先完成就跳出fork join_any块,执行父线程。
2、fork join_none:直接跳出fork join_none块,执行父线程。

1.2FIFO验证点

功能类:

一、时钟测试点提取:
read/write相同时钟和不同时钟同时读写;
Read时钟快,write时钟慢,同时读写;
Read时钟慢,write时钟快,同时读写;
大比例时钟时正常工作:1)write时钟频率是read的4倍,同时读写;2).write时钟频率是read的1/4倍,同时读写.
二、复位测试点提取:
read端口reset测试;
Write端口reset测试;
先reset read端口,在reset write端口;
先reset write端口,在reset read端口;
同时将read和write 进行reset。
三、其他功能测试点提取:
基本的写功能验证;
基本的读功能验证;
读写功能同时进行的验证;
接口类:

一、Clk验证点提取:
验证不同频率下功能点是否正确;

二、Reset验证点提取:
验证不同时刻reset,功能是否正确;

三、寄存器接口验证:
验证寄存器访问是否正确;

四、串行接口:
验证发送接收是否符合预期;

五、中断接口:
验证产生中断触发条件,中断输出以及中断清除是否符合预期;

场景类:

一、验证收发功能:
验证是否可以正常接收发送数据,是否符合通信协议;

异常类:

空状态下读;
满状态下写。

1.2FIFO面试相关

1.2.1理解异步FIFO设计代码:主要侧重于设计要点(格雷码+俩寄存器同步),代码要看懂

(1)什么是异步FIFO?与同步FIFO有何不同?异步FIFO的设计理念和设计要点是什么?同步FIFO和异步FIFO的应用场景是什么?
a.FIFO是一种现先进先出的数据缓冲器,特点是没有外部的读写地址。
b.由于没有外部的地址信号,所以只能顺序的读写,而不能跳读。FIFO的读写是根据满和空信号设 计写使能和读使能来写/读FIFO,当FIFO满的时候不可以往里面写、当FIFO空的时候不能读数据。读FIFO时,内部的读指针自动的加一,当写FIFO时写指针自动的加一。
c.同步FIFO:数据写入FIFO的时钟和数据读出FIFO的时钟是同步的
异步FIFO: 数据写入FIFO的时钟和数据读出FIFO的时钟是异步的

(2)空满状态位是怎么得出的?为什么要用格雷码编码而不用二进制编码和独热码编码?为什么要经过俩级寄存器的同步再进行指针的对比(涉及到亚稳态)?
a.写指针:总是指向下一个将要被写入的单元,复位时指向第一个单元。
读指针:总是指向当前要被读出的数据,复位时指向第一个单元。
也就是说,复位时读写指针都指向第一个单元。并且向FIFO写入一个数据,写指针加1。从FIFO中 读出一个数据,都指针加1。
b.判空:读指针追上写指针的时候,两者相等,为空。
判满:写指针追上读指针的时候,两者相等,为满
c.读写指针的数据位宽上再加1位来区分是满还是空。比如FIFO的深度位8,那么需要3位二进制数来表地址,则需要再最高之前再加一位,变成4位。一开始读写都是0000,FIFO为空。当写指针增加并越过最后一个存储单元的时候,就将这个最高位取反,变成1000。这时是写地址追上了读地址,FIFO为满。同理,当读地址越过最后一个存储单元的时候把读地址的最高位也取反。可以看到,当最高位相同,并且剩下的位也相同的时候FIFO为空;当最高位不同,并且剩下的位相同时,为满。
d.二进制码的跳变可能涉及到多位,跳变可能出现很多中间过程,时钟可能采样到跳变的值;而格雷码每次只有一位改变,能够解决同一时间又2个bit以上变化的问题;为啥不用独热码,因为独热码速度较慢,触发器占用资源较多,面积较大。

(3)亚稳态相关问题:什么是CDC(跨时钟与传输问题)?CDC为什么会产生亚稳态?建立时间和保持时间的概念?如何尽可能降低亚稳态的发生概率?单bit数据怎么进行跨时钟域的传输以及多bit如何进行跨时钟域的传输?
a.当信号在不同的时钟域传输,就被称为跨时钟域
b.当数字信号跨时钟域传输时,就会产生亚稳态问题。亚稳态是指触发器无法在某个规定时间段内达到一个可确认的状态。每一个触发器都有其规定的建立(setup)和保持(hold)时间参数, 在这个时间窗口内, 输入信号在时钟的上升沿是不允许发生改变的。如果触发器的数据输入端口上数据在这个时间窗口内发生变化(或者数据更新),那么就会产生时序违规,触发器的输出将徘徊在不可预知的电平状态,即亚稳态。
c.亚稳态是不可避免的,但是可以降低发生的概率,具体的方法有使用两级寄存器同步、使用格雷码
d.处理多bit数据的跨时钟域时,采用较多的是异步双口RAM或者异步FIFO

1.2.2制定验证计划、提取验证功能点:(接口方面、功能方面、异常方面)

(1)关于这块面试官通常让你介绍一下你的验证功能点   
     验证计划其实就是模块级别的验证,主要用sv语言搭建了验证平台进行验证。验证功能点也相对简单,最最重要的验证点就是功能(异步FIFO的读和写功能),除此之外就是验证接口这块,主要包含时钟和复位,比如验证读写时钟不一致的情况,比如写时钟快,读时钟慢,又或者写时钟慢,读时钟快,以及同时读写,先写再读等情况。异常情况就是FIFO的写满和读空。

1.2.3搭建验证平台:主要描述验证平台结构以及数据流方向

关于验证环境这块,大部分面试官只会问验证框架是怎么样的,数据流是怎么样的?极少部分让讲你的某个class具体代码是如何实现的。
(1)介绍你的验证环境是怎么样的?
一般来说,从最顶层Top层向下一层一层介绍你的验证环境,比如top里面例化了DUT、interface、env等等。然后env里面又例化了比如driver、monitior等等。
包括的组件有interface,packet,fifo_params,clockgenerator,resetgenerator,driver,monitor,scoreboard,environment.fifo_top,top等
验证结构框图
interface是接口连接,是DUT和TB验证环境之间的信号传递的媒介
clockgenerator,resetgenerator分别产生时钟和复位信号
generator负责验证数据的产生
driver主要负责激励的驱动,将generator产生的数据驱动到interface上去,在本环境中还设置了另一个功能,将激励通过mailbox传送到scoreboard。
monitor 主要负责从interface上边检测到激励后送到scoreboard进行比较
scoreboard接收到monitor检测到的数据进行对比
environment 验证环境,主要负责将以上组件进行组合,具有层次结构性
fifo_top是将DUT和TB信号进行连接
top是将interface,fifo_top,environmen进行关联
(2)介绍你的数据流向(读操作和写操作具体怎么进行的)?
比如写操作:driver产生数据后通过interface发送给DUT(具体发送到哪个端口?),以及monitior从DUT的哪个端口读取数据(读操作)?
itf.wdata
itf.rdata
(3)你的环境中的scoreboard是怎么对比数据的? 不同组件(class)之间是用什么进行通信的(mailbox)?
将数据从mailbox 使用get方法得到,分别从driver和monitor得到

1.2.4跑仿真:主要验证了什么

  (1)你是怎么跑仿真的?
   使用verdi看波形,比较scoreboard打印出来的值
    (2)你写了几个case?
    13
    (3)都验证了那些情况?你写scoreboard了吗?scoreboard是怎么实现的?
    验证了,
    (4)采取的定向测试还是随机化测试?你的driver是怎么实现随机化的?
     定向测试+随机化测试
     有专门的数据生成组件datagenerator,数据生成时随机化的,生成的数据通过mailbox传递给driver

1.2.5收集覆盖率:代码覆盖率和功能覆盖率情况

    (1)你是怎么样衡量你的验证完善程度? 
             覆盖率报告 ,BUG曲线是否稳定趋近于0
   可以使用—个反馈回路来分析覆盖率的结果,并决定采取哪种行动来达到100%的覆盖率。

• 首要的选择是使用更多的种子来运行现有的测试程序。
• 当大量种子依然对于覆盖率增长没有帮助时, 需要建立新的约束。
• 只有在确实需要的时候才会求助于创建定向测试。
(2)代码覆盖率有哪几种?分别讲讲你的代码覆盖率情况?
代码覆盖率100%
行覆盖率、路径覆盖率、翻转覆盖率、状态机覆盖率
• 代码覆盖率最终的结果用于衡量你执行了设计中的多少代码。
• 关注点应该放在设计代码的分析上, 而不是测试平台。
• 未经测试的设计代码里可能隐藏硬件漏洞, 也可能仅仅就是冗余的代码。
• 代码覆盖率衡量的是测试对于硬件设计描述的“实现"究竟测试得有多彻底, 而非针对验证计划。
• 代码覆盖率达到了100%, 并不意味着验证的工作已经完成, 但代码覆盖率100%是验证工作完备性的必要条件
(3)功能覆盖率怎么实现?你写了哪些covergroup和coverpoint?最终功能覆盖率的情况如何?
功能覆盖率100%
• 验证的目的就是确保设计在实际环境中的行为正确。
• 功能描述文档详细说明了设计应该如何运行, 而验证计划则列出了相应的功能应该如何激励、 验证和测量。
• 当你收集测量数据希望找出哪些功能已经被覆盖时, 你其实就是在计算”设计“的覆盖率。
• 功能覆盖率是和功能设计意图紧密相连的, 有时也被称为”描述覆盖率”, 而代码覆盖率则是衡量设计的实现清况。
• 某个功能在设计中可以被遗漏, 代码覆盖率不能发现这个错误, 但是功能覆盖率可以。
• 每一次仿真都会产生一个带有覆盖率信息的数据库, 记录随机游走的轨迹。

• 把这些信息全部合并在一起就可以得到功能覆盖率, 从而衡量整体的进展程度。
• 通过分析覆盖率数据可以决定如何修改回归测试集。
• 如果覆盖率在稳步增长, 那么添加新种子或者加长测试实际即可。
• 如果覆盖率增速放缓, 那么需要添加额外的约束来产生更多“有意思”的激励。
• 如果覆盖率停止增长, 然而设计某些测试点没有被覆盖到 , 那么就需要创建新的测试了。
• 如果覆盖率为100%但依然有新的设计洞洞 , 那么覆盖率可能没有覆盖到设计中的某些设计功能区域。

    (4)如果你的代码覆盖率低该怎么改善?功能覆盖率低该怎么改善?

a.增加测试case
b.添加随机化次数,添加约束,自定义bin

1.3 封装、继承和多态

(1)封装:封装是面向对象编程的核心思想,是指将对象的属性和行为封装起来,
封装的载体是类,类通常对用户隐藏其实现的细节,这就是封装的思想。
采用封装的思想保证了类内部数据结构的完整性,应用该类的用户不能
轻易直接操纵该数据结构,而只能执行该类允许公开的数据。这样可以
避免外部对内部数据的影响,提高程序的可维护性。
(2)继承:类的继承包括了继承父类的成员变量和成员方法。也就说一个子类在继承父类成员变量
的同时也继承了父类操作这些成员变量的成员方法。
(3)多态:当一个类派生出子类的时候,基类中的一些方法可能需要被重写;
用对象中的类型来决定调用哪一个实现方法,这是一个动态的过程。
动态的选择方法的实现方式叫多态。
没有继承就没有多态。

1.4 virtual Interface和Interface

(1)Interface:接口可以取代很多的信号连接,使代码更加容易维护和修改,还可以减少出错
程序块可以减少待测器件和测试平台之间的竞争状态
在接口中使用modport进行信号分组,使用时钟块使得测试平台能够相对于时钟正确地驱 动和采样设计信号
(2)virtual Interface:interface 简化了模块之间的连接,但是无法很好地适用于基于OOP的测试平台,无法在program 、class 中进行实例化,所以引入了虚接口,virtual interface的本质是指针,是指向interface的指针,即virtual interface是可以在class中实例化的数据类型,interface将测试平台与DUT分开, virtual interface可以在TB的不同位置操纵一组虚拟信号,而不是直接操纵实际的信号。

2.UVM相关

2.1 AHB和APB时序

2.2 建立时间和保持时间

建立时间:
时钟有效沿到来之前的某段时间内,数据必须稳定,否则触发器锁存不住数据,这段时间成为建立时间,用Tsetup或者Tsu表示,也就是说要锁存的数据比上升沿早来的时间必须大于建立时间。
保持时间:
时钟有效沿到来之后的某段时间内,数据也必须稳定,否则触发器锁存不住数据,这段时间成为保持时间,用Thold或者Th表示。也就是说,要锁存的数据,在上升沿到来之后,还要停留比保持时间大的时间。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值