网站模版 源码之家网店美工具体要求

当前位置: 首页 > news >正文

网站模版 源码之家,网店美工具体要求,6.网站开发流程是什么,阿里云做视频网站犯法吗IC每日一题#xff1a;IC验证面试–UVM验证-2 2.9 get_next_iterm()和try_next_item()的区别#xff1f;2.10 一个典型的UVM验证平台#xff0c;谈一下UVM验证环境结构#xff0c;各个组件之间的关系#xff1f;2.11 uvm组件之间通信的方式#xff1f; analysis_port和其… IC每日一题IC验证面试–UVM验证-2 2.9 get_next_iterm()和try_next_item()的区别2.10 一个典型的UVM验证平台谈一下UVM验证环境结构各个组件之间的关系2.11 uvm组件之间通信的方式 analysis_port和其他的区别analysis_port是否可以不连或者连接多个import2.12 uvm_tlm_anlysis_fifo类是什么有什么端口2.13 UVM组件中常用的方法各种phase关系phase机制2.14 phase中的domain概念2.15 run_phase和main_phase之间的关系2.16 UVM组件的通信方式TLM的接口分类和用法peek和get的差异2.17 sequence和item(uvm_sequence, uvm_sequence_item)的分类2.18 为什么会有sequencesequencer以及driver为什么我们分开实现这样做的好处是什么2.19 如何在driver中使用interface2.20 config_db的作用以及传递其使用时的参数含义 【博客首发与微信公众号《漫谈芯片与编程》欢迎专注一下】 本篇博客开始介绍IC验证基本功–UVM-2的相关问题 2.9 get_next_iterm()和try_next_item()的区别 get_next_item() 和 try_next_item() 是 uvm_sequencer 类提供的两个方法用于从 sequencer 中获取下一个transaction。 get_next_item()–阻塞调用: 这个方法会阻塞当前的执行线程直到 sequencer 中有可用的 item。如果 sequencer 中没有 item调用 get_next_item() 的线程会一直等待直到有 item 被放入 sequencer。一旦获取到 itemget_next_item() 会返回这个 item并且调用者可以继续执行。 task run_phase(uvm_phase phase);forever beginseq_item_port.get_next_item(req); // 阻塞调用直到有新的事务可用drive(req); // 处理事务seq_item_port.item_done(); // 通知序列器事务已完成end endtask try_next_item()–非阻塞调用 当驱动器调用 try_next_item() 时如果当前没有可用的事务它会立即返回不会阻塞。try_next_item() 返回一个布尔值表示是否成功获取到事务。 task run_phase(uvm_phase phase);forever beginif (seq_item_port.try_next_item(req)) { // 非阻塞调用drive(req); // 处理事务seq_item_port.item_done(); // 通知序列器事务已完成} else {// 没有事务时执行其他任务do_something_else();}end endtask典型应用场景 get_next_item()当你希望驱动器总是等待事务并按顺序处理时使用 get_next_item()。这是最常见的用法特别是在简单的驱动器实现中。try_next_item()当你希望驱动器在没有事务时能够执行其他任务或者在多事务流场景下需要灵活处理时使用 try_next_item()。这在需要更高的响应性和灵活性的场景中非常有用 2.10 一个典型的UVM验证平台谈一下UVM验证环境结构各个组件之间的关系 UVM验证环境的基本组成 环境uvm_env包含所有验证组件。 代理uvm_agent包含驱动器、监视器和序列器与DUT进行交互。 驱动器uvm_driver将事务转换为信号驱动到DUT。 监视器uvm_monitor监控DUT的输入和输出并将信号转换为事务。 序列器uvm_sequencer从序列中获取事务并传递给驱动器。 序列uvm_sequence生成事务。 参考模型 (reference_model): 参考模型是一个功能性的模型它独立于DUT实现同样的功能参考模型的输出可以用来与DUT的实际输出进行比较从而判断DUT的功能是否正确。 记分板uvm_scoreboard检查DUT的输出是否符合预期。 虚拟接口virtual interface连接UVM组件与DUT。 寄存器模型uvm_reg_block描述DUT中的寄存器和寄存器块。 在这里重点介绍一下参考模型的Demo: class my_reference_model extends uvm_component;uvm_component_utils(my_reference_model)uvm_analysis_imp #(my_transaction, my_reference_model) imp;function new(string name, uvm_component parent);super.new(name, parent);imp new(imp, this);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);endfunctionfunction void write(my_transaction tr);// 执行与DUT相同的操作// 例如计算期望的结果my_transaction exp_tr tr.clone();exp_tr.data perform_function(tr.data); // 假设有一个函数 perform_function// 将期望的结果发送到记分板uvm_info(REF_MODEL, \(sformatf(Expected data: %h, exp_tr.data), UVM_HIGH)// 这里假设记分板已经连接到了参考模型的分析端口endfunction// 假设这是一个简单的函数模拟DUT的功能function bit [7:0] perform_function(bit [7:0] input_data);// 实现一些功能例如简单的加法return input_data 1;endfunctionendclassclass my_scoreboard extends uvm_scoreboard;uvm_component_utils(my_scoreboard)uvm_analysis_imp #(my_transaction, my_scoreboard) imp;uvm_tlm_analysis_fifo #(my_transaction) exp_fifo;function new(string name, uvm_component parent);super.new(name, parent);imp new(imp, this);exp_fifo new(exp_fifo, this);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);endfunctionfunction void write(my_transaction tr);// 将DUT的实际输出放入FIFOimp.write(tr);endfunctionfunction void check_phase(uvm_phase phase);my_transaction act_tr, exp_tr;while (exp_fifo.try_get(exp_tr)) beginif (!imp.get(act_tr)) beginuvm_error(SB, No actual transaction to compare with expected)continue;endif (act_tr.data ! exp_tr.data) beginuvm_error(SB, \)sformatf(Data mismatch: Expected %h, Actual %h, exp_tr.data, act_tr.data))end else beginuvm_info(SB, \(sformatf(Data match: %h, act_tr.data), UVM_HIGH)endendendfunction endclassclass my_env extends uvm_env;uvm_component_utils(my_env)my_agent agent;my_scoreboard scoreboard;my_reference_model ref_model;function new(string name, uvm_component parent);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);agent my_agent::type_id::create(agent, this);scoreboard my_scoreboard::type_id::create(scoreboard, this);ref_model my_reference_model::type_id::create(ref_model, this);endfunctionfunction void connect_phase(uvm_phase phase);super.connect_phase(phase);agent.monitor.ap.connect(scoreboard.imp);agent.monitor.ap.connect(ref_model.imp);endfunctionendclass 2.11 uvm组件之间通信的方式 analysis_port和其他的区别analysis_port是否可以不连或者连接多个import UVM组件之间的通信方式 1.TLM ports and exports uvm_port 和 uvm_export: 用于请求-响应式的通信。例如uvm_blocking_put_port 和 uvm_blocking_get_port。 uvm_analysis_port 和 uvm_analysis_imp: 用于单向数据流的通信主要用于监控和收集数据。 2.Phases and Callbacks 通过 UVM 的 phase 机制可以在特定的 phase 中进行组件间的通信。回调callbacks也可以用于在特定事件发生时进行通信。 3.uvm_config_db 通过 uvm_config_db 机制可以在组件之间传递配置信息; uvm_analysis_port可以不连接任何uvm_analysis_imp–这种情况下发送的数据将被忽略 uvm_analysis_port可以连接多个uvm_analysis_imp允许多个组件同时接收相同的数据是通过uvm_analysis_port::connect方法来实现的 uvm_analysis_port和uvm_analysis_imp的实现示例 // 定义一个简单的事务类 class my_transaction extends uvm_sequence_item;rand int data;uvm_object_utils(my_transaction)function new(string name my_transaction);super.new(name);endfunction endclass// 定义一个产生事务的组件 class producer extends uvm_component;uvm_component_utils(producer)uvm_analysis_port #(my_transaction) ap;function new(string name, uvm_component parent);super.new(name, parent);ap new(ap, this);endfunctiontask run_phase(uvm_phase phase);my_transaction tr;tr my_transaction::type_id::create(tr);tr.randomize();ap.write(tr); // 将事务发送到分析端口endtask endclass// 定义一个接收事务的组件 class consumer extends uvm_component;uvm_component_utils(consumer)uvm_analysis_imp #(my_transaction, consumer) imp;function new(string name, uvm_component parent);super.new(name, parent);imp new(imp, this);endfunctionfunction void write(my_transaction t);uvm_info(CONSUMER, \)sformatf(Received data: %0d, t.data), UVM_HIGH)endfunction endclass// 定义顶层环境 class env extends uvm_env;uvm_component_utils(env)producer prod;consumer cons1, cons2;function new(string name, uvm_component parent);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);prod producer::type_id::create(prod, this);cons1 consumer::type_id::create(cons1, this);cons2 consumer::type_id::create(cons2, this);endfunctionfunction void connect_phase(uvm_phase phase);super.connect_phase(phase);prod.ap.connect(cons1.imp); // 连接到第一个消费者prod.ap.connect(cons2.imp); // 连接到第二个消费者endfunction endclass// 测试用例 module top;initial beginrun_test();end endmodule 2.12 uvm_tlm_anlysis_fifo类是什么有什么端口 uvm_tlm_analysis_fifo 是 UVMUniversal Verification Methodology提供的一个类它结合了 TLMTransaction Level Modeling和 FIFOFirst-In-First-Out的功能用于在验证环境中存储和转发事务。这个类特别适用于需要缓存事务数据的场景例如在监控器和记分板之间传递数据。 uvm_tlm_analysis_fifo的主要端口 uvm_analysis_imp: 用于接收事务数据。这是一个单向的数据流通常用于监控器将数据发送到 FIFO。uvm_get_port: 用于从 FIFO 中取出事务数据。这是一个请求-响应式的端口通常用于记分板或其他组件从 FIFO 中获取数据 使用uvm_tlm_analysis_fifo的端口 //transaction class my_transaction extends uvm_sequence_item;rand int data;uvm_object_utils(my_transaction)function new(string name my_transaction);super.new(name);endfunction endclass//monitor class my_monitor extends uvm_monitor;uvm_component_utils(my_monitor)uvm_analysis_port #(my_transaction) ap;virtual my_if vif;function new(string name, uvm_component parent);super.new(name, parent);ap new(ap, this);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);if (!uvm_config_db#(virtual my_if)::get(this, , vif, vif))uvm_fatal(NOVIF, Failed to get vif)endfunctiontask run_phase(uvm_phase phase);my_transaction tr;forever begin(posedge vif.clk);if (vif.valid vif.ready) begintr my_transaction::type_id::create(tr);tr.data vif.data;ap.write(tr); // 将事务发送到分析端口endendendtask endclass//scoreboard class my_scoreboard extends uvm_scoreboard;uvm_component_utils(my_scoreboard)uvm_tlm_analysis_fifo #(my_transaction) fifo;function new(string name, uvm_component parent);super.new(name, parent);fifo new(fifo, this);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);endfunctiontask run_phase(uvm_phase phase);my_transaction tr;forever beginfifo.get(tr); // 从 FIFO 中取出事务uvm_info(SCOREBOARD, \(sformatf(Received data: %0d, tr.data), UVM_HIGH)endendtask endclass//env class my_env extends uvm_env;uvm_component_utils(my_env)my_monitor monitor;my_scoreboard scoreboard;function new(string name, uvm_component parent);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);monitor my_monitor::type_id::create(monitor, this);scoreboard my_scoreboard::type_id::create(scoreboard, this);endfunctionfunction void connect_phase(uvm_phase phase);super.connect_phase(phase);monitor.ap.connect(scoreboard.fifo.analysis_export); // 连接监控器和 FIFOendfunction endclass//test class my_test extends uvm_test;uvm_component_utils(my_test)my_env env;function new(string name, uvm_component parent);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);env my_env::type_id::create(env, this);endfunction endclass//module module top;initial beginrun_test(my_test);end endmodule uvm_tlm_analysis_fifo 可以有效地在监控器和记分板之间传递和缓存事务数据。 2.13 UVM组件中常用的方法各种phase关系phase机制 组件的生命周期是通过一系列的phase来管理的。这些phase包括构建阶段Build Phase、连接阶段Connect Phase、运行阶段Run Phase等。 new()构造函数用于创建组件实例。 build_phase()构建阶段用于创建和配置组件的子组件。 connect_phase()连接阶段用于连接组件之间的端口和接口。 pre_run_phase()在仿真运行之前的一些配置准备阶段 run_phase()运行阶段执行组件的主要功能如发送事务、接收事务等。 report_phase()仿真结束后报告阶段用于生成验证结果的报告。 Phase机制UVM的phase机制是通过一个全局的phase控制器来管理的。这个控制器负责调度和执行各个phase。在每个phase开始时控制器会调用所有组件的相应phase方法。组件可以通过重载这些方法来实现自定义的行为。 function new(string name, uvm_component parent);super.new(name, parent); endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);// 创建子组件my_child my_child::type_id::create(my_child, this); endfunctionfunction void connect_phase(uvm_phase phase);super.connect_phase(phase);// 连接端口my_child.my_port.connect(my_other_child.my_export); endfunctionfunction void start_of_simulation_phase(uvm_phase phase);super.start_of_simulation_phase(phase);// 初始化某些全局变量global_var 0; endfunctiontask run_phase(uvm_phase phase);super.run_phase(phase);// 生成激励repeat (10) beginmy_transaction tr my_transaction::type_id::create(tr);tr.randomize();my_sequencer.starting_sequence.put(tr);end endtaskfunction void report_phase(uvm_phase phase);super.report_phase(phase);// 生成报告uvm_report_server::get_server().write_report_messages(); endfunction 2.14 phase中的domain概念 domain 是一个用于管理和同步不同时钟域之间的信号和事件的概念。在不同的模块可能运行在不同的时钟频率上这就需要一种机制来确保跨时钟域的信号传输和事件处理是正确和可靠的 domain 通常与 clocking block 一起使用clocking block 是一种特殊的代码块用于描述信号在时钟边沿上的行为。通过将信号声明在 clocking block 中可以确保信号的采样和驱动是同步的并且符合特定的时钟约束。 // 定义一个时钟域 clocking cb (posedge clk);input data;output ack; endclocking// 在组件中使用时钟域 class MyComponent extends uvm_component;virtual clocking cb;function new(string name, uvm_component parent);super.new(name, parent);// 初始化时钟域cb new(cb, this);endfunctiontask run_phase(uvm_phase phase);forever begin// 在时钟上升沿采样输入数据(cb);data cb.data;// 处理数据//...// 在时钟上升沿驱动输出信号cb.ack 1b1;(cb);cb.ack 1b0;endendtask endclass 在这个示例中clocking block cb 定义了一个时钟域其中包含一个输入信号 data 和一个输出信号 ack。在 MyComponent 类中run_phase 任务使用 (cb) 来等待时钟上升沿然后采样输入数据并驱动输出信号。 2.15 run_phase和main_phase之间的关系 run_phase和main phase动态运行都是task phase且是并行运行的后者称为动态运行(run-time)的phase。 如果想执行一些耗费时间的代码那么要在此phase下任意一个component中至少提起一次objection这个结论只适用于12个run-time的phase。对于run_phase则不适用由于run_phase与动态运行的phase是并行运行的如果12个动态运行的phase有objection被提起那么run_phase根本不需要raise_objection就可以自动执行。 2.16 UVM组件的通信方式TLM的接口分类和用法peek和get的差异 事务级建模Transaction Level ModelingTLM是一种用于在验证环境中进行组件间通信的方法。TLM 接口和方法提供了一种标准化的方式来实现组件之间的通信。 UVM提供的TLM接口分类put/get 接口和 analysis 接口 put/get 接口: uvm_put_port/uvm_put_imp: 用于将数据从一个组件传递到另一个组件发送方不需要接收方的响应。 uvm_get_port/uvm_get_imp: 用于从另一个组件请求数据发送方需要接收方的响应。 uvm_peek_port/uvm_peek_imp: 用于查看另一个组件中的数据但不移除数据。类似于 get但不会消耗数据。 uvm_transport_port/uvm_transport_imp: 用于双向通信发送方发送数据并接收响应。 analysis 接口: uvm_analysis_port/uvm_analysis_imp: 用于单向数据流通常用于监控和收集数据。发送方不需要接收方的响应。 class my_transaction extends uvm_sequence_item;rand int data;uvm_object_utils(my_transaction)function new(string name my_transaction);super.new(name);endfunction endclassclass producer extends uvm_component;uvm_component_utils(producer)uvm_put_port #(my_transaction) put_port;function new(string name, uvm_component parent);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);put_port new(put_port, this);endfunctiontask run_phase(uvm_phase phase);my_transaction tr;tr my_transaction::type_id::create(tr);tr.randomize();put_port.put(tr); // 将事务发送到 put_portendtask endclassclass consumer extends uvm_component;uvm_component_utils(consumer)uvm_get_imp #(my_transaction, consumer) get_imp;function new(string name, uvm_component parent);super.new(name, parent);get_imp new(get_imp, this);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);endfunctionfunction void get(my_transaction tr);uvm_info(CONSUMER, \)sformatf(Received data: %0d, tr.data), UVM_HIGH)endfunction endclassclass my_env extends uvm_env;uvm_component_utils(my_env)producer prod;consumer cons;function new(string name, uvm_component parent);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);prod producer::type_id::create(prod, this);cons consumer::type_id::create(cons, this);endfunctionfunction void connect_phase(uvm_phase phase);super.connect_phase(phase);prod.put_port.connect(cons.get_imp); // 连接 put_port 和 get_impendfunction endclassclass my_test extends uvm_test;uvm_component_utils(my_test)my_env env;function new(string name, uvm_component parent);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);env my_env::type_id::create(env, this);endfunction endclassmodule top;initial beginrun_test(my_test);end endmodule 【总结】 put/get 接口:用于组件之间的数据传递。put 用于发送数据get 用于接收数据并消耗数据。peek 用于查看数据但不消耗数据。 analysis 接口:用于单向数据流通常用于监控和收集数据。uvm_analysis_port 用于发送数据uvm_analysis_imp 用于接收数据。 2.17 sequence和item(uvm_sequence, uvm_sequence_item)的分类 uvm_sequence_item(transaction) uvm_sequence_item 是 UVM 中表示单个事务的基本类。uvm_sequence_item 类通常包含事务的数据字段如地址、数据、命令类型等。事务类可以包含随机化约束用于生成符合特定条件的事务。 class my_transaction extends uvm_sequence_item;rand bit [31:0] address;rand bit [⅛:0] data;rand bit [2:0] command;constraint c_address {address inside { [0:1023] };}constraint c_data {data dist { [0:255] : 7, [256:511] : ˜3 };}constraint c_command {command inside { READ, WRITE, NOP };}uvm_object_utils_begin(my_transaction)uvm_field_int(address, UVM_DEFAULT)uvm_field_int(data, UVM_DEFAULT)uvm_field_int(command, UVM_DEFAULT)uvm_object_utils_endfunction new(string name my_transaction);super.new(name);endfunction endclass uvm_sequence uvm_sequence 是 UVM 中用于控制事务生成和发送的类。它负责创建事务并将其发送到 uvm_sequencer后者再将事务传递给 uvm_driver。 class read_sequence extends uvm_sequence #(read_transaction);uvm_object_utils(read_sequence)function new(string name read_sequence);super.new(name);endfunctionvirtual task body();read_transaction tr;repeat (10) beginuvm_do(tr) // 生成并发送读事务endendtask endclassclass write_sequence extends uvm_sequence #(write_transaction);uvm_object_utils(write_sequence)function new(string name write_sequence);super.new(name);endfunctionvirtual task body();write_transaction tr;repeat (10) beginuvm_do(tr) // 生成并发送写事务endendtask endclassclass mixed_sequence extends uvm_sequence #(read_transaction, write_transaction);uvm_object_utils(mixed_sequence)function new(string name mixed_sequence);super.new(name);endfunctionvirtual task body();read_transaction read_tr;write_transaction write_tr;repeat (5) beginuvm_do(read_tr) // 生成并发送读事务uvm_do(write_tr) // 生成并发送写事务endendtask endclass 【总结】 item 是事务的基本单元包含了验证环境中事务的最小信息。 sequence 是一系列 item 的集合用于构建和管理验证环境中的测试场景。 通过合理地分类和设计 uvm_sequence 和 uvm_sequence_item从而可以构建灵活且高效的激励生成机制提高验证平台的可重用性和可维护性 2.18 为什么会有sequencesequencer以及driver为什么我们分开实现这样做的好处是什么 首先介绍一下各自的职责 sequence负责生成事务transaction并将其发送到sequencer。sequence可以包含复杂的逻辑如随机化、条件分支等以生成多样化的测试场景。 sequencer作为sequence和driver之间的桥梁负责接收sequence发送的事务并将其转发给driver。sequencer还可以对事务进行仲裁和调度确保事务按照正确的顺序和时间发送给driver。 driver负责将接收到的事务转换为实际的信号电平并驱动到DUTDevice Under Test的接口上。driver通常与DUT的接口协议紧密相关需要实现具体的信号驱动逻辑。 好处 1.职责单一 事务生成与硬件驱动分离sequence 专注于事务生成而 driver 专注于硬件驱动。这种分离使得事务生成逻辑和硬件驱动逻辑可以独立开发和调试。 仲裁与调度:sequencer 负责事务的仲裁和调度使得 sequence 和 driver 不必关心这些细节。这种分离使得 sequence 和 driver 可以专注于各自的核心功能。 2.灵活性和可拓展性 可以轻松地添加新的 sequence 来生成不同的激励模式。 可以通过配置 sequencer 来改变事务的调度策略。 可以通过嵌套 sequence 来构建复杂的激励模式。 可以通过添加新的 driver 来支持不同的 DUT 接口。 3.易于调试和维护: 隔离问题: 如果某个组件出现问题可以单独调试该组件而不影响其他组件。 清晰的责任划分: 每个组件都有明确的职责使得问题定位更加容易。 代码简洁: 每个组件的代码量相对较少使得代码更加简洁和易于阅读。 //transaction class my_transaction extends uvm_sequence_item;rand bit [31:0] address;rand bit [⅛:0] data;rand bit [2:0] command;uvm_object_utils_begin(my_transaction)uvm_field_int(address, UVM_DEFAULT)uvm_field_int(data, UVM_DEFAULT)uvm_field_int(command, UVM_DEFAULT)uvm_object_utils_endfunction new(string name my_transaction);super.new(name);endfunction endclass//sequence class my_sequence extends uvm_sequence #(my_transaction);uvm_object_utils(my_sequence)function new(string name my_sequence);super.new(name);endfunctionvirtual task body();my_transaction tr;repeat (10) begintr my_transaction::type_id::create(tr);start_item(tr);assert(tr.randomize() with { address inside {[0:1023]}; });finish_item(tr);endendtask endclass//driver class my_driver extends uvm_driver #(my_transaction);uvm_component_utils(my_driver)virtual my_if vif;function new(string name, uvm_component parent);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);if (!uvm_config_db#(virtual my_if)::get(this, , vif, vif))uvm_fatal(NOVIF, Failed to get vif)endfunctiontask run_phase(uvm_phase phase);my_transaction tr;forever beginseq_item_port.get_next_item(tr);drive_transaction(tr);seq_item_port.item_done();endendtasktask drive_transaction(my_transaction tr);vif.cb.address tr.address;vif.cb.data tr.data;vif.cb.command tr.command;(vif.cb);endtask endclass//sequencer class my_sequencer extends uvm_sequencer #(my_transaction);uvm_component_utils(my_sequencer)function new(string name, uvm_component parent);super.new(name, parent);endfunction endclass//env class my_env extends uvm_env;uvm_component_utils(my_env)my_sequencer seqr;my_driver drv;function new(string name, uvm_component parent);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);seqr my_sequencer::type_id::create(seqr, this);drv my_driver::type_id::create(drv, this);endfunctionfunction void connect_phase(uvm_phase phase);super.connect_phase(phase);drv.seq_item_port.connect(seqr.seq_item_export);endfunction endclass 通过这种分离的设计UVM验证环境可以更加灵活、高效地进行事务级验证同时提高代码的可维护性和可重用性。 2.19 如何在driver中使用interface 在driver中进行virtual interface声明并接收来自顶层通过config_db传递的interface。 // 定义一个简单的interface interface my_interface (input clk, input rst_n);logic [7:0] data;logic valid;logic ready; endinterface// driver的实现 class my_driver extends uvm_driver #(my_transaction);// 实例化interfacevirtual my_interface vif;function new(string name, uvm_component parent);super.new(name, parent);endfunction// 在build_phase中获取interface的句柄function void build_phase(uvm_phase phase);super.build_phase(phase);if (!uvm_config_db#(virtual my_interface)::get(this, , vif, vif)) beginuvm_error(my_driver, Failed to get vif handle)endendfunction// 在run_phase中使用interface与DUT通信task run_phase(uvm_phase phase);my_transaction tr;forever beginseq_item_port.get_next_item(tr);// 使用interface中的信号驱动DUTvif.data tr.data;vif.valid 1b1;(posedge vif.clk);while (!vif.ready) (posedge vif.clk);vif.valid 1b0;seq_item_port.item_done();endendtask endclass 2.20 config_db的作用以及传递其使用时的参数含义 config_db 在 UVMUniversal Verification Methodology是一个配置数据库用于在验证环境中的不同组件之间传递配置信息–来配置和共享参数 uvm_config_db 提供了两种主要的方法来设置和获取配置信息uvm_config_db#(T)::set uvm_config_db#(T)::get; // 在测试用例中设置配置信息 class my_test extends uvm_test;my_agent my_agent_inst;function void build_phase(uvm_phase phase);super.build_phase(phase);my_agent_inst my_agent::type_id::create(my_agent_inst, this);// 设置配置信息uvm_config_db#(int)::set(this, my_agent_inst, num_transactions, 100);endfunction endclass// 在代理agent中获取配置信息 class my_agent extends uvm_agent;int num_transactions;function void build_phase(uvm_phase phase);super.build_phase(phase);// 获取配置信息if (!uvm_config_db#(int)::get(this, , num_transactions, num_transactions)) beginuvm_error(my_agent, Failed to get num_transactions config)end// 使用配置信息uvm_info(my_agent, $sformatf(Number of transactions: %0d, num_transactions), UVM_LOW)endfunction endclass在build_phase中的执行顺序是从上到下进行执行的;