基于UVM的软硬件协同验证平台设计

2022-08-23 07:16李姝萱韩宇昕
计算机技术与发展 2022年8期
关键词:数据包串口编码

李姝萱,卜 刚,韩宇昕

(南京航空航天大学 电子信息工程学院,江苏 南京 211106)

0 引 言

随着大规模集成电路设计和半导体工艺的快速发展,芯片研究周期不断缩短,当前的软件仿真速度日渐难以承受千万门级功能复杂的SoC设计。传统的系统设计及验证方法亟待改进,而软硬件协同仿真以及验证的概念由此应运而生。为了提高验证效率,该文利用FPGA硬件加速的思想,在UVM验证方法学的基础上提出了一种基于FPGA的软硬件协同验证方案。

该文旨在将验证平台与待测设计进行明确的软件和硬件划分,将功能和计算复杂的待测设计下载到了Altera DE2-115硬件开发板中,UVM验证平台的各组件仍保留在PC端QuestaSim仿真器中运行。这样不仅可以利用FPGA大量的内部资源和高速性能以缩短硬件运行时间,还可以利用UVM的面向对象和可重用性高等优点获取更加可靠的验证结果[1]。

1 待测设计

国际标准ISO/IEC18000-6规定,RFID数字基带系统中标签——阅读器链路需采用FM0和Miller编码,具体编码方式由阅读器发送给标签的Query命令中参数m[1:0]的值决定。m[1:0]参数的取值范围共有4个值,当m[1:0]为2’b00时,采用FM0编码方式;当m[1:0]为2’b01、2’b10、2’b11时,则采用Miller编码方式[2]。

1.1 FM0编码

根据ISO/IEC18000-6协议规定,FM0编码原理是基于电平的翻转来实现的。当编码模块检测到有数据输入时,将会在一个编码周期内输出两位码元。在每个编码周期内,数据-0和数据-1进行电平翻转的次数不同。

数据-0的编码在码元周期起始处和码元周期中间分别进行一次电平的翻转;而数据-1的编码只在码元周期开始时进行一次电平的翻转。图1显示了FM0的编码规则以及状态转换。在编码结束后,需要依照协议的相关规则给出编码结束符,添加在编码数据流的末端。

图1 FM0编码及状态跳转

1.2 Miller编码

Miller编码与FM0编码基本类似,同样也是基于电平翻转的原理来实现。其编码规则以及状态转换如图2所示。

图2 Miller编码及状态跳转

相较于FM0编码,Miller编码相对复杂一些。每一位数据经过Miller编码后,可能产生4位、8位或16位码元,具体编码规则取决于参数m[1:0]的值。参数m[1:0]为2’b01,2’b10,2’b11所对应的M值分别为十进制的2,4和8。M值不同,每位码元编码后的数据长度也不同。M=2时,码元长度为4位;M=4时,码元长度位8;M=8时,码元长度位16。由图3可见,三种编码方式下的Miller编码在两个连续的0之间均不发生电平翻转,在1和0之间以及两个连续的1之间则在数据边界处进行一次电平翻转。

图3 Miller编码序列

与FM0编码相同,所有待编码数据进行Miller编码结束后也将按照协议相关规则在数据后面添加相应的结束符标识。

2 软硬件协同验证平台

FPGA作为硬件原型,其运行速度为真实的周期时间,而仿真器仅仅作为PC端一个软件仿真应用程序,其运行硬件模型的每一个周期都将需要耗费几百个真实的时钟周期,因此,对于同一个待测设计的验证,在做好软件和硬件模块划分以及数据交换链路的前提下,利用FPGA进行软硬件协同验证相较于仿真器下的软件验证具有较为明显的加速效果。

该文提出的基于UVM验证方法学的软硬件协同验证平台的基本原理是将待测设计综合、布局布线并使用FPGA开发软件Quartus Ⅱ通过JTAG配置到Altera DE2-115硬件开发板上,UVM验证平台仍保留在PC端仿真器QuestaSim软件中进行,FPGA目标测试硬件平台利用其RS-232串口与PC主控机之间进行收发通信,PC端使用winsock API进行串口编程,两者之间连接一根9-pin公转母电缆即可实现数据上下行通路,各自完成激励的下传和结果的上传,数据传输速率为115 200 bps[3]。该平台架构如图4所示。

图4 软硬件协同验证平台

2.1 UVM验证方法学

UVM是一个以SystemVerilog类库为主体搭建验证平台的验证方法学,最早由Accellera标准组织推出,并得到三大厂商(Cadence、Synopsys和Mentor)的一致支持,于2014年推出了最新版本UVM 1.2。其之所以能够成为当今数字IC验证最为广泛使用的主流验证方法学,主要是因为其具备以下几点优势:

2.1.1 UVM的优势

(1)UVM验证平台兼具封装、继承的特点,又具备SystemVerilog编程语言的面向对象等特点,其验证组件具有很高的可重用性、可移植性以及可继承性,使得验证人员无需耗费大量精力在搭建验证平台上,可以将大部分精力专注于待测设计功能点的研究以及测试用例的编写。

(2)验证人员利用其可重用组件构建具有标准化层次结构和接口的功能验证环境[4],平台可维护性强。

(3)主流EDA工具支持,方便验证人员学习和调试。

(4)与传统的Testbench相比,UVM验证平台实现了受约束的随机激励的产生,自动化的结果比对以及代码和功能覆盖率的收集[5]。

(5)开发了factory、config、phase、override等机制,可根据工程特性灵活地搭建验证结构,实现了平台的自动化和层次化运行,一定程度上减少了验证人员的调试成本。

(6)UVM组件之间的通信采用事务级建模(Transaction Level Modeling,TLM)的方式,不同于DUT中各模块之间的比特级数据传输方式,UVM验证组件之间的数据传输是以数据包为单位的。TLM通信使得数据在验证组件的端口之间流通更为方便。

2.1.2 UVM的结构和组件

图5为标准的UVM验证平台结构[6]。

图5 UVM验证平台结构

UVM验证平台是由uvm_componet和uvm_object组成的。uvm_componet继承于uvm_object的同时,拥有uvm_object没有的一些特性。下面介绍几个重要组件的功能特性。

(1)test:派生于uvm_test,是整个验证平台的入口,内部例化了env,是case的父类。由于DUT的待测功能各有不同,所以需要编写不同的case进行验证。case与sequence一一对应,在每个case中利用UVM的config机制将其对应的sequence设置为sequencer的default_sequence。

(2)transaction:继承于uvm_sequence_item,在UVM验证平台中,各组件之间的通信是以数据包transaction为单位的[7]。定义两个transaction类型,分别为transaction_in、transaction_out。前者为输入端数据包,后者为输出端数据包。driver首先需要把数据从transaction_in中提出来,然后把其转换为DUT能够接收的pin级别数据类型,驱动到DUT的各个管脚。类似地,transaction_out在monitor内部的转化机制也是如此,监测到DUT的输出管脚后将信息整合为数据包再送至scoreboard中与参考模型进行对比。

(3)sequence:继承于uvm_sequence,通过随机化数据的方式产生数据包,并由sequencer传递给driver,driver则将数据包中定义的数据信息通过virtual interface配置给另一端的DUT管脚。验证过程中,sequence利用repeat()和`uvm_do等宏来产生大量不同的激励施加给DUT,从而使功能覆盖率达到100%[7]。

(4)sequencer:从driver的职能中分离出来的组件,继承于uvm_sequencer,将sequence通过seq_item_port端口发送给driver。

(5)monitor:继承于uvm_monitor,分别创建monitor_before和monitor_after两个类,各用来监测driver施加给DUT的激励以及DUT的输出结果,另外还负责收集功能覆盖率,验证FM0和Miler编码的三种方式是否都得到验证以及待编码数据是否覆盖所有可能值[8]。其中,monitor_before中的覆盖率组定义如下:

covergroup fm0_miller_in_cg;

data_cov:coverpoint tr.data[7:4]{

bins value={[0:7]};

}

m_cov: coverpoint tr.data[1:0]{

bins m0={2'b00};

bins m2={2'b01};

bins m4={2'b10};

bins m8={2'b11};

}

endgroup

(6)reference_model:由uvm_blocking_get_port端口从monitor_before中获取数据,并由uvm_analysis_port端口将参考模型结果传递到scoreboard中进行比对[9]。本设计采用C语言编写参考模型,SystemVerilog通过DPI-C接口调用该模型。对于FM0编码,首先依次读入待编码数据,设置一个变量data_tmp,初始值为1。若对数据-0编码,则依次输出码元~data_tmp,data_tmp,data_tmp值保持不变;若对数据-1编码,则依次输出码元~data_tmp和~data_tmp,data_tmp值进行一次翻转。以这样的规则依次对待编码数据的每一位进行编码,对于Miller编码,data_tmp初值为0,结合m值,不断更新data_tmp的值来输出编码码流。

(7)scoreboard:继承于uvm_scoreboard,在main_phase中使用fork-join块开启两个进程,其中一个用于从reference_model中获取数据包,另外一个用于从monitor_after中获得数据包,调用compare函数将两者进行对比,若一致则对比成功,DUT功能正确,若出现对比失败,则代表DUT和参考模型输出不一致,存在漏洞。

(8)env:继承于uvm_env,其中分别例化了reference_model、scoreboard和agent组件,并在connect_phase中使用fifo实现以上组件之间的互连。连接部分代码如下:

agt.i_ap.connect(agt_mdl_fifo.analysis_export);

model.port.connect(agt_mdl_fifo.blocking_get_ export);

agt.o_ap.connect(agt_scb_fifo.analysis_export);

scb.from_dut.connect(agt_scb_fifo.blocking_get_export);

model.ap.connect(mdl_scb_fifo.analysis_export);

scb.from_rfm.connect(mdl_scb_fifo.blocking_get_export)。

2.2 数据通路

软硬件协同验证平台中,QuestaSim仿真器中运行的UVM平台要与硬件中运行的待测设计进行数据交互,该文采用的方法就是利用仿真器提供的DPI(Direct Programming Interface)接口来实现[10]。通过DPI,SystemVerilog能够间接地连接C、C++等编程语言。使用import语句声明并导入一个C程序,并将DPI接口C语言端的参数在SystemVerilog中对应一致,例如SV的string类型,C使用char*类型。这样,C程序就可以作为SystemVerilog的子程序一样被调用[11]。

winsock是一个基于socket模型的API,在Windows操作系统类中使用。本设计使用winsock API编写带有返回值的C函数,该函数在对串口进行一系列必要的参数配置之后,调用系统函数WriteFile()和ReadFile()来对串口进行写入和读取数据[12],其主要功能有:

(1)获取仿真器中UVM验证平台所产生的随机测试激励,在对其进行数据分析之后,将其发送至串口端,并由串口下传至FPGA硬件平台。

(2)每一次PC端向FPGA端发送激励,待DUT运行完成一次之后,串口获取FPGA端的回传结果,进行数据分析、打包等处理后发送至仿真器,验证平台将其和参考模型进行结果对比。

(3)实现PC端的时序控制,确保验证流程的有序进行[13]。

仿真器端与外部C函数连接部分核心代码实现如下:

import "DPI-C" function longintserial_port(input int data_in,longint data_str);

……

task main_phase(uvm_phase phase);

……

data_pin=send_receive(tr5.data,data_str1);

tr_out.data_out=data_pin[63:0]。

软硬件协同验证平台中,FPGA硬件平台主要完成的工作有串口收发模块、数据控制模块以及顶层模块的设计。

其中串口模块包括波特率产生、发送模块和接收模块。本设计采用的波特率为115 200 bps,即串口所能达到的最大传输速率。接收模块将来自串口的数据流通过数据控制模块解析出DUT管脚对应的各项参数并将其配置给DUT。若干周期后,DUT输出FM0或Miller编码码流以及完成标识,发送模块一旦监测到完成标识从0变成1,立即将编码结果上传至PC端。该过程通过循环算法实现了串口的多字节发送。顶层模块例化了串口收发模块、数据控制模块以及FM0和Miller编码模块,并协调各个模块之间的工作有序进行。

整个待测设计的工程在Quartus Ⅱ中完成综合、布局布线、时序约束以及编译并且通过JTAG下载到DE2-115开发板中,至此,完成了软硬件协同验证平台硬件部分的设计。

3 验证结果

3.1 验证过程

当验证流程开始启动时,首先由PC端仿真器开始仿真,sequence组件中产生的测试激励通过seq_item_port端口传递给driver,由driver通过uvm_analysis_port端口发送给monitor_before和monitor_after[14]。monitor_before将激励传递给参考模型C_model,在monitor_after中开始对FPGA端的DUT单元进行访问,仿真器通过winsock将激励下传给FPGA,经过数据控制模块的解析后配置给DUT管脚。经过若干周期,DUT编码结束,FPGA端将输出结果进行分析整合并回传到仿真器中,仿真器继续下一阶段的仿真。此时,由于FPGA开发板的高速性能,DUT的回传结果比参考模型C_model的结果先到达于scoreboard,所以将DUT的结果get_actual数据包压入队列actual_queue中,待C_model将编码结果get_expect数据包传给scoreboard后,将队列中的get_actual弹出,调用compare函数将两者进行对比,输出对比结果[15-17]。至此,一次完整的软硬件协同验证完成。

3.2 验证结果

图6为仿真软件在一个验证周期内的打印信息,如图所示,待编码数据data为4,m值为2,对应的M值为4,则依照图2和图3的规则进行Miller编码,理论输出值的二进制码流应该为1010_0101_0101_0101_1010_1010_1010_0101,对应的十六进制值为0xa555aaa5。图中data_str为monitor_after监测到的DUT的编码结果,data_out为C_model的编码结果,经scoreboard对比,二者的输出一致,scoreboard输出Compare SUCCESSFULLY。底部分别打印DUT和C_model编码数据和编码长度信息。

由于该文采用了软硬件协同验证的方法,DUT在FPGA上运行,所以PC端仿真软件无法收集代码覆盖率。在搭建验证平台之前,首先要针对待测设计制定一套完整的验证计划,要求在可控的时间范围内完成高质量的验证工作。其中包括确定端口、提取功能点、编写受约束的随机激励、收集覆盖率以及模拟故障等。

图6 打印信息

为了确保验证工作的完备性和可靠性,针对DUT的关键特性编写了大量受约束的随机激励,此时的功能覆盖率已经达到70%~80%左右。为了进一步提高功能覆盖率,确保验证的完整性和可靠性,再针对事先制定的验证计划中的少数没有被随机测试所覆盖到的边界条件和逻辑施加对应的定向激励。

功能覆盖率情况如图7所示。本设计定义了两个功能覆盖率组,分别为发送数据功能覆盖率组fm0_miller_in_cg以及接收数据功能覆盖率组fm0_miller_cg,每个功能覆盖率组里定义了若干仓。由图可见,待编码数据的所有可能值和FM0编码以及Miller编码的3种编码方式均被覆盖到,最终实现功能覆盖率达到100%。

图7 功能覆盖率

纯软件环境下的验证和基于FPGA的软硬件协同验证所得到的UVM Report Summary分别如图8和图9所示。

图8 纯软件验证结果

图9 软硬件协同验证结果

对比两者可以发现,在运行相同测试用例的情况下,纯软件仿真所耗费的时间为16 410 ns,而软硬件协同验证平台所耗费的时间为11 590 ns,为纯软仿耗时的71.81%。

经进一步验证发现,加速效果随着测试用例数量的增加及设计的复杂度而提高,即验证过程中运行的测试用例数量越多,待测设计越复杂,软硬件协同验证平台的验证效率越高。面对大规模Soc的验证工作,由于待测设计功能十分复杂,所需要的测试用例可能达到成百上千,再者,待测设计运行一次需要耗费大量时钟周期,若采用该软硬件协同验证平台将会大大缩短验证所需时间,提高验证效率。

4 结束语

利用硬件加速思想,结合UVM验证方法学,搭建了一个基于FPGA的软硬件协同验证平台。用Verilog语言编写串口收发模块、数据控制模块,连同待测设计FM0和Miller编码模块下载到FPGA硬件开发板中。采用串口通信作为物理通道,PC端则使用winsock API编写串口驱动函数,仿真器通过DPI调用该接口函数,将UVM平台产生的受约束的随机激励下传至DUT,经过DUT内部运行后输出编码结果,回传到仿真器中。仿真器将DUT结果与C语言编写的参考模型进行比对,判断DUT是否能正确地完成编码功能。该平台实现了软硬件整体协同运行,提高了验证效率,功能覆盖率达到了100%,经验证,该平台能够为大型、复杂的SoC验证所复用。

猜你喜欢
数据包串口编码
基于时隙ALOHA与NOMA的通信系统性能分析
住院病案首页ICD编码质量在DRG付费中的应用
C#串口高效可靠的接收方案设计
高效视频编码帧内快速深度决策算法
MCS—51单片机中的多串口通讯技术的应用
网络数据包的抓取与识别
全国计算机等级考试机房准备工作探讨
微机串口的测试诊断
不断修缮 建立完善的企业编码管理体系
基于VC串口通信的实现