Thought Leadership

Register Testing the “Easy Way” at DVCON Europe

By Rich Edelman

DVCON Europe is coming to Munich, December 6-7, 2022. Hope to see you there! I’ll be presenting a paper on “Register Testing – Exploring Tests, Register  Model Libraries, Sequences and Backdoor Access” between 10:45am and 12:15pm on Wednesday, December 7.

Writing Simple Code

It’s really a paper on writing simple, easy to understand models and libraries as opposed to building a register package – although the examples operate as small register packages.

I’ll share a simple register modeling package and share a small example as we cruise through the ideas and concepts.

DVCON Europe, Dec 6-7, 2022 in Munich
Simple register model package

The UVM Register package is well used, and well loved – clocking in at about 20,000 lines of code in total. The package discussed in the paper does not assume to be as complete as the UVM Register package – but is it complete enough? I’d love to hear your thoughts in Munich.

I’m a fan of registers, but many (most?) registers cannot just be randomized or stomped through with marching ones. Some can. But could you imagine setting registers to random values in the control chip for the wood chipper that the tree guys use? Wood chippers are scary enough already.

Instead, I think register tests “know what the registers can do” – they are aware. Or at least register tests embody relationships between registers (regA has to be non-zero, when regB[3] is 1). These kinds of relationships can be captured in tests or constraints for example.

Sometimes a useful register testbench just monitors the addresses, and maps the addresses into register names for easier debug.

In any case, a register model is a useful thing. But does it have to be so big?

Register-To-Bus Layering

You were getting ready to ask – “What about the register-to-bus layering”? Simple. A sequence does the work. You write code to go back and forth between the register layer and the bus protocol layer. But not much code. You can change format. You can issue many transactions. It’s just code. And small.

class REGISTERtoBUS_rw_sequence extends uvm_sequence#(bus_transaction);

  bit all_done;

  task body();
    `uvm_info(get_type_name(), "...running", UVM_MEDIUM)
    all_done = 0;
    wait (all_done == 1);

  task start_reg_item(register_transaction register_tr);
    bus_transaction bus_tr;
    // Translate to BUS
    bus_tr = new("bus_tr"); =;
    bus_tr.addr = register_tr.addr; =;
    register_tr.bus_tr = bus_tr; // Save it for later.
    // Translate back to register

  task finish_reg_item(register_transaction register_tr);
    bus_transaction bus_tr;
    // Translate to BUS
    $cast(bus_tr, register_tr.bus_tr); =;
    bus_tr.addr = register_tr.addr; =;
    finish_item(bus_tr); =;
    // Translate back to register

But now I’m getting ahead of the story. More details and discussion at the show.

A Register

Create functionally interesting registers like a status register with a READ-ONLY field named ‘active_tr’. The bit-fields are described with a struct. The behavior of this register is “regular” – nothing fancy, except that the the field ‘active_tr’ is READ-ONLY. It cannot be written. So the write() routine is implemented as such.

typedef struct packed {
  reg [1:0] status;
  reg [7:0] error_count;
  reg [4:0] active_tr; // READ-ONLY
} csr_t;

class csr_RO_active_tr extends register#(csr_t);
  function void write(T v); 
    value.status      = v.status;
    value.error_count = v.error_count;



Come by DVCON Europe to chat – the paper will be presented Wednesday, December 7. The conference is December 6 and 7. Hope to see you there.


Leave a Reply

This article first appeared on the Siemens Digital Industries Software blog at