UVM实战指南(6)

2019-08-30 16:37

20多年前,设计者从门级转向RTL级。这次转换来自于标准Verilog/VHDL的RTL编码风格,以及RTL综合实现工具的推出。使用RTL最大的好处是让设计者更多的专注于时序行为的设计以及功能的正确性,而很少考虑门级相关设计。

TLM(事务级建模)同样在抽象级别上更进了一步,在设计和验证领域都有出现。通过TLM, 中心放在系统级别的各种事务流的建模,而更少关心时钟级别的行为。

TLM在测试向量中已经使用多年。通常,在产生激励和覆盖率检查的时候使用事务而不是用时钟级别建模,这种方式就是TLM. 为了验证RTL级别的DUT(需要测试的模块),测试向量使用事务发生器(transactor)(有时也称为总线功能模型(BFM)),将RTL级和事务级进行转换。在UVM中,此事务发生器也被叫做驱动(driver)或者收集器(collector)。 TLM中,事务通过方法调用和类对象来建模。使用事务级而不是信号级别来建模有几个显著的好处:

? ?

TLM比RTL更简洁,仿真速度快。

TLM模型的抽象级别更高,更加契合验证工程师或设计工程师对内部功能的考虑,从而使得建模更简单,并且更容易被其他工程师理解。

TLM模型将不符合复用的部分移到模型之外,因此TLM很适合复用。并且,TLM使用面向对象的技术,比如继承、实现和接口分离的技术。

?

TLM的采纳依赖于标准的TLM建模技术的出现,就像RTL综合流程的采纳归功于标准RTL编码风格的实现。幸运的是,近些年来,几个重要的标准TLM应用程序接口(API)得到定义。在EDA和ESL领域,两个最重要的标准是开放SystemC计划(OSCI)的TLM1.0以及TLM2.0标准。

OSCI TLM 1.0标准是一个简单通用的TLM API, 用来建模消息传递。在消息传递时,对象(事务)在组件之间传递的方式和封包在网络之间传递的方式类似。

在发送封包的消息传递中,发送端和接收端之间没有共享的状态,他们之间的通讯讯息仅仅包含在消息中。

The OSCI TLM 2.0标准能够用来开发SystemC中的高速虚拟平台模型。TLM2.0标准特别被用作片上存储映射的总线系统,包含许多能够进行片上总线互联的整合复用模块. OSCI TLM 1.0和TLM 2.0是互相独立的标准,满足不同的需要。有人可能通过其命名方式认为TLM2.0优于TLM1.0,但是实际上并不是这样。

UVM提供的TLM 类和API是基于TLM1.0标准的。这是因为TLM通用消息传递语法很好的满足了多种验证组件的事务级建模。TLM1.0也适合多种语言之间的通信建模,比如SystemVerilog, SystemC以及e语言之间的建模。UVM中TLM1.0接口甚至可以用来和SystemC中的TLM2.0模型进行通讯。

这一章节阐述了UVM中TLM的几个重要概念,让读者理解如何使用TLM来构造可复用的验证组件。关于TLM各种类的更详细说明请参阅UVM参考手册。

4.6.1 UVM中TLM的关键概念

4.6.1.1 对事务建模

在UVM中, 从uvm_sequence_item继承而来的任何类都是事务。用户根据需要定义事务类的字段和方法,用来在验证环境中不同组件之间进行信息交换。例如,一个简单的包如下所示:

1. class simple_packet extends uvm_sequence_item; 2. rand int src_addr; 3. rand int dst_addr;

4. rand byte unsigned data[];

5. constraint addr_constraint { src_addr != dst_addr; } 6. ... 7. endclass

事务通常包含足够多的数据字段让驱动器(driver)或者事务产生器能够产生事务的真实信号级别的动作表示。事务也可以包含更多的数据字段,来控制数据的随机产生,或者是验证环境中的其他目的。可以通过继承方式来增加更多的数据成员,方法以及约束。后续章节将会说明,如何通过继承事务,从而花费最小的代价来完成特定的验证任务。

4.6.1.2 TLM调用端口(Ports)和实现端口(Exports)

UVM中的TLM使用一系列特殊的方法调用来进行模型之间的事务通讯。在UVM中,一个port对象定义了一系列可以被调用的方法,而export对象提供了对这些方法的实现。在构建验证环境的时候,port和export通过connect()函数进行连接,之后,调用port端的TLM方法将会执行export中对此TLM方法的实现。 实例4.7: 使用put方法将事务从生产者传递给消费者

在UVM的TLM中,put接口能够被用来将transaction从生产者发送给消费者。一个简单的生产者示例如下:

class producer extends uvm_component;

uvm_blocking_put_port #(simple_packet) put_port;

function new(string name, uvm_component parent); put_port = new(\ endfunction

virtual task run();

simple_packet p = new(); ..

put_port.put(p); endtask endclass

之前有提到,put port通过调用connect()函数连接到put export. 对上面的put方法的实现将由消费者组件来完成,如下:

class consumer extends uvm_component;

uvm_blocking_put_imp #(simple_packet, consumer) put_export;

task put(simple_packet p); // consume the packet endtask endclass

将port连接到export之后,调用生产者的put方法将会触发消费者的put方法实现得到执行,从而使得simple_packet对象从生产者传递到了消费者。

TLM也引入了标准的图形化示意来描述不同类型的通讯。put通讯流程的模块图如下:

图4-2: 简单的生产者/消费者的put通讯

TLM接口定义了一些生产者和消费者都必须遵循的简单规则,在这个示例中,对于put接口,规则如下:

?

put方法的实现在执行时有可能阻塞,因此对put方法调用的对象必须负责确保在put方法阻塞的时候能够正常工作。

? 生产者负责创建封包,而消费者不能修改封包(如果需要修改,必须先拷贝一份新的)

满足了上述规则,能够很容易的将生产者或者消费者替换成其他的模型,只要这些模型满足相同的TLM接口即可。TLM API提供了一个简单的能够互相操作的接口协议,类似硬件世界中的USB,以太网标准一样。由于能够容易的替换模型,UVM的TLM在满足模型复用和验证目标上发挥了关键性的作用,我们可以在后续章节进一步了解。

上述示例,在生产者中存在单独一个进程,当调用put方法时,控制流转到消费者中的put方法中。put方法将事务沿着方法调用控制流相同的方向进行传送。

在某些情况,由于消费者中包含一个需要事务数据的进程,希望将事务沿着TLM方法调用控制流相反的方向传送。在这种情形下,生产者/消费者将使用get接口来实现,示例如下:

1. 2. 3. 4. 5. 6. 7. 8. 9.

class producer_2 extends uvm_component;

uvm_blocking_get_imp #(simple_packet, producer_2) get_export;

task get(output simple_packet p); simple_packet p_temp = new(); ...

p = p_temp; endtask endclass

class consumer_2 extends uvm_component;

10. uvm_blocking_get_port #(simple_packet) get_port; 11. function new(string name, uvm_component parent); 12. get_port = new(\13. endfunction 14. virtual task run(); 15. simple_packet p; 16. ...

17. get_port.get(p); 18. endtask 19. endclass

在上面的put接口示例中,UVM对使用put接口的生产者和消费者设定了如下规则:

?

get方法实现可能被阻塞。因此调用方必须确保当此方法阻塞的时候也能够正确工作。

get方法的实现必须创建并返回一个事务对象给get的调用方。

?

get接口通讯的图形化示意如下:

图4-3: 消费者调用生产者中的get方法

4.6.1.3 连接port和export

上面例子中,port对export的连接是通过调用connect方法完成的。用户需要在消费者/生产者的父组件中的connect回调函数[仿真阶段函数connect())中调用此connect方法:

class parent_comp extends uvm_component; producer producer_inst; consumer consumer_inst; ...

virtual function void connect();

producer_inst.put_port.connect(consumer_inst.put_export); endfunction endclass

连接port和export的通用准则是:子组件中port的connect方法以子组件export作为参数进行调用.

4.6.1.4 port和port的连接以及export和export的连接

Verilog RTL中,模块的端口(port)代表信号级别的界面。Verilog RTL模块的内部也可以包含子模块,子模块也有各自的信号端口。然而,只有父模块的端口代表整个模块的接口,子模块的接口被当作实现细节而被隐藏。

同样的,UVM的TLM中,组件的port和export代表了组件的TLM的对外接口。其子组件以及子组件的port和export被看作是实现细节而被隐藏。此种隐藏内部结构的方式加强了整个验证环境的模块化,能够更加容易的复用以及被替换。


UVM实战指南(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:《苹果树上的外婆》整本书读书规划

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: