ESL MODEL在VMM1.2中的应用
刘 星sean.liuxing@huawei.com
杜小伟duxiaowei@huawei.com
汪迪娜wangdina@huawei.com
叶 成yecheng@huawei.com
海思
摘要
本文主要介绍了使用VMM1.2实现ESL 模型在验证中重用的经验。VCS新的版本2011.03提供了TLI适配层来实现SC和SV之间的通 信,解决ESL 模型和验证环境的交互问题。接下来我们面临一系列的问题,例如,ESL开发人员和验证人员如何协同工作,如何 让ESL模型满足验证的需求,验证对ESL模型的有哪些额外的需求,ESL模型和验证环境如何真正的结合,如何管理ESL 模型中依 赖验证平台代码,如何用ESL 模型替换RTL,如何确保抽象层次的正确性等等。本文将主要介绍我们在方面所做的探索工作取得 的经验。
Abstract
This article introduces the experience how to use VMM1.2 to reuse ESL model in verification environment. New VCS2011.03 version supports SC communicates with SV by TLI adapter to resolve ESL model interact with verification environment. Now we face those questions. Such as, how do ESL team and verification team work together? How can we make ESL model to meet verification requirements? What kind of requirements do we need for ESL model in verification? How do we incorporate ESL model into verification environment? How to manage the code depend on test bench in ESL model? How to use ESL MODE replace RTL? How to ensure the ESL models correct? This article will continue to share the experience about these.
1. 简介
本文主要介绍了使用VMM1.2实现ESL模型在验证中应用的经 验。ESL和验证在芯片开发工作中都越来越重要,ESL为验证 架构而开发的模型和验证的RM(Reference Model)都是对架构 的一种抽象实现。传统上ESL模型主要用于验证架构,而RM则 和RTL进行对比以确保RTL设计正确,二者一般由不同团队、不同阶段分别开发。ESL开发的模型在完成架构验证之后弃之 不用,而RM需要重新开发、测试,随着芯片规模的增加,这样 的重复开发越来越不可接受。
完美的解决方案是ESL的模型能够直接为验证所用,这样验证 工程师不需要再完成RM的开发和测试工作,从而更快的建立验 证环境,聚焦于芯片验证本身。额外的好处是,ESL模型通常 测试不够充分,在作为RM时,可以使ESL模型测试充分。
另外一个方面现在越来越多芯片的验证都和软件相关,而软件 的灵活性也使覆盖所有的场景成了一项非常有挑战性的工作。 另外由于RTL的仿真效率问题,几乎不可能对很多复杂的应用 场景进行全面的覆盖。但是ESL model在这个方面有着明显的优势,所以如果能够先将软件在ESL model中调试充分,然后 再通过验证活动保证ESL model和RTL的一致性,也不失为一 种可行的方法。
第二章讨论了如何让ESL模型满足验证的需求。 第三章讨论了如何将ESL模型集成到验证环境中的问题。 第四章讨论了ESL和DUT如何比对的问题。 第五章讨论了ESL集成到VMM1.2时如何调试的问题。 第六章讨论了ESL作为DUT运行的作用和好处。
2. 验证对ESL的需求
本章主要介绍验证对ESL的需求,这是一个非常重要的工作, ESL能否和验证协同工作起来,这一步至关重要。我们的做法 是在验证团队和ESL团队各自有一个接口人共同负责需求的搜 集和整理工作,验证接口人根据架构文档和验证环境的框架向 ESL接口人列出需求清单,ESL接口人通过ESL团队评估并反馈 需求的可行性,根据架构和环境的变化重复这一过程,最终形 成一个验证对ESL的需求文档。同时ESL团队会根据需求文档 来调整模型的模块划分,建模粒度等。
2.1 时序
如果只是功能模型那么时序也许并不重要。不过为了尽快的定 位,我们的一些模块需要ESL和RTL进行cycle级的比对,这就 要求ESL和RTL的时序要完全一致。由于在很多情况下ESL模型 开发要先于RTL,所以对于模型的开发尽量采用功能和时序分 开,并且时延可配。
2.2 接口
ESL与验证交互的接口必须完全覆盖RTL 的所有信号,其它额 外的信息则不需要有什么要求。对于接口数据的定义,一般采 用sc_bv类型,因为不仅可以对其中某一个bit进行操作,而且 还可以表示比较多位宽的总线。
2.3 ESL随路信息
为了定位,验证环境经常需要给DUT的数据增加额外的信息用 来跟踪数据的处理过程,这样可以快速的知道哪些数据在什么 阶段出错了。通常RTL不能提供这些额外的数据,对RTL来说 面积通常更重要。
对于ESL来说则没有这个问题,一方面添加额外的信息更容 易,另一方面ESL并不会拿来综合并生成最终的芯片。既然 我们ESL的实现已经精细到cycle级,同时和RTL接收同样的 输入,那么我们就可以让ESL携带额外的数据,来帮助RTL定 位。因为有Adapter类型,所以可以携带任意的随路信息。
2.4 ESL交付标准
传统上RM是由验证人员来确保正确性的,并且通常RM是抽象 级的实现,所以调试相对简单。而现在我们的RM是由ESL开发人员编写的,并且是相当精确的模型,所以测试的难度大大增 加,同时ESL对模型的测试强度从验证人员的角度来看是很不充分的,那么如何保证ESL交付的模型的质量呢?
验证人员对RTL如何验证是最为了解的,而ESL和RTL现在是 如此相似,所以让验证人员给出交付标准是最适当不过的。验证人员给出基本用例,这些用例可以确保ESL的大部分错误已 经检查出来,ESL开发人员在交付之前,需要完全跑通这些用 例,这样就保证了ESL的交付质量。
3. ESL如何集成到验证环境
将ESL集成到验证环境面临选择合适技术的问题,DPI可以很 容易跨语言通信,不过对于C++语言来说则比较麻烦。我们采用的是TLI adapter的方式,虽然底层同样使用DPI技术,但是它提供了对TLM的支持,让SC和SV之间的通信能够使用TLM 标准,这使得VMM1.2和ESL开发以及它们之间的通信都采用 同样的标准。VMM1.2实现了TLM2.0的大部分功能,这让验 证环境和ESL有了类似的接口。VCS新的版本(我们使用了 VCS1103)提供了TLI适配层完成SC和SV之间的通信,这使得 SC侧和SV侧相同的TLM接口可以很容易的连接起来。
3.1 ESL adapter
有人说过所有的软件问题都可以增加一层来解决,所以我们在 SC侧增加了ESL Adapter来隔离开验证和ESL原来的代码,减 少ESL和验证环境的耦合。

图 1 – Fake top
eg0和eg1是我们需要的ESL代码,所以我们在Fake top(eg0_eg1_top)中将它们实例化,同时将它们联接起来。
eg0和eg1和原来的ESL中的其它模块也有联系,图2展示了我们如何处理eg0和IR之间的联系。ir和eg0之后通过tlm socket联接,现在没有了IR,所以fake top接手了这一工作,它实现了socket接口,并和eg0中的socket绑定。
ir被ir_subenv替代,eg0需要和ir_subenv之间交换数据,虽然eg0并不知道这些。但是验证环境中我们使用的是analysis port而非tlm socket,所以在fake top中我们需要实现analysis port和t lm socket之间的数据搬移。 我们定义了eg0_eg1_top这个类,来例化EG0和EG1这两个模块,同时定义了一些fake socket来顶替我们剥离的ir模块:
class eg0_eg1_top : public SC_MODULE
{
EG0 *m_eg0;
EG1 *m_eg1;
tlm_ir_to_eg0* m_tlm_ir_to_eg0;
tlm::tlm_analysis_port m_ap_eg0_to_ir;
typedef tlm_utils::simple_initiator_socket
ir_init_skt_t; ir_init_skt_t m_skt_init_ir_to_eg0; // ir to eg0
…
};
eg0_eg1_top的构造函数,例化eg0和eg1并把它们connect起来,同时注册fake socket的bw函数:
eg0_eg1_top:: eg0_eg1_top(SC_MODULE_NAME name)
sc_module(name),
m_ap_eg0_to_ir(“ap_eg0_to_ir”)
{
m_eg0 = new(…);
m_eg1= new(…);
m_eg0.m_skt_init_eg0_to_eg1(m_eg1.m_skt_tgt_eg1_to_eg0);
m_skt_init_ir_to_eg0.register_nb_transport_bw(this,& eg0_eg1_top::inc_credit_eg0);
…
}
inc_credit_eg0接收到eg0发往ir的trans,转换为TLI接口的格式并通过analysis port发往验证环境:
void eg0_eg1_top::inc_credit_eg0(
trans_t& trans,
phase_t& phase,
sc_core::sc_time& t)
{
intf_ir_eg0_t *p_cmd = (intf_ir_eg0_t *)(trans.get_data_ptr());
intf_eg0_to_ir ir_trans;
ir_trans.XXX = p_cmd->YYY;
…
m_skt_init_ir_to_eg0.write(ir_trans);
return tlm::TLM_COMPLETED;
tlm_ir_to_eg0实现接收ir到eg0的trans的analysis subscriber, 主要实现write函数。write函数接收到ir_subenv发送过来的TLI 格式的trans并转换为ESL内部格式的trans,并调用eg0_eg1_ top::ir_trans_to_eg0将trans送往eg0:
class tlm_ir_to_eg0 : public sc_module
{
eg0_eg1_top *m_top;
void write(const typename TYPES::tlm_intf_ir_to_eg0_type &gp)
{
intf_sm_eg0_t dt_ir_eg0;
dt_ir_eg0.AAA = gp.BBB;
…
m_top->ir_trans_to_eg0(dt_ir_eg0);
}
};
3.2 ESL 内部接口
我们需要查看ESL内部的一些接口信号,这样在通过socket将 数据发送到sokcet的另一端时, 我们也需要把这些数据通过 analysis port发送给验证环境。
在cpp文件中需要提取trans的地方加入宏定义和函数调 用,这样在不影响正常ESL编译的情况下,将需要的功能通 过函数插入。
void egtop::req_proc()
{
…
#indef ESL_FOR_DV
adapter_egtop_to_dv(trans);
#endif
…
}
在egtop.h中,通过宏和include egtop_dv.h增加的头文件,同 样不影响ESL的编译:
#include …
#indef ESL_FOR_DV
include “egtop_dv.h”
#endif
class egtop : public sc_module
{
#indef ESL_FOR_DV
#include “egtop_ap.h”
#endif
…
}
egtop_dv.h和egtop_ap.h都在adapter目录,ESL和验证的代码 修改互不干扰。
egtop_dv.h中:
#include “tli_sc_bindings.h”
#include “tli_sc_bindings.h”
#inlcude “tlm_fifo.h” “intf_egtop_to_eg.h”
egtop_ap.h中定义analysis port,并实现analysis port的构造和 删除,以及ESL内部trans向验证环境转换的函数:
tlm::tlm_analysis_port
void adapter_egtop_init()
{
…
}
void adapter_egtop_destory()
{
…
}
void adapter_egtop_to_dv(trans)
{
…
m_ap_egtop_to_eg->write(…);
…
}
4. ESL和DUT的比对
ESL和DUT的比对用来检查ESL和DUT的实现是否一致,如果 不一致则说明某一方可能有问题,所以ESL和DUT的比对相当 重要。但是由于我们ESL模型粒度太细,也会有一些问题需要解决。
4.1 ESL和RTL的实现差异
有些时候ESL和RTL用不同的方法实现了同样的功能,这些功
能应该如何实现是没有在文档中定义的。这个时候我们对中间结果的比较就陷入了麻烦,通常如果只是简单的每个比特的比较就会报错。
目前验证平台对ESL和DUT的对比出现问题主要表现在以下两个方面,对于这些问题在讨论过后发现都是ESL改动比较容 易,所以基本都是ESL在配合改动。但是如果此类问题过多就 会加重ESL人员的工作量,所以在最初建模时尽量将以下问题 考虑进去,虽然不能完全预见,但是预防可以减少后续无谓的工作量。
1. 由于处理过程不一致导致结果比对不一致:
1) 要对比的中间结果或者最终结果有一部分不关心其值到底是多少,对于这部分的处理,ESL设计和RTL设计最好约定到底是清零还是设成某一固定值。因为验证的时候不关心到底哪部分有效哪部分无效,只关系到底相等不相等。
2)对于细节实现:ESL的建模相对来说是比较灵活的,在某一操作的先后顺序做对于ESL来讲是一样的,但是这些细节如果加入时序考虑就会导致和RTL输出有所差,尤其加上某些临界值的发生。所以原则ESL这部分应该尽量和 RTL设计保持一致。
2 .时序:
1)如果要保证ESL和RTL有相同的时序起始点,那么reset 信号是至关重要的。目前ESL内部调度计数器是随时钟计 数,时钟是验证平台产生,此时验证和ESL保持同样的计 数,那么在这个计数器满足一定条件的时候发起reset信 号,并适当的时机来撤销reset。也就是验证保证与ESL设 计同步的前提下控制RTL的 复位信号。
2)对于ESL时序的建模,尽量将所有的不同类型的时序点都 抽取出来,之前做的时候因为预定一些时序是会在同一段 时间内完成,但是经过设计的修改这些时序变得不一致, 结果又重新配参数,虽然不难,但是又增加了工作量,所 以尽可能一次到位,将有可能发生时序建模的点都提取出 来,这样ESL的配置可以灵活调整。
4.2 对比策略
每个比特的对比是最容易也是最稳妥的方式,所以在ESL模型 和RTL在输出数据时,首先进行bit级的对比。如果对比不成 功,那么有可能是哪里出错了,出错的信息是给人看的,所以 出错信息的可读性就非常重要。在这个时候,我们需要将接口 数据转换为有意义的域段,同时告诉用户哪些域段出错了。另 一方面,在将接口数据转换为有意义的域段之后比较,因为可 以忽略一些不关心的部分,这个时候很有可能对比通过了,所 以在bit级对比时不应该报错,这个时候应该是一个警告,在域 段级对比时才能确定到底是不是出错了。
对比不能通过时如何定位?是ESL设计还是RTL设计的问题? 是否有足够多的信息?解决的办法倒是有很多,比如让验证 环境忽略掉这些不同的地方,或者ESL的处理调整得和RTL相 同,或者RTL的处理调整得和ESL相同。
ESL模型如此精确,如何确保抽象层次的正确性?额外的function model或是更高层次的验证?我们选择了更高层次的 验证,在UT我们使用了ESL做为RM进行精细比较,但在IT我们 使用SV写的功能级RM完成端到端检查。
5. 调试
调试总是一件富于挑战的工作,在你知道错误原因以前,这可能是一个非常痛苦的过程。在SC和SV相互通信的时候,我们必须找到一个好方法来进行调试,否则发出的数据可能就像湮灭了一样。ESL开发人员和验证人员还是不同的工程师,通常 ESL开发人员不了解验证,验证人员对ESL的了解也很有限。 最高效的方式是需要有人对ESL和验证环境都有所了解,这样 可以快速定位是哪里出了问题。所以我们需要相互了解,包括了解对方的工作,能够使用对方的开发工具。目标就是ESL人 员可以使用验证人员的工具来确保交付给验证的代码是可用 的,验证人员则需要掌握ESL开发人员的工具同时能看懂ESL 的代码。
5.1 GDB调试
GDB是linux上调试利器,在调试SC和TLI时同样非常有用。在 用syscan编译SystemC代码时在-CFLAGS中增加-g选项,在用 vcs编译整个环境时在-CFLAGS中增加-g选项,编译完成之后 就可以用GDB来调试simv文件了。在ESL和VMM1.2验证环境 集成的初期,我的所有调试工作都是使用GDB完成的。
5.2 DVE图形化界面调试
DVE提供了图形化的界面,能够同时支持多种语言的调 试,所以在SV和SC联合调试时应该非常有用,这里就不做详细介绍。
5.3 UCLI接口调试
在仿真卡死的时候,UCLI是最佳的定位方式。用-debug_all重 新编译环境,然后在仿真卡死的时候按下Ctrl+C进入UCLI模式。这时可以用thread –current命令查看当前thread,同时可以用listing列出当前正在执行的代码,一般就能很快定位出问题所在。
这对我们使用了TLI方式传送数据特别有价值,数据在穿越TLI层的 时候,我们可以使用的手段不多,如果用GDB看汇编代码是一件极有挑战的工作,所以熟练掌握UCLI的调试方法是必要的。

图 2 – UCLI thread
5.4 LOG
在所有的调试方法中,log信息是极有价值的一种。通过在我们关注的地方输出需要的信息,我们就能很快的知道错误可能的发生 的地方和原因,甚至直接知道代码中的错误。
5.4.1 Align VMM and SC message
SystemC的标准输出不能用simv的-l选项捕获,屏幕的缓冲区也是有限的,所以在仿真结束时,这些标准输出的有用信息我们就 可能无法取得。虽然可以将标准输出通过重定向的方式写入文件,但是-l选项效率更高一些。
5.4.2 哪些信息需要记录
一个基本的原则,log信息是可以分级打印的,当然如果能更精细的指定哪些信息需要记录也是很有用的。对ESL在VMM1.2中复 用来说,在调试的过程SC侧和SV侧之间发送的接口数据一定要详细的记录下来。这可以帮助我们初步定位问题究竟出在哪一侧, 这很重要,因为同时了解ESL和验证的人现在并不多。所以记录的信息需要能快速的帮助我们划出了范围,能够让合适的人来定 位,提高验证效率。
6. ESL作为DUT运行
在RTL可用以前,如果ESL已经完成,则可以用ESL做为DUT来运行,这样在RTL可用的时候,验证环境已经基本稳定,可以更多
的精力集中在RTL上而不是环境本身。 类似eg0_eg1_top我们封装一个eg0_eg1_dut的顶层,用来例化ESL内部模块和实现fake socket以及signal级的外壳:
class eg0_eg1_dut : public sc_module
{
public
: sc_in_clk clk;
// ir to eg0
sc_in
…
// eg0 to ir sc_out
…
private:
EG0 *m_eg0;
EG1 *m_eg1;
typedef tlm::tlm_fifo
ir_eg0_fifo_t *m_eg0_to_ir_fifo;
…
};
在构造函数中,我们例化ESL内部的模块并将它们connect起来,使用tlm_fifo来缓存ESL发往外部的信号。
eg0_eg1_dut::eg0_eg1_dut(sc_module_name name):
sc_module(name)
{
m_eg0 = new(…);
m_eg1 = new(…);
m_eg0_to_ir_fifo = new ir_eg0_fifo_t(“ir_eg0_fifo”,2);
SC_METHOD(eg0_to_ir_method);
sensitive << clk.pos();
don't_initialize();
SC_METHOD(ir_to_eg0_method);
sensitive << clk.pos();
don't_initialize();
...
}
eg0向ir的输出我们先放入fifo中:
sync_enum_t eg0_eg1_dut::inc_credit_eg0(
trans_t& trans,
phase_t& phase,
sc_core::sc_time& t)
{
intf_ir_eg0_t *p_cmd = (intf_ir_eg0_t *)trans.get_data_ptr();
intf_eg0_to_ir ir_trans;
ir_trans.incr_credit = p_cmd->incr_credit;
…
m_eg0_to_ir_fifo->nb_put(ir_trans);
return tlm::TLM_COMPLETED;
}
每个cycle我们查看fifo中是否有trans,如果有则转换为signal信号输出:
void eg0_eg1_dut::eg0_to_ir_method()
{
intf_eg0_to_ir ir_trans;
if(m_eg0_to_ir_fifo->nb_can_get()){
m_eg0_to_ir_fifo->nb_get(ir_trans);
inc_credit = ir_trans. inc_credit;
}
else{
inc_credit = 0;
…
}
}
每个cycle我们都查看eg0的输入是否有效,如果有效则将signal信号转换为trans,把trans交给ir_trans_to_eg0处理:
void eg0_eg1_dut::ir_to_eg0_method()
{
if(wr_req.read() == 1){
dt_ir_eg0.wr_req = wr_req.read().to_uint();
…
}
ir_trans_to_eg0();
}
ir_trans_to_eg0通过fake socket将trans输送给ESL内部:
sync_enum_t eg0_eg1_dut:: ir_trans_to_eg0()
{
…
skt_init_ir_to_eg0->nb_transport_fw(ir_trans,…);
…
}
同时因为ESL的运行效率比RTL代码仿真要高很多,所以我们也计划在顶层仿真时,使用部分ESL模块来替换RTL中的模块,这样来提高整个验证环境的运行速度。
7. 结论及建议
ESL模型能够简单高效的在VMM1.2中应用。跨语言的通信已经有了TLI方式的支持,而且使用TLM接口使得整个环境使用统一的标准。但是还是有不少需要团队分工才能完成的工作,在将ESL用于VMM1.2验证环境之前详细的评估和计划是必不可少的, ESL团队和验证团队的交流顺畅也是非常重要,这就要求验证人员需要对ESL有一定了解,ESL开发人员也需要了解如何满足验证需求。
8. 参考文献
《VCS UserGuide》



