apb_i2c实验
具备APB接口的I2C_master控制器验证
验证计划
基于uvm的i2c模块验证
- 和以前项目的不同:不再是台阶,而是给你指定一个终点
- 虚拟项目给大家提供要给模拟的环境
- 按照模块验证时间,给大家6周时间(真实环境需要8-12周)
- 为什么有的8周有的12周?测试点列的越多所花费时间会用的更久,该项目不会特别多测试点
- 演练环节
- 每周会推出至少一版中的代码->石墨文档教下载最新代码
- 相关资料在课程说明里面(每周目标)
- 设计功能描述文档
- 验证文档
- 代码资料(github)
- 虚拟项目讲义
- 每周目标(6周)
- 第1周 熟悉材料(文档+代码),在Questa(Win)/VCS(Linux),都可以把对应版本的代码,根据简单指令提示运行起来
- 第2周 构建初步的验证环境(APB VIP, I2C VIP, virtual sequencer, env, test, RGM/adapter/predictor)完成build/connect/run,最终呈现一个清晰的验证结构层次,准备验证文档(使用DVT build文件,很快的理解结构与VIP中的方法)
- 第3周 发送典型激励:register test(简单的测试或者直接用内建测试)、i2c的TX/RX两个方向的数据发送、中断的发起和清除,最终应该有对应的virtual sequence和test
- 第4周 按照Quessta Vplan表格 / VCS HVP的表格(VCS的HVP可能不会提供),对应Coverage Model(env例化组件cgm),在测试点和功能覆盖率之间做映射,完善测试用例;同时,应该逐步完善scoreboard
- 第5周 准备验证文档(老实讲第2周就应该准备验证文档),可以作为一个面试材料呈现给面试官;继续填充sequence/tests,并且开始走收集覆盖率的流程(不管收集到哪里)
- 第6周 结合v2pro-第四周内容的回归管理(Quest Run Manager),利用这个回归管理工具,进行回归测试、覆盖率收敛
- 所有的核心在前五周,第六周使用回归管理工具/脚本把编译流程、收集覆盖率流程、覆盖率分析流程,全部固化到脚本中,通过用户界面的方式,很快的进行迭代工作
- 验证文档的框架(虚拟项目的说明的石墨文档)
- I2C虚拟项目背景
- 设计来源Synopsys DesignWare I IP(属于design IP)(OpenCore上的开源I2C IP太简单wishbound总线)
- 通过CoreTool/coreConsultant独立配置(参数),生成代码或文档(RTL代码、RGM代码、寄存器相关的HTLM、设计配置参数文档)
- 设计文档不需要每一页都读,对应我们参数设置到的
- VIP来源
- APB3 package来源于v2.3 VIP初级开发
- I2C package来源于v3.2 I2C VIP高级开发(3周)
- 顶层集成验证环境代码
- 较为完整文件列表
- 类名已预定义好
- 类内部多数为空(需要大家填充)
- 设计来源Synopsys DesignWare I IP(属于design IP)(OpenCore上的开源I2C IP太简单wishbound总线)
提供文档,为了方便理解设计文档、协议文档、接口文档
DW:DesignWare
- 使用LVC(Liezhen Verification Component)系列,比如lvc_i2c_pkg
- 参考Synopsysy SVT svt_i2c_pkg,即参考Sysnopsys的i2c的VIP文档(
- 所有类名和文件名,保持高度一致(只是将svt替换为lvc)
- 各个类的成员变量和方法(一部分保留,一部分做了剪裁)
- 建立DVT环境(build.dvt),通过UVM type/hierarchy browser,查看lv2_i2c_pkg每一个类的成员(你是做集成而不是开发,所以最快的方法是通过DVT的方法)第二周
- 提供example,学习lvc_i2c master/slave 集成、配置(configuration)、激励发送(transaction/sequence)
- 学习过程中,参考V3.1 SVT APB VIP说明(选学),掌握如何快速认识一个SVT VIP,比如I2C VIP,要用到的文档最多就是uvm class reference->index.html
- 主要学习的两个类:
- svt_i2c_configuration -> lvc_i2c_configuration,配置参数一摸一样,我们只是类名改了(学习如何配置)
- svt_i2c_transaction -> lvc_i2c_transaction(学习如何发送)
- 学习方式:参考example,或者rkv_config.sv,学习方法如下:
- 参考Synopsysy SVT svt_i2c_pkg,即参考Sysnopsys的i2c的VIP文档(
看配置参数
- configuration
- 如何发送transaciton(这个是sequence,到时候找文档是查询transaction配置的参数)
找文档解析
DW_apb_i2c_databook.pdf阅读
1.3 Feature思路对照配置内容
- 设计IP配置
- Synopsys coreConsultant,用于生成design ip
- 参数配置,进行功能裁剪
- 接口信号数量
- 寄存器和寄存器域数量
- 内部功能逻辑填充
- 在阅读DW_apb_i2c_databook功能文档时,对照我们的配置,去查看功能(相关配置信息截图如下)
2.Functional Description 功能描述
- 2.2到2.7为i2c协议,可以在design里面或者i2c协议里面看
- 2.8根据设计功能走的可以配置成什么样的工作模式,2.9,2.10增么样配置
- 2.11到2.14不用看
- 2.15可以看
- 2.16应该是不用看的吧(hold没有用)
- 2.17不用看
- 2.18很简单,简单看一下就好
- 2.19 IO接口很重要的,涉及到I2c接口的上拉电阻的处理(上拉电阻的意义:多驱动都保持低时,该点保持为高,由于i2c为低有效所以使用到了上拉电阻),需要我们在验证环境中实现相应连接的逻辑(看一下路桑怎么处理的)
- 2.20在第五章先不讲了
- 2.21不用看也是disable
3.Parameter Descriptions
参数在生成的verilog文件中:
xxxxxx_i2c_cc_constans.v
xxxxxx_i2c_bcm_params.v
,主要看这个,CoreTool是对这个进行了修改,这里面的每一个参数都跟spec下面的相关:
更简明扼要的参数配置信息在report的HTML里面
Generated Reports看着这个就够了
- I/O:中断接口、I2C接口、APB接口,Debug接口(设计流片/验证)
- Area stimate:后端相关不用看
- Component Registers:寄存器说明
- Component Configuration:配置表,配置表往往表明了哪些feature你需要验,讲的很明白了,只不过时英文的
Optional View不用看了,对应寄存器生成的头文件,UVM RGM在tb文件夹里有对应视频提到
- Activity Summary Report不用看
4.Signal Description不用看,看上面那个HTML,这里面讲的太全了
5.Register Description不用看,看上面那个HTML,这里面讲的太全了
6.Programming the DW_apb_i2c很有意义的,但可以不用看
- 编译、测试、配置会给建议的,但是以I2C的软件,C的配置为主,暂时不看不影响
7.Verification不需要看,我们不需要Vera的testbench
DW_apb_i2c_RGM_doc
也是寄存器的描述,是VCS生成寄存器模型的时候生成的HTML,但是比较简陋,大概浏览是够的
NXP I2C Specification and User Manual.pdf 时序协议
i2c的bus以前是在飞利浦从内部标准衍生为外部标准
主要看:就是看3.1
- 1-8要看
- 7-9都是disable
- 14-17是disable
- 13不测广播,目前是single
- 11 12可以测
- 10了解,我们VIP是slave,测得I2C的ip设置为master
不要看3.2
- 不需要看3.2我们已经disable了,目前我们就看standra fast fast-mode-plus这几种传输速度下的不同feature
4.Other不用看
5.Bus speeds可以看一下这些不同模式的要求
6.Electrical电气特性的要求,在不一样的情况下的时序要求,了解就可以了,在真正的验SoC的IIC是很重要的,如果不满足则不能满足电气上的要求
对于synopsys的VIP时序要求都会检查的,在设计IP或者目前我们自己写的IIC-VIP,关于时序检查电气特性的检查没有做要求
7.Electrical connection电气上的连接,主要做了解,主要是一个上拉电阻的处理,更多的关于电气特性的要求和SoC做集成时候的要求关系不大,包括上拉电阻的处理我们一般在板上面进行一个处理,当然放在SoC内部也是ok的
APB VIP文档
本不需要文档,v2.3第一周第二周就知道怎么用了
I2C VIP文档
这里推这个VIP,是参考sysnopsys VIP开发的,目前还没有这个文档,V3会运行sysnopsys VIP,但这个对我们来说太大太冗余了,因此我们用自己实现的20%功能的VIP,而且这个商业VIP也是加密的
这里参考Sysnopsys的文档
Synopsys SVT I2C VIP doc
- getting starting:快上手,这个可以看,参考这个把VIP集成进Testbench里面,目前提供的顶层env已经把该有的集成元素放进来了,你只需要在build和connect中进行例化与连接
- user_guide:重点!涉及到I2C VIP component是什么?如何配置的?User Interface是什么
如何看VIP的feature?那么多feature不需要看,主要看虚拟项目牵扯到的driver和monitor,送给scoreboard和coverage model。如何学习iic的VIP完全可以从APB的VIP开始
- uvm_class_reference非常重要
是synopsys vip里面每一个ip的说明,详尽的不得了,看的方法仍然参考APB VIP的阅读指导
- callbacks和functional coverage可以暂时不看
UVM代码环境介绍
规范
- agents包含目前的VIP,apb-master,apb-slave,i2c-master,i2c-slave
- cfg顶层的配置,第二周才会讲,参考代码第三周才ok,结合参考代码与DVT才能看出作用来
- cov功能覆盖率模型,跟vplan做一个映射
- doc生成的寄存器html(可以直接看设计这边的report),可有可无吧
- docs没有任何作用,删掉
- reg寄存器模型,如何自动生成?通过sysnopsys工具生成设计ip的时候带着ralf文件,借助vcs工具reg gen从ralf文件生成寄存器模型
- seq_lib空的,你不会填怎么办?先做一个quick_reg_access测试一下寄存器能否访问到(这是前两周的任务),因为第三周我们要做四个典型测试(register test,TX,RX,中断发起和清楚),其实第三周你知道测试怎么做了基本上是一个循序渐进的过程
- 如何运行?两条路线Questa和VCS,仿真都可以进行,但是只有Questa的会有覆盖率收敛与vplan的工具链讲解,VCS的没有
Questa运行步骤:
1 |
|
VCS运行步骤:Makefile(这里你直接看视频吧)
rkv_2c_sim.do文件作用:
- 编译(39行前)
- 仿真
第二周
顶层环境更新、测试用例要求、本周要求
验证环境
designware_apb_i2c有三类接口:
- apb_slave
- i2c_master
- interrupt
为啥这里还有i2c_master_agent?因为方便如果要验证DUT的slave模式,不过本实验仅验证DUT的master模式
coverage model第四周提供,这里为空
为什么不画框图?因为DVT给你画了验证结构
测试用例要求
directed_read
directed_write
dirct_interrupt:实现任意一个interrupt拉高的测试都可以
每一个test对应一个sequence
在做的时候要依赖底层的一些sequence
这周的要求
填写vritual sequence
把test跑起来,看vseq发送的激励与DUT输出的波形
底层序列库说明
如何填坑seq?
elem_seqs
1.rkv_apb_xxx_sequence.sv
:利用寄存器模型对寄存器进行访问
rkv_apb_config_seq
:会对设计里面的若干寄存器做操作,以实现DUT工作前的预期状态
rkv_apb_write_packet_seq
:把packet[]数据写入DUT
rkv_apb_read_packet_seq
:
- 根据packet数量,把读命令全部写入寄存器中
- 根据packet数量,把数据读出来(只要rx FIFO不为空就读)
rkv_apb_wait_empty_seq
:严格来说应该是wait_tx_empty_seq
,读状态寄存器,如果ACTIVITY等于零并且FIFO为空
rkv_apb_intr_enable_seq
:内部为空,可能不需要使用到后期可能会删除这个seq,因为目前没有intr没有相应的enable,i2c的intr不需要给他intr,只需要给他对应状态,不需要使能
rkv_apb_intr_wait_seq
:根据intr_id不同,等待不同的intr
rkv_apb_intr_clear_seq
:好多intr可以通过软件clear掉(直接用rgm写寄存器)
2.rkv_i2c_slave_xxx_sequence.sv
:表示目前外接的i2c_slave VIP,需要做一些反馈
就是一个write和read(和上图比删掉了rkv_i2c_slave_rx_seq)
对总线进行约束,没有进行randomize(nack=0)
- read多了一个packet.size,因为多了一个反馈嘛~
- read同时对data部分做了一个约束
路科这里讲的和傻逼一样,搁着绕口令呢
3.举个例子:如何实现directed_write
先调用apb_config_seq,再调用apb_write_packet写一个数据,同时调用i2c_salve_write_response确保slave是ack的
directed_read
也是这个思路
directed_interrupt
有一点不一样,具体问题具体分析(可以写满后检查,或者写满后清空再检查)
4.任务
第二周、第三周、第四周,这几周慢慢的补充这些sequence;第三周第四周给一个function coverage,给一个vplan,这个vplan不是一个非常全面的一个还需要考虑大家的时间,有可能这个vplan量不是很大,但是希望这些coding自己做
用户测试用例开发策略
- vseq填充完毕后对应的test也能跑起来了
第四周主要在做vplan和对应的cgm
路科就和傻逼一样,念车轱辘话,真他妈傻逼
自定义
自己写的elem_seq要写在user_elem_seqs里面
自己写的virt_seq要写在user_virt_seqs里面
- 写完后include到对应的
xxx_sequences.svh
里面
自己写的test要写在user_tests里面(include同上)
DVT项目配置及验证结构
项目目录:tb目录,不用包括设计IP,在build里面会添加设计IP的目录
default.build使用sim目录下提供的dvt.build,内容直接复制即可
编译使用Internal Builder
编译完成查看验证层次
查看验证结构图
修改查看层次:
查看object参差(点完以后,重新按照上一步修改层次Apply后,层次结构图就更新出来了)
图标保存
第三周
上一周任务:完善我们几个virtual sequence:
- quick_reg
- master_directed_read
- master_directed_write
- master_directed_interrupt
寄存器名称简写:
- CON:control
- TAR:target
- FS:fast speed
- DATA:
域:
RSVD前缀表示用不到
MST=master,一般表示master模式下的某种状态
SLV=slave,一般表示slave模式下的某种状态
其他:
STANDARD\FAST\HIGH三种模式:不同的速度模式的波特率、频率不一样
测试序列示例讲解1
quick_reg_access_virtual_sequence
1.在这里面利用寄存器模型写一些基本操作
调用顶层rkv_i2c_interface的一些函数,进行时序操作:
- wait_rstn_release();等待总线释放
- wait_apb();等待是个周期
2.do_reset_callback(),每次发现reset操作,就会同步的把register model也reset
3.rand一般表示可写入,没有rand一般表示只读
4.desired value
应该set而不能直接write,否则会导致寄存器整体被修改而不是特定field,或者使用get先获取如下:
5.FAST MODE & FAST SPEED
CON配置FAST SPEED模式,FS配置计数器
- HCNT、LCNT分别表示信号为高和为低的周期,一共加起来4us
- 200*10ns为2us
- 默认值在DesignWare配置的时候已经设置好了
6.最后使能,原因是因为很多配置寄存器的操作要求I2C模块是停止状态
7.DATA_CMD
DATA_CMD重要寄存器!这个寄存器除了写的命令和数据外,其他部分RSVD保留了(也就是说用不到,因为我们配置的时候取消了)
8.寄存器模型数据更新
- set的好处:会整体的写出去
为什么调用的是自定义的update_regs()
而没有直接rgm自带的rgm.update(status)
?因为rgm.updata(status)只会做写操作不会读操作,且会对所有寄存器都进行写操作,导致会对状态寄存器进行一个写操作,写入的为我们RGM中的数值,因此造成状态寄存器状态失效
rgm.update()源码:
updata_regs(寄存器数组):
- 在所有virtual sequence内定义的更新寄存器任务
- 含义:按照顺序对输入参数寄存器一个一个进行更新,而不是全部寄存器更新(rgm.update这种)
测试序列示例讲解2
做了questa仿真
run 0ns看了验证结构
设了断点,用于查看quick_reg_virt_seq执行
测试序列示例讲解3
master_directed_write_packet_virtual_sequence
这个vseq主要内容:apb发送数据到tx_fifo,i2c拿到这个数据写到i2c_slave
1.查看第一个uvm_do_on_with
- 不使用10BitADDR模式
2.配置seq设置了默认值,方便覆盖
值默认-1,方便seq被启动的时候overwrite
3.查看第二个uvm_do_with之apb_write_packet+sequence
定义packet动态数组
核心就是写数据
为啥要读?读FIFO是否为满
4.对i2c_slave一个要求
设置slave的ACK的i2c_slv_write_resp_seq在写TX_FIFO后面不会出问题吗?不会,写TX_FIFO是在很短时间内发生的,还没发送完全
能不能把34行放前面?可以,但是最好和27行fork_join_none
5.最后等待
为了让所有数据发出来,最后等待一个信号(但是路科觉得这个逻辑还要改)
但是路科觉得apb_wait_empty_seq需要改,增加RX_empty和TX_empty都为1的时候不应该光TX_empty
6.关于scoreboard一点提示
主要看master_scoreboard,后期测试用例越来越复杂,scoreboard会报错,这时候需要修改
8.波形一点小提示
这点毛刺不用管
9.debug信号很好用
s_gen:开始
p_gen:p结束
data:数据周期
addr:地址周期
…
由于设计是verilog代码,我们后期把debug_mst_cstate和debug_slv_cstate改枚举方便查看
测试序列示例讲解4
master_directed_read_packet_virtual_sequence
1.配置我们就不看了
2.这里有个fork_join
3.apb_read_packet_seq只需要指定大小,不需要指定内容
4.apb_read_packet_seq
写入读命令:
等待I2C返回读数据:
- 条件:RX_FIFO不为空(之前写是TX_FIFO不为满)
5.i2c_slv_read_resp_seq
slave_i2c不仅返回ACK,并且返回两个读数据
6.为啥没有在seq里做数据比对
在模块一级,我们倾向于把数据比对放到单独的scoreboard(这里是master_scoreboar)
7.到后期提升coverage
写自己的virtual_seq(在user文件里)
master_directed_interrupt_virtual_sequence
interrupt不是针对某一种行为发起interrupt,而是针对很多行为interrupt
后期coverage达到100%最难的就是制造interrupt场景
1.CLR,清空异常
每一个interrupt都有i个对应的CLR寄存器,CLR是只读寄存器,但CLR读了以后对应的异常会被清除
但TX_EMPTY拉低不了,因为他是硬件的行为,软件尚不支持直接CLR,他不是个异常(你说说路科讲的是不是依托答辩?)
2.查看vseq
- 配置不看了
- 直接把resp挂着
- 写了两个数
- wait_seq
4.wait_seq
读状态寄存器,等中断
和DUT(apb_i2c)顶层中的中断标志信号中INTERRUPT的名称做对比
这些INTERRUPT名称使用场景如下(并不是和状态寄存器完全匹配,有些可能没有):
5.最后写一下仿真命令吧
vsim work.rkv_i2c_tb -classdebug -sv_seed $SEED +UVM_TESTNAME=rkv_i2c_master_directed_read_packet_test +UVM_VERBOSITY=$VERB -l sim.log
第四周
测试点拆解
梳理功能,测试点拆解(正常应该第一节开始做),路科想让你先从底层框架开始拆解功能点
第四周、第五周、第六周,需要列出测试功能点,拿着这些功能点去定义coverage group和testcase
在映射方面,v3是vcs基础上通过hvp的表格使用verdi进行管理跟踪,v2pro是通过run manager和verification manager进行管理跟踪
1.手册阅读
我们使用到了4-50的feature,其他的没用到
2.查看configuration这个表决定了哪些功能要测试
3.questa_vplan(跟1.2.有关)
- 只列了我们要测的,并不是这个设计IP全部特性,为什么?
- 虚拟项目时长有关
- 和实际情况有关,我们只是用到master
- 有些feature测和不测都一样不影响
- 顺序
- 首当其冲先测寄存器
- 第二个i2c本身的协议
- 部分测试点解释
- 2.4有没有发生过restart
- 3.1查看时idel还是activity,是master模式下的activity还是slave还是同时master和slave模式?
- 3.2 enable还是disable
- 5.3 hardware signal在DUT顶层接口上的中断信号
- 5.4 tx_abort_source是一个专门的情况,状态寄存器STAT.TX_ABRT一旦拉高,需要去ABRT_SOURCE寄存器查看ABRT原因,但这些SOURCE不一定在design里面都发生,有的存在有的不一定(原因:有些source没有起到作用interrupt直接一直为0了)
- 6 SDA control,根据SDA_SETUP和SDA_HOLD寄存器描述,通过不同配置后观察波形是否出现相应的setup和hold timing来实现测试
- 好处:一方面软件知道怎么去配置了,一方面送到pad做接口交互时配置时更了解了
- uart、spi都不需要配置这个
- 7 timeout counter,读REG_TIMEOUT_RST寄存器,内容:一旦复位以后就开始做counting down,计数是计的占用apb总线的时间
功能覆盖率定义和收集
第六周,助手会在user目录里定义参考的sequence
1.关于2.1的覆盖率
with function sample
:覆盖covergroup内建采样函数
- 作用:外部调用sample的时候会传递两个参数进来
- 和直接在target_address_and_slave_address_cg加参数的不同:只是作为covergroup在例化的时候传递进去的参数,而with sample是外部传递进来的
- 这样做的好处?与之前学到的covergroup定义不同,可以不用传递interface进来了
2.为啥这里没写?添加自己的设置,你认为min、max多少合适,边界尽量cover到就行
3.wildcard,x或?表示不关心
4.covergroup的例化
5.采样
主要是检测APB总线
检测到APB上有数据(事件)则进行采样
- i2c_field_access_fd_e前门访问事件
- i2c_field_access_bd_e后门访问事件(寄存器测试中不会触发,所以添加了一个enable变量进行控制)
CLR的采样第一个参数修改为1
给事件产生添加enable条件
- 设置中设置
- scoreboard获取
- cgm应用
CDV脚本及流程演示
最后走一遍流程吧
questa_vplan就是i2c的plan,不管是xml还是xlsx都是插件编辑导出的,可以直接用vplan.ucdb
脚本流程
- 遍历运行UVM_TEST(不需要单独运行了,所有49行注释了)
- 最后所有ucdb与questa_vplan.ucdb进行合并
结束后打开覆盖率收集文件
图标右上角有p,表示plan
看什么
- 在ip的集成里面我们不会看ip的code coverage,最多看toggle coverage,因为IP设计公司提供的代码针对不同feature进行不同配置,因此code coverage在不同情况下覆盖率都不一样
- 主要看covergroups
回顾一下后门访问的优势
测试日记
3/15
第一次运行tb5收集覆盖率,遇到了Failed to open design unit file "../agents/lvc_i2c_mti/lvc_i2c_if.sv" in read mode.
问题,原因是原工程目录中lvc_i2c
目录应该是lvc_i2c_mti
,修改下名字即可
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!