分层协议验证还需创建新的环境组件?不!引入UVM序列项才是Easy Way
一. 引言
分层协议架构可将复杂协议分解为更为简单的任务,因此通常被应用于各个不同领域。在模块级和芯片级设计中,分层协议的应用也很普遍。分层协议的一些示例,如PCIe、串行Rapid IO和MIPI等,均具有上层逻辑层,且该逻辑层的数据包会转换为协议规定的信号来传输互连,被传递到下层物理层。对于集成电路IP设计,模块级通信通常使用标准接口协议,以简化整体架构并提高设计组件的复用性。而将高级特殊数据转换为接口上期望的标准数据格式时,常常需要使用分层协议,以传输到其他块。为了在硬件中确保实现协议在不同层工作的正确性,分层协议验证就显得至关重要。
有多种使用通用验证方法学(UVM)来实现分层协议验证的方法。本文讨论了一种使用分层序列项以简化和加速实现分层协议验证的解决方法。这种方法将协议的详细信息封装在UVM序列项中,以消除与分层agent或分层sequencer相关的开销和复杂性,能最大程度地提高组件的复用性并减少开发时间。值得一提的是,该方法已成功用于验证多个具有双层协议实例的实际设计中,所有实例均在下层共享一个公用接口协议,在上层实现其特殊数据的转换行为。
为了简化在测试平台内的使用,本文还提供了用于各层之间协议转换的标准API。
二. 背景
分层协议验证示例方案的设计框图如图1所示,较低层是两个IP之间的公用层,使用Valid/Ready握手协议将数据从源块传递到目标块。图1所示的“Valid/Ready层”,即驱动接口的最低层,其并不关心数据内容,仅在协议级运行。图1所示的“Packet层”并不知道接口上使用的通信协议的详细信息,其负责将原始的接口数据转换为有意义的数据字段,此打包的数据可以发送到其他高层进行进一步的转换或处理,但为了简单起见,本文的研究将采用这种双层示例。
图1. 分层协议示例
基于Valid/Ready握手机制的数据传输协议,传输源端将在接口上向原始数据呈现有效信号,即使用Valid表明数据是有效的;当接收器准备好接收新数据时,目的端使用Ready表明已准备好接收该原始数据信息;当同时声明Valid和Ready信号时,将接收原始数据并完成握手过程。
在此示例中,因为“Packet层”有意义的数据字段以平面数组的形式打包到原始数据中,则接口上的数据即为原始数据。Valid/Ready协议的时序图如图2所示,显示了多个原始数据的传输。
图2. Valid/Ready握手示例的时序图
类似握手协议的一些示例还包括AXI4-Streaming和本地链路。
Packet层可能包含许多字段。为了演示Packet序列项的构造,将使用如下三个任意字段:数据包ID(8位值),ADDR(16位值)和DATA(32位值)。通过将每个字段展平为更大的56位数据数组,Packet数据可转换为Valid/Ready原始数据,该Valid/Ready层所使用的原始数据如图3所示。
图3. 打包成原始数据的数据包字段
在反向转换时,通过从它们在原始数据总线上的偏移位置中提取每个字段,并将它们分配给Packet序列项的相应数据字段,即上述打包的逆过程,亦称解包。
三. 相关研究
目前已经研究讨论了多种用于分层协议验证的方法。Chauhan等人[1]实现了可重用和可扩展的架构,该架构中分层的各个agent与设计中的每个层都相对应,并且高层级的driver用于将高层协议数据转换为低层协议数据。这种方法具有用点对点的模块级验证来验证各单独层的灵活性。另外,这种方法也很容易在不同层上注入错误以实现最大的可控性。如果不需要考虑这种层的灵活性,那么此解决方案整体来讲会很耗时,也会增加测试平台的复杂性。显然,当用第二部分所描述的示例方案分析时,这种方法并不太适合,在agent的开发上会花费更多的时间,在验证高层的设计时也不需要扩展其可见性和可控性。
Fitzpatric和Doulous等人也提出了一种类似的方法,但是并没有开发与每个层都相对应的完整的agent模块,而是从高层级中删除了driver。精简后的agent对执行从高层协议到低层协议转换的sequencer进行分层。monitor则执行反向转换,将低层协议重构为高层协议,然后再传输要在测试平台中使用的事务。该方法非常适用于第二部分所描述的示例场景。然而,如果有多个共享同一个下层的特定上层,那么为各个上层开发这些自定义的精简agent会相当耗时。图4描述了此方法的测试平台架构的设计框图。以上这俩种方式都很灵活,可被不同的分层协议所使用。图4仅显示了scoreboard与Packet层的连接,但是为了匹配用于验证每个层的第一种方案,将添加与Valid/Ready agent中monitor的连接。通过使用分层组件,可以在每一层独立地验证不同层之间的事务。
图4. 先前的研究所提出的方法
本文将介绍另一种使用UVM序列项进行分层协议验证的简单方法,即将特定转换协议重构为UVM序列项,而不是创建新的环境组件进行转换。这种方法无需开发新的组件,因而简化了测试平台架构,并缩短了测试平台的启动时间。
四. 方法的提出
图5. 提出的使用分层序列项的方法
图5显示了我们根据第二部分的示例方案所提出的使用分层协议验证的方法。Valid/Ready协议用于低层级,图3所描述的Packet层用于高层级。
通过Packet序列项中的转换函数(pack_data)可将Packet协议转换为Valid/Ready协议。在反向转换的过程中,通过调用Packet序列项中的转换函数(upack_data)可将Valid/Ready协议转换为Packet协议。如图5所示,unpack_data函数在scoreboard中被调用,可连接到Valid/Ready agent中monitor的所有类也都需要unpack_data。随着Packet序列项中转换的发生,可以直接实例化Valid/Ready agent模块,而不会增加层或转换类的环境复杂性。在此示例中,这种通用的Valid/Ready agent模块包含参数化的总线宽度,将按56位来实例化以适应数据传输的大小。
每一层的设计中都需创建一个序列项,则在此双层示例中需要两个序列项。其中一个序列项是对应于基层协议的agent,即Valid/Ready agent模块;另一个序列项是对应于包含有意义数据字段和转换函数的Packet层。高层级序列项必须扩展基本的序列项以继承基层的字段和函数。在此示例中,Packet序列项扩展了Valid/Ready序列项,添加了有意义的数据字段,并实现了转换函数:pack_data和unpack_data。
图6. Valid/Ready序列项
图7. Packet序列项
图6和图7演示了基本序列项(vld_rdy_seq_item)和派生序列项(pkt_seq_item)的伪代码。在基本序列项中定义了两个虚函数:pack_data和unpack_data,这两个函数必须在派生序列项中实现。Pack_data函数定义了如何将数据包数据字段转换为原始数据,unpack_data函数定义了如何将Valid/Ready协议中的原始数据转换为数据包数据。因为这两个函数在协议的不同层之间执行数据转换,故其重要性不容忽视。
一旦定义了Valid/Ready序列项和Packet序列项后,序列将照常使用Packet序列项生成数据,然后将此事务转换为Valid/Ready序列项,才能在agent中的squencer上启动driver进行传输。sequence主体的编写流程如下:
-
在sequence中实例化并创建一个本地的Packet序列项。注:只有在高层级才能在Packet序列项上调用随机化函数生成适合的通信。
-
在sequence主体内部,Packet序列项将会调用pack_data来把高层数据转换为低层数据格式,这种情况仅发生在原始数据总线上。另外,如果使用随机化生成通信场景,可像在pkt_seq_item的伪代码中一样,将pack_data放置在post_randomize函数末尾的序列项中,以确保在随机化之后始终对数据进行转换。对于随机化序列可以删除这一额外的步骤,而对于不调用随机化的定向方案,此步骤是必须的。
-
将Packet序列项转换为Valid/Ready序列项,以便于它是sequencer可接收的正确数据类型。
-
继续将Valid/Ready序列项发送到driver以实现接口上的传输通信。
随机化Packet序列的示例如图8所示,演示了如何按照这些步骤来实现sequence主体的编写。
图8. Packet序列项到Valid/Ready序列项的转换
通过此流程,按照高层Packet序列项来编写sequence,会隐藏来自test或者sequence编写器的低层协议的所有底层细节,这使熟悉高层协议的人,无需了解编写低层协议的任何知识,就可轻松协助完成测试用例编写。
如上文所述,从低层级monitor接收的任何事务类都必须先执行反向转换,然后才能访问在测试平台中使用的数据包字段。Packet序列项的构造遵循与sequence类似的格式。当输入端口上接收到基本序列项之后,该基本序列项的原始数据将被分配到Packet序列项的原始数据总线上,然后调用unpack_data函数来构造Packet序列项的高级数据,之后就可以使用Packet序列项了。在图5中,由于scoreboard与Valid/Ready agent中的monitor连接,因此对于从monitor接收到的传输都需遵循此流程。如图9所示,scoreboard的伪代码演示了Valid/Ready序列项到Packet序列项的转换。
图9. Valid/Ready序列项到Packet序列项的转换
在实际中Packet层可能会有许多具有共享接口协议的接口,只是为其定义了不同的字段。换句话说,在项目之间可以使用通用的接口协议,但是需在Packet层做一些必要的改动。由于不需要为每个特定实例开发新的分层组件,因此本文所提出的方法对于实际应用越来越有益,有效地控制了验证时间。
五. 展望
本文采用双层协议演示了这种分层协议验证的简化方法,这种方法对于多层协议很容易扩展,如前面第四部分所提到的,将在每一层创建序列项以对协议的每一层和相应的转换函数进行建模。相同的示例场景将被扩展到实现三层协议验证,即在Packet层的顶层增加新的Large Packet层,如图10演示了这种三层场景的示例框图。
图10. 扩展到多层
每一层的序列项都必须从其直接下层派生。在这种情况下,Large Packet序列项将从Packet序列项扩展。Large Packet到Valid/Ready转换的转换函数(pack_data)将实现从Large Packet协议到Packet协议的转换,在函数的最后再调用super.pack_data以实现从Packet协议到Valid/Ready协议的转换,从而实现从Large Packet协议到Valid/Ready协议的完整转换。在函数的最后调用super.pack_data确保了转换以正确的顺序进行。unpack_data函数的实现会稍有不同,它要求在函数的开始就需调用super.unpack_data,这确保了Valid/Ready协议首先被转换到Packet层,然后再转换到Large Packet层。Large Packet的unpack_data仅实现了从Packet数据到Large Packet数据的转换。添加的每一层都将遵循层之间转换的相同结构。
如图10所示,通过继承可证明这每个序列项的类型都存在于Large Packet序列项中,图中的绿色箭头表明将递归调用pack_data和unpack_data函数。我们注意到,这里不需要显式创建每个序列项的类型,也不需要为每一层手动调用转换函数,其都将在后台完成,其可见性和可控性则主要表现在最高层和最低层,而且对于在测试平台的类中的转换仅需添加最少的代码。
未来研究的另一个领域可能是尝试使用此理论实现每个层的验证。从理论上讲是可行的,但尚未在实际的设计中得到证明。由于转换函数中序列项的继承和递归的实现,每一层都存在于高级序列项中,因此,可以从高级序列项中访问任一层的字段。例如,要检查图10中所示的中间Packet层,如果只需要Packet层的内容,就可以很容易地实例化Packet序列项,而不是实例化高层的Large Packet序列项以解包Valid/Ready数据。另一种方式是始终实例化Large Packet序列项,再将Valid/Ready数据解包到Large Packet中,然后会在后台实现递归解包所有层。当定义每个序列项时,可以添加compare_<layer>函数来比较特定层的字段。为了只检查Packet层的字段,可以在Large Packet序列项中调用compare_packet函数,则将只会比较存在于Large Packet序列中的Packet层的字段。这一领域还需做更多的研究以确定这种方法对于每个层的验证的可行性和局限性。
六. 结论
本文所提出的方法(见第四部分),只需为每一层创建新的序列项,并在现有类中添加最少的代码。无需包装UVC、无需转换类,亦无需实现sequencer的复杂分层。环境组件数量的减少进而会减少初始开发时间,也会加速测试平台的启动。在设计中为每个特定Packet层的扩展也会节约开发时间。将此方法与图4所示的方法进行比较,有两个特定Packet层的设计需要开发两个序列项、两个转换monitor、两个转换sequencer和两个包装类,并将其添加到测试平台环境中,而这种简化的方式则只需创建两个序列项即可。
本文所提出的方法旨在通过从测试平台中提取各层之间的底层协议信息来简化分层协议验证。在实际设计中侧重于高级功能而不是单个层的验证,所以这种简化的方法对于实际的设计很有意义。可见,确保为分层协议验证选择正确的方法以满足验证需求非常重要。
第五部分的展望,描述了如何为具有两层以上的分层协议扩展此概念。基于以前的经验和理论分析,这种简化的方法很有可能用于验证各单个层,但是可能还需要根据示例中的描述进行一些代码修改。由于尚未证明可以验证实际的设计,因此未来还需做更多的研究以确定需要进行哪些修改。
参考文献
[1] Rahul Chauhan, Grupreet Kaire, Ravindra Ganti, Subhranil Deb, “Layering Protocol verification: A Pragmatic Approach Using UVM”, SNUG 2014
[2] Doulous, “Requests, Responses, Layered Protocols and Layered Agents”, Online resources at http://www.doulos.com/knowhow/sysverilog/uvm/easier_uvm_guidelines/layering
[3] Tom Fitzpatric, “Layering in UVM”, Verification Horizons
原文来自:DVCon2017_USA, 点击阅读原文去路科官网下载DVCon2017论文合集,还有更多资料等你来哦!
扫描二维码可直达课程页面,马上试听
往期精彩:
理解UVM-1.2到IEEE1800.2的变化,掌握这3点就够