基于FPGA 的PIE 编码与UVM 验证平台的设计*
2021-06-30李姝萱
李姝萱,卜 刚
(南京航空航天大学 电子信息工程学院,江苏 南京 211106)
0 引言
随着集成电路的快速发展,芯片研究周期不断缩短,传统的基于testbench 的验证方式由于效率低、难达到预期覆盖率以及可移植性差等缺点,不适合日渐复杂的SOC 芯片开发。目前,通用验证方法学(Universal Verification Methodology,UVM)已成为IC 验证领域最为广泛使用的验证方式。UVM 兼具封装、继承、面向对象等特点,拥有大量功能全面的组件和基类,同时开发了factory、config 等机制,可根据工程特性灵活地搭建验证结构。
RFID 是非接触式的无线通信技术,它通过对射频信号进行调制、解调来实现信息的传输,是当今最有发展前景的技术之一。目前,RFID 技术已经广泛应用在众多行业和领域,如物流运输、资源管理、军事国防、智能交通、门禁考勤、医疗电子等领域[1-2]。本文针对无线射频识别(Radio Identification,RFID)数字基带处理单元中阅读器发送链路编码模块进行设计,并进行了仿真和板级验证,采用串口通信作为物理通道,实现了PC 端与FPGA 板之间实现互传数据。为进一步验证编码功能,搭建了UVM 验证平台,采用DPI 接口调用C 语言编写的参考模型,实现了待测设计和C 模型在记分板中的输出结果对比一致。
1 PIE 编码
图1 为RFID 阅读器发送链路结构图。阅读器产生命令信息,经编码、调制后发送至标签。标签对信息进行解调、译码,从而识别阅读器命令,做出相应反馈。
图1 RFID 阅读器发送链路结构
编码在信息传输中起到防干扰的作用,使得信息能够高效、安全地到达收方。ISO/IEC18000-6 协议规定,基带处理单元中阅读器至标签链路的数据编码采用PIE编码方式,即脉冲宽度编码。编码原理是通过对数据-0和数据-1 进行不同码元长度的编码来实现,主要体现在脉冲下降沿前所持续的高电平时间不同。PIE 的编码规则如图2 所示[3]。
图2 PIE 编码规则
其中,Tari 表示的是阅读器向标签发送信息的基准时间间隔,具体取值需要根据实际要求作出一定调整,在实际情况下,需要参考地方无线电规则。Tari 的详细取值如表1 所示。低电平部分长度PW 的取值范围在0到Tari 之间[3]。
表1 最佳阅读器对标签Tari 值
本文中Tari 取值为12.5 μs,低电平部分长度PW 取为基准时间间隔的一半,x 取值为1,则数据-1 编码后长度为2Tari,数据-0 编码后长度为Tari,即数据-1 长度是数据-0 的两倍。因此,数据-0 在经过两个时钟周期后的输出“10”序列;数据-1 在经过在四个时钟周期后输出“1110”序列0。
经过Modelsim 仿真后,在工程中添加了一个伪随机数发生器模块,其功能是产生8 位伪随机数作为PIE 编码的输入数据。工程经Quartus Ⅱ综合、编译并下载到FPGA 开发板中,观察并分析实验结果。本文所用的板子型号是Altera 的DE2-115。
图3 描述了使用SignalTap Ⅱ逻辑分析仪抓到的输入和输出波形。如输入8 位十六进制数据8Ch,对应的二进制数据为1000_1100,按照PIE 编码规则编码后的数据应为11_1010_1010_1110_1110_1010,高位补0 后得到对应十六进制数据为3AAEEAh。经查验,PIE 编码设计能够正常工作。
图3 PIE 编码SignalTap Ⅱ波形图
在设计基础上增加串口收发模块,本设计中串口发送模块实现了多字节发送。具体实现了PC 端发送一个1 字节数据给下载了由PIE 编码模块和串口收发模块共同组成的工程的FPGA 开发板,并通过串口通道收到经过PIE 编码后的4 字节数据。图4 是串口助手发送和接收数据。
图4 串口收发数据图
2 UVM 验证结构
UVM 是一个以SystemVerilog 类库为主体搭建验证平台的验证方法学,验证人员利用其可重用组件构建具有标准化层次结构和接口的功能验证环境。UVM由A-ccellera 标准组织推出,并得到三大厂商(Cadence、Synopsys 和Mentor)的一致支持。2011 年以后陆续推出了1.0、1.1、1.1a、1.1b、1.1c 和1.1d 版本。2014 年推出了最新UVM 1.2 版本[4],UVM 作为如今验证领域最广泛使用的验证方法学,基本代表IC 验证的大致发展方向。
UVM 平台主要由uvm_componet 和uvm_object 组成。uvm_componet 继承于uvm_object 的同时,拥有uvm_object没有的一些特性。与传统的Testbench 相比而言,UVM 验证平台实现了受约束的随机激励的产生,自动化的结果比对以及代码和功能覆盖率的收集[5]。本文采用如图5所示的UVM 验证平台结构[6],下面将对各验证组件进行详细介绍。
图5 UVM 验证平台结构
(1)interface:声明DUT 接口。
(2)test:派生于uvm_test,是整个验证平台的入口,例化了env,是case 的父类,在不同的case 中设置了sequencer的default_sequence。
(3)transaction:继承于uvm_sequence_item,在验证平台中,信息在各组件中不以比特的形式流动,用transaction来处理与表征数据[7]。定义两个transaction 类型,分别为transaction_in、transaction_out。前者为输入端数据包,后者为输出端数据包。driver 首先需要把数据从transaction_in 中提出来,然后把其转换为DUT 的管脚能够接收的数据。通常来说,一个driver 只能接收一种transaction,所以在my_driver 被定义成了一个参数化的类,这个参数就是 my_driver 所能接收的transaction 的类型。transaction_out 在monitor 内部的转化机制同理。
(4)sequence:继承于uvm_sequence,产生数据包,并通过sequencer 传递给driver,driver 则将transaction 中定义的数据信息配置给DUT 管脚。验证过程中需要对DUT施加大量不同的激励,就要使sequence 产生不同的激励。
(5)sequencer:继承于uvm_sequencer,将sequence 发送给driver。
(6)driver:继承于uvm_driver,向sequencer 请求transaction,经过数据转化后通过下传给DUT[5]。driver 请求transaction 的部分代码如下:
其中,seq_item_port 是用于连接driver 和sequence 的一个端口,driver 如果想要发送数据就要从这个端口中获得;sequencer 如果有数据要交给 driver,也要通过这个端口送给driver。从这个端口申请数据要调用这个端口的get_next_item 方法。当数据驱动完毕时,要通过调用item_done 来告知这个端口。
(7)monitor:继承于uvm_monitor,创建monitor_before 和monitor_after 两个类,分别用来获取driver 发送给DUT的数据和DUT 的输出结果[8]。
(8)agent:继承于uvm_agent,在build_phase 函数中,通过is_active 值来例化内部不同的组件。is_active 值以UVM_PASSIVE 方式运转的agent 例化sequencer、driver、monitor_before,其作用是驱动总线,也可以监测总线;以UVM_ACTIVE 方式运行的agent 只例化monitor_after,监测总线而不驱动总线。
(9)reference_model:继承于uvm_componet,使用uvm_blocking_get_port 端口从monitor_before 中获取数据,调用DPI-C,获取经C_model 运算过的输出结果,通过uvm_analysis_port 端口将数据发送给scoreboard 组件[9-10]。
其中,pie_data 和pie_length 分别为计算PIE 编码结果和长度的C 函数,tr1.data 是monitor_before 发送给参考模型的数据。tr2 是reference_model 发送给scoreboard 的数据包。
(10)Scoreboard:继承于uvm_scoreboard,main_phase 中使用fork 开启了两个进程,其中一个进程用于从reference_model 中获得数据,另外一个进程用于从monitor中获得数据。一般情况下,同样的两组激励,经过DUT的处理后会有一定的延迟,但是在reference_model 中不会出现延迟。因此reference_model 中的数据总是比DUT 先到达scoreboard,所以在scoreboard 中可进行如下操作:将reference_model 发送来的数据先放入一个队列中等待。当接收到DUT 的输出后,从队列中依次弹出数据,调用compare 函数和DUT 的输出比较。
(11)env:继承于uvm_env,例化了reference_model、scoreboard 和agent 组件,并在其connect_phase 中使用FIFO实现端口之间的相互连接。例如,要实现reference_model 和scoreboard 的通信,只要在env 中声明一个FIFO,然后用FIFO 将reference_model 的analysis_port 和soreboard 的get_port 进行互相连接即可。连接部分代码如下[11]。
3 仿真结果
在验证平台的顶层(pie_top_tb)例化整个PIE_ENCODE 模块作为DUT,并利用SystemVerilog 的run_test 函数作为验证平台的入口。在命令行输入UVM_TESTNAME=casex(x 为所定义的case 的序号),创建并运行测试用例,达到验证目的[12-13]。通过利用SystemVerilog 的interface 机制[14]定义一组虚拟接口(Virual Interface,V-IF)来连接UVM 动态验证环境以及基于RTL 模型的DUT。使用uvm_config_db 机制使得虚拟接口能够连接两者。
图6 是验证平台的打印信息面板。这里的tr1 是scoreboard 从reference_model 中获取的数据包,tr_out 则是monitor_after 收集到的DUT 端口信息所构成的数据包。由图可见。参考模型和DUT 输出结果在记分板中对比结果一致,达到了验证效果。
图6 打印信息面板
图7 为由覆盖率驱动的且受约束的随机分层验证平台运行出的波形图。由此可见,每个时钟周期内,PIE 编码输入对应的输出都是正确的。
图7 DUT 仿真波形图
图8 显示了DUT 的功能覆盖率,验证平台对实例化的接口输入和输出信号分别进行了采集,功能覆盖率达到了100%。对于传统的基于testbench 的验证平台,缺少特定的方法对功能覆盖率进行统计,很难收集并分析功能覆盖率的具体情况。
图8 功能覆盖率
图9 描述的是DUT 的代码覆盖率,其中,分支覆盖率、条件覆盖率、表达式覆盖率和语句覆盖率均达到了100%,总代码覆盖率也达到100%。
图9 代码覆盖率
4 结论
UVM 验证方法学作为如今IC 验证领域最广泛使用的验证方式,其拥有大量库及基类、面向对象等特点,有效提高了验证效率和产品可靠性。本文设计了RFID 阅读器发送链路PIE 编码模型,在建模、仿真的基础上进一步实现了FPGA 原型验证,进而实现了FPGA 串口多字节发送的功能以及和PC 的通信。此外,基于UVM 验证方法学及SystemVerilog 语言特性,借助DPI 调用高抽象层次C 模型,搭建了具有高度复用性的功能全面的验证平台,在此基础上编写覆盖率驱动的受约束随机激励,实现了SystemVerilog 和C 语言协同仿真。最终使得代码的分支覆盖率、条件覆盖率、表达式覆盖率、语句覆盖率均达到100%,总覆盖率达到100%,功能覆盖率也达到100%,达到了验证目的。