Dr. Ambar Sarkar, Chief Verification Technologist, Paradigm Works Inc.
Let’s start with a quick and easy quiz.
Imagine you are verifying a NxN switch where N is configurable, and it supports any configuration from 1×1 to NxN. Assume that for each port, you instantiate one set of verification components such as monitors, bfms, scoreboards. For example, if this was a PCIe switch with 2 ingress and 3 egress ports, you would instantiate 2 ingress and 3 egress instances of PCIe verification components. So, for N = 5, how many environments you should actually write code for and maintain?
The answer better be 1 J™. Maintaining NxN = 25 distinct environments will be quixotic at best. What you want is to write code that creates the desired number and configurations of component instances based on some runtime parameters. This is an example of what is known as “structural” configuration, where you are configuring the structure of your environment.
In VMM1.2 parlance, this means that you want to make sure you can communicate to your build_ph() phase the required number of ingress and egress verification component instances. The build phase can then construct the configured number of components. This way, you get to reuse your verification environment code in multiple topologies, and reduce the number of unique environments that need to be separately created and maintained.
Hopefully, this establishes why structural configuration is important. So the questions that arise next are:
How do you declare the structural configuration parameters?
How do you specify the structural configuration values?
How do you use the structural configuration values in your code?
Declaring the configurable parameters
Structural configuration declarations should sit in a class that derives from vmm_unit. A set of convenient macros are provided, with the prefix `vmm_unit_config_xxx where xxx stands for the data type of the parameter. For now, xxx can be int, boolean, or string.
For example, for integer parameters, you have:
<name of the int data member>,
<describe the purpose of this parameter>,
<name of the enclosing class derived from vmm unit>
If you want to declare the number of ports as configurable, you can declare a variable num_ports as shown below:class switch_env extends vmm_group;
int num_ports; // Will be configured at runtime
vip bfm[$]; // Will need to create num_port number of instances
function new(string inst, vmm_unit parent = null);
super.new(get_typename(), inst, parent); // NEVER FORGET THIS!!
// Declare the number of ingress ports. Default is 1.
`vmm_unit_config_int(num_ports,”Number of ingress ports”, 1, switch_env);
Specifying the configuration values
There are two main options:
1. From code using vmm_opts.
The basic rule is that you need to specify it *before* the build phase gets called, where the construction of the components take place. A good place to do so is in vmm_test::set_config().
// Override default with 4. my_env is an instance of switch_env class.
2. From command line or external option file. Here is how the number of ingress ports could be set to 5.
The command line supersedes option set within code as shown in 1.
Do note that one can specify these options for specific instances or hierarchically using regular expressions.
Using the configuration values
This is the easy part. As long as you declare the parameter using `vmm_unit_config_xxx , you are all set. It will be set to the correct value when the containing object derived from vmm_unit is created.
function switch_env::build_ph(); ?
// Just use the value of num_ports
for (i = 0; i< num_ports; i++) begin
bfm[i] = new ($psprintf(“bfm%0d”, i), this);
This article is the 6th in the Verification in the trenches series. Hope you found this article useful. If you would like to hear about any other related topic, please comment or drop me a line at firstname.lastname@example.org. Also, if you are starting out fresh, please check out the free VMM1.2 environment generator at http://resourceworks.paradigm-works.com/svftg/vmm .