blob: aa7109bc9ab2c5c17cb29d3a4607cbb3b827e6ee [file] [log] [blame]
//
// -------------------------------------------------------------
// Copyright 2010-2011 Synopsys, Inc.
// All Rights Reserved Worldwide
//
// Licensed under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in
// writing, software distributed under the License is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See
// the License for the specific language governing
// permissions and limitations under the License.
// -------------------------------------------------------------
//
//
// This example demonstrates how to include a coverage model
// in a register model.
//
// Three coverage models are included:
// - Register level coverage
// - Address-leel coverage
// - Field value coverage
//
// This example demonstrates *how* to integrate a coverage model
// in a UVM Register model. The details of the coverage model itself
// are generator-specific and outside the scope of UVM.
//
class reg_R extends uvm_reg;
rand uvm_reg_field F1;
rand uvm_reg_field F2;
local uvm_reg_data_t m_current;
local uvm_reg_data_t m_data;
local uvm_reg_data_t m_be;
local bit m_is_read;
covergroup cg_bits;
wF1_0: coverpoint {m_current[0],m_data[0]} iff (!m_is_read && m_be[0]);
wF1_1: coverpoint {m_current[1],m_data[1]} iff (!m_is_read && m_be[0]);
wF1_2: coverpoint {m_current[2],m_data[2]} iff (!m_is_read && m_be[0]);
wF1_3: coverpoint {m_current[3],m_data[3]} iff (!m_is_read && m_be[0]);
wF2_0: coverpoint {m_current[4],m_data[4]} iff (!m_is_read && m_be[0]);
wF2_1: coverpoint {m_current[5],m_data[5]} iff (!m_is_read && m_be[0]);
wF2_2: coverpoint {m_current[6],m_data[6]} iff (!m_is_read && m_be[0]);
wF2_3: coverpoint {m_current[7],m_data[7]} iff (!m_is_read && m_be[0]);
endgroup
covergroup cg_vals;
F1: coverpoint F1.value[3:0];
F2: coverpoint F2.value[3:0];
F1F2: cross F1, F2;
endgroup
function new(string name = "reg_R");
super.new(name, 8, build_coverage(UVM_CVR_REG_BITS +
UVM_CVR_FIELD_VALS));
if (has_coverage(UVM_CVR_REG_BITS))
cg_bits = new();
if (has_coverage(UVM_CVR_FIELD_VALS))
cg_vals = new();
endfunction: new
virtual function void build();
F1 = uvm_reg_field::type_id::create("F1",,get_full_name());
F1.configure(this, 4, 0, "RW", 0, 8'h0, 1, 1, 1);
F2 = uvm_reg_field::type_id::create("F2",,get_full_name());
F2.configure(this, 4, 4, "RO", 0, 8'h0, 1, 1, 1);
endfunction: build
`uvm_object_utils(reg_R)
virtual function void sample(uvm_reg_data_t data,
uvm_reg_data_t byte_en,
bit is_read,
uvm_reg_map map);
if (get_coverage(UVM_CVR_REG_BITS)) begin
m_current = get();
m_data = data;
m_be = byte_en;
m_is_read = is_read;
cg_bits.sample();
end
endfunction
virtual function void sample_values();
super.sample_values();
if (get_coverage(UVM_CVR_FIELD_VALS))
cg_vals.sample();
endfunction
endclass : reg_R
class mem_M extends uvm_mem;
local uvm_reg_addr_t m_offset;
covergroup cg_addr;
MIN_MID_MAX: coverpoint m_offset
{
bins MIN = {0};
bins MID = {[1:1022]};
bins MAX = {1023};
}
endgroup
function new(string name = "mem_M");
super.new(name, 1024, 8, "RW", build_coverage(UVM_CVR_ADDR_MAP));
if (has_coverage(UVM_CVR_ADDR_MAP))
cg_addr = new();
endfunction: new
`uvm_object_utils(mem_M)
virtual function void sample(uvm_reg_addr_t offset,
bit is_read,
uvm_reg_map map);
if (get_coverage(UVM_CVR_ADDR_MAP)) begin
m_offset = offset;
cg_addr.sample();
end
endfunction
endclass : mem_M
class block_B extends uvm_reg_block;
rand reg_R Ra;
rand reg_R Rb;
mem_M M;
local uvm_reg_addr_t m_offset;
covergroup cg_addr;
Ra: coverpoint m_offset
{
bins hit = {'h0000};
}
Rb: coverpoint m_offset
{
bins hit = {'h0100};
}
M: coverpoint m_offset
{
bins MIN = {'h2000};
bins MAX = {'h23FF};
}
endgroup
covergroup cg_vals;
Ra: coverpoint Ra.F1.value[3:0];
Rb: coverpoint Rb.F1.value[3:0];
RaRb: cross Ra, Rb;
endgroup
function new(string name = "B");
super.new(name, build_coverage(UVM_CVR_ADDR_MAP+UVM_CVR_FIELD_VALS));
if (has_coverage(UVM_CVR_ADDR_MAP))
cg_addr = new();
if (has_coverage(UVM_CVR_FIELD_VALS))
cg_vals = new();
endfunction: new
virtual function void build();
default_map = create_map("", 0, 4, UVM_BIG_ENDIAN, 0);
Ra = reg_R::type_id::create("Ra",,get_full_name());
Ra.configure(this, null);
Ra.build();
Rb = reg_R::type_id::create("Rb",,get_full_name());
Rb.configure(this, null);
Rb.build();
M = mem_M::type_id::create("M",,get_full_name());
M.configure(this);
default_map.add_reg(Ra, 'h0000, "RW");
default_map.add_reg(Rb, 'h0100, "RW");
default_map.add_mem(M, 'h2000, "RW");
endfunction : build
`uvm_object_utils(block_B)
virtual function void sample(uvm_reg_addr_t offset,
bit is_read,
uvm_reg_map map);
if (get_coverage(UVM_CVR_ADDR_MAP)) begin
m_offset = offset;
cg_addr.sample();
end
endfunction
virtual function void sample_values();
super.sample_values();
if (get_coverage(UVM_CVR_FIELD_VALS))
cg_vals.sample();
endfunction
endclass : block_B