UVM面试题36-55

3 6 、 生成 sequence 时, early randomization 和 late randomization 有什么区别?

在early randomization中,先调用randomize()方法对sequence对象进行随机化,然后再使用start_item()来请求对sequencer的访问,如下例所示:

task body()
assert(req.randomize());
start_item(req);
//Can consume time based on sequencer arbitration
finish_item(req);
endtask

在 late randomization 中,先调用 start_item (),直到从 sequencer 授予仲裁,然后在将事务发送到 sequencer/driver 之前调用 randomize 。

task body()
start_item(req); 
//Can consume time based on sequencer arbitration
assert(req.randomize());
finish_item(req);
endtask

37、什么是subsequence?

从sequence的body()任务中,如果调用了另一个sequence的start(),则通常将其称为subsequence。

38、get_next_item()和try_next_item()有什么区别

get_next_item() 是一个阻塞调用,直到存在可供驱动的sequence item为止,并返回指向sequence item的指针。 try_next_item() 是非阻塞调用,如果没有可供驱动的sequence item,则返回空指针。

39、UVM driver类中的get_next_item()和get()方法之间有什么区别?

get_next_item() 是一个阻塞调用,用于从sequencer FIFO获取sequence item。driver驱动完sequence item后需要先使用item_done()完成握手,然后再使用get_next_item()请求新的sequence item。

get() 也是一个阻塞调用,同样用于从sequencer FIFO获取sequence item。但是在使用get()时,由于get()方法隐式完成了握手,因此无需显式调用item_done()。

40、driver中带和不带有参数的item_done()调用有什么区别?

item_done()方法是driver中的一种非阻塞方法,用于在get_next_item()或try_next_item()成功之后与sequencer完成握手。如果不需要发回响应,则调用不带参数的item_done()。如果需要发回响应,则将指向sequence_item的指针作为item_done()参数。

41、以下哪个driver类方法是阻塞调用哪些是非阻塞调用?

  1. get()

  2. get_next_item()

  3. item_done()

  4. put()

  5. try_next_item()

  6. peek()

get(),get_next_item(), peek() 是阻塞调用;

try_next_item(),item_done()和put() 非阻塞调用

42、在UVM driver类中,以下哪个代码是错误的?

1)

function get_drive_req();

 forever begin
 req = get();
 req = get();
 end

endfunction

2)

function get_drive_req();

forever begin
req =get_next_item();
req =get_next_item();
item_done();
end

endfunction

3)

function get_drive_req();

forever begin
req = peek();
req = peek();
item_done();
req = get();
end

endfunction

2)错误,因为不能在调用item_done()之前两次调用get_next_item(), 无法完成与sequencer的握手

43、如何停止在sequencer上运行的所有sequences?

sequencer具有 stop_sequences() 方法,可用于停止所有sequences。但是此方法不检查driver当前是否正在驱动任何sequence_items,如果driver调用item_done()或put(),则可能会出现Fatal Error,因为sequences指针可能无效。

44、调用sequence.print()方法时,应该调用sequence中的哪个方法?

convert2string(): 建议实现此函数,该函数返回对象的字符串形式(其数据成员的值),这对于将调试信息打印到仿真器界面或日志文件很有用。

45、找出UVM sequence的以下部分代码中的任何潜在问题

task body();

seq_item_c req;
start_item(req);
#10 ns;
assert(req.randomize());
finish_item(req);

endtask

应该避免在 start_item 和 finish_item 之间添加延迟。 start_item 返回后,该 sequence 将赢得仲裁并可以访问 sequencer/driver 。 从那时起直到 finish_item 的任何延迟都将使得 sequencer/driver 暂停 ,不能被其他 sequence 使用 。

46、什么是virtual sequence,在哪里使用?有什么好处?

virtual sequence是控制多个sequencers中激励生成的sequence。由于sequences,sequencers和drivers都只针对单个接口,几乎所有测试平台都需要virtual sequence来 协调 不同接口之间的激励。

Virtual sequences在子系统或系统级测试平台上也很有用,可以使模块级的sequence协调地运行。

47、使用new()和create()方法创建对象有什么区别?

UVM推荐使用内置方法 :: type_id :: create() ,而不是直接调用构造函数new()创建组件或事务对象。

create方法在内部调用factory机制以查找所请求创建的类型,然后调用构造函数new()以实际创建一个对象而 无需 更改 任何代码 。

48、我们如何注册uvm_component类和uvm_sequence类?

uvm_sequence类使用 uvm_object_utils() 宏在factory中注册,并将类名作为参数传递:

class test_seq_c extends uvm_sequence;

`uvm_object_utils(test_seq_c)

uvm_component类使用 uvm_component_utils() 宏在factory中注册,并将类名作为参数传递:

class test_driver_c extends uvm_component;

`uvm_component_utils(test_driver_c)

49、我们为什么要在factory中注册类?

factory是UVM中使用的 特殊查找表 ,用于创建component 或者transaction类型的对象。使用factory创建对象的好处是,测试平台可以在 运行仿真时 决定创建哪种类型的对象。

一个类可以用另一个派生类替换,而无需更改任何代码。 为确保此功能,建议所有类都在factory中注册。 如果不向factory注册类,则将无法使用factory方法:: type_id :: create()构造对象。

50、instance override和type override之间有什么区别?

顾名思义, type override 适用于该组件类型所在层次结构中的所有实例, instance override 仅覆盖类的特定实例,即该组件在UVM组件层次结构中的位置。 由于只有UVM 组件类具有层次结构,因此只有组件类能进行instance override,而sequen ces (UVM objects)只能进行type overridden。

51 、什么是 objections 概念,用在什么地方?

uvm_objection类提供了一种在多个components和sequences之间共享计数器的方法。每个component/sequence可能会异步地“raise”和“drop” objections,这会增加或减少计数值。当计数值达到零(从非零值开始)时,则称发生“all dropped”条件。

objection机制最常用于UVM phase机制中 ,以协调每个run-time phase的结束。在用户进程开始时raises an objection,在用户进程结束 时 drops the objection。当一个phase中的所有用户进程都drops objection时,该phase的objections计数将变为零。这种“all dropped” 条件向phase机制表明,每个用户进程都同意结束该phase。

下面是一个示例说明如何在sequencer(my_sequencer)上启动sequence(my_test_sequence),并在sequence执行完成之后drops objection。

task main_phase( uvm_phase phase);

phase.raise_objection(this);
my_test_sequence.start(my_sequencer);
phase.drop_objection(this );

endtask

52、我们如何在UVM中实现仿真超时机制(simulation timeout mechanism)?

如果由于某些错误导致超出最大仿真时间, 仿真超时机制 可以帮助停止仿真。 在UVM中有一个很方便的函数 set_global_timeout(timeout) 用于将 uvm_top.phase_timeout 变量设置为超时值。 如果run()phase 在该超时值之前没有结束,则仿真将停止并报告错误。

module test;

initial begin
    set_global_timeout(1000ns);
end

initial begin
        run_test();
end
endmodule

53、UVM方法学中phase的概念是什么?

不同于基于module的验证测试平台(所有module静态地存在于层次结构中),基于class的验证测试平台需要 管理不同对象的创建和其方法的执行 。

Phase使得验证平台具有一致的执行流程。测试的执行可以分为以下任务-配置**( configuration ),创建验证平台组件( creation ),运行激励( stimulus )和测试检查结束( end of test checks )**。

54、UVM组件有哪些不同的phases?UVM run_phase()的subphases是什么?

UVM使用标准phases来排序仿真过程中的主要步骤,有三组phases,按以下顺序执行。

1、Build phases –在构建phases 配置和构建测试平台,它具有以下子phases ,这些子phases 都在uvm_component基类中作为virtual方法实现。

1)build_phase()

2)connect_phase()

3)end_of_elaboration()

2、Run time phases – 这些phases 会消耗时间,这是大多数测试执行的地方。

  1. start_of_simulation()

  2. run_phase(),进一步分为12个子phases:

  3. pre_reset

  4. reset

  5. post_reset

  6. pre_configure

  7. configure

  8. post_configure

  9. pre_main

  10. main

  11. post_main

  12. pre_shutdown

  13. shutdown

  14. post_shutdown

3、Clean up phase – 该清理阶段在测试结束后执行,用于收集并报告测试的结果和统计信息,包括以下子phase:

1)extract()

  1. check()

  2. report()

  3. final()

55、uvm_component类中的phase_ready_to_end()方法有什么用途?

phase_ready_to_end(uvm_phase phase) 是component类中的 回调(callback) 方法,当该phase的所有objections均被drop之后调用该方法。component类可以使用此回调方法来定义phase即将结束时需要执行的功能。

如果某个组件希望在objections被drop之后将phase结束延迟到某个条件,可以使用此回调方法来完成。

おすすめ

転載: blog.csdn.net/weixin_44582960/article/details/106959151