1. Introduction

    The UVM configuration database - the uvm_config_db - is used for setting parameters and controls. This database has a hierarchical aspect, is typed, has precedence or priority and has rules about first-wins or last-wins. In short, the UVM configuration database is a complex machine used by every SystemVerilog UVM testbench. It can also be hard to debug and complex to understand.

    This paper will try to shed some light on the complexity and provide some useful code extensions for debug. We will explore the UVM 1.1d config database implementation and theory with an effort to explaining the desired functionality to the new user, as well as clarifying how to best do debug when things go wrong. Additionally, UVM 1.1d to UVM 1.2 changes will be discussed, and a proposal for a simple, easier to understand and easier to debug implementation will be proposed.

    The output from the instrumented code is demonstrated below. The UVM 1.1d output is listed and the enhanced UVM 1.1d output is listed. For UVM 1.1d, this output is generated by using +UVM_CONFIG_DB_TRACE +UVM_RESOURCE_DB_TRACE during simulation.

    Messages from UVM 1.1d

    In the UVM 1.1d example, the output looks like:

    ./uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 101: reporter
    Configuration ‘uvm_test_top.e2.a2.b2.c2.XXX_3’
    (type string) read by uvm_test_top.e2.a2.b2.c2 = (string) 2env.
    a1.<STAR>*::XXX_3
    ./uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 101: reporter
    Configuration ‘uvm_test_top.e2.a2.b2.c2.XXX_4’
    (type string) read by uvm_test_top.e2.a2.b2.c2 = null (failed
    lookup)

    Two lines of debug are produced with the final results. Each line has a common prefix referring to the line where the message is printed in the UVM. This is not a helpful location.

    ./uvm-1.1d/src/base/uvm_resource_db.svh(121)

    For a failure, a “cannot find” message is printed. Also, not a helpful message.

    reporter Configuration ‘uvm_test_top.e2.a2.b2.c2.XXX_4’ (type
    string) read by
    uvm_test_top.e2.a2.b2.c2 = null (failed lookup)

    Messages from UVM 1.1d enhanced

    In the UVM 1.1d enhanced library, the complete output looks like:

    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 Looking for ‘XXX_3’ in ‘uvm_test_
    top.e2.a2.b2.c2’
    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 Item # 0: P:1000 Type handle
    matches ((string) 2env.a1.<STAR>*::XXX_3), Scope
    (uvm_test_top.e2.a2.b2.c2) doesn’t match (/^uvm_test_top\.e1\.a1\..*$/)
    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 Item # 1: P:1000 Type handle
    matches ((string) 2env.a1.<STAR>*::XXX_3), Scope
    (uvm_test_top.e2.a2.b2.c2) doesn’t match (/^uvm_test_top\.e1\.a2\..*$/)
    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 Item # 2: P:1000 Type handle
    matches ((string) 2env.a1.<STAR>*::XXX_3), Scope
    (uvm_test_top.e2.a2.b2.c2) doesn’t match (/^uvm_test_top\.e2\.a1\..*$/)
    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 Item # 3: P:1000 Type handle
    matches ((string) 2env.a1.<STAR>*::XXX_3), Scope
    (uvm_test_top.e2.a2.b2.c2) matches (/^uvm_test_top\.e2\.a2\..*$/)
    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 Found 1 match for ‘XXX_3’ in
    ‘uvm_test_top.e2.a2.b2.c2’
    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 Looking for highest precedence
    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 Found properly typed ((string)
    2env.a1.<STAR>*::XXX_3) resource in the queue. (Last
    one)
    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 ‘uvm_test_top.e2.a2.b2.c2.
    XXX_3’ (type string) read by uvm_test_top.e2.a2.b2.c2 =
    (string) 2env.a1.<STAR>*::XXX_3
    t.sv(101) @ 101: uvm_test_top.e2.a2.b2.c2 SUCCESS: Found value “2env.
    a1.<STAR>*::XXX_3”
    t.sv(104) @ 101: uvm_test_top.e2.a2.b2.c2 Looking for ‘XXX_4’ in ‘uvm_test_
    top.e2.a2.b2.c2’
    t.sv(104) @ 101: uvm_test_top.e2.a2.b2.c2 Item # 0: P: 997 Type handle
    matches ((string) env.a1::XXX_4), Scope
    (uvm_test_top.e2.a2.b2.c2) doesn’t match (/^uvm_test_top\.e2\.a1$/)
    t.sv(104) @ 101: uvm_test_top.e2.a2.b2.c2 Item # 1: P: 997 Type handle
    matches ((string) env.a1::XXX_4), Scope
    (uvm_test_top.e2.a2.b2.c2) doesn’t match (/^uvm_test_top\.e1\.a1$/)
    t.sv(104) @ 101: uvm_test_top.e2.a2.b2.c2 Found NO matches for ‘XXX_4’ in
    ‘uvm_test_top.e2.a2.b2.c2’
    t.sv(104) @ 101: uvm_test_top.e2.a2.b2.c2 ‘uvm_test_top.e2.a2.b2.c2.
    XXX_4’ (type string) read by uvm_test_top.e2.a2.b2.c2 =
    null (failed lookup)
    t.sv(104) @ 101: uvm_test_top.e2.a2.b2.c2 [C] Can’t find XXX_4

    Multiple lines are produced for each call to get(), outlining the internal decisions taken for both failure and success. In the enhanced library, each line is prefixed with the actual line where the get() call is located. This is a helpful location.

    For a failure, a complete history of the algorithm and failure is listed – with which items were checked from the resource queue:

    Looking for ‘XXX_4’ in ‘uvm_test_top.e2.a2.b2.c2’
       Item # 0: P: 997 Type handle matches ((string) env.
       a1::XXX_4), Scope
       (uvm_test_top.e2.a2.b2.c2) doesn’t match (/^uvm_test_top\.
       e2\.a1$/)
       Item # 1: P: 997 Type handle matches ((string) env.
       a1::XXX_4), Scope
       (uvm_test_top.e2.a2.b2.c2) doesn’t match (/^uvm_test_top\.
       e1\.a1$/)
    Found NO matches for ‘XXX_4’ in ‘uvm_test_top.e2.a2.b2.c2’
    ‘uvm_test_top.e2.a2.b2.c2.XXX_4’ (type string) read by uvm_
    test_top.e2.a2.b2.c2 = null (failed lookup)
  2. Download Paper