UVM入门系列(一)----通过uvm_gen脚本快速搭建一般验证平台(上)

UVM入门系列(一)----通过uvm_gen脚本快速搭建一般验证平台(上)


前言

文中所有代码已上传,可通过以下链接下载:
代码链接

待测设计:简单的8bit加法器;
仿真工具:vcs+verdi
DUT代码如下:

`timescale 1ns/1ps
module add(
    input clk,
    input rst,
    input [7:0] a,
    input [7:0] b,
    input cin,
    output reg cout,
    output reg [7:0] sum
);
always@(posedge clk or negedge rst) begin
    if(!rst) begin
        cout<=1'b0;
        sum<=8'b0;
    end
    else begin 
        {cout,sum}<=cin+a+b;
    end
end
endmodule

一、uvm_gen脚本

代码生成

首先介绍一下本文使用的uvm_gen脚本,通过使用该脚本会自动生成一个标准的UVM结构框架,针对本文DUT使用该脚本工具会生成如下图所示的基本框架代码。
在这里插入图片描述

图中可以看出脚本已经完成了验证平台的部分基础代码,接下来的工作是针对验证方案进行代码的补全。

cr_agent

脚本会自动生成一个cr_agent,用于生成时钟和复位信号(后续文章会对该部分进行进一步描述),本文工程简单起见直接使用该代码,不做改动。

二、代码的补全

*括号内为文件路径

1.interface

interface

1.1.i_agent_if.sv(verf/tb/agent/i)

脚本生成代码如下:

`ifndef I_AGENT_IF_SV
`define I_AGENT_IF_SV

interface i_agent_if();
//
endinterface : i_agent_if 

`endif // I_AGENT_IF_SV

加入DUT输入端口,代码完成如下:

`ifndef I_AGENT_IF_SV
`define I_AGENT_IF_SV

interface i_agent_if();
	logic [7:0] a;
	logic [7:0] b;
	logic cin;
endinterface : i_agent_if 

`endif // I_AGENT_IF_SV

1.2.o_agent_if.sv(verf/tb/agent/o)

同上操作,加入DUT输出端口:

`ifndef O_AGENT_IF_SV
`define O_AGENT_IF_SV

interface o_agent_if();
    logic cout;
    logic [7:0] sum;
endinterface : o_agent_if 

`endif // O_AGENT_IF_SV

2.i_seq_item.sv(/verf/tb/agent/i)

i_seq_item即为驱动入DUT的数据包。
脚本生成的代码如下

`ifndef I_SEQ_ITEM_SV
`define I_SEQ_ITEM_SV

class i_seq_item extends uvm_sequence_item;

	`uvm_object_utils(i_seq_item)
	
  extern function new(string name = "i_seq_item");
endclass : i_seq_item 

function i_seq_item::new(string name = "i_seq_item");
  super.new(name);
endfunction : new

`endif // I_SEQ_ITEM_SV

添加激励信息和注册域的自动化:

`ifndef I_SEQ_ITEM_SV
`define I_SEQ_ITEM_SV

class i_seq_item extends uvm_sequence_item;
    rand bit [7:0] a;
    rand bit [7:0] b;
    rand bit       cin;

	`uvm_object_utils_begin(i_seq_item)
        `uvm_field_int(a,UVM_DEFAULT)
        `uvm_field_int(b,UVM_DEFAULT)
        `uvm_field_int(cin,UVM_DEFAULT)
    `uvm_object_utils_end

  extern function new(string name = "i_seq_item");
endclass : i_seq_item 

function i_seq_item::new(string name = "i_seq_item");
  super.new(name);
endfunction : new

`endif // I_SEQ_ITEM_SV

3.add_tb.sv

该文件中进行dut的例化,接口的传递。
自动生成的代码如下(后面文章不再贴出原代码)

`timescale 1ns/1ns
module add_tb;


  `include "uvm_macros.svh"

  import uvm_pkg::*;

  import i_agent_pkg::*;
  import o_agent_pkg::*;
  import cr_agent_pkg::*;
  import add_env_pkg::*;

  logic  sysclock;
  logic  sysresetn;
  cr_if  m_cr_if();
  assign sysclock  = m_cr_if.sysclock;
  assign sysresetn = m_cr_if.sysresetn;

  i_agent_if   m_i_agent_if();
  o_agent_if   m_o_agent_if();
  //
  //dut
  //
  initial
  begin
      uvm_config_db #(virtual cr_if)::set(null,"\*", "m_cr_if", m_cr_if);
      uvm_config_db #(virtual i_agent_if)::set(null,"\*", "m_i_agent_if", m_i_agent_if);
      uvm_config_db #(virtual o_agent_if)::set(null,"\*", "m_o_agent_if", m_o_agent_if);

    run_test();
  end

endmodule

自动生成的代码只需要进行例化的DUT即可。
添加例化:

 add dut(
      .clk(sysclock),
      .rst(sysresetn),
      .a(m_i_agent_if.a),
      .b(m_i_agent_if.b),
      .cin(m_i_agent_if.cin),
      .cout(m_o_agent_if.cout),
      .sum(m_o_agent_if.sum)
  );

添加vcs dump波形代码

initial begin
      $fsdbDumpfile("sim.fsdb");
      $fsdbDumpvars();
  end

4.i_driver(verf/tb/agent/i)

1、例化时钟接口

 virtual interface cr_if cvif;

2、get时钟接口(接口从env传递,后面会说明如何在env中向i_driver传递该接口)

 if (!uvm_config_db #(virtual cr_if)::get(this, "", "cvif", cvif))
    `uvm_error("NOVIF", {"virtual interface must be set for: ",get_full_name(),".cvif"})

3、驱动激励信号

task i_driver::do_drive(i_seq_item req);
	vif.a=req.a;
	vif.b=req.b;
	vif.cin=req.cin;
	@(posedge cvif.sysclock);
endtask : do_drive

5.add_env.sv(verf/tb/env)

传递接口至上文所述i_driver,

	uvm_config_db#(virtual cr_if)::set(this, "m_i_agent.*", "cvif", m_cr_if);

6.构造sequence

在/verf/testcase/ 新建文件夹seq和test,

6.1 add_seq.sv

在seq文件夹新建add_seq.sv文件。
add_seq继承自自动生成的i_base_seq,具体代码如下:

class add_seq extends i_base_seq;
    `uvm_object_utils(add_seq)
    uvm_event seq_begin_ev;
    extern function new(string name="add_seq");
    extern task body();
endclass

function add_seq::new(string name="add_seq");
    super.new(name);
endfunction

task add_seq::body();
    seq_begin_ev=uvm_event_pool::get_global("seq_begin_ev");
    `uvm_info(get_type_name(),"Default sequence starting",UVM_HIGH)
    repeat(100) begin
        `uvm_do(req);
    end
    `uvm_info(get_type_name(),"Default sequence end",UVM_HIGH)
endtask

启动该sequence会发送100个随机激励包给driver。

6.2 seq_pkg.sv

seq文件夹新建seq_pkg.sv文件,方便后续扩展seq文件的管理。代码如下:

package seq_pkg;
    import uvm_pkg::*;
    import i_agent_pkg::*;
    `include "uvm_macros.svh"
    `include "add_seq.sv"
endpackage

6.3 add_test.sv

test文件夹新建test.sv文件,用于启动激励,控制仿真。


class add_test extends add_test_base;
    `uvm_component_utils(add_test)
    add_seq tc_seq;
    extern function new(string name,uvm_component parent=null);
    extern task main_phase(uvm_phase phase);
endclass

function add_test::new(string name,uvm_component parent=null);
    super.new(name,parent);
endfunction

task add_test::main_phase(uvm_phase phase);
    phase.raise_objection(this);
    this.tc_seq=new("tc_seq");
    tc_seq.start(m_env.m_vsequencer.m_i_seqer);
    #20;
    phase.drop_objection(this);
endtask

6.4 test_pkg.sv

test文件夹新建test_pkg.sv,方便管理test文件。

package test_pkg;
    import uvm_pkg::*;
    `include "uvm_macros.svh"
    `include "add_test_base.sv"
    `include "add_test.sv"
endpackage

7 待后续更新

总结:

至此,现在验证平台已经可以通过仿真并查看波形,monitor、reference model 和scoreboard部分的代码会在后续更新继续介绍,后续也会介绍如何使用脚本使用vcs仿真。

  • 6
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
UVM是一种利用SystemVerilog语言开发的硬件验证平台,旨在提高硬件验证的效率和可重用性。APB和SPI作为两种常见的通信协议,在芯片设计中也得到了广泛的应用。基于UVM的APB-SPI验证,可以有效地验证芯片中的通信功能,确保数据传输的正确性和稳定性。 在UVM APB-SPI验证流程中,通过建立测试环境、生成测试用例、执行测试和分析结果等步骤,逐步实现对APB和SPI通信协议的验证。其中,测试环境是搭建UVM框架的基础,通常由DUT(设计单元)、测试控制器、测试代理以及信号记录器等组件构成。测试用例的生成是测试环节的核心,通过模拟不同的使用场景、数据和模式,覆盖不同的协议功能,完整地检查APB和SPI的特性和功能,并对其进行评估和优化。测试执行阶段主要是对测试用例进行仿真验证,并记录其输出结果,包括通信数据、时序波形和错误信息等。最后,在测试结果分析阶段,通过对输出结果的统计分析和比较,识别和解决发现的问题,不断优化和改进芯片的设计和开发,提高生产效率和质量。 总之,基于UVM的APB-SPI验证是一种高效可靠的硬件验证方法,能够在芯片设计和开发阶段准确评估通信协议的性能和功能,发现和解决可能存在的问题,保证芯片设计的质量和可靠性,提高整个芯片研发流程的效率和成功率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值