Friday, October 21, 2016

UVM 101.

Packages
  • Provide a common name space •
  • Can be imported • 
  • Can contain common objects •
// You can have the followings in a package
// • Common typedefs 
// • Common class definitions
// • Shared instances or variables

import uvm_pkg::*;

`include "defines.svh"
`include "macro_defines.svh"
`include "test_plugin.svh"

module top;
        initial begin
                #10ns;
                uvm_top.uvm_report_info ($psprintf("%m"),
                        "This is an info message");
        end
endmodule


Macros
`define info(msg)    uvm_top.uvm_report_info($psprintf("%m"), msg);
`define warning(msg) uvm_top.uvm_report_warning($psprintf("%m"), msg);
`define error(msg)   uvm_top.uvm_report_error($psprintf("%m"), msg);
`define fatal(msg)   uvm_top.uvm_report_fatal($psprintf("%m"), msg);

import uvm_pkg::*;

module top;
    initial begin
        `info ("My info message goes here");
        `warning ("My warning message goes here");
        `error ("My error message goes here");
        `fatal ("My fatal message goes here");
    end
endmodule

`ifdef FPGA

module sythesizable_block;
endmodule // monitor

`else

module beh_model;
endmodule // beh_model;

`endif // !`ifdef FPGA

// Define macro when you compile in dofile
% if (file exists work) {delete -all}
% vlib work
% vlog top.sv +define+FPGA
% vsim -novopt top
% run -all

Classes
class read_op extends memory_op;
    constraint read_only_c {mem_op == read;};
endclass // read_op

// • Put each class in individual .svh file
// • Put all .svh files in a package "tb_pkg" using `include
// • Put all files in a file list "vfiles.f" to compile 
// • In the top test bench file, import "uvm_pkg" and this "tb_pkg"


UVM package
  • uvm_report_object
    • uvm_cmdline_processor
    • uvm_component
      • uvm_agent
      • uvm_driver #()
      • uvm_env
      • uvm_monitor
      • uvm_port_component_base
      • uvm_root
      • uvm_scoreboard
      • uvm_sequencer_base
      • uvm_test
      • uvm_tlm_fifo_base #()
  • UVM phases used in uvm_test
    • function void build_phase()
    • function void connect_phase()
    • function void end_of_elaboration_phase()
    • function void start_of_simulation_phase()
    • function void run_phase()
    • function void extract_phase()
    • function void check_phase()
    • function void report_phase()
  • Use "+UVM_TESTNAME=test1" to run different tests
    • The sub classes extended rom uvm_test with UVM_TESTNAME plusarg will start the run_test() that is defined in uvm_pkg and the run_test() uses UVM factory pattern to create a test object.

class test1 extends uvm_test;
   `uvm_component_util(test1)

    function new (string name, uvm_component base);
        super.new(name, base);
    endfunction : new

    task run_phase(uvm_phase phase);
        phase.raise_objection(this); // tell UVM this thread started
        super.run();
        `uvm_info("test1: ", "Starting...", UVM_INFO);
        phase.drop_objection(this);  // tell UVM this thread finished
    endtask
endclass : test1

// in top module
module top;

    initial run_test(); // this will create a test object 
                        // and executes its run_phase() 
endmodule : top


UVM Structure
  • Top
    • uvm_test or program in SystemVerilog
      • task run();
      • uvm_env
        • uvm_agent
          • driver
            • run
          • monitor
            • $monitoron / $monitoroff
            • sync_reset
            • semaphore
              • semaphore sem = new(1);
              • sem.get(1) ... sem.put(1)
              • `uvm_raise_objection(this)
                / `uvm_drop_objection(this)
            • disable <block_name>;
          • sequencer
            • sequence
              • body
              • start
            • transaction
              • build
              • run
        • uvm_scoreboard or ovm_subscriber
        • uvm_agent for coverage
    • interface
    • DUT

UVM Randomization and Constraints
typedef logic [15:0] addr_type;
typedef logic [7:0] data_type;
typedef enum {read, write, nop} op_type;

class my_op;
   rand addr_type addr;
   rand data_type data;
   rand op_type cmd;
   ...
endclass : my_op

class read_op extends my_op;
   constraint read_only_cmd {my_op == read;};
endclass // read_op

module top;
   my_op op;
   read_op rdop;
   addr_type addr2;

   initial begin
      op = new();
      addr2 = $random;
      repeat (2) begin

         assert(op.randomize());
         // with constraint
         assert(op.randomize() with {my_op == read;});

         assert(rdop.randomize()); // this will be limited to read only

      end
   end
endmodule // top



No comments:

Post a Comment