Beruflich Dokumente
Kultur Dokumente
Register Package
Verification Engineer
Agnisys Technology Pvt. Ltd.
Agenda
Introduction to UVM
UVM Register Model
Our experience with using Register Model
Register Model Generator
Verification Methodologies
History
February 2011 Accellera releases UVM 1.0
Recently, June 2011 UVM 1.1 is released
Introduction to UVM
Universal Verification Methodology
A methodology and a class library for building
Advanced Reusable Verification Components
UVM Environment
Module top () as top level element.
Test Class
Contains Testbench
Reusable components
with different config
Whats in UVM ?
Base Classes
Factory Classes
Phasing
Configuration
TLM
Sequences & Sequencers
Message Reporting
Register Model
Base Classes
Facilitate the design of modular, scalable, reusable verification
environments
The basic building blocks for all environments are components
and the transactions they use to communicate
establish structal
hierarchy
transactions
phase-- build,
connect, run, etc.
Factory Classes
Manufacture (create) UVM objects and
components.
Only one instance of the factory is present in a
given simulation
class uvm_component_registry #(
type T = uvm_component,
string Tname = "<unknown>"
) extends uvm_object_wrapper
Phasing
Several new runtime phases
in parallel with run_phase()
TLM
Unidirectional put/get interfaces
TLM 2.0
put
Initiator
target
get
10
Sequencers
Arbiter for controlling transaction flow
pull or push semantic between Driver
11
Message Reporting
Messages print trace information with advantages
over $display:
Aware of its hierarchy/scope in testbench
Allows filtering based on hierarchy, verbosity, and
time
`uvm_info("PKT", "Packet Sent, UVM_LOW);
12
Agenda
Introduction to UVM
UVM Register Model
Our experience with using Register Model
Register Model Generator
13
Register Model
Object oriented Shadow Model for Registers
and Memories in DUT
Components
Field
Register
Register File
Memory
Block
14
Register Model
BLK_1
R0
F1
F2
F3
F4
F10
R0
F1
uvm_reg
F11
F10
Registers
F11
.
.
.
F10
F11
F5
F6
F3
F10
F11
F10
F11
ARR[0]
ARR[1]
F11
ARR[n]
Register Arrays
F9
F6
F7
F8
.
.
.
F9
.
.
F5
F6
F7
F8
F10
F9
uvm_reg_block
F4
F7
F8
F5
F2
R0
R1
MEM_0
F5
.
.
.
BLOCK
BLK_n
R0
F1
F2
F3
F4
F10
F11
F10
F6
F8
uvm_reg_file
F5
F9
F6
F9
F11
F6
F8
F5
F6
F8
F7
F8
F7
F9
RF0 [m]
RF1 [m]
F9
.
.
F5
F6
F7
F9
RF0 [0]
RF1 [0]
RF0 [1]
RF1 [1]
.
.
F11
F5
F5
F7
F8
.
.
.
F10
F7
F6
F8
F9
MEM_0
F7
uvm_mem
Memory
MEM_0
MEM0
15
Generator
Adapter
Backdoor
Bus Specific
R/W
Bus Agent
16
Mirroring
Register model mirrors content of registers in DUT
Updated on read() and write()
Scoreboard for checking
Memories :
Scoreboard
uvm_mem::peek()
Monitor
uvm_mem::poke()
R0
R1
Monitor
DUT
R0.read (. . .);
...
R1.write (. . .);
Sequence
R0
Sequencer
Driver
APB
R1
17
Hardware writable
Scoreboard
R0
R1
Monitor
DUT
R0.read (. . .);
...
R1.write (. . .);
Sequence
R0
Sequencer
Driver
APB
R1
18
Agenda
Introduction to UVM
UVM Register Model
Our experience with using Register Model
Register Model Generator
19
HDL Path
HDL path components are specified using the following methods:
a) uvm_reg_block::configure() and uvm_reg_block::add_hdl_path()
b) uvm_reg_file::configure() and uvm_reg_file::add_hdl_path()
c) uvm_reg::configure() and uvm_reg::add_hdl_path_slice()
d) uvm_mem::configure() and uvm_mem::add_hdl_path_slice()
CODE:
R0.clear_hdl_path();
R0.add_hdl_path_slice("dut.R0", 0, 32);
R1.clear_hdl_path();
R1.add_hdl_path_slice("dut.R1", 0, 64);
R0
R1
array name
And For Register Arrays:
Monitor
DUT
Sequence
Sequencer
Driver
foreach (reg_array[i])
begin
APB
reg[i].clear_hdl_path();
reg[i].add_hdl_path_slice($sformatf(DUT_ARRAY[%0x]", i), 0, 32);
end
R0
R1
20
Mapping in Block
byte-width
of the bus
Base Address
APB_map = create_map("APB", h0, 4, UVM_LITTLE_ENDIAN, 1);
APB_map_map.add_reg (R0, h0);
APB_map.add_reg (R1, h4);
endianess
Byte addressing:
consecutive
addresses refer are
1 byte apart
R0 - 32 bit
R1 - 64 bit
R0
Monitor
R1
DUT
Sequence
R0
Sequencer
Driver
APB
R1
21
Coverage
For all elements except in Register File
Pre-defined Functional Coverage Type Identifiers
Block
R0
F1
F2
F3
0x008
R1
7
F4
.
.
in registers.
0x000
F5
F6
F8
F7
F9
MEM_0
0x014
0x015
0x020
- 0x030
22
Coverage
class block_MEM0
block_block
extends
extends
uvm_mem;
uvm_reg_block;
my_reg_R1
extends
uvm_reg;
local
uvm_reg_addr_t
MEM0;
m_offset;
randblock_MEM0
uvm_reg_field
F1;
R1;
randblock_R1
uvm_reg_field
F2;
covergroup
cg_addr;F3;
rand
uvm_reg_field
local
QUADRANTS
uvm_reg_addr_t
: coverpoint
m_offset;
m_offset {
bins FIRST = {[0:2]};
covergroup cg_vals;
covergroup
cg_addr;
bins SECOND = {[3:5]};
F1: coverpoint
F1.value[6:0];
block_MEM0
bins
: coverpoint
THIRD = {[6:8]};
m_offset {
F2: coverpoint
F2.value[13:0];
bins hit
bins
= FOURTH
{ ['h18
= :
{[9:11]};
'h47] };
F3: coverpoint
F3.value[19:0];
}
endgroup}
endgroupblock_reg1 : coverpoint m_offset {
bins hit =
{ h4
};
function new(string
name
= "my_reg_R1");
function
}new(string
name
= "block_mem_reg");
super.new(name,
32,
build_coverage(
endgroup
super.new(name, 'h30, 32, "RW",
UVM_CVR_FIELD_VALS));
build_coverage(UVM_CVR_ADDR_MAP));
. . .
function
new(string name = "block_block");
endfunction
super.new(name,
if (has_coverage(UVM_CVR_ADDR_MAP))
build_coverage(UVM_CVR_ADDR_MAP));
cg_addr
= new();
virtual
function
void sample(uvm_reg_data_t data,
if (has_coverage(UVM_CVR_ADDR_MAP))
uvm_reg_data_t byte_en,
endfunction
cg_addr = new();
bit is_read,
endfunction
uvm_reg_map map);
`uvm_object_utils(block_MEM0)
if (has_coverage(UVM_CVR_FIELD_VALS))
virtual
function void sample(uvm_reg_addr_t
cg_vals.sample();
offset,
bit
is_read,
uvm_reg_map
map);
virtual
function
void
sample(uvm_reg_addr_t
endfunction
if (get_coverage(UVM_CVR_ADDR_MAP))
offset,
bit is_read, uvm_reg_map map); begin
= offset;
ifm_offset
(get_coverage(UVM_CVR_ADDR_MAP))
virtual
function
void sample_values();begin
cg_addr.sample();
m_offset = offset;
super.sample_values();
end
ifcg_addr.sample();
(get_coverage(UVM_CVR_FIELD_VALS))
end
cg_vals.sample();
endfunction
. . .
endclass : block_block
endclass
Register
R0
F1
F2
F3
F10
F11
F10
F11
ARR[0]
ARR[1]
F11
ARR[n]
Register
Arrays
.
.
.
F10
F5
F6
F7
F8
F5
F9
F6
F7
F8
Register
File
F9
RF0 [0]
RF1 [0]
RF0 [1]
RF1 [1]
.
.
F5
F6
F8
Memory
R0
R1
F7
F9
MEM_0
RF0 [m]
RF1 [m]
MEM0
23
Pre-Defined Sequences
Sequence
ignores this
Register
uvm_resource_db#(bit)::set({"REG::",regmodel.blk.r0.get_full_name()},
"NO_REG_TESTS", 1, this);
SEQUENCES
ATTRIBUTES
uvm_reg_hw_reset_seq
uvm_reg_bit_bash_seq
uvm_reg_access_seq
uvm_mem_walk_seq
uvm_mem_access_seq
uvm_reg_mem_built_in_seq
uvm_reg_mem_hdl_paths_seq
NO_REG_TESTS
NO_MEM_TESTS
NO_REG_HW_RESET_TEST
NO_REG_BIT_BASH_TEST
NO_REG_ACCESS_TEST
NO_MEM_WALK_TEST
NO_MEM_ACCESS_TEST
24
Special Registers
Pre-Defined Registers
INDIRECT_REG[0]
INDIRECT_REG[1]
INDIRECT_REG[2]
IND_IDX
[0:7] 0x00
IND_DATA
0x04
data
25
Special Registers
cont. .
Aliased Registers
Accessible from multiple addresses in the same address map.
Fields in aliased registers will have different behavior depending on
the address used to access them.
R0
F1
F2
Ra
F3
F4
h100
F10
F11
F10
F11
Rb
h200
F10
F11
Aliased
Registers
26
Special Registers
FIFO
27
Agenda
Introduction to UVM
UVM Register Model
Our experience with using Register Model
Register Model Generator
28
GENERATOR
EDA
Vendors
29
30
Synopsys : Ralgen
RALF to UVM
Agnisys : IDSExcel
Excel to UVM
31
Summary
UVM register package must be used for any
serious SoC verification
Not using a register model is painful
Not using a generated register model is very
painful
Any questions?
32
33
34
cont. .
35
Scoreboard
Monitor
Register
Model
Monitor
DUT
R0.read (. . .);
...
R1.write (. . .);
Sequence
R0
Sequencer
Driver
APB
R1
36
Introspection
37
Special Registers
cont. .
Aliased Registers
R0
F1
F2
F3
F4
F10
F11
F10
F11
F10
F11
38