随着uvm 和sv 在行业中使用的越来越广泛,公司需要为其工程师掌握uvm 或sv 安排大量的时间,更糟的是, 当工程师第一次用一门新语言为项目编码时很容易出错,这些错误不但要耗费debug时间,还会影响tb覆盖率和质量。 并且,当一个tb由多个工程师编码时, 顶层连接也可能出错。
而减少这些时间的一种方法是使用脚本产生顶层甚至更低层次的结构代码,这样确保了代码风格一致,连接一致,使得验证工程师有更多时间专注于实际design的验证,而非开发验证环境。 下面以创建基于DSP的验证环境为例向读者阐述。
下图(图1)显示了一个典型基于DSP的系统的框图: 下图(图2)显示了适用于单个FFE / FEC / DEC / NEC滤波器模块的UVM agent,它遵循标准UVM方法。
每个模块级 env 都实例化一个发送代理和一个接收代理, 发送代理又实例化 driver 和发送monitor; 接收代理实例化接收monitor; 发送monitor收集数据给reference model, reference model 处理完数据又交给scoreboard, 而scoreboard负责比较reference model端输出数据和接收代理monitor收集的数据。
下图(图3)显示了顶层env里实例化了若干个模块层env. 如上图(图3)所示,顶层env实例化了FFE env, FEC env, DEC env, NEC env等,要在很紧迫的期限内开发好这个复杂的UVM环境,写出所有UVM driver, monitor, sequence, agent等是不切实际的, 因此,我们用下面perl脚本产生每个block的UVM组件代码。
脚本根据block的各种参数生成UVM组件模板(driver,monitor,sequence,sequencer,scoreboard,Tx和Rx代理)。
下面显示了产生适用于DSP chip的driver的perl脚本代码, 脚本可以根据输入的不同产生相应block名字,事务类型,位宽的driver模板。 脚本先保存输入参数到变量$block_name,以及$tx_type, 然后传递参数并执行子程序gen_template(), 这个子程序实际上又执行另外两个子程序 create_header() 和create_uvm_class().因篇幅有限,只列出部分子程序create_uvm_class()的代码:
脚本自动产生的driver代码如下图所示,同样因篇幅限制只列出部分代码:
driver类定义了build phase(), run phase()等函数, 验证工程师现在就可以专注于写扩展的drive_dut()函数,而不用花时间再写这些通用的代码(如build/run phase, new function 等等)。以此类推,脚本也可以产生monitor, sequence, scoreboard, agent, env, test类的模板。
脚本能产生约60%的代码, 剩余40%的核心代码需要验证工程师自己填充,总体来说,它节省了很多的编码时间。 使用此脚本产生模块级tb用了一天时间,绝大部分随机测试和定向测试都能通过脚本产生。
脚本可以产生模块层和顶层验证结构,这节省了大量的时间以使得验证工程师可以专注投身于实际设计的验证。