何正浩 李威震
(江苏海洋大学电子工程学院 江苏省连云港市 222005)
伴随着集成电路技术的进步,SoC 设计的规模和复杂性也随之快速增长,此时对于验证人员而言,高效、结构化的验证环境变得比以往任何时候都更加重要。在实际芯片验证工作当中,在人力资源分配方面,很多时候验证人员是设计人员的1.5 倍,而对于实际工作量,“验证人员的工作量基本占到整体验证工作量的60%~80%”[1]。就通常情况而言,由于芯片设计的长周期特性,约在早期发现bug,所修补花费的成本也就越低,若是直至流片后才检查出,有可能造成芯片报废,需要重新更改设计后送交流片。这就对验证工作提出了更高要求,尽可能提高验证效率以满足工作进度需求,这就需要验证组件具有较强的可复用性,在不同层级验证时,验证组件能够复用,减少验证人员工作量,从而加快对目标模块的仿真速度,以达到快速验证,最终实现设计的快速迭代。
“对于验证,最传统的方法是直接使用Verilog 来编写testbench”[2]。这种方法对于简单的模块尚可一用,在复杂的设计当中,Verilog 就越来越力不从心。于是Verisity Design 公司(2005年被Cadence 收购)在2000年提出了e 语言,一种面向对象的编程语言。e 语言包括激励生成,结果对比,覆盖率模型等内容。“这是业内首次使用面向对象的编程语言来构建验证平台”[3]。2002年,Verisity 提出了第一个验证库,eRM(elanguage Reusable Methodology)。“2003年Synopsys 公司推出了采用Vera 语言的RVM(Reuseable Verification Methodology) 验证库”[4]。2006年,Menter 公布了基于System C 的AVM(Advanced Verification Methodology)。
2006年,Synopsys 推出了基于新语言System Verilog 的VMM(Verification Methodology Manual), 放弃了Vera 语言。次年Cadence 公司也放弃e 语言,全面过渡至System Verilog,并退出URM(Universal Reusable Methodology)。
2008年,“Cadence 与Mentor 联合推出开源的OVM(Open Verification Methodology)”[6]。2010年,Accellera 公 司 基 于OVM,推出了UVM(Universal Verification Methodology),UVM综合了VMM 和OVM 的优点,从VMM 中引入了寄存器解决方案。
2010年,“Synopsys 公司推出VMM1.2,这个版本参考了OVM 的TLM 通信机制和implicit phase,并进一步优化验证流程”[7]。2011年,“Accellera 公司正式宣布了UVM 1.0 版本,同时得到各EDA 厂商的大力支持”[8],目前最新框架版本是1.2 版本,由于UVM 作为新一代验证方法学,没有旧版本的兼容性负担,同时综合过往验证方法学的优点,目前UVM 已成为验证领域事实上的统一标准。
随着验证方法学的发展,作为硬件验证语言(Hardware Verification Language,HVL)的最新成果,System Verilog 目前已经成为使用最广泛的IC 验证语言。其综合了Verilog,VHDL,C++的语法特性,兼容Verilog。此外在不断演变过程中OpenVera发展成为SystemVerilog 中硬件验证语言子集,进一步扩展了语言特性。2005年,SystemVerilog 获批成为IEEE 1800-2005 标准。当时Verilog 作为IEEE 1364-2005 标准尚独立存在。2009年,SystemVerilog 与的Verilog 进行了合并,成为了新的IEEE 1800-2009 标准。现在的最新标准是IEEE 1800-2012 标准。
UVM 自身主要给出一套验证标准库,包含常用的基类和方法,这使得验证人员在搭建验证环境时,它的结构得以标准化。由于验证常常需要众多人员共同参与,一个标准化且组织良好的testbench结构,一致性的验证平台就显得尤为重要。同时可以减少多个验证工程师完成的验证工作之间的质量差距。UVM 给出了一种方法来提高验证的工作效率,验证代码的可移植性以及EDA 软件与VIP之间的互操作性。UVM 的所有功能并非都能适用于所有情况,UVM 的应用取决于用户和设计环境。
UVM 提供一系列的标准单元组件包括:Sequence 和Sequencer,负责激励的产生。Sequence 会借助SV 的随机化方法,产生符合要求目标数量和要求的事务,每个事务的数据均不相同。transaction 经由Sequencer 发往Driver。Sequencer 是uvm_component 类型,其自身并不产生激励,作用是作为sequence 与driver 之间的管道。transaction 是封装好的一组数据,一般是按照总线通信协议要求的各种参数的数据包。Driver 承担向Sequencer发出请求的责任,不断地要求transaction,除非仿真停止,否则这一过程会一直进行下去。在拿到事务数据后,driver 利用TLM 通信机制把收到的事务数据转化为实际信号发送给DUT。Monitor 负责的内容与driver 相反,monitor 负责从DUT 上采集信号,并转化为transaction 交给scoreboard。Agent 自身没有实际的操作内容,它主要用于将sequencer、driver 和monitor 进行一个简单封装,便于不同项目或仿真层次下,相同协议模块的复用,以减少验证人员的工作量,优化工作效率。Reference module 是用于模拟DUT 的功能,它会将和DUT 接收相同的数据,并将各自输出交由scoreboard进行比较。Environment 是对整个验证环境的封装,便于复用。
UVM 的主要特性:
(1)UVM 加入了Phase 机制,利用这一机制,即可在仿真阶段就开始进行组件层次化。
(2)UVM Factory 机制的存在使得在验证环境中替换实例和类型更容易、更灵活。但是被替换的组件必须与被替换的组件兼容。
(3)在UVM 则通过objection 机制来控制验证平台的关闭。
(4)利用域的自动化有关的宏,可以简化对象的复制。
(5)config 提供这样一个机制,来实现仿真时的环境控制。
本文的待设计模块是soc 系统当中的一部分。设计是基于平头哥的无剑100 开源平台实现音频播放,无剑100 开源平台是一个以E902 为核心的soc 系统,此平台搭载了gpio,uart,iic 等基础外设模块,内部也集成了DMA 等模块,功能较为齐全。设计就是在此平台基础之上实现MP3 播放。采用sd card 存放MP3 文件,在sd card 上挂载FATFS。通过FATFS 来读取MP3 文件,使用开源的helixMP3 解码库,helix 是一个定点的解码库,其占用内存较小,比较适合用在小型的32 位处理器上。解码之后的数据通过DMA 复制到IIS 模块,而CPU 与此同时继续解码,并行工作,增强CPU 工作效率。此外添加了vga 显示模块,用于实时展示播放状态和简单外部按键操作提示。至此实现了一个完整的应用场景。
本模块是属于音频传输部分。在CPU 对音频数据解码完成后,即可将解码后的数据传输给本模块,本模块负责将从ahb 接收到的数据缓存并转换为iis 接口格式的数据,随后发送给音频芯片。功能可以概括为协议转换,状态寄存器控制,fifo 数据缓存,数据发送。
之所以只用fifo 是由于ahb 与iis 时钟处在不同时钟域,解决跨时钟域问题。在CPU 利用AHB 端口发送数据时,本设计会检测ahb 控制信号,判断是否选通当前设计,trans,write 是否有效,将检测后的数据写入状态寄存器,作为fifo 的控制使能。而fifo 的时钟自然为ahb 时钟,同时fifo 会返回一个状态信号给hrdata。
对于数据发送,模块首先检测IIS LRC 字段选择信号的跳变,在这里我们默认左右声道数据相同。检测IIS CK 串行时钟线,利用计数器,作为数据指针将数据并转串发送数据。
I2S 模块接口如图1所示。
图1:I2S 模块接口
验证实现完成了对接口模块、事务级建模、序列发生器、驱动器、监视器、代理器等模块的编程设计。interface 接口模块是用于连接硬件和软件部分的桥梁。一般将模块接口信号在interface 中定义为logic 类型,通过运用modport 来设置信号的传输方向。利用clocking,基于时钟周期对信号进行驱动和采样,同时可以一定程度上避免信号竞争。利用clocking 进行事件同步。通过定义clocking skew(时钟偏移量),一般定义输入采样为负值,输出驱动为正值。这样形成事件时间前后的采样驱动可以有效避免出现信号竞争。如代码所示,在这其中我们定义输入驱动延时1ps,输出采样延时1ps。
接口设计中部分代码如下:
验证仿真工具是采用Mentor 公司的Questa Sim 2020.1。Questa与通常熟知的Modelsim 仿真软件类似,Questa 是其的升级版,主要是对UVM 的支持更好。验证过程是采用Makefile 脚本自动管理。通过Questa 通过的命令接口,以命令行的形式来控制仿真的过程。这种方法简化了复杂的图形化界面操作,自动创建过程并添加文件,启动仿真并添加波形。
使用vlib 指令创建环境,通过vlog 语句来编译目标文件,在这里要注意,uvm 验证环境当中类的编译顺序是有要求的,底层的要先编译,高层的后编译。随后利用vsim 语句来启动仿真,使用附加指令-do,来添加tcl 脚本实现自动添加波形;“使用+UVM_TESTNAME 来指定当前仿真的测试激励”[12]。目前版本需要添加附加选项-voptargs=+acc 来避免设计被优化导致仿真结果不符合要求。
I2S 时钟为11.025kHz,量化位宽16bit,DACLRC 则为BCLK的32 分之一,约为344.53Hz。I2S 模块等待LRC 的跳变边沿,利用边沿检测,在每次下降沿触发传输。利用移位寄存器进行并串转换,随后发送至输出端口。
通过自主搭建一个UVM 验证环境,实现按预定要求生成激励数据,并发送,基本完成设计目标。UVM 极大的提高了验证的工作效率,每个模块都是标准的输入输出,通过总线互联矩阵来进行连接。针对不同速率的传输,未来需要添加对应的时钟切换模块,切换时要考虑到时钟稳定时间,切换结果的确认;同时对于时钟切换,需要设置对应的配置寄存器,并开放给CPU 访问。设计改进需要添加状态寄存器,反应当前模块的传输状态信息,提高整个设计的处理效率。