uvm5

Download as pdf or txt
Download as pdf or txt
You are on page 1of 11

UVM 1.

2 User’s Guide October 8, 2015

Example: ubus_env.sv

1 function void ubus_env::build_phase(uvm_phase phase);


2 string inst_name;
3 // set_phase_domain("uvm");
4 super.build_phase(phase);
5 if(!uvm_config_db#(uvm_integral_t)::get(this,””,
"num_masters",num_masters))
6 `uvm_fatal("NONUM",{"‘num_masters’ must be set for:",
7 get_full_name()});
8 if(has_bus_monitor == 1) begin
9 bus_monitor = ubus_bus_monitor::type_id::create("bus_monitor",
this);
10 end
11 uvm_config_db#(int)::get(this, “”, “num_masters", num_masters);
12 masters = new[num_masters];
13
14 for(int i = 0; i < num_masters; i++) begin
15 $sformat(inst_name, "masters[%0d]", i);
16 masters[i] = ubus_master_agent::type_id::create(inst_name, this);
17 void'(uvm_config_db#(int)::set(this,{inst_name,".monitor"},
18 "master_id", i);
19 void'(uvm_config_db#(int)::set(this,{inst_name,".driver"},
20 "master_id", i);
21 end
22 void uvm_config_db#(int)::get(this,””, "num_slaves", num_slaves);
23 slaves = new[num_slaves];
24 for(int i = 0; i < num_slaves; i++) begin
25 $sformat(inst_name, "slaves[%0d]", i);
26 slaves[i] = ubus_slave_agent::type_id::create(inst_name, this);
27 end
28 endfunction: build

Line 1 Declare the build_phase() function.

Line 4 Call super.build_phase(). This guarantees that the configuration fields (num_masters,
num_slaves, and has_bus_monitor) are updated per any resource settings.

Line 8 - Line 10 Create the bus monitor if the has_bus_monitor control field is set to 1. The create
function is used for creation.

Line 11 - Line 21 The master’s dynamic array is sized per the num_masters control field, which is read
from the resource database. This allows the for loop to populate the dynamic array according to the
num_masters value. The instance name that is used for the master agent instance is built using
$sformat so the instance names match the dynamic-array identifiers exactly. The iterator of the for loop is
also used to set a resource value for the master_id properties of the master agent and all its children
(through the use of the asterisk). This defines which request-grant pair is driven by the master agent.

Line 22 - Line 27 As in the master-agent creation code above, this code creates the slave agents using
num_slaves but does not set a resource for the slave agent.

7.7 UBus Master Agent

The ubus_master_agent (shown in Figure 43) and ubus_slave_agent are structured identically;
the only difference is the protocol-specific function of its subcomponents.

Copyright © 2011 - 2015 Accellera. All rights reserved. 171


October 8, 2015 UVM 1.2 User’s Guide

The UBus master agent contains up to three subcomponents: the sequencer, driver, and monitor. By default,
all three are created. However, the configuration can specify the agent as passive
(is_active=UVM_PASSIVE), which disables the creation of the sequencer and driver. The
ubus_master_agent is derived from uvm_agent.

ubus_example_tb0.ubus0.master0
ubus_master_agent
uvm_sequencer
#(ubus_transfer)

ubus_master_driver

ubus_master_monitor

Figure 43—Instance of ubus_master_agent

The build_phase() function of the ubus_master_agent is specified to create the driver, sequencer,
and the monitor. The is_active property controls whether the driver and sequencer are created.

Example: ubus_master_agent.sv

1 function void ubus_master_agent::build_phase(uvm_phase phase);


2 super.build_phase();
3 monitor = ubus_master_monitor::type_id::create("monitor", this);
4 if (is_active == UVM_ACTIVE) begin
5 sequencer =
uvm_sequencer#(ubus_transfer)::type_id::create("sequencer",
this);
6 driver = ubus_master_driver::type_id::create("driver", this);
7 end
8 endfunction : build_phase
9
10 function void ubus_master_agent::connect_phase(uvm_phase phase);
11 if (is_active == UVM_ACTIVE) begin
12 driver.seq_item_port.connect(sequencer0.seq_item_export);
13 end
14 endfunction : connect_phase

Line 1 Declare the build_phase() function.

Line 2 Call super.build_phase(). This guarantees that the configuration field (is_active) is
updated per any overrides.

Line 3 Create the monitor. The monitor is always created. Creation is not conditional on a control field.

Line 4 - Line 7 Create the sequencer and driver if the is_active control field is set to UVM_ACTIVE.
The create() function is used for creation. Note the use of the base uvm_sequencer.

Line 10 Declare the connect_phase() function.

172 Copyright © 2011 - 2015 Accellera. All rights reserved.


UVM 1.2 User’s Guide October 8, 2015

Line 11 - Line 13 Since the driver expects transactions from the sequencer, the interfaces in both
components should be connected using the connect() function. The agent (which creates the monitor,
sequencer, and driver) is responsible for connecting the interfaces of its children.

7.8 UBus Master Sequencer

This component controls the flow of sequence items to the driver (see Figure 44).

ubus_example_tb0.ubus0.master0.sequencer
ubus_master_agent

ubus_master_sequencer

sequences
read_modify_write_seq
incr_read_seq
incr_read_write_seq
r8_w8_r4_w4_seq
incr_write_seq

Figure 44—Instance of ubus_master_sequencer

The sequencer controls which sequence items are provided to the driver. The uvm_sequencer base class
will automatically read the sequence resource set for each specific run-time phase and start an instance of
that sequence by default.

7.9 UBus Driver

This component drives the UBus bus-signals interface by way of the xmi virtual interface property (see
Figure 45). The ubus_master_driver fetches ubus_transfer transactions from the sequencer and
processes them based on the physical-protocol definition. In the UBus example, the seq_item_port
methods get_next_item() and item_done() are accessed to retrieve transactions from the
sequencer.

ubus_example_tb0.ubus0.master0.driver
ubus_master_agent

ubus_master_driver

signal-driving methods
from event pool

vif

pointer to ubus_if ‚interface

Figure 45—Instance of ubus_master_driver

Copyright © 2011 - 2015 Accellera. All rights reserved. 173


October 8, 2015 UVM 1.2 User’s Guide

The primary role of the driver is to drive (in a master) or respond (in a slave) on the UBus bus according to
the signal-level protocol. This is done in the run_phase() task that is automatically invoked as part of
UVM’s built-in simulation phasing. For the master driver, the core routine is summarized as follows:

task ubus_master_driver::run_phase();
...
@(negedge vif.sig_reset);
forever begin // Repeat the following forever.
@(posedge vif.sig_clock);
seq_item_port.get_next_item(req); // Pull item from sequencer.
...
drive_transfer(req); // Drive item onto signal-level bus.
...
seq_item_port.item_done(); // Indicate we are done.
seq_item_port.put_response(rsp); // Provide response
end
endtask

Once the sig_reset signal is deasserted, the driver’s run task runs forever until stopped by having all
run_phase objections dropped. You are encouraged to study the UBus driver source code to gain a deeper
understanding of the implementation specific to the UBus protocol.

7.10 UBus Agent Monitor

The UBus monitor collects ubus_transfers seen on the UBus signal-level interface (see Figure 46). If
the checks and coverage are present, those corresponding functions are performed as well.

The primary role of the UBus master monitor is to sample the activity on the UBus master interface and
collect the ubus_transfer transactions that pertain to its parent master agent only. The transactions that
are collected are provided to the external world by way of a TLM analysis port. The monitor performs this
duty in the run task that is automatically invoked as part of simulation phasing. The run task may fork other
processes and call other functions or tasks in performance of its duties. The exact implementation is
protocol- and programmer-dependent, but the entry point, the run task, is the same for all components.

ubus_example_tb0.ubus0.master0.monitor
ubus_master_agent

ubus_master_monitor

checks
covergroups

vif

pointer to ubus_if ‚interface

Figure 46—Instance of ubus_master_monitor

The monitor’s functionality is contained in an infinite loop defined with the run_phase() task. Once all
of the run_phase objections were dropped, the run_phase() tasks finish, allowing other simulation
phases to complete, and the simulation itself to end.

174 Copyright © 2011 - 2015 Accellera. All rights reserved.


UVM 1.2 User’s Guide October 8, 2015

The checks are responsible for enforcing protocol-specific checks, and the coverage is responsible for
collecting functional coverage from the collected ubus_transfers.

7.11 UBus Bus Monitor

The UBus bus monitor collects ubus_transfers seen on the UBus signal-level interface and emits
status updates via a state transaction, indicating different activity on the bus. The UBus bus monitor has
class checks and collects coverage if checks and coverage collection is enabled. The UBus bus monitor is
instantiated within the UBus environment.

The ubus_env build_phase() function has a control field called has_bus_monitor, which
determines whether the ubus_bus_monitor is created or not. The bus monitor will be created by default
since the default value for this control field is 1. You can use the uvm_config_db interface to override
this value.

uvm_config_db#(int)::set(this, "ubus0", "has_bus_monitor", 0);

Here, the ubus0 instance of ubus_env has its has_bus_monitor control field overridden to 0.
Therefore, the ubus_bus_monitor in ubus0 will not be present. The build_phase() function for
the ubus_env that uses the has_bus_monitor control field can be found in Section 7.6.

7.11.1 Collecting Transfers from the Bus

The UBus bus monitor populates the fields of ubus_transfer, including the master and slave, which
indicate which master and slave are performing a transfer on the bus. These fields are required to ensure a
slave responds to the appropriate address range when initiated by a master.

In the UBus protocol, each master on the bus has a dedicated request signal and a dedicated grant signal
defined by the master agent’s ID. To determine which master is performing a transfer on the bus, the UBus
bus monitor checks which grant line is asserted.

To keep the UBus bus monitor example simple, an assumption has been made that the nth master connects
to the nth request and grant lines. For example, master[0] is connected to grant0, master[1] is
connected to grant1, and so on. Therefore, when the UBus bus monitor sees grant0 is asserted, it
assumes master[0] is performing the transfer on the bus.

To determine which slave should respond to the transfer on the bus, the UBus bus monitor needs to know the
address range supported by each slave in the environment. The environment developer has created the user
interface API, ubus_env::set_slave_address_map(), to set the address map for the slave as well
as the bus monitor. The prototype for this function is

set_slave_address_map(string slave_name, int min_addr, int max_addr);

For each slave, call set_slave_address_map() with the minimum and maximum address values to
which the slave should respond. This function sets the address map for the slave and provides information to
the bus monitor about each slave and its address map.

Using the address map information for each slave and the address that is collected from the bus, the bus
monitor determines which slave has responded to the transfer.

Copyright © 2011 - 2015 Accellera. All rights reserved. 175


October 8, 2015 UVM 1.2 User’s Guide

7.11.2 Number of Transfers

The bus monitor has a protected field property, num_transactions, which holds the number of
transfers that were monitored on the bus.

7.11.3 Notifiers Emitted by the UBus Bus Monitor

The UBus bus monitor contains two analysis ports, which provide information on the different types of
activity occurring on the UBus signal-level interface
a) state_port—This port provides a ubus_status object which contains an enumerated
bus_state property. The bus_state property reflects bus-state changes. For example, when
the bus enters reset, the bus_state property is set to RST_START and the ubus_status object
is written to the analysis port.
b) item_collected_port—This port provides the UBus transfer that is collected from the signal
interface after a transfer is complete. This collected transfer is written to the item_collect-
ed_port analysis port.
NOTE—Any component provided by the appropriate TLM interfaces can attach to these TLM ports and listen to the
information provided.

7.11.4 Checks and Coverage

The UBus bus monitor performs protocol-specific checks using class checks and collects functional
coverage from the collected ubus_transfers.

The UVM field coverage_enable and checks_enable are used to control whether coverage and
checks, respectively, will be performed or not. Refer to Section 4.10 for more information.

7.12 UBus Interface

The UBus interface is a named bundle of nets and variables such that the master agents, slave agents, and
bus monitor can drive or monitor the signals in it. Any physical checks to be performed are placed in the
interface. Refer to Section 4.10.

Assertions are added to perform physical checks.The ubus_env field intf_checks_enable controls
whether these checks are performed. Refer to Section 4.10 for more information.

The code below is an example of a physical check for the UBus interface, which confirms a valid address is
driven during the normal address phase. A concurrent assertion is added to the interface to perform the
check and is labeled assertAddrUnknown. This assertion evaluates on every positive edge of
sig_clock if has_checks is true. The has_checks bit is controlled by the
intf_checks_enable field. If any bit of the address is found to be at an unknown value during the
normal address phase, an error message is issued.

always @(posedge sig_clock)


begin
assertAddrUnknown:assert property (
disable iff(!has_checks)
(($onehot(sig_grant) |-> ! $isunknown(sig_addr)))
else
$error("ERR_ADDR_XZ\n Address went to X or Z during Address Phase");
end

176 Copyright © 2011 - 2015 Accellera. All rights reserved.


UVM 1.2 User’s Guide October 8, 2015

8. UBus Specification

8.1 Introduction

8.1.1 Motivation

The motivation for the UBus specification is to provide an example of a simple bus standard for
demonstration purposes and to illustrate the methodology required for a bus-based verification component.
As such, the UBus specification is designed to demonstrate all of the important features of a typical modern
bus standard while keeping complexity to a minimum.

8.1.2 Bus Overview

The UBus is a simple non-multiplexed, synchronous bus with no pipelining (to ensure simple drivers). The
address bus is 16-bits wide and the data bus is byte-wide (so as to avoid alignment issues). Simple burst
transfers are allowed and slaves are able to throttle data rates by inserting wait states.

The bus can have any number of masters and slaves (the number of masters is only limited by the arbitration
implementation). Masters and slaves are collectively known as “bus agents”.

The transfer of data is split into three phases: Arbitration Phase, Address Phase, and Data Phase. Because
no pipelining is allowed, these phases happen sequentially for each burst of data. The Arbitration and
Address Phases each take exactly one clock cycle. The Data Phase may take one or more clock cycles.

8.2 Bus Description

8.2.1 Bus Signals

The list of bus signals (not including arbitration signals) is shown in Table 15. All control signals are active
high.

Table 15—Bus Signals

Signal Width
Driven By Purpose
Name (bits)

clock 1 n/a Master clock for bus

reset 1 n/a Bus reset

start 1 arbiter This signal is high during the Arbitration Phase and low during the
Address and Data Phases

addr 16 master Address of first byte of a transfer

size 2 master Indicates how many bytes will be transfers:


00 => 1 byte
01 => 2 bytes
10 => 4 bytes
11 => 8 bytes

read 1 master This signal is high for read transfers (write must be low)

Copyright © 2011 - 2015 Accellera. All rights reserved. 177


October 8, 2015 UVM 1.2 User’s Guide

Table 15—Bus Signals (Continued)

Signal Width
Driven By Purpose
Name (bits)

write 1 master This signal is high for write transfers (read must be low)

bip 1 master Burst In Progress—driven high by master during Data Phase for all
bytes, except the last byte of the burst. This signal, when combined
with wait and error, can be used by the arbiter to determine if the bus
will start a new transfer in the next clock cycle

data 8 master/slave Data for reads and writes

wait 1 slave High if slave needs master to wait for completion of transfer

error 1 slave High if slave error condition applies to this transfer

8.2.2 Clocking

All bus agents operate synchronous to the rising edge of the clock signal with the exception of gnt signals
(see Section 8.3).

8.2.3 Reset

The active high reset signal is synchronous to the rising edge of clock. reset shall be asserted during power
up and shall remain asserted for a minimum of five rising edges of clock* after power and clock have
stabilized. Thereafter, reset shall be de-asserted synchronous to a rising edge of clock.

reset may be asserted at any time during operation. In such cases, reset must be asserted for at least three
clock cycles and must be both asserted and de-asserted synchronous to the rising edge of clock. The
assertion of reset cancels any pending transfer at the first rising edge of clock where reset is asserted. Any
bytes that have been transferred prior to assertion of reset are considered to have succeeded. Any byte that
would have succeeded at the rising edge of clock where reset is first asserted is considered to have failed.

While reset is asserted, all agents should ignore all bus and arbitration signals. While reset is asserted, the
arbiter should drive start and all gnt signals low. At the first rising edge of clock where reset is de-asserted,
the arbiter should drive start high. Thereafter, the normal bus operation should occur.

8.3 Arbitration Phase

Each UBus shall have a single, central arbiter to perform arbitration and certain other central control
functions.

The Arbitration Phase always lasts for one clock cycle. During the Arbitration Phase, the arbiter shall drive
the start signal high. At all other times, the arbiter should drive the start signal low. The start signal can
therefore be used by slaves to synchronize themselves with the start of each transfer. The arbiter shall
always drive start high in the cycle following the last cycle of each Data Phase or in the cycle following a
“no operation” (NOP) Address Phase (see Section 8.4.1). The last cycle of a Data Phase is defined as a Data
Phase cycle in which the error signal is high, or both the bip and wait signals are low.

Each master on the bus has a dedicated req signal and gnt signal. The arbiter samples all req signals at each
falling edge of clock where start is asserted and asserts a single gnt signal based on an unspecified priority
system. At all falling edges of clock where start is not asserted, the arbiter shall drive all gnt signals low.

178 Copyright © 2011 - 2015 Accellera. All rights reserved.


UVM 1.2 User’s Guide October 8, 2015

Thus, a master can see assertion of its gnt signal not only as an indication that it has been granted the bus, but
also as an indication that it must start an Address Phase. It is not necessary for the master to check the start
signal before starting its Address Phase.

Once a master is granted the bus, it must drive a transaction onto the bus immediately. No other master is
allowed to drive the bus until the current master has completed its transaction.
NOTE—Only the arbiter is allowed to drive a NOP transfer. This means a master must drive a real transfer if it is
granted the bus. Therefore, masters should not request the bus unless they can guarantee they will be ready to do a real
transfer.

Arbitration signals shall be active high and shall be named according to a convention whereby the first part
of the name is the root signal name (req_ for the request signal; gnt_ for the grant signal) and the second part
of the name is the logical name or number of the master. Although the arbitration signals form part of the
UBus specification, they are not considered to be “bus” signals as they are not connected to all agents on the
bus.

It is up to individual implementations to choose an appropriate arbitration system. Arbiters might allocate


different priorities to each master or might choose randomly with each master having equal priority.

8.4 Address Phase

The Address Phase lasts for a single clock cycle and always immediately follows the Arbitration Phase.

8.4.1 NOP Cycle

Where no master has requested the bus and the start signal is asserted at the falling edge of clock, no gnt
signal is asserted at the start of the Address Phase and the arbiter itself is responsible for driving the bus to a
“no operation” (NOP) state. It does this by driving the addr and size signals to all zeroes and both the read
and write signals low. A NOP address phase has no associated data phase so the arbiter shall assert the start
signal in the following clock cycle.
NOTE—This means the arbiter is connected to certain bus signals in addition to the arbitration signals and behaves as a
“default master”.

8.4.2 Normal Address Phase

If, at the rising edge of clock, a master sees its gnt signal asserted, then it must drive a valid Address Phase
in the following cycle. The master should also de-assert its req signal at this clock edge unless it has a
further transfer pending.

During the Address Phase, the granted master should drive the addr and size signals to valid values and
should drive either read or write (but not both) high.The address driven on addr represents the address of the
first byte of a burst transfer. It is up to the slave to generate subsequent addresses during burst transfers.

The master shall only drive the addr, size, read, and write signals during the Address Phase. During the
subsequent Data Phase, the master should not drive these signals.

8.5 Data Phase

The Data Phase may last for one or more clock cycles. The Data Phase follows immediately after the
Address Phase (and is immediately followed by the Arbitration Phase).

Copyright © 2011 - 2015 Accellera. All rights reserved. 179


October 8, 2015 UVM 1.2 User’s Guide

8.5.1 Write Transfer

The master shall drive the first byte of data onto the bus on the clock cycle after driving a write Address
Phase. If, at the end of this clock cycle, the slave has asserted the wait signal, then the master shall continue
to drive the same data byte for a further clock cycle. The data signal may only change at the end of a cycle
where wait is not asserted. Thus, the slave can insert as many wait states as it requires. The master shall
drive the bip signal high throughout the Data Phase until the point where the final byte of the transfer is
driven onto the bus, at which point it shall be driven low.

At the end of the transfer (the end of the cycle where both bip and wait are low) the master shall cease to
drive all bus signals.

8.5.2 Error during Write Transfer

The slave shall drive the error throughout the Data Phase. If a slave encounters an error condition at any
point during the Data Phase of a write transfer, it may signal this by asserting the error signal. To signal an
error condition, the slave must drive the error signal high while driving the wait signal low. This indicates to
the master that the associated byte of the transfer failed—any previous bytes in the burst are considered to
have succeeded; any subsequent bytes in the burst are abandoned. The assertion of error always terminates
the Data Phase even if bip is asserted simultaneously.

8.5.3 Read Transfer

On the clock cycle after the master drives a read Address Phase, the slave can take one of two actions: drive
the first byte of data onto the bus while driving the wait signal low or drive the wait signal high to indicate it
is not yet ready to drive data. Each byte of data is latched only by the master at the end of a cycle where wait
is low—thus the slave can insert as many wait states as is required. The master shall drive the bip signal high
throughout the Data Phase until the point where the master is ready to receive the final byte of the transfer, at
which point it shall be driven low.

At the end of the transfer (the end of the cycle where both bip and wait are low) the master shall cease to
drive all bus signals.

8.5.4 Error during Read Transfer

The slave shall drive the error throughout the Data Phase. If a slave encounters an error condition at any
point during a read transfer, it may signal this by asserting the error signal. To signal an error condition, the
slave must drive the error signal high while driving the wait signal low. This indicates to the master that the
associated byte of the transfer failed—any previous bytes in the burst are considered to have succeeded; any
subsequent bytes in the burst are abandoned. The assertion of error always terminates the Data Phase even if
bip is asserted simultaneously.

180 Copyright © 2011 - 2015 Accellera. All rights reserved.


UVM 1.2 User’s Guide October 8, 2015

8.6 How Data is Driven

Table 16 specifies how data is driven in the UBus specification.

Table 16—What Drives What When

Signal
Arbitration Phase Address Phase Data Phase
Name

start Driven to 1 by arbiter Driven to 0 by arbiter Driven to 0 by arbiter

addr Not driven Driven by master (or to 0 by arbiter Not driven


for NOP)

size Not driven Driven by master (or to 0 by arbiter Not driven


for NOP)

read Not driven Driven by master (or to 0 by arbiter Not driven


for NOP)

write Not driven Driven by master (or to 0 by arbiter Not driven


for NOP)

bip Not driven Not driven Driven to 1 by master for all but
last byte of transfer

data Not driven Not driven Driven by master during writes.


Driven by slave during reads in
cycles where wait is low; other-
wise, don’t care (may be driven to
unknown state or not driven at all)

wait Not driven Not driven Driven by slave

error Not driven Not driven Driven by slave

8.7 Optional Pipelining Scheme

As previously stated, the UBus standard does not normally support pipelining. However, pipelining can
optionally be implemented.
NOTE—All agents (including arbitration) on a bus must agree either to pipeline or not to pipeline. Mixing pipelined and
non-pipelined agents on the same bus is not supported.

Because pipelining overlaps the Arbitration, Address, and Data Phases, two levels of pipelining are
provided; i.e., there are a total of three transfers in progress at any one time.
NOTE—Pipelining results in different bus agents driving the same signals in consecutive clock cycles. As such, there is
no period where the signal is not driven as part of a change of sequencers. As a result, care is necessary in the physical
design of the bus to ensure that bus contention does not occur. A multiplexed approach will be required (in the form of
either a ring or a star).

8.7.1 Pipelined Arbitration Phase

In a pipelined system, the Arbitration Phase is performed in parallel with the Address and Data Phases.
Arbitration is carried out in every clock cycle regardless of whether this is necessary or not. This is because
the arbiter cannot predict whether the next clock cycle will mark the start of a new Address Phase.

Copyright © 2011 - 2015 Accellera. All rights reserved. 181

You might also like