uvm数字IC验证覆盖率收集

目录

1 概述

1.1 代码覆盖率收集:

1.2 功能覆盖率收集:

1.3 断⾔覆盖率收集:

2 如何查看收集后的覆盖率?


1 概述

在进⾏芯⽚验证时,最重要的⼀个环节就是完成对dut的覆盖率收集⼯作,覆盖率主要分为下⾯三类:

  1. 代码覆盖率
  2. 功能覆盖率
  3. 断⾔覆盖率

如何完成覆盖率收集?

1.1 代码覆盖率收集:

代码覆盖率是衡量验证进展的最简易的⽅式。它的作⽤是检查代码是否冗余,设计要点是否遍历,被检测的对象是RTL代码,⽽代码覆盖率的检测⼀般由⼯具⾃动⽣成的。⾏覆盖率(Line coverage)、分⽀覆盖率(Branch coverage)、路径覆盖率(Path Coverage)、翻转覆盖率(Toggle coverage)、条件覆盖率(Conditional coverage)、有限状态机覆盖率(FSM coverage)。

在makefile中添加

-cm line+fsm+tgl+cond+assert

可完成相对应的代码覆盖率的收集。(在编译和运⾏时都需添加)

1.2 功能覆盖率收集:

功能覆盖率是⼀个⽤户定义的度量标准,它测量了设计规范的多少部分,通过测试计划中的特性枚举,已经被执⾏。它可以⽤来衡量是否有兴趣的场景、⾓落⽤例、规格不变量,或者其他适⽤的设计条件(作为测试计划的特性捕获)已经被观察、验证和测试。

这⾥简单介绍下如果你收集的代码覆盖率很⾼但是功能覆盖率缺很低,这个可能是:

  1. design没有完全按照功能spec⽂档规格实现所有功能,设计不完善;
  2. 验证平台monitor监视器存在漏洞,设计代码实现了功能但没有覆盖到他们;
  3. 功能正确,但是发送的激励不对,对应功能的覆盖率⽆法收集。

如果你收集的功能覆盖率很⾼但是代码覆盖率缺很低,这可能是:

  1. 设计代码没有按照spec实现功能,在design中是⽆效代码,
  2. ⽤户定义的功能覆盖率收集存在错误,没有完全定⽐覆盖率收集的边界,测试计划未捕获所有设计功能/场景/边界,或者缺少功能覆盖率监视器。代码覆盖率中未覆盖的设计代码可能会映射到这些功能上。
  3. 在实现功能覆盖率监视器时可能存在潜在的错误,导致它们收集了错误的覆盖率。因此,在验证项⽬中,对⽤户定义的功能覆盖率指标及其实现进⾏适当的检查很重要。

定义⼀个coverage class,在类中指定你要收集的coveragegroup和coveragepoint,也可指定你要收集的仓bins。

`ifndef GUARD_COVERAGE
`define GUARD_COVERAGE

class coverage;
    packet pkt;

    covergroup switch_coverage;
        length : coverpoint pkt.length;
        da : coverpoint pkt.da {
            bins p0 = { `P0 };
            bins p1 = { `P1 };
            bins p2 = { `P2 };
            bins p3 = { `P3 }; }
        length_kind : coverpoint pkt.length_kind;
        fcs_kind : coverpoint pkt.fcs_kind;
        all_cross: cross length,da,length_kind,fcs_kind;
    endgroup

    function new();
        switch_coverage = new();
    endfunction : new

    task sample(packet pkt);
        this.pkt = pkt;
        switch_coverage.sample();
    endtask:sample

endclass
`endif

在scoreboard完成coverage模块的调⽤,coverage cov = new() 新建所要使⽤的类,cov.sample(pkt_exp)采样pkt_exp数据包。

`ifndef GUARD_SCOREBOARD
`define GUARD_SCOREBOARD

class Scoreboard;
    mailbox drvr2sb;
    mailbox rcvr2sb;

    coverage cov = new();
    function new(mailbox drvr2sb,mailbox rcvr2sb);
        this.drvr2sb = drvr2sb;
        this.rcvr2sb = rcvr2sb;
    endfunction:new

    task start();
        packet pkt_rcv,pkt_exp;
        forever begin
            rcvr2sb.get(pkt_rcv);
            $display(" %0d : Scorebooard : Scoreboard received a packet from receiver ",$time);
            drvr2sb.get(pkt_exp);
            if(pkt_rcv.compare(pkt_exp)) begin
                $display(" %0d : Scoreboardd :Packet Matched ",$time);
                cov.sample(pkt_exp);
            end
            else
                error++;
            end
    endtask : start

endclass
`endif

1.3 断⾔覆盖率收集:

通过设定断⾔,⼀般完成接⼝时序相关的覆盖率收集。如AHB总线时序在对同⼀个地址先做写操作再不间隔做读操作,可使⽤property指定两次操作的地址是相同的,在cover该property。

property p_write_read_burst_trans;
    logic[31:0] addr;
    @(posedge clk) ($rose(penable) && pwrite, addr=paddr) |-> (##2 ($rose(penable) && !pwrite && addr==paddr));
endproperty: p_write_read_burst_trans

cover property(p_write_read_burst_trans);

2 如何查看收集后的覆盖率?

收集后的覆盖率保存在simv.vdb⽂件夹中,可使⽤urg⼯具转成可视化的html⽂件或直接使⽤dve⼯具查看simv.vdb

直接查看指令:

dve -full64 -cov -dir simv.vdb&

urg转成html⽂件:

urg -dir simv.vdb -report urgReport

相同代码不同tc的覆盖率合并:

urg -full64 -dir tc1.vdb tc2.vdb -dbname merged.vdb -report urgReport

  • 12
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的UVM覆盖率收集例子: ``` class my_cov_model extends uvm_subscriber #(uvm_analysis_port #(my_transaction)); `uvm_component_utils(my_cov_model) uvm_analysis_port #(my_transaction) analysis_export; uvm_coverage coverage; function new(string name, uvm_component parent); super.new(name, parent); coverage = new("coverage", this); endfunction function void write (input my_transaction tr); coverage.sample(tr); endfunction endclass ``` 在上面的代码中,我们首先定义了一个`my_cov_model`类,它继承了`uvm_subscriber`类。然后我们定义了一个名为`analysis_export`的UVM分析端口,它将用于接收事务数据。接下来,我们创建了一个名为`coverage`的UVM覆盖率对象。 在新建函数中,我们实例化了覆盖率对象。在write函数中,我们将收到的事务作为参数传递给UVM覆盖率对象的sample函数,以收集覆盖率信息。 要使用这个UVM覆盖率收集器,您需要将其连接到使用UVM的测试环境中的其他组件。您可以将其连接到模拟器、分析器或其他收集数据的组件。例如,如果您有一个名为`my_test`的测试环境,您可以将其连接到该测试环境中的其他组件,如下所示: ``` class my_test extends uvm_test; `uvm_component_utils(my_test) my_cov_model cov_model; my_agent my_agent; ... function void build_phase(uvm_phase phase); super.build_phase(phase); cov_model = my_cov_model::type_id::create("cov_model", this); my_agent = my_agent::type_id::create("my_agent", this); ... my_agent.analysis_port.connect(cov_model.analysis_export); endfunction endclass ``` 在上面的代码中,我们首先定义了一个名为`my_test`的测试环境。然后,我们在`build_phase`中实例化了`cov_model`和`my_agent`对象。最后,我们使用`analysis_port`将`cov_model`连接到`my_agent`,以收集覆盖率信息。 请注意,这只是一个简单的例子。实际上,UVM覆盖率收集可能会更加复杂,具体取决于您的测试环境和所需的覆盖率信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小wang的IC自习室

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

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

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

打赏作者

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

抵扣说明:

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

余额充值