A Step by Step Guide: UVM Framework Alu Tutorial
A Step by Step Guide: UVM Framework Alu Tutorial
ALU TUTORIAL
A Step By Step Guide
Using UVMF_2019.4
Sept 2016
Agenda
Introduction
ALU Overview
Config Files Explained
Compile and Simulate Generated Code
Adding DUT Specific Functionality
— The main aim is to take the user through the complete flow (from start to finish) to show how to generate a working
UVM testbench for a simple IP using the UVM Framework (UVMF) code generators
— Each step is explained to help the user understand what information has to be provided to the UVMF code generators
in order to produce the initial testbench infrastructure
— The tutorial also highlights where the user is expected to modify the generated code to add DUT specific functionality
in order to create a fully operational UVM testbench
Completed Solution
— A fully completed version of the ALU UVMF testbench is provided within the completed_solution folder as a
reference to the user
— This contains all of the modification made after the initial code generation to add the DUT specific details
Operand A 8
16 Result
Operand B 8 ALU
valid done
ready
Operator
000 = nop
001 = and
010 = add
011 = xor
100 = mul
111 = rst
operator
valid 2
3
ready … 6
5
done
result
4
1. Apply operands & operation on input pins 4. After X cycles, ALU presents result
2. Raise valid for 1 cycle (start) 5. ALU raises done for 1 cycle
3. ALU drops ready signals 6. ALU raises ready signal
© Mentor Graphics Corp. Company Confidential
uvmf:
interfaces:
“<interface_nameA>”
YAML File Format <properties>
“<interface_nameB>”
— All UVMF YAML files must be presented as part of a specific top level format <properties>
util_components:
shown opposite
“<util_component>”
— Whitespace indentation is used to denote structure; however, tab characters are <properties>
never allowed as indentation environments:
— Comments start with the number sign (#), can start anywhere on a line and “<env_nameA>”
continue until the end of the line <properties>
— The information can be spread across multiple files or can be contained in a benches:
single file “<bench_nameA>”
<properties>
Number Of Agents
— First need to determine how many interfaces there are for the ALU
— Group signals into interfaces
— Create a YAML configuration file for each interface
– The YAML config file captures the pin information and the transaction information for the interface (agent)
— For the ALU, you have 2 separate interface files, 1 environment file and 1 bench file
NOTES:
1. Clock signal is required. Additional clocks will have to be manually
added after code generation
hdl_typedefs:
- name: alu_in_op_t
type: enum bit[2:0] {no_op = 3’b000, add_op …….., rst_op = 3’b111}
— Define any types used by the HDL side of the testbench
— Here you define the valid ALU operations and specify the bit values for each operation
hvl_typedefs:
— Define any types used by the HVL side of the testbench
— Here we define all of the signal names, directions and widths for the
agent/interface
NOTES:
— Direction specified here is in relation to the testbench
o i.e. ‘alu_rst’ is an output from the testbench and an input pin on the DUT
— The agent has to be able to execute a ‘rst_op’ operation and will need to drive the
ALU reset pin in response to such a request
— The ‘a’ & ‘b’ use the ALU_IN_OP_WIDTH parameter which was defined under the
parameters section of the config file
response_info:
data: []
operation: 1’b0
— The data directive allows the user to specify what response data should be passed back from the driver to the
originating sequence. We have no response data for this ALU interface
— The operation directive allows the user to define if the driver should pass any response data back to the sequence.
Here we set the value to 1’b0 which tells the driver not to send back any response
NOTES:
— Failing to disable responses when none are returned, will result in run times errors reporting ‘response queue overflow’
transaction_contraints:
- name : valid_op_c
- value: `{op inside {no_op,add_op, and_op, xor_op, mul_op};}’
transaction_vars:
- iscompare : ‘True’
- isrand: ‘True’
- name: ‘op’
NOTES:
— Unconstrained arrays cannot be specified
— If you need an unconstrained array, declare a fixed array and
modify the generated code
© Mentor Graphics Corp. Company Confidential
— You can create a simple .bat file on Windows to set the $UVMF_HOME
environment variable and then call python on your config file
— All generated code for the ALU_in agent will be saved under the ALU_in_pkg
folder [as shown opposite]
UVMF Transactors
— ALU_in_driver & ALU_in_monitor are class based and will be
instantiated inside the agent class
— ALU_in_filelist_hdl.f
Compilation list of hdl files (the interface and the 2 BFMs)
— ALU_in_filelist_hvl.f
Compilation list of hvl files (all other files)
— ALU_in_pkg.sv
This is the verification package (HVL) that `includes all the generated classes for our
VIP agent (all from directory src)
— ALU_in_pkg_hdl.sv
This package will be used for the HDL part of the VIP. The HDL part is synthesized
by the emulator.
— compile.do
Contains the compile command for the generated agent. Use on Windows or Linux
— Makefile
Contains the compile commands for the generated agent. Use on Linux
NOTES:
There may be some additional meta-data files generated in the ALU_in_pkg directory. These can be ignored.
© Mentor Graphics Corp. Company Confidential
— ALU_in_typedefs.svh
This file contains defines and typedefs used only in the testbench (HVL) side
of the testbench. Package may not contain any defines or typedefs after
but will still be generated
— ALU_in_typedefs_hdl.svh
This file contains defines and typedefs used by the interface package
performing transaction level simulation activities. This package is used by
the driver/monitor BFMs
— Separate YAML configuration file for the ALU output signal interface
— Agent name = ALU_out
— Primary clock = clk
— Primary reset = rst, with active low polarity
hdl_typedefs: []
hvl_typedefs: []
— No types declared for the ALU_out agents
parameters:
- name: ALU_OUT_RESULT_WIDTH
- type: int
- value: ‘16’
— Parameter to define the width of the ALU result defined
NOTES:
— Direction specified here is in relation to the testbench
o i.e. ‘done’ is an output from the ALU (DUT) and an input to the
testbench
— The ‘result’ signal use the ALU_OUT_RESULT_WIDTH
parameter which was defined in the parameter section of the
YAML configuration file
response_info:
data: []
operation: 1’b0
— For the ALU_out agent, we have no response data to be passed back to the sequence
— Leave with empty/default values.
transaction_contraints: []
transaction_vars:
- iscompare: ‘True’
isrand: ‘False’
name: result
type: bit [ALU_OUT_RESULT_WIDTH-1:0]
— The ALU_out agent has a transaction class which contains a single variable called ‘result’. The width of the
variable is defined by the agent parameter ALU_OUT_RESULT_WIDTH), which is set to 16 by default.
— Since we only monitor this interface, there is no need to randomize the transaction so we specify isrand:
‘False’
— We will want to compare the result variable in the transaction class do_compare method so we specify
iscompare: ‘True’
— All generated code for the ALU_out agent will be saved under the ALU_out_pkg
folder [as shown opposite]
— UVMF uses a separate environment level YAML configuration file to generate the environment level classes
— The classes for the environment, its configuration, and sequence are included in the generated environment package
— It can optionally include predictor and scoreboard classes
— The environment package can be reused when a block level UVMF testbench is being used as part of a subsystem/chip
level testbench.
The environment config file (ALU_environment.yaml) is covered in more detail in the following slides
uvmf:
environments:
ALU: Tells UVMF code generator to create an
environment with name ‘ALU_env_pkg’
agents:
- name: ALU_in_agent
type: ALU_in
- name: ALU_out_agent
type: ALU_out
Tells UVMF code generator to include 1 x ALU_in agent and 1 x ALU_out agent.
-name defines the instance name
-type is the name of the agent given by the user in the interface YAML configuration file
analysis_components:
- name: ALU_pred
type: ALU_predictor
Tells UVMF code generator to include a component of type ALU_predictor with instance name
ALU_pred.
This ALU_predictor component has not been defined yet and will be described in a separate
YAML configuration file.
analysis_exports: [] These allow the user to specify analysis exports & ports to add to the environment class,
typically implemented when the block level environment is to be utilized within a larger system
analysis_ports: [] level UVM testbench.
config_constraints: []
config_vars: []
parameters: []
These allow the user to specify environment level configuration variables, configuration
constraints and parameters for the environment class.
Parameters specified here can be passed down into any of the instantiated agents or other
analysis components.
scoreboards:
- name: ALU_sb
sb_type: uvmf_in_order_scoreboard
trans_type: ALU_out_transaction
subenvs: [] The scoreboards entry allow the user to specify any scoreboard components to be added the environment class.
The subenvs entry allows the user to import other pre-generated UVMF environments, thus creating a
hierarchical environment.
Typically this is used when importing QVIP UVMF environments or creating a system level UVMF testbench that
is reusing block level UVMF environments
The tlm_connections entry allows the user to specify a point to point connection between 2 ports/exports
For the ALU testbench we specify 3 connections as shown in the diagram below
connection 01
connection 00 connection 02
ALU_predictor ALU_sb
ALU_in ALU_out
ALU dut
agent agent
uvmf:
util_components: Tells UVMF code generator to create an analysis
ALU_predictor: component with name ‘ALU_predictor’
analysis_exports:
- name: ALU_in_agent_ae
type: ‘ALU_in_transaction #()’ Tells UVMF code generator to create exports/ports with the
analysis_ports: specified names and specified transaction types
- name: ALU_sb_ap
type: ‘ALU_out_transaction #()’
type: predictor Currently the only supported util_component type is predictor. In future
releases of UVMF this will be expanded to include coverage components
python $UVMF_HOME/scripts/yaml2uvmf.py \
ALU_in_interface.yaml \
ALU_out_interface.yaml \
ALU_util_comp_alu_predictor.yaml \
ALU_environment.yaml
— You can create a simple .bat file on Windows to set the $UVMF_HOME environment
variable and then call python on your YAML config files as shown below
ALU_environment.svh
— ALU environment class that instantiates the agents, scoreboards, predictors & connects them
ALU_env_configuration.svh
— Configuration class for ‘ALU’ environment
ALU_env_sequence_base.svh
— Base sequence class for any environment level sequences
ALU_env_typedefs.svh
— Contains any defines and typedefs to be compiled for use with the environment package
ALU_predictor.svh
— Generated predictor class for ALU environment.
— User will need to add code to predictor model to implement the prediction function
ALU_env_pkg.sv
— ALU Environment package
compile.do
— Contains the compile commands for the generated environment package. Use on Windows or Linux
Makefile
— Contains the compile commands for the generated environment package. Use on Linux
© Mentor Graphics Corp. Company Confidential
— The bench config file will be used to generate the UVMF top level testbench
— The top level testbench will instantiate the ALU env (which in turn instantiates the ALU interface agents as well as the
environment configuration class
— It facilitates the top-down configuration of the environment, which in turn configures the agents.
— It provides a default sequences and a default test to run
— It provides a simulation directory and makefile/run.do file for compiling and simulating the generated code
— The code generated from the bench level config file is specific to the DUT it is testing and in general will be non-reusable
code.
top_env: ALU The name of the top level environment to instantiate in this
bench. For the ALU testbench this is the ALU environment
python $UVMF_HOME/scripts/yaml2uvmf.py \
ALU_in_interface.yaml \
ALU_out_interface.yaml \
ALU_util_comp_alu_predictor.yaml \
ALU_environment.yaml \
ALU_bench.yaml
— You can create a simple .bat file on Windows to set the $UVMF_HOME environment variable and then call python on
your YAML config files as shown below
uvmf_template_output/project_benches/ALU
uvmf_template_output/project_benches/ALU
docs
uvmf_template_output/project_benches/ALU
registers
uvmf_template_output/project_benches/ALU
rtl
NOTE:
This is an optional location to place the DUT code.
The user can place their DUT code anywhere they want.
rtl/verilog/verilog_dut.v
― Dummy Verilog DUT code created by the code generator and instantiated in hdl_top
rtl/vhdl/vhdl_dut.v
― Dummy VHDL DUT code created by the code generator and instantiated in hdl_top
uvmf_template_output/project_benches/ALU
sim
— Also contain some other support files for emulation users plus a testlist
for Questa VRM users.
uvmf_template_output/project_benches/ALU
tb
Parameters
— Top level testbench params package (interface names, etc)
Sequences
— top level sequence and a sequence base class
— register sequence template class
— Sequence package
testbench
— hdl_top.sv : top level module based TB
— hvl_top.sv : non-synthesizable parts of top level TB
tests
— default test (test_top), extended from test base class
— Derived test (extended from test_top) template class
— register test template class
— test package
© Mentor Graphics Corp. Company Confidential
— Linux
– make debug : compiles and loads the testbench in the Questa GUI (interactive simulation)
– make build : only compiles the generated code
– make run_gui : invokes interactive simulation without recompiling the code
– make run_cli : invokes command line simulation without recompiling the code
— Windows
– do compile.do : compiles the generated testbench code
– do run.do : loads the testbench in Questa
– invoke_questa.bat : invokes Questa and executes the compile.do and run.do TCL files to compiled and
load the simulation
— Also applies several other switches to vsim that are required to run the UVMF simulation
o Example vsim command from the run.do script is shown below
o We recommend that you do not remove any of the switches being applied
Loaded Simulation
scoreboard
predictor
ALU_out agent
ALU_in agent
Wave Window : Auto populated with UVMF agent interface signals and transactions
― Screen shot shows wave window after running simulation for 500 ns
The following slides will look at the code changes required to implement each of the above steps
— The clock frequency, clock offset, reset polarity & reset duration were
specified from the bench level YAML configuration file
The DUT
— The DUT RTL model is alu.v
— This file is located at the top level of the tutorial directory.
— You can copy this file into the corresponding rtl folder under your
uvmf_template_output/project_benches/ALU/rtl/verilog which was created when you ran
your python config files
NOTE: You do not have to place the DUT RTL code in this this directory. This is merely a
placeholder location for DUT source code but it can reside anywhere on disk.
Original Code
Modified Code
NOTES:
The testbench power up reset signal ‘rst’ is passed in to the agent BFM interfaces. However, the
ALU ‘rst’ pin needs to be driven active either when the power up reset is active or when a
RST_OP transaction is generated by a UVM test/sequence. The ALU ‘rst’ is therefore be driven by
the ALU_in agent. You will modify the ALU_in driver BFM file to implement this in a later step.
— compile.do :
o Remove the compilation lines for the default verilog_dut.v & vhdl_dut.vhd
Original
o Replace with the vlog command to compile the ALU.v source file
Modified
— Makefile
o Modify the source file list from the default verilog_dut.sv to use the alu.v source file
Original Modified
— Windows
– Use the invoke_questa.bat script to compile & load the
testbench
– Check that there are no compile errors
– Check that the ALU (instance name DUT) appears in the
hierarchy of hdl_top
Original Code
Modified Code
NOTES:
The reset op code only drives the ALU reset
pin and is therefore handled separately in it’s
own task.
NOTES:
Any control signals like the ALU reset & valid must be driven at all times New Code
Any data signals like the ALU operator and operands are only driven for specific
cycles and then set back to ‘Z’ values
© Mentor Graphics Corp. Company Confidential
Original Code
Modified Code
NOTES:
• We want to reset the ALU if either the top level reset (rst_i) is active or when a RST_OP operation is received (which drives alu_rst_o low).
So we logically AND the 2 reset driving signals together.
— For any DUT controls that need to be at a defined ‘0’ or ‘1’ value, then we need to add code to reset them
Additional Code
NOTES:
• We add an always block inside the driver bfm that is sensitive to the reset to procedurally assign the
storage signals that are continuously driven onto the pins based on INITIATOR/RESPONDER setting.
• For the ALU we set the valid_o and alu_rst_o signals to 0 when reset is activated
• For the ALU we have to also add an always block to set alu_rst_0 when the external reset is removed.
Original Code
NOTES
This is why we see the ALU_in_transactions are all 4 cycles
long and the displayed data values are just the language type
defaults
Modified Code
NOTES
• Wait until either valid goes high or reset goes active
• Read bus values
• If reset active then wait until reset becomes inactive, then assign
RST_OP code
2. The ALU_out_transactions still have default values since you have not modified the ALU_out_monitor BFM code yet.
Original Code
NOTES
This is why we see the ALU_out_transactions are all 4
cycles long and the displayed ‘result’ data values are just
the language type defaults
Modified Code
NOTES
• Wait until done_i goes high
• Read result value
Modified Code
© Mentor Graphics Corp. Company Confidential
— During the simulation, the scoreboard will generate a message each time it does a compare of the expected data
from the predictor and the actual data from the DUT
— You should see several messages (one for each transaction) similar to the following:
# UVM_INFO
C:/MentorTools/questasim_10.7b/examples/UVM_Framework/UVMF_3.6h/uvmf_base_pkg/src/uvmf_in_order_scoreboard.svh(106) @
2269000: uvm_test_top.environment.ALU_sb [SCBD] MATCH! - EXPECTED: result:0x00fc ACTUAL: result:0x00fc
— The scoreboard will also report a summary of the total number of compares and the number of
MATCHES/MISMATCHES
# UVM_INFO C:/MentorTools/questasim_10.7b/examples/UVM_Framework/UVMF_3.6h/uvmf_base_pkg/src/uvmf_scoreboard_base.svh(234)
@ 6379000: uvm_test_top.environment.ALU_sb [SCBD] SCOREBOARD_RESULTS: PREDICTED_TRANSACTIONS=22 MATCHES=22
MISMATCHES=0
— If you see the above messages, then the predictor and scoreboard are working correctly
Still To Do
— Create a new test & sequence to exercise the RST_OP which is currently not being tested.
— This is due to the constraint we specified back in the YAML config file for the ALU_in interface which only selects
from the following ALU operations.
82 UVMF ALU Tutorial : Step By Step Guide [UVMF 2019.4] Test & Sequence
Creating an interface reset sequence
verification_ip/interface_packages/ALU_in_pkg/src
ALU_in_reset_sequence.svh
interface_packages/ALU_in_pkg/src/ALU_in_random_sequence.svh
2. It randomizes ALU operations, selecting from no_op, add_op, and_op, xor_op & mul_op
83 UVMF ALU Tutorial : Step By Step Guide [UVMF 2019.4] Test & Sequence
Creating an interface reset sequence
verification_ip/interface_packages/ALU_in_pkg/src
ALU_in_reset_sequence.svh
Modified Code
© Mentor Graphics Corp.
Company Confidential
84 UVMF ALU Tutorial : Step By Step Guide [UVMF 2019.4] Test & Sequence
Creating an interface reset sequence
verification_ip/interface_packages/ALU_in_pkg/ALU_in_pkg.sv
STEPS
85 UVMF ALU Tutorial : Step By Step Guide [UVMF 2019.4] Test & Sequence Modified Code
Creating a new bench virtual sequence
project_benches/ALU/tb/sequences/src/ALU_random_sequence.svh
86 UVMF ALU Tutorial : Step By Step Guide [UVMF 2019.4] Test & Sequence
Creating a new bench virtual sequence
project_benches/ALU/tb/sequences/src/ALU_random_sequence.svh
8
New Sequence Code
87 UVMF ALU Tutorial : Step By Step Guide [UVMF 2019.4] Test & Sequence
Creating a new bench level sequence
project_benches/ALU/tb/sequences/ALU_sequence_pkg.sv
STEPS
Modified Code
88 UVMF ALU Tutorial : Step By Step Guide [UVMF 2019.4] Test & Sequence
Adding a New UVM Test
project_benches/ALU/tb/tests/src/ALU_random_test.svh
2. In the build phase, specify a factory override of the default sequence (which is
ALU_bench_sequence_base) to replace it with the new sequence ALU_random_sequence.
New Code
© Mentor Graphics Corp. Company Confidential
89 UVMF ALU Tutorial : Step By Step Guide [UVMF 2019.4] Test & Sequence
Adding a New UVM Test
project_benches/ALU/tb/tests/ALU_tests_pkg.sv
Modified Code
90 UVMF ALU Tutorial : Step By Step Guide [UVMF 2019.4] Test & Sequence
Simulating The New Test
Windows Users
— Edit run.do and modify the modify the last line where +UVM_TESTNAME specifies the test to run
Linux Users
— Execute ‘make debug TEST_NAME=ALU_random_test’