Beyond UVM: Creating Truly Reusable Protocol Layering: Abstract-Protocols That Are Transported by Other Lower-Level
Beyond UVM: Creating Truly Reusable Protocol Layering: Abstract-Protocols That Are Transported by Other Lower-Level
Beyond UVM: Creating Truly Reusable Protocol Layering: Abstract-Protocols That Are Transported by Other Lower-Level
Abstract—Protocols that are transported by other lower-level level protocols can be transparently tunneled through a higher-
protocols are modeled using a layering structure that mirrors the layer protocol. For example, an IP stream (itself carrying a
layering of the protocol. In UVM, it is recommended that the variety of higher-layer protocols) can be encrypted then
layering be performed using a layering sequence. However, the wrapped into TCP packets and tunneled through a TCP
many examples of protocol layering sequences in the UVM transport layer to be decrypted and processed at the other end
literature show that it requires implementation techniques that as if they had been natively transported.
are not scalable and often not reusable. This paper details a UVM
protocol layering approach that uses a layering driver as an Transfers Transfers
implementation that is both scalable and reusable.
Host Endpoint
Keywords—UVM; protocol; layering; delayering; reusable;
Transactions Transactions
scalable; sequence
Master Device
I. INTRODUCTION
Packets Packets
Communication protocols are specified and implemented
according to layers. These layers are often labeled using the Serializer Deserializer
popular OSI modelError! Reference source not found.. A
higher-layer protocol is transparently transported on a lower- Serial 1’s & 0’s Serial 1’s & 0’s
layer protocol. That lower-layer protocol may in-turn be
transparently transported on an even lower-layer protocol. For Figure 2. USB Protocol Layers
example, as illustrated in Figure 1. , TCP protocol packets can
first be segmented into IPv4 frames; the IPv4 frames can then When implementing protocol verification IP, it is important
be encapsulated into Ethernet frames then transmitted over a that the independence of the protocol layering structure be
XAUI interface onto a fiber optic medium. Another example maintained, The output of a higher-layer protocol VIP can thus
illustrated in Figure 2. , USB transfers are composed of USB be transported by different lower-layer protocol VIPs.
transactions which are composed of USB packets. Similarly, a single instance of a lower-layer protocol VIP must
TCP Packets TCP Packets
be able to transport multiple higher-layer protocols coming
from multiple instances of different higher-layer protocol VIPs.
Segmentation Reassembly Conversely, lower-layer protocol monitors must be able to feed
a variety of higher-layer protocol monitors.
IPv4 Frames IPv4 Frames
II. PROTOCOL LAYERING IN UVM
Encapsulation Decapsulation
IV. DELAYERING
If protocols are layered on the way down, they must
similarly be “delayered” on the way up. Reference [3] does
show how a delayering monitor can observe lower-level
transactions through an analysis export and report observed
higher-layer transactions through its own analysis port. Figure 6. Layered Duplex Protocol
function write(lli_typ lli);
// Only consider lower-level items
The only problem with connecting the analysis port of a
// that belong to us monitor to the layering sequence (or any sequence for that
if (lli.dest != addr) return; matter) is that analysis exports must be implemented by a
write() method located in a uvm_component type.
// Collect lower-level items and Unfortunately, because sequences are not components, they
// re-constitute higher-layer items cannot have analysis exports. That is why [3] encapsulates the
hli.data[i] = lli.data; layering sequence and delayering monitor in a layering
if (hli.data.size() == hli.len) begin uvm_subscriber component that includes an analysis export for
ap.write(hli); the lower-layer protocol.
hli = hli_typ::type_id::create(“hli”);
end This puts the onus on the users to encapsulate each protocol
endfunction layering operation into individual components so the analysis
ports can be properly connected. In an environment where N
higher-layer protocols need to be layered on M lower-layer seq_item_port.item_done();
protocols, this approach requires N x M layering sequences end
encapsulated in N x M components. Adding a new higher-layer endtask
protocol requires creating M new layering components. Adding
a new lower-layer protocol requires N new layering endclass
components. The layering driver should be implemented as an extension
of the default agent driver. This will make it possible to replace
V. LAYERING AGENTS the original driver in the higher-level agent using the factory.
All of the existing layering examples seem to assume that
higher-level protocols can only be layered onto a lower-level
protocol and that no agent already exists for that protocol. They
assume that the user is free to create and instantiate a sequencer
for those higher-level protocols. But what if a sequencer for
that particular protocol already exists? What if it needs to be
connected to the monitor or driver in specific ways because of
the reactive nature of the protocol? What if the protocol
transactions require configuration information from the agent
context to be properly randomized? That is why UVM defines
the agent as the smallest unit of protocol-level reuse, not the
sequencer or the monitor.
Furthermore, some higher-level protocols may very well
have a physical transport implementation and thus need not
necessarily be layered. For example, Ethernet frames can be
transmitted over a variety of physical interfaces for which a
driver would be available. But they may also be transported by
another protocol (for example Ethernet-over-PPP) and thus
would require layering.
Layering agents is a more efficient reuse strategy, as it Figure 7. Layering Drivers
enables reusing the sequencer and monitor they contain instead
of instantiating and connecting new one. The only component The layering driver should be connected to the lower-layer
that needs replacing is the driver: should it remain in place, it sequencers using a simple passthru sequence. That passthru
will compete with the layering sequence for the agent’s sequence is functionally equivalent to the virtual interface of a
sequence items and break the execution of the higher-layer “regular” driver and thus should similarly be passed via the
protocol. configuration database. A passthru sequence is used in
preference to using the uvm_sequencer_base::send_request()
VI. A REUSABLE AND SCALABLE IMPLEMENTATION or uvm_sequencer_base::execute_item() methods so it can be
configured with state information, such as priority, to shape the
Because the driver in a protocol agent needs to be replaced
lower-level protocol traffic.
or shut down when that protocol needs to be layered, and since
layering sequences connect sequencers and are therefore class ll_passthru_seq extends
essentially components, the layering should be implemented in uvm_sequence#(lli_typ);
a layering driver, more specifically in its run_phase() method.
A layering driver is implemented using the same familiar lli_typ req;
techniques used to implement a “regular” driver, except that a int priority = -1;
sequence item is executed in terms of lower-level transactions
task body();
instead of pin wiggling through a virtual interface.
forever begin
class h2l_layering_driver extends ll_driver; wait (req != null);
... start_item(req, priority);
virtual task run_phase(uvm_phase phase); finish_item(req, priority);
forever begin req = null;
seq_item_port.get_next_item(hli); end
while (...) begin endtask
`uvm_create(lli) endclass
// Slice and dice hli to form lli’s class h2l_layering_driver extends ll_driver;
lli.data[i] = ...;
... virtual task run_phase(uvm_phase phase);
execute(lli) ll_passthru_seq ll_seq;
end uvm_config_db#(ll_passthru_seq)::get(this,
“seq”, ll_seq); The concept of the layering driver is also in keeping with
forever begin the current concept of a driver in UVM. What is a driver if not
seq_item_port.get_next_item(hli); a layering device between a sequence item and physical
while (...) begin signals?
`uvm_create(lli)