Source browser

The complete UVM fixture

A sanitized ready/valid environment: test, environment, agent, sequence, scoreboard, coverage, interface, and a small DUT. These are the exact source files used to generate the interactive wiki.

examples/demo_uvm/filelist.f

Download original source · 6 lines

+incdir+./tb/classes
+define+DEMO_DATA_WIDTH=16
-f ./filelists/rtl.f
./tb/demo_if.sv
./tb/demo_pkg.sv
./tb/demo_top.sv

examples/demo_uvm/filelists/rtl.f

Download original source · 1 lines

../rtl/demo_dut.sv

examples/demo_uvm/rtl/demo_dut.sv

Download original source · 20 lines

module demo_dut (
  input  logic                         clk,
  input  logic                         reset_n,
  input  logic                         valid,
  output logic                         ready,
  input  logic [`DEMO_DATA_WIDTH-1:0] data
);

  logic [31:0] accepted_count;

  assign ready = reset_n;

  always_ff @(posedge clk or negedge reset_n) begin
    if (!reset_n)
      accepted_count <= '0;
    else if (valid && ready)
      accepted_count <= accepted_count + 1'b1;
  end

endmodule

examples/demo_uvm/tb/classes/demo_agent.svh

Download original source · 26 lines

class demo_agent extends uvm_agent;
  `uvm_component_utils(demo_agent)

  demo_sequencer sequencer;
  demo_driver    driver;
  demo_monitor   monitor;

  function new(string name = "demo_agent", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    monitor = demo_monitor::type_id::create("monitor", this);
    if (is_active == UVM_ACTIVE) begin
      sequencer = demo_sequencer::type_id::create("sequencer", this);
      driver    = demo_driver::type_id::create("driver", this);
    end
  endfunction

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    if (is_active == UVM_ACTIVE)
      driver.seq_item_port.connect(sequencer.seq_item_export);
  endfunction
endclass

examples/demo_uvm/tb/classes/demo_coverage.svh

Download original source · 23 lines

class demo_coverage extends uvm_subscriber #(demo_item);
  `uvm_component_utils(demo_coverage)

  bit [`DEMO_DATA_WIDTH-1:0] sampled_data;

  covergroup data_cg;
    option.per_instance = 1;
    data_cp: coverpoint sampled_data {
      bins low  = {[0:63]};
      bins high = {[64:255]};
    }
  endgroup

  function new(string name = "demo_coverage", uvm_component parent = null);
    super.new(name, parent);
    data_cg = new();
  endfunction

  function void write(demo_item item);
    sampled_data = item.data;
    data_cg.sample();
  endfunction
endclass

examples/demo_uvm/tb/classes/demo_driver.svh

Download original source · 29 lines

class demo_driver extends uvm_driver #(demo_item);
  `uvm_component_utils(demo_driver)

  virtual demo_if vif;

  function new(string name = "demo_driver", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    if (!uvm_config_db #(virtual demo_if)::get(this, "", "vif", vif))
      `uvm_fatal(get_type_name(), "virtual interface was not configured")
  endfunction

  task run_phase(uvm_phase phase);
    vif.valid <= 1'b0;
    vif.data  <= '0;
    forever begin
      seq_item_port.get_next_item(req);
      @(posedge vif.clk);
      vif.valid <= 1'b1;
      vif.data  <= req.data;
      do @(posedge vif.clk); while (!vif.ready);
      vif.valid <= 1'b0;
      seq_item_port.item_done();
    end
  endtask
endclass

examples/demo_uvm/tb/classes/demo_env.svh

Download original source · 28 lines

class demo_env extends uvm_env;
  `uvm_component_utils(demo_env)

  demo_env_config cfg;
  demo_agent       agent;
  demo_scoreboard  scoreboard;
  demo_coverage    coverage;

  function new(string name = "demo_env", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    if (!uvm_config_db #(demo_env_config)::get(this, "", "cfg", cfg))
      cfg = demo_env_config::type_id::create("cfg");
    agent = demo_agent::type_id::create("agent", this);
    agent.is_active = cfg.is_active;
    scoreboard = demo_scoreboard::type_id::create("scoreboard", this);
    coverage = demo_coverage::type_id::create("coverage", this);
  endfunction

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    agent.monitor.item_ap.connect(scoreboard.item_imp);
    agent.monitor.item_ap.connect(coverage.analysis_export);
  endfunction
endclass

examples/demo_uvm/tb/classes/demo_env_config.svh

Download original source · 13 lines

class demo_env_config extends uvm_object;
  uvm_active_passive_enum is_active = UVM_ACTIVE;
  int unsigned item_count = 8;

  `uvm_object_utils_begin(demo_env_config)
    `uvm_field_enum(uvm_active_passive_enum, is_active, UVM_DEFAULT)
    `uvm_field_int(item_count, UVM_DEFAULT)
  `uvm_object_utils_end

  function new(string name = "demo_env_config");
    super.new(name);
  endfunction
endclass

examples/demo_uvm/tb/classes/demo_item.svh

Download original source · 15 lines

class demo_item extends uvm_sequence_item;
  rand bit [`DEMO_DATA_WIDTH-1:0] data;

  `uvm_object_utils_begin(demo_item)
    `uvm_field_int(data, UVM_DEFAULT)
  `uvm_object_utils_end

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

  constraint data_c {
    data inside {[0:255]};
  }
endclass

examples/demo_uvm/tb/classes/demo_monitor.svh

Download original source · 29 lines

class demo_monitor extends uvm_monitor;
  `uvm_component_utils(demo_monitor)

  virtual demo_if vif;
  uvm_analysis_port #(demo_item) item_ap;

  function new(string name = "demo_monitor", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    item_ap = new("item_ap", this);
    if (!uvm_config_db #(virtual demo_if)::get(this, "", "vif", vif))
      `uvm_fatal(get_type_name(), "virtual interface was not configured")
  endfunction

  task run_phase(uvm_phase phase);
    demo_item observed;
    forever begin
      @(posedge vif.clk);
      if (vif.reset_n && vif.valid && vif.ready) begin
        observed = demo_item::type_id::create("observed");
        observed.data = vif.data;
        item_ap.write(observed);
      end
    end
  endtask
endclass

examples/demo_uvm/tb/classes/demo_scoreboard.svh

Download original source · 24 lines

class demo_scoreboard extends uvm_scoreboard;
  `uvm_component_utils(demo_scoreboard)

  uvm_analysis_imp #(demo_item, demo_scoreboard) item_imp;
  int unsigned observed_count;

  function new(string name = "demo_scoreboard", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    item_imp = new("item_imp", this);
  endfunction

  function void write(demo_item item);
    observed_count++;
    `uvm_info(get_type_name(), $sformatf("observed data 0x%0h", item.data), UVM_MEDIUM)
  endfunction

  function void report_phase(uvm_phase phase);
    `uvm_info(get_type_name(), $sformatf("observed %0d items", observed_count), UVM_LOW)
  endfunction
endclass

examples/demo_uvm/tb/classes/demo_sequence.svh

Download original source · 19 lines

class demo_sequence extends uvm_sequence #(demo_item);
  int unsigned item_count = 8;

  `uvm_object_utils(demo_sequence)

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

  task body();
    repeat (item_count) begin
      req = demo_item::type_id::create("req");
      start_item(req);
      if (!req.randomize())
        `uvm_fatal(get_type_name(), "demo_item randomization failed")
      finish_item(req);
    end
  endtask
endclass

examples/demo_uvm/tb/classes/demo_sequencer.svh

Download original source · 7 lines

class demo_sequencer extends uvm_sequencer #(demo_item);
  `uvm_component_utils(demo_sequencer)

  function new(string name = "demo_sequencer", uvm_component parent = null);
    super.new(name, parent);
  endfunction
endclass

examples/demo_uvm/tb/classes/demo_smoke_test.svh

Download original source · 28 lines

class demo_smoke_test extends uvm_test;
  `uvm_component_utils(demo_smoke_test)

  demo_env        env;
  demo_env_config cfg;

  function new(string name = "demo_smoke_test", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    cfg = demo_env_config::type_id::create("cfg");
    cfg.item_count = 8;
    uvm_config_db #(demo_env_config)::set(this, "env", "cfg", cfg);
    env = demo_env::type_id::create("env", this);
  endfunction

  task run_phase(uvm_phase phase);
    demo_sequence sequence;
    phase.raise_objection(this);
    sequence = demo_sequence::type_id::create("sequence");
    sequence.item_count = cfg.item_count;
    sequence.start(env.agent.sequencer);
    #20ns;
    phase.drop_objection(this);
  endtask
endclass

examples/demo_uvm/tb/demo_if.sv

Download original source · 28 lines

`ifndef DEMO_DATA_WIDTH
`define DEMO_DATA_WIDTH 16
`endif

interface demo_if (
  input logic clk,
  input logic reset_n
);
  logic                        valid;
  logic                        ready;
  logic [`DEMO_DATA_WIDTH-1:0] data;

  modport driver_mp (
    input  clk,
    input  reset_n,
    input  ready,
    output valid,
    output data
  );

  modport monitor_mp (
    input clk,
    input reset_n,
    input valid,
    input ready,
    input data
  );
endinterface

examples/demo_uvm/tb/demo_pkg.sv

Download original source · 16 lines

package demo_pkg;
  import uvm_pkg::*;
  `include "uvm_macros.svh"

  `include "demo_item.svh"
  `include "demo_env_config.svh"
  `include "demo_sequence.svh"
  `include "demo_sequencer.svh"
  `include "demo_driver.svh"
  `include "demo_monitor.svh"
  `include "demo_agent.svh"
  `include "demo_scoreboard.svh"
  `include "demo_coverage.svh"
  `include "demo_env.svh"
  `include "demo_smoke_test.svh"
endpackage

examples/demo_uvm/tb/demo_top.sv

Download original source · 32 lines

module demo_top;
  import uvm_pkg::*;
  import demo_pkg::*;

  logic clk = 1'b0;
  logic reset_n = 1'b0;

  always #5ns clk = ~clk;

  demo_if demo_vif (
    .clk     (clk),
    .reset_n (reset_n)
  );

  demo_dut dut (
    .clk     (clk),
    .reset_n (reset_n),
    .valid   (demo_vif.valid),
    .ready   (demo_vif.ready),
    .data    (demo_vif.data)
  );

  initial begin
    repeat (4) @(posedge clk);
    reset_n = 1'b1;
  end

  initial begin
    uvm_config_db #(virtual demo_if)::set(null, "*", "vif", demo_vif);
    run_test("demo_smoke_test");
  end
endmodule