UVM实战(一):简单加法器的uvm验证

我们模拟了一个简单的加法器DUT,并使用UVM验证环境对其进行功能验证。UVM验证环境包括以下组件:

adder_env:验证环境,包括了监控器(adder_monitor)、驱动(adder_driver)和代理(adder_agent)。验证环境通过分析端口(trans_analysis_port)与测试基准(adder_test)和DUT连接。

在测试中,我们定义了一个测试基准类(adder_sequence),它构建了一个简单的测试序列,生成了一个加法事务(adder_trans),将其发送给驱动,并等待测试序列的结束。测试基准类继承自uvm_sequence

顶层模块testbench实例化了测试类adder_test,并通过UVM配置数据库将接口(virtual interface)vif、参考模型(reference model)refmod和DUT连接到验证环境中。

最后,我们在主程序中创建了测试环境、验证环境和DUT对象,并运行UVM测试。

这个示例展示了如何使用UVM验证加法器的功能,包括生成随机测试数据、驱动DUT、监测输出并通过分析端口传递事务对象。通过使用UVM的验证方法,我们可以更好地组织测试代码、自动化测试过程,并提高验证效率和可重用性。

// DUT (Design Under Test) - 加法器
module adder(input [7:0] a, b, output [7:0] sum);
  assign sum = a + b;
endmodule

// UVM验证环境
class adder_env extends uvm_env;
  // 添加需要的端口和信号声明
  uvm_analysis_port#(adder_trans) trans_analysis_port;
  adder_monitor monitor;
  adder_agent agent;
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_analysis_port = new("trans_analysis_port", this);
    monitor = adder_monitor::type_id::create("monitor", this);
    agent = adder_agent::type_id::create("agent", this);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    // 连接验证环境的各个组件
    agent.analysis_port.connect(trans_analysis_port);
  endfunction
  
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    // 连接DUT和monitor
    monitor.a <= agent.driver.a;
    monitor.b <= agent.driver.b;
    monitor.sum <= agent.driver.sum;
  endfunction
endclass

// UVM事务定义
class adder_trans extends uvm_sequence_item;
  rand bit [7:0] a;
  rand bit [7:0] b;
  bit [7:0] sum;
  
  `uvm_object_utils(adder_trans)
  
  function new(string name = "adder_trans");
    super.new(name);
  endfunction
  
  function void display();
    $display("Transaction: a=%d, b=%d, sum=%d", a, b, sum);
  endfunction
endclass

// UVM监控器
class adder_monitor extends uvm_monitor;
  // 添加需要的端口和信号声明
  adder_trans trans;
  bit [7:0] a, b, sum;
  
  `uvm_component_utils(adder_monitor)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction
  
  task run_phase(uvm_phase phase);
    forever begin
      // 监测DUT的输出并创建一个事务对象
      @(posedge dut.sum);
      trans = new();
      trans.a = a;
      trans.b = b;
      trans.sum = sum;
      trans.display();
      // 通过分析端口发送事务对象
      trans_analysis_port.write(trans);
    end
  endtask
endclass

// UVM驱动
class adder_driver extends uvm_driver#(adder_trans);
  `uvm_component_utils(adder_driver)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  task run_phase(uvm_phase phase);
    // 创建事务并驱动DUT
    repeat (10) begin
      adder_trans trans = new();
      trans.randomize(); // 随机生成事务数据
      trans.display();
      seq_item_port.write(trans);
      @(posedge sequencer.seq_item_done);
    end
  endtask
endclass

// UVM代理
class adder_agent extends uvm_agent;
  adder_driver driver;
  uvm_analysis_port#(adder_trans) analysis_port;
  
  `uvm_component_utils(adder_agent)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
    driver = adder_driver::type_id::create("driver", this);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    analysis_port = new("analysis_port", this);
  endfunction
endclass

// UVM测试
class adder_test extends uvm_test;
  adder_env env;
  adder_agent agent;
  uvm_sequence#(adder_trans) sequence;
  
  `uvm_component_utils(adder_test)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    sequence = adder_sequence::type_id::create("sequence");
  endfunction
  
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    env = adder_env::type_id::create("env", this);
    agent = adder_agent::type_id::create("agent", this);
    env.agent = agent;
  endfunction
  
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    phase.raise_objection(this);
    seq.start(agent, sequence);
    phase.drop_objection(this);
  endtask
endclass

// UVM测试基准类
class adder_sequence extends uvm_sequence#(adder_trans);
  `uvm_object_utils(adder_sequence)
  
  function new(string name = "adder_sequence");
    super.new(name);
  endfunction
  
  task body();
    // 构建具体的测试序列
    adder_trans trans = new();
    trans.a = 10;
    trans.b = 20;
    seq_item_port.write(trans);
    wait_for_sequence_end();
  endtask
endclass

// UVM顶层
class testbench extends uvm_env;
  adder_test test;
  
  `uvm_component_utils(testbench)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    test = adder_test::type_id::create("test");
  endfunction
endclass

// 主程序
module test;
  initial begin
    // UVM设置
    uvm_config_db#(virtual adder_env)::set(null, "*", "env", "vif", vif);
    uvm_config_db#(virtual adder_env)::set(null, "*", "env", "refmod", refmod);
    uvm_config_db#(virtual adder_env)::set(null, "*", "env", "dut", dut);
    
    // 创建测试环境、验证环境和DUT对象
    testbench tb = new("tb", null);
    adder_env env = adder_env::type_id::create("env", tb);
    adder_refmod refmod = adder_refmod::type_id::create("refmod");
    adder dut();
    
    // 设置验证环境的接口
    env.set_interface(refmod.intf);
    
    // 运行UVM测试
    run_test();
  end
endmodule

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值