UVM--uvm_scoreboard、uvm_env & uvm_test

1 uvm_scoreboard

•    从名字来看,uvm_scoreboard担任着同SV中checker一样的功能, 即进行数据比对和报告
•    uvm_scoreboard本身也没有添加额外的成员变量和方法,但UVM建议用户将自定义的scoreboard类继承于uvm_scoreboard类, 这便于子类在日后可以自动继承于可能被扩充到uvm_scoreboard 类中的成员。
•    在实际环境中,uvm_scoreboard会接收来自于多个monitor的监测数据,继而进行比对和报告。

正由于uvm_scoreboard通用的比较数据特性,UVM自带的其它两个用来做数据比较的类其实很少被使用到:

uvm_in_order_comparator  #  (type T) 
uvm algorithm comparator # (type BEFORE, type AFTER, type TRANSFORMER) 

•    uvm_in_order_comparator是 一个参数类,并且它有两个端口before_export和after_export分别从DUT的输入端monitor和输出端monitor获取观测到的数据事务。这些数据事务是将多个时钟周期内的数据整合为更高抽象级的数据对象,而且要求前后端监测到数据事务类型应该相同
•    uvm_algorithm_comparator也是一个参数类,它的参数数目要更多,这是为了贴合在更多实际场景中,DUT的输入端监测数据格式不同于输出端数据格式,因此typeBEFORE与typeAFTER两个事务类可以不相同, 同时用户也应该提供用来将BEFORE类转换为AFTER类的转换类type TRANSFORMER。

更多关于上述两种comparator的说明,请参考红宝书。

•    在scoreboard中通常会会声明TLM端口以供monitor传输数据。
•    简易比较的方法, 可以采用UVM预定义的comparator,.
•    对于复杂的设计, 参考SV模块中的做法, 可以在scoreboard中分别创建reference model和comparator。
•    以此为例, 也需要注意的是, 如果一个组件中有子一级的组件, 应该考虑它们的创建、连接和通信问题。

class cpu_scoreboard extends uvm_scoreboard; 
	uvm_analysis_export#(bus_xact) in_export;
	uvm_analysis_export#(bus_xact) out_export;
	typedef uvm_in_order_comparator #(bus_xact) comp_t; 
	comp_t m_comp;
    function void build_phase(uvm_phase phase); 
	super.build_phase(phase); 
    in_export = new("in_export", this); 
    out_export= new("out_export", this);
    m_comp= comp_t::type_id::create ("m_comp", this);
	endfunction
    function void connect_phase(uvm_phase phase);
	super.connect_phase(phase); 
    in_export.connect(m_comp.before_export);
	out_export.connect(m_comp.after_export);
	endfunction
endclass: cpu_scoreboard

2 uvm_env

 从环境层次结构而言,uvm_env可能包含多个uvm_agent和其它component。

 这些不同组件共同构成一个完整的验证环境,而这个环境在将来复用中可以作为子环境被
进一步集成到更高的环境中。

下面的验证结构中,就定义了一个高层的环境,它里面包含 sub_env、agent、scoreboard。

•    uvm_env的角色就是一个结构化的容器,它可以容纳其它组件同时它也可以作为子环境在更高层的集成中被嵌入。
•    在实际使用中,用户容易混淆uvm_env与uvm_agent之间的嵌套关系,而且容易在创建对象阶段出现错误,建议:
•    uvm_agent作为一个标准单元,在更上层的集成中应该被例化到uvm_env。
•    uvm_env在更高层的复用中,可以被其它uvm_env所嵌套。

class top_env extends uvm_env;
	sub_env m_se; 
    my_agent m_agt; 
    my_scoreboard m_sb; 
    uvm_component_utils(top_env ) 
    extern function new(string name, uvm_component parent);
	function void build_phase(uvm_phase}; 
	m_se = sub_env::type_id::create("m_se", this}; 
    m_agt = my_agent::type_id::create("m_agt", this};
    m_sb = my_scoreboard::type_id::create("m_sb", this};
	endfunction
	...
endclass: top_env

3 uvm_test

uvm_test类本身没有什么新成员,但是作为测试用例的代言人,它不但决定着环境的结构和连接关系,也决定着使用哪一个测试序列。
如果没有这个代言人,整个环境都无从建立,所以uvm_test是验证环境的唯一入口,只有通过它才能正常运转UVM的phase机制。

我们从下面的示例看到,在一个顶层test中可以例化多个组件,譬如uvm_env或者uvm_agent, 而在仿真时通过uvm_test可以实现验证环境的运转。

我们推荐在uvm_test中只例化一个顶层uvm_env, 这便于提供一个唯一环境节点以形成树状的拓扑结构,而这种树状环境结构也会对应着一种树状配置结构。

class env extends uvm_env; 
    `uvm_component_utils(env)
    ...	
     endclass 
    class agent extends uvm_agent;
	`uvm_componen_utils(agent)
	...
	endclass 
    class test1 extends uvm_test;
	`uvm_component_utils(test1)
    env el, e2; 
    agent al;
    function void build_phase(uvm_phase phase);
	el = env::type_id::create("cl", this); 
	e2 = env::type_id::create("c2", this);
	al = agent::type_id::create("al", this) ;
	endfunction 
endclass

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
UVM(Universal Verification Methodology)是一种基于SystemVerilog的验证方法学,用于构建可重用、可扩展的验证环境。以下是一个简单的UVM平台的实现示例。 1. 创建一个Testbench模块,该模块包含了UVM框架的主要组件,例如Env、Agent、Driver、Monitor和Scoreboard。 ``` `include "uvm_macros.svh" module tb_top; // UVM Components `uvm_component_name(tb_env) tb_env env; `uvm_component_name(tb_agent) tb_agent agent; `uvm_component_name(tb_driver) tb_driver driver; `uvm_component_name(tb_monitor) tb_monitor monitor; `uvm_component_name(tb_scoreboard) tb_scoreboard scoreboard; // Constructor function new(string name, uvm_component parent); super.new(name, parent); endfunction // Build Phase function void build_phase(uvm_phase phase); super.build_phase(phase); // Create UVM Components env = tb_env::type_id::create("env", this); agent = tb_agent::type_id::create("agent", this); driver = tb_driver::type_id::create("driver", this); monitor = tb_monitor::type_id::create("monitor", this); scoreboard = tb_scoreboard::type_id::create("scoreboard", this); // Connect UVM Components agent.monitor_port.connect(monitor.analysis_export); driver.seq_item_port.connect(agent.seq_item_export); scoreboard.analysis_export.connect(agent.scoreboard_export); endfunction // Run Phase task run_phase(uvm_phase phase); super.run_phase(phase); endtask endmodule ``` 2. 创建一个Env模块,该模块包含了被测设备的接口和其他环境组件。 ``` `include "uvm_macros.svh" class tb_env extends uvm_env; // UVM Components `uvm_component_name(tb_env_driver) tb_env_driver driver; `uvm_component_name(tb_env_monitor) tb_env_monitor monitor; // Constructor function new(string name, uvm_component parent); super.new(name, parent); endfunction // Build Phase function void build_phase(uvm_phase phase); super.build_phase(phase); // Create UVM Components driver = tb_env_driver::type_id::create("driver", this); monitor = tb_env_monitor::type_id::create("monitor", this); // Connect UVM Components driver.clock = env_clk; driver.reset = env_reset; monitor.clock = env_clk; monitor.reset = env_reset; endfunction endclass class tb_env_driver extends uvm_driver #(tb_env_packet); // Interface uvm_blocking_put_port #(tb_env_packet) put_port; // Constructor function new(string name, uvm_component parent); super.new(name, parent); endfunction // Run Phase virtual task run_phase(uvm_phase phase); tb_env_packet packet; forever begin // Generate Packet packet = new; packet.data = $random; // Send Packet put_port.put(packet); // Delay #10; end endtask endclass class tb_env_monitor extends uvm_monitor #(tb_env_packet); // Interface uvm_analysis_port #(tb_env_packet) analysis_port; // Constructor function new(string name, uvm_component parent); super.new(name, parent); endfunction // Run Phase virtual task run_phase(uvm_phase phase); tb_env_packet packet; forever begin // Wait for Packet @(posedge env_clk); packet = get_packet(); // Send Packet to Analysis analysis_port.write(packet); end endtask // Private Methods function tb_env_packet get_packet(); tb_env_packet packet; packet = new; packet.data = env_data; return packet; endfunction endclass ``` 3. 创建一个Agent模块,该模块包含了一个Driver和一个Monitor。 ``` `include "uvm_macros.svh" class tb_agent extends uvm_agent; // UVM Components `uvm_component_name(tb_agent_driver) tb_agent_driver driver; `uvm_component_name(tb_agent_monitor) tb_agent_monitor monitor; // Constructor function new(string name, uvm_component parent); super.new(name, parent); endfunction // Build Phase function void build_phase(uvm_phase phase); super.build_phase(phase); // Create UVM Components driver = tb_agent_driver::type_id::create("driver", this); monitor = tb_agent_monitor::type_id::create("monitor", this); // Connect UVM Components monitor.agent = this; driver.monitor_port.connect(monitor.analysis_export); endfunction endclass class tb_agent_driver extends uvm_driver #(tb_agent_sequence_item); // Interface uvm_blocking_put_port #(tb_agent_sequence_item) seq_item_port; // Constructor function new(string name, uvm_component parent); super.new(name, parent); endfunction // Run Phase virtual task run_phase(uvm_phase phase); tb_agent_sequence_item seq_item; forever begin // Get Sequence Item seq_item_port.get(seq_item); // Drive Sequence Item drive_sequence_item(seq_item); // Delay #10; end endtask // Private Methods function void drive_sequence_item(tb_agent_sequence_item seq_item); // Drive Sequence Item endfunction endclass class tb_agent_monitor extends uvm_monitor #(tb_agent_sequence_item); // Interface uvm_analysis_port #(tb_agent_sequence_item) analysis_port; // Agent tb_agent agent; // Constructor function new(string name, uvm_component parent); super.new(name, parent); endfunction // Run Phase virtual task run_phase(uvm_phase phase); tb_agent_sequence_item seq_item; forever begin // Wait for Sequence Item @(posedge agent.clock); seq_item = get_sequence_item(); // Send Sequence Item to Analysis analysis_port.write(seq_item); end endtask // Private Methods function tb_agent_sequence_item get_sequence_item(); tb_agent_sequence_item seq_item; seq_item = new; return seq_item; endfunction endclass ``` 4. 创建一个Scoreboard模块,该模块用于比对Agent的输出和Env的输出。 ``` `include "uvm_macros.svh" class tb_scoreboard extends uvm_scoreboard; // UVM Components `uvm_component_name(tb_scoreboard_driver) tb_scoreboard_driver driver; // Constructor function new(string name, uvm_component parent); super.new(name, parent); endfunction // Build Phase function void build_phase(uvm_phase phase); super.build_phase(phase); // Create UVM Components driver = tb_scoreboard_driver::type_id::create("driver", this); // Connect UVM Components driver.agent = agent; endfunction endclass class tb_scoreboard_driver extends uvm_driver #(tb_scoreboard_sequence_item); // Agent tb_agent agent; // Constructor function new(string name, uvm_component parent); super.new(name, parent); endfunction // Run Phase virtual task run_phase(uvm_phase phase); tb_scoreboard_sequence_item exp_seq_item; tb_agent_sequence_item act_seq_item; forever begin // Get Expected Sequence Item exp_seq_item = get_expected_sequence_item(); // Get Actual Sequence Item act_seq_item = get_actual_sequence_item(); // Compare Sequence Items compare_sequence_items(exp_seq_item, act_seq_item); // Delay #10; end endtask // Private Methods function tb_scoreboard_sequence_item get_expected_sequence_item(); tb_scoreboard_sequence_item seq_item; seq_item = new; return seq_item; endfunction function tb_agent_sequence_item get_actual_sequence_item(); tb_agent_sequence_item seq_item; seq_item = new; return seq_item; endfunction function void compare_sequence_items(tb_scoreboard_sequence_item exp_seq_item, tb_agent_sequence_item act_seq_item); // Compare Sequence Items endfunction endclass ``` 5. 创建一个Sequence模块,该模块用于生成测试序列。 ``` `include "uvm_macros.svh" class tb_sequence extends uvm_sequence #(tb_agent_sequence_item); // Constructor function new(string name); super.new(name); endfunction // Body virtual task body(); tb_agent_sequence_item seq_item; forever begin // Generate Sequence Item seq_item = new; // Send Sequence Item seq_item_port.put(seq_item); // Delay #10; end endtask endclass ``` 6. 最后,在顶层模块中实例化Testbench模块和Sequence模块,并运行UVM测试。 ``` module top; // Testbench tb_top tb; // Sequence tb_sequence seq; // Clock logic clk; // Reset logic reset; // Constructor initial begin // Create Testbench tb = new; // Create Sequence seq = tb_sequence::type_id::create("seq"); // Set Clock clk = 0; forever begin #5 clk = ~clk; end // Set Reset reset = 1; #10 reset = 0; // Run UVM Test run_test(); end endmodule module env; // Clock logic clk; // Reset logic reset; // Data logic [31:0] data; // Constructor initial begin // Set Clock clk = 0; forever begin #5 clk = ~clk; end // Set Reset reset = 1; #10 reset = 0; // Run Testbench top.tb.env_clk = clk; top.tb.env_reset = reset; run_test(); end endmodule ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

创芯人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值