automatic register verification -...
TRANSCRIPT
Automatic Register Verification
Munish Kumar Hardware Engineer @Agnisys
1
Agenda • Generation of register model • Problem in verification. • How to automate register verification from specifications
and get 100 % coverage? • Introduction to UVM • Constraints and coverage • UVM Register Model Usage • Specifications with constraints • Generated Regmodel • Generated Sequence • Results • Summary
2
GENERATOR EDA
Vendors
Generation of Register Model
3
Problems in verification
• Verification Engineer has to develop constraint and coverage models manually
• Verification teams spend a large amount of time verifying the functionality surrounding registers in the design
• Teams need to sift thru simulation results and coverage reports to determine if the coverage has been achieved.
4
How to automate register verification from specifications and get 100 % coverage?
1. Generate constraints for constrained-random stimulus.
2. Generate coverage code based on the constraints in specifications
3. Generate sequences that reads-writes into the DUT.
… preferably do all this automatically from the spec.
5
Introduction to UVM
• Universal Verification Methodology
– A methodology and a class library for building Advanced Reusable Verification Components
• Relies on strong, proven industry foundations
– Engineers worldwide can write thorough and reusable test environments
6
UVM Enviroment
7
• Module top () as top level element. • Test Class
• Contains Testbench • Reusable components with different config
Constraints
• Random Variable can be constrained to fall under some set of values using constraints
• Using constraints, one can find hard-to-reach corner cases
• Speed up the bug finding process
8
class Bus;
rand bit[15:0] addr;
rand bit[31:0] data;
constraint data_align
{ data[1:0] == 2'b0; }
constraint legal_addr
{ addr inside {[10:50]}; }
endclass
Coverage
• Coverage is used to gauge how far we are from completion
• User specified based on the design specification/intent
• Covergroup is like a user defined type that encapsulates and specifies the coverage
• ŠIt can be defined in a package, module, program, interface or class
9
Coverage contd.... • Triggered by sample()
function
• It contains coverage points
• – Variable or expression
• – Bins explicitly defined or automatically inferred
• Coverage points imply a set of bin associated with its sampled values or its value transitions.
• Contains optional enabling condition (iff)
10
bit [7:0] var;
covergroup cg @(posedge clk);
cvp:coverpoint var {
bins a = {[0:63],65};
bins c[] = {100,101,102};
bins others[] = default;
}
endgroup
UVM Register model Usage
11
R0
R1
APB
R0.read (. . .); . . . R1.write (. . .);
R0
R1
DUT
Sequence Sequencer Driver
Monitor
Scoreboard
Monitor
Specification with constraints
12
1 block_name block_name
0x00000
offset external size
block[@name='block_name']
1.1 Reg1 Reg1
0x00000
offset external default 0x0
block[@name='block_name']/reg[@name='Reg1']
7 6 5 4 3 2 1 0
bits name s/w h/w default Description
7:0 field1 Rw Rw 0 {Constraint = “ value = [‘h30:’h50]”}
1.2 Reg2 Reg2
0x00001
offset external default 0x0
block[@name='block_name']/reg[@name='Reg2']
7 6 5 4 3 2 1 0
bits name s/w h/w default Description
7:0 Field2 Rw Rw 0 {Constraint = “if (Reg1.field1 >= ‘h30 && Reg1.field1 <= ‘h50) value = [‘h1:’hF] else value = ‘h12,’h13,’h34 ”}
Generated Regmodel class block_name_Reg1 extends uvm_reg;
rand uvm_reg_field field1;
constraint Reg1_field1_constraint
{ field1.value[7:0] inside {['h30:'h50]}; }
covergroup wr_cg_bits;
field_0: coverpoint {m_current[0],m_data[0]}
iff (!m_is_read && m_be[0] &&
field1.value[7:0] inside
{[’h30:’h50]})
{
illegal_bins c_x = {1,2};
}
:
:
field_7: coverpoint {m_current[6],m_data[6]}
iff (!m_is_read && m_be[0] &&
field1.value[7:0] inside
{[’h30:’h50]})
{
illegal_bins c_x = {1,2,3};
}
endgroup
13
covergroup wr_cg_vals;
field1: coverpoint field1.value[7:0]
{
bins vals[5] = {['h30:'h50]};
illegal_bins err = default;
}
endgroup
:
endclass
class block_name_Reg2 extends uvm_reg;
rand uvm_reg_field field1;
covergroup wr_cg_bits;
field_0: coverpoint {m_current[0],m_data[0]}
iff (!m_is_read && m_be[0] &&
field1.value[7:0] inside
{[’h1:’hF],’h12,’h13,’h34})
{
illegal_bins c_x = {1,2};
}
:
:
endgroup
Constraints for field1
Bitwise coverage of mirrored and desired values based on constraints
Covergroups for field values
Contd.. class block_name_block extends uvm_reg_block;
rand block_name_Reg1 Reg1;
rand block_name_Reg2 Reg2;
constraint Reg2_Field2_constraint
{
if (Reg1.field1.value[7:0] >= 'h30 &&
Reg1.field1.value[7:0] <= 'h50)
Reg2.Field2.value[7:0] inside {['h1:'hF]};
else
Reg2.Field2.value[7:0] inside{'h12,'h13,'h34};
}
:
covergroup cg_addr;
Reg1 : coverpoint m_offset
{
bins hit = { 'h0};
}
Reg2 : coverpoint m_offset
{
bins hit = { 'h1};
}
endgroup
14
covergroup wr_cg_vals;
Field2_if: coverpoint Reg2.Field2.value[7:0]
iff (Reg1.field1.value[7:0] >= 'h30 &&
Reg1.field1.value[7:0] <= 'h50)
{
bins vals[4] = {['h1:'hF]};
illegal_bins err = default;
}
Field2_else: coverpoint Reg2.Field2.value[7:0]
iff (!(Reg1.field1.value[7:0] >= 'h30
&& Reg1.field1.value[7:0] <= 'h50))
{
bins vals[1] = {'h12,'h13,'h34};
illegal_bins err = default;
}
endgroup
:
endclass : block_name_block`endif
Collects Address Coverage for block
Constraints as a result of
interdependency between register fields
Collects Coverage for field values as a result
of interdependency
Generated Sequence
15
1. sequence randomizes whole regmodel 2. After every randomization stimulus for each register will be constrained value
Reg1
Reg2
APB
Reg1
Reg2
DUT
Sequence Sequencer Driver
Monitor
Scoreboard
Monitor
class Sequence extends uvm_sequence ; : Register_model rm ; rand uvm_reg_data_t data; uvm_status_e status; : task body : repeat (20) begin if (rm.randomize() == 1 ) // Writing rm.reg1.write(status,rm.reg1.get(),.path( UVM_FRONTDOOR),.parent(this)) ; rm.reg2.write(status,rm.reg2.get(),.path( UVM_FRONTDOOR),.parent(this)) ; //Reading rm.reg1.read(status,data,.path(UVM_FRONTDOOR), .parent(this)); rm.reg2.read(status,data,.path(UVM_FRONTDOOR), .parent(this)) ; end : endtask : body endclass :sequence
Results
0
200
400
600
800
1000
1200
1400
8 bit Field 16 bitField
32 bitField
64 bitField
Unconstrained & NonCoverage DrivenVerification
Constrained Random+ Coverage DrivenVerification
16
No
. of
tim
es r
and
om
izat
ion
d
on
e to
get
10
0 %
co
vera
ge
{co
nst
rain
t =
“val
ue
= [‘
h1
E:’h
46
]”}
Using Questa 10.0d
25(approx.)
Results
0
100
200
300
400
500
600
700
800
900
10 30 50 70
Random Stimulus +Non-Coveragedriven verification
Constained Stimulus+ Coverage DrivenVerification
17
No
. of
tim
es r
and
om
izat
ion
d
on
e to
get
10
0 %
co
vera
ge
{co
nst
rain
t =
“val
ue
= [‘
h1
E:’h
46
]”}
Using Questa 10.0d No. of Registers inside Block
Results
0
5000
10000
15000
20000
25000
30000
8-bit field 16-bit field 32-bit field 64-bit field
Random Stimulus +Coverage DrivenVerification Only
Constraint Random +Coverage DrivenVerification
18
No
. of
tim
es r
and
om
izat
ion
d
on
e to
get
10
0 %
co
vera
ge
{co
nst
rain
t =
“val
ue
= [‘
h1
E:’h
46
]”}
Here illegal_bins are also covered
Using Questa 10.0d
25(approx.)
Summary
• Eliminates false Positives in both bitwise and field coverage since coverpoints are enabled based on conditions in constraints expression
• Reduction in no. of iterations to get 100 % coverage(Saves from Redundant efforts)
• No need to manually write constraints, coverage code • Register verification has been made automatic by 1. By generating sequence for reading – writing(Just plug in the seq in enviroment) 2. Generating Regmodel that allows both Constraint Driven and Coverage Driven Verification
19
Thank You
20
Backup Slides
21
Motivation
• UVM 1.1 D Standard sequences for Register Read-Write
- uvm_reg_hw_reset_seq
- uvm_reg_bit_bash_seq
- uvm_reg_access_seq
But None of them supports randomization
• UVM Standard sequences do not incorporate interdependency between registers
• Writing tests for reading and writing is time consuming.
22