by Prashant Dixit, Questa VIP Product Team, Mentor Graphics
ABSTRACT
Functional verification is critical in the development of today's complex digital designs. Increasing hardware complexity generally tracks Moore's Law; however, verification complexity grows at an even faster rate. Verification cycle is widely acknowledged as the major bottleneck in design methodology. Up to 70 percent of design time and resources are spent on functional verification. And yet, functional bugs are the number one cause of silicon re-spins.
Another aspect of verification comes into play during integration and system-level verification by the customer once the IP is integrated into a System on Chip (SoC). One of the most time consuming aspects of SoC verification is creating a testbench that models the SoC's interfaces, which can include DDR, Ethernet, USB, PCI Express, and many others.
A better option is to use a commercial verification IP solution that models all interfaces as components that can be plugged into an SoC testbench and simulated along with the chip. This in turn reduces risk and improves time-tomarket for both IP vendors and customers. Verification Intellectual Properties (VIPs) accelerate the chip design and verification cycle with higher reliability, and lower risk and cost.
INTRODUCTION
Now a days, off-the-shelf VIP has become an indispensable part of any verification environment, be it block level or SoC level. This is because the specifications for standard interface protocols can often run hundreds of pages long. Deciphering these specifications and accurately modeling the protocols require huge development effort and deep technical knowledge. VIPs can help verify IP and SoC designs faster, more accurately, and with less effort. Modern-day commercial VIPs include the following features:
- A pre-verified functional model that includes all features listed in the specifications.
- Ease of integration and support for verification methodologies such as OVM and UVM, and several HVL and HDL platforms such as SystemVerilog and SystemC.
- Built-in monitors and protocol checkers (assertions) for verifying compliance to interface specifications.
- Comprehensive compliance test suites to exercise the design with compliant and non-compliant traffic.
- A coverage engine to identify corner cases and verification closure.
- An ability to verify system-level functionality and validate target performance by generating application-specific traffic.
Figure 1 shows a block diagram of the Questa Verification IP (QVIP), which includes all of the aforementioned features.
 |
Figure 1: Block View of Questa Verification IP |
QVIPs are one of the most widely used VIPs because they can be easily and quickly integrated into user's test benches. Users can follow these steps to integrate an Ethernet QVIP into their test bench:
I. SETTING UP THE QVIP INSTANCE
The core of the QVIP is the SystemVerilog interface, which contains all wires associated with the protocol. The name of the SystemVerilog interface for Ethernet is mgc_ethernet. Users must instantiate this interface in the top module as follows:
mgc_ethernet ethernet_if (.iclk_0(1'bz), .iclk_1(1'bz), .ireset(1'bz), .iMDC(1'bz), .ian_clk_0(1'bz), .ian_clk_1(1'bz))
Here, mgc_ethernet is instantiated as ethernet_if with various clock and reset signals. These signals are driven with 1'bz if the clock and reset are required to be generated by the QVIP. If the clock and reset are supplied from the test bench, the corresponding wires must be connected to the QVIP wires in the interface port list.
In the top module, the QVIP interface wires must be connected to the Design Under Test (DUT) wires. Connect the Tx Data and Control wires of the DUT with the QVIP Rx as follows:
assign ethernet_if.XD[1][0] = dut.txd[0]
assign ethernet_if.XD[1][1] = dut.txd[1]
assign ethernet_if.XD[1][2] = dut.txd[2]
assign ethernet_if.XD[1][3] = dut.txd[3]
assign ethernet_if.XC[1][0] = dut.txc[0]
assign ethernet_if.XC[1][1] = dut.txc[1]
assign ethernet_if.XC[1][2] = dut.txc[2]
assign ethernet_if.XC[1][3] = dut.txc[3]
Connect the Rx Data and Control wires of the DUT with the QVIP Tx as follows:
assign dut.rxd[0] = ethernet_if.XD[0][0]
assign dut.rxd[1] = ethernet_if.XD[0][1]
assign dut.rxd[2] = ethernet_if.XD[0][2]
assign dut.rxd[3] = ethernet_if.XD[0][3]
assign dut.rxc[0] = ethernet_if.XC[0][0]
assign dut.rxc[1] = ethernet_if.XC[0][1]
assign dut.rxc[2] = ethernet_if.XC[0][2]
assign dut.rxc[3] = ethernet_if.XC[0][3]
In UVM, the SystemVerilog interface communicates with various classes through the UVM configuration database (uvm_config_db).
Users must provide a handle of this interface in the common database using the set API so that it can be retrieved from anywhere within the UVM environment using the get API. This involves creating a virtual interface for the SystemVerilog interface to place into the configuration database as follows:
typedef virtual mgc_ethernet bfm_type
uvm_config_db #( bfm_type )::set (null , "uvm_test_
top" , "ETHERNET_IF" , ethernet_if )
This code puts the handle bfm_type of ethernet_if in the uvm_config_db with the name ETHERNET_IF. This should be done inside an initial block in the top module.
Next, call the run_test method of uvm_test to create the UVM environment based on the UVM_TESTNAME as follows:
run_test("")
II. CONFIGURING THE ETHERNET AGENT
An agent's job is to drive and/or monitor activity on the interface. Usually, an agent contains a driver, sequencer, coverage engine, and configuration options. The environment (env) is the placeholder for the agent and the analysis components such as scoreboard and coverage collector.
 |
Figure 2: Ethernet Agent |
Figure 2 shows ethernet_agent, a single class which provides numerous options to users to configure the agent according to custom verification requirements and testbench structure. Following are some of the configuration options provided in the agent:
A. Abstraction Level Settings
The abstraction level (Active or Passive) for Tx and Rx ends of the Ethernet interface can be set using options provided in the agent, as shown on the following page:
<cfg_obj>.agent_cfg.is_active = 1;
<cfg_obj>.agent_cfg.is_tx = 1;
The above setting configures the Tx end of the Ethernet interface as Active.
B. Interface Type
Ethernet is a highly configurable QVIP and supports numerous interface types on various speeds. The required interface can be set using the following option:
<cfg_obj>.agent_cfg.if_type = ETHERNET_XGMII;
The above setting configures the Ethernet QVIP as XGMII. Similarly, users can configure the Ethernet QVIP for other interfaces such as CGMII and 10GBASE-R.
C. Clocks and Reset
The agent contains the following options to control the source of the clock and reset signals:
<cfg_obj>.agent_cfg.ext_clock = 1;
<cfg_obj>.agent_cfg.ext_reset = 1;
The above setting configures the clock and reset source as external if users want to supply clock and reset signals from the testbench. Setting these options to 0 enables users to generate clock and reset signals from the QVIP. Users can also select clock source as internal and reset as external or vice-versa.
D. Monitors and Listeners
The QVIP provides built-in listeners for common Ethernet frames such as Data, Control, and Type. Users can enable these listeners as required on both the Tx and Rx ends of the Ethernet interface using the following options:
<cfg_obj>.agent_cfg.en_txn_ltnr.data_frame = 1;
This option enables the listener for data frames.
<cfg_obj>.agent_cfg.en_txn_ltnr.cntrl_frame = 1;
This option enables the listener for control frames.
E. Coverage Collectors
Various built-in coverage collectors are provided with the QVIP to collect functional coverage for common frame properties, interface-specific codes and ordered sets, and coverage related to application packets and so on.
User can attach single or multiple coverage collectors through the following setting:
<cfg_obj>.agent_cfg.en_cvg.tx.frames = 1;
This option attaches the frame coverage collector to the Tx end of the Ethernet interface and samples coverage data from the frames sent on the Tx end.
<cfg_obj>.agent_cfg.en_cvg.rx.frames = 1;
This option attaches the frame coverage collector to the Rx end of the Ethernet interface and samples coverage data from the frames sent on the Rx end. Similarly, to enable interface-specific coverage collector on the Rx end, the following option can be used:
<cfg_obj>.agent_cfg.en_cvg.rx.if_specific = 1;
The above option attaches an interface-specific coverage collector based on the selected interface type. For example, 10GBASE-R coverage collector is attached to Rx end if the 10GBASE-R interface type is selected.
III. SETTING UP ADDITIONAL COMPONENTS
Although ethernet_agent provides various configuration options for common Ethernet verification requirements, sometimes users might require design-specific components. QVIP facilitates adding custom components through various APIs.
QVIP agents contain a number of programmable analysis ports (APs) corresponding to various sequence items. Some built-in APs cater to commonly used sequence items while specific APs can be created as required.
void'(<cfg_obj>.set_monitor_item("mdio_write_ap",
ethernet_sta_mdio_write::get_type()));
The above API creates the AP mdio_write_ap corresponding to the sequence item ethernet_sta_mdio_ write for MDIO Write frames.
After creating an AP within the agent, it can be used to connect components such as built-in mvc_listener as follows:
<cfg_obj>.set_analysis_component("mdio_write_ap"
, "listener_mdio_write" , mvc_item_listener #(
ethernet_sta_mdio_write )::type_id::get());
The above API attaches mvc_item_listener to the AP mdio_write_ap created above with the name listener_ mdio_write. This listener reports if the sequence item ethernet_sta_mdio_write for MDIO Write frame is received.
Similarly, the above APIs can be used to attach listeners for various application layer frames such as IPv4 and IPv6.
Users can also attach their design-specific analysis components (coverage classes or end-to-end scoreboards) to the analysis ports of the agent using the APIs described above. Figure 3, below, shows a sample coverage tracker.
 |
Figure 3: Sample Coverage Tracker |
IV. USING SEQUENCES AND SEQUENCE ITEMS
QVIP provides a complete set of sequence items for modeling meaningful communication.
Sequence items can be sent or received for active agents and broadcast from the monitor (passive agents). Internal and external analysis components such as data checkers, scoreboards, and coverage classes can use sequence items during processing.
A QVIP sequence communicates with an agent by creating a sequence item and calling start_item and finish_item (or one of the UVM sequence macros) in the normal way:
ethernet_device_data_frame data_frame = ethernet_
device_data_frame::type_id::create("data_frame")
start_item(data_frame)
finish_item(data_frame)
These sequence items can also be randomized to generate random traffic. Inline constraints can also be added to the randomize () with function as follows:
start_item(data_frame);
if ( !data_frame.randomize() with {
data_frame.tx_error == 1'b0;
data_frame.tx_error_on_cycle == 0;
data_frame.len_type_field == 42;
data_frame.vlan_mode == ETH_VLAN_
UNTAGGED ;}) `uvm_error("ASSERT_
FAILURE","Assert
statement failure");
finish_item(data_frame);
QVIP also provides a sequence library to generate various traffic scenarios. These sequences can be used as is to generate the required traffic on the bus and are available at the following path:
<QVIP_install_area>/questa_mvc_src/sv/ethernet/shared/device_sequence/
Users can also extend these sequences or write their own based on custom requirements.
V. ANALYZING WAVEFORMS AND LOGS
Usually the first thing to do after running the simulation is to confirm whether the clock and reset wires are driven properly. Users should first confirm the active level of the reset and then proceed to check the data signals.
As the Ethernet QVIP supports numerous interfaces, it has a large set of wires defined in the specifications for the respective interface types. For example, for XGMII, the data and control signals are defined as XD and XC. Users must ensure that appropriate wires are connected with the DUT wires.
In Questa, the Transaction View feature is useful in debugging and analyzing the traffic. Transaction View displays all fields of transactions such as data_frame and control_frame. Figure 4 shows a sample view of the selected transactions.
 |
Figure 4: Transaction View GUI |
Simulation logs are recorded in the transcript, which is very useful for debugging as it contains information such as:
- Start and end times of transactions
- Information about various fields of sequence items
- Information about protocol checkers such as trigger time, Tx or Rx end, and an elaborative statement describing the error message and the related specification section number.
Figure 5 shows a sample transcript containing the abovementioned information, which is useful in locating and resolving issues.
VI. UNDERSTANDING ERROR MESSAGES
Usually, users encounter two types of errors—UVM_ ERROR and Assertions—while using the QVIPs.
- UVM_ERROR is triggered by scoreboard in case of data integrity issues.
- Assertions are built-in protocol checks in the QVIP that are triggered on protocol violations.
Assertions are complemented with an elaborative message and the specification section as shown in Figure 5.
Assertions are enabled by default. During error testing, users can turn off assertions if they do not want the QVIP to trigger errors using the following APIs:
<cfg_obj>.m_bfm.set_config_enable_all_ assertions(2'b00);
The above API disables all assertions on Tx and Rx ends.
<cfg_obj>.m_bfm.set_config_enable_assertion_
index2(<device end>, <assertion name> , 1'b0)
The above API disables an individual assertion specified in <assertion name> on the device end specified in <device end>; the device end can be 0 or 1 (signifying Tx and Rx respectively).
Assertions are logged with the string Error on Questa Simulator and with the string MVC_ERROR on IUS and VCS simulators. Also, users can convert the logging of assertions into UVM_ERRORS to determine the status (pass or fail) of regression runs.
 |
Figure 5: Sample Transcript |
VII. HELPFUL COMMANDS FOR QVIP DEBUGGING
A few debug commands that can be used during QVIP integration and in later stages of verification are provided below:
log –r -mvcall /<hierarchical path to QVIP interface>/*
The above command logs all QVIP transactions, messages, wires, and signals so that they can be viewed in the wave window for debugging. By default, only wires and signals are logged.
QUESTA_MVC::questa_mvc_show("MVC_CONFIG");
The above command can be included in an initial block in the top module to display the values of QVIP configurations and the abstraction level of both the ends. The command can be enabled dynamically to gather runtime configuration information.
CONCLUSION
The steps described in this article help users to quickly integrate the Ethernet QVIP in their verification environment, thus saving more time for important and concrete verification activities.
In this article, the steps to integrate the QVIP in the testbench are described using Ethernet as an example. However, the generic information described in this article holds good for integrating the QVIP for other protocols.
REFERENCES
- QVIP HTML Reference Manual @ <QVIP_Install_Area>/docs/questa_vip_reference.html
- Ethernet User Guide @ <QVIP_Install_Area>/docs/ pdfdocs/qvip_eth1g_user.pdf
Back to Top