数字IC验证成长录--其他技能介绍

以下内容来源牛客特邀专刊《数字IC验证成长录》,作者@竹秋一

接下来介绍一些验证方向之外的知识,原因有两点:一方面验证人员要对一些设计结构有个大概了解,不能什么都不知道,另一方面是笔试会经常考这些东西。

跨时钟域

当两个不同时钟频率的模块进行通信时,需要进行跨时钟域处理,否则会导致亚稳态、数据丢失等问题。

这里我直接推荐学习资料:知乎搜索“李虹江”老师,进入主页找他的文章“CDC的那些事”,这是个系列文章,看完之后基本就能搞清楚跨时钟域,我当时就是跟着这个文章学会的。或者腾讯课堂搜索“异步电路设计”,老师叫“goodman2046”,课程很便宜,一顿饭钱。

静态时序分析

笔试题经常会给出一个电路图,让你计算最大频率或者问是否存在保持时间违例。STA的知识并不难,只要记住公式的推导过程以及一些概念性的东西,基本都能做全对。

首先推荐“IC创新学院”搜索“静态时序分析”,邸志雄老师的课程,讲的非常细,看完一遍基本遇到STA的笔试题都不怕了。不过这个网站最近不知道出了什么问题一直进不去,没关系,B站也有同款视频,搜索“数字集成电路静态时序分析基础”,up主“讲芯片的邸老师”。另外一个就是腾讯课堂里的“FPGA静态时序分析精讲”,V3学院的免费课,讲的也是很不错的。

总线协议

总线协议是验证工程师必会的知识点,在实际项目中经常接触,并且也是面试官常考的问题。

先总结:AMBA总线必须学,至少要会AHB和APB,有能力的就把AXI也掌握了,其次UART、SPI、I2C、I2S、CAN协议比较简单,可以选择性的学习,最后如果有机会的话,USB、PCIe协议也可以了解一下。

AMBA协议文档方面我优先推荐的是看官方的文档,其次是网上的中文资料。原因是英文原版表达出来的意思不会偏差,而网上中文翻译的文档都会多少带着翻译人自己的理解,而且看英文文档能锻炼阅读能力。同时找一些带着AMBA接口的项目做一下,跑一跑波形,对着波形图去理解,在实践中学习。

UART、I2C等协议也是一样的方法。

记住实践很重要,只对着文档看而不去操作,是无法深入理解的。

题库

这里是一些我亲身经历的IC验证岗位的笔试面试题,并附上了我的实际回答情况,可能有错误或不全面的地方,如果发现欢迎指正。

由于笔试题存在很多非验证题目,而且笔者没有怎么整理过笔试题,所以最终选择的合适的笔试题数量不多,更多的题目可以在牛客网搜索。面试题目也只是整理了一些适合读者借鉴的题目,并且进行了筛选,和我个人简历或者项目相关的题目我都省略了。

笔试题

  • SV中类默认的成员属性是

A. Local

B. Private

C. Public

D. Automatic

答案:C。声明成员时如果没有指明,则默认类型为Public,子类和外部都可以访问;如果是local,那么只有该类可以访问,子类和外部无法访问;如果是protected,那么该类和其子类可以访问,外部无法访问。

  • 一段程序如下,请问在45这个时刻上,A B的值各是多少

A. 1,1

B. 0,1

C. 0,0

D. 1,0

答案:C。begin end块里顺序执行,因此每个延迟都是叠加的,不是具体的时刻。fork join块里并行执行,因此这两个begin end块同时开始,并且没有握手通信,互不干扰。所以在45时刻,两个begin end块都执行了“#20 A/B = 0;”,直到50时刻才被赋1,所以结果都是0。

  • 在SV中,调用$write可以自动地在输出后进行换行

A. 正确

B. 错误

答案:B。$display打印会自动换行,$write不会。

  • 以下SV程序的运行结果为

A. 32’hFFFFFFFF

B. 32’h00000000

C. X

D. 32’h00000001

答案:B。该例中定义了一个Test类,并例化出句柄t,调用new函数创建对象,并传入了一个参数值“32'h1”,这个“32'h1”赋值给了new函数中的addr,将addr的值“32'h1”赋值给“另一个”addr,但这并不是另一个addr,不是Test类中定义的addr,而是new函数自己的参数。知识点:在函数中索引一个变量名,会优先“就近寻找”,比如该例中的new函数中的addr就是形式参数addr,想要指向类中的变量,是需要this关键词指示的,比如“this.addr”,因此t句柄指向对象中的addr仍然为初始值,bit是二值逻辑,因此addr的初始值为0。在打印消息时,调用了display_addr方法,该方法中的addr同样就近寻找,发现function中没有定义addr,则继续向上一层寻找,找到类中的addr,并进行打印。因此最终打印结果为0。

  • 关于uvm sequence常用宏,以下说法不正确的是

A. uvm_do_on_pri可指定transaction发送时采用的sequencer,同时指定优先级

B. uvm_do_on可指定transaction发送时采用的sequencer

C. uvm_do_with可添加激励约束

D. uvm_do可指定transaction发送时采用的sequencer,同时添加激励约束

答案:D。宏里有“on”表示可以选择采用的sequencer,有“with”表示可以添加约束,带“pri”表示可以指定该trans的优先级。

面试题

  • 模块级和系统级验证的关注点有什么不一样

模块级验证更加注重模块接口及内部的细节,包括接口时序、代码覆盖率、边界情况等,例如模块能否处理错误的接口时序、工作时复位状态机能否正常跳回、未执行的代码分支的原因等,并且测试用例多为SV或UVM用例;系统级验证关注整个SoC的场景以及各模块的协同工作,例如数据的吞吐率、中断信号是否正确交给CPU等,并且测试用例多为C测试。

  • UVM工厂机制的好处

使用工厂创建的类,成员可以使用UVM提供的高效方法,如克隆、打印,对象也可以在创建前被新的类型覆盖,保证环境的封闭性。

  • 如何划分验证功能点

可以根据接口、寄存器、中断以及配置流程划分。接口可以根据时序和协议划分一系列功能,如同时读写、连续读写、非法地址访问、不同时钟频率不同的工作状态等;寄存器可以根据每个寄存器域的功能划分各种工作场景,并将它们cross在一起;中断可以划分为触发中断、清除中断、屏蔽中断等;配置流程方面,比如连续配置寄存器使模块不断切换模式进行运作、复位后重新使能等。最后加上边界情况,大致功能点就划分好了。当然一个人的想法是有限的,划分出的功能点需要和设计人员以及leader进行多次review,不断补充。

  • 功能覆盖率怎么定义(手撕代码),采样的信号从哪里来

class my_coverage_model extends uvm_component;

`uvm_component_utils(my_coverage_model)

covergroup cg with function sample(bit value);

mode: coverpoint value

{

bins value_0 = 0;

bins value_1 = 1;

        }

……

    endgroup: cg

……

function new(string name = "my_coverage_model", uvm_component parent);

super.new(name, parent);

cg = new();

……

endfunction


task build_phase(uvm_phase phase);

super.build_phase(phase);

……

endtask


task run_phase(uvm_phase phase);

super.run_phase(phase);

fork

this.do_sample();

join_none

endtask


task do_sample();

forever begin

@(posedge clk iff rstn);

cg.sample(value);

end

endtask

endclass

大概写一下就可以了,说清楚细节。采样的信号可以从接口上获取,也可以从寄存器模型里get,如果有必要,可以从trans获取随机后的值。

  • 写一个driver class基本的结构

class my_driver extends uvm_driver #(my_trans);

virtual my_interface vif;

`uvm_component_utils(my_driver)

    

function new (string name = "my_driver", uvm_component parent);

        super.new(name, parent);

    endfunction


function void set_interface(virtual my_interface vif);

if(vif == null)

    `uvm_error("GETVIF","interface handle is NULL, please check if target interface has been intantiated")

else

    this.vif = vif;

endfunction


task run_phase(uvm_phase phase);

        fork

    this.drive();

    this.reset();

join

endtask

task reset();

forever

begin

    ……

end

endtask

task drive();

my_trans req, rsp;

@(posedge vif.rstn);

forever begin

    seq_item_port.get_next_item(req);

    this.do_driver(req);

    void'($cast(rsp, req.clone()));

    rsp.rsp = 1;

    rsp.set_sequence_id(req.get_sequence_id());

    seq_item_port.item_done(rsp);

end

endtask

        

task do_driver(my_trans t);

……

endtask

endclass

driver的写法有很多种,这里只举一个简单的例子。但同样也要讲清楚每一行代码的意义。

  • sequence怎么挂载到sequencer上,激励怎么发出来

顶层sequence在test中创建并start到virtual_sequencer上,子sequence在顶层sequence中声明,使用`uvm_do_on_with等宏实现创建、随机和挂载,sequence里的transaction被发送到对应的sequencer上,传递给driver,通过driver向interface驱动发送出来。

  • Interface怎么传递到环境里

使用uvm_config_db的set和get方法,在tb的initial里set,在环境中get。

  • 两个task怎么并行执行

使用fork join/join_any/join_none调用两个task。

  • `ifndef,`define,`endif有什么用

编译代码时工具会记录这些参数,当遇到同名的参数时,就不会编译`define中的内容,减少编译时间。

  • uvm_object和uvm_component的区别

简单来说,uvm_conponent及其子类始终存在于环境中,而transaction、sequence等激励属于object,只有在仿真过程中被创建,并在完成发送激励的使命后消失。

  • 如何使用set_factory_override

该方法用于在不改变原始代码的情况下,完成在类被创建前进行类型覆盖,需要满足以下条件:被覆盖类是覆盖类的父类;都使用工厂机制注册过;该方法需要在build阶段之前使用。

  • 如何在一个sequence中发送两种不同类型的item

在sequence中声明两种item,使用带有“on”的宏方法挂载到不同的sequencer上。

  • monitor将数据交给了谁。

scoreboard、参考模型、覆盖率模型。

  • 讲一下virtual_sequence和virtual_sequencer的内容和用法。

virtual_sequencer中声明了环境中所有sequencer的句柄。virtual_sequence中使用宏`uvm_declare_p_sequencer声明一个virtual_sequencer类型的p_sequencer,继承于virtual_sequence的top_sequence中定义的sequence和item就可以使用宏方法通过p_sequencer句柄找到自己的sequencer进行挂载。

  • m_sequencer和p_sequencer之间的关系。

m_sequencer是p_sequencer的父类。m_sequencer存在于uvm_sequence中,类型为uvm_sequencer,当该sequence挂载到一个sequencer上时,m_sequencer指向该sequencer。p_sequencer在virtual_sequence中声明,类型为virtual_sequencer,用于让各个sequence能够在编译和仿真阶段找到自己的sequencer。

  • top_seq一般在哪里挂载到virtual_sequencer。

在每个test的run_phase中挂载。

原文链接:数字IC验证成长录-其他技能篇


#数字IC设计工程师#
全部评论
楼主厉害,感谢分享,写的非常详细。
点赞 回复 分享
发布于 2022-02-24 16:44

相关推荐

码农索隆:想看offer细节
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
5
55
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务