Use Systemverilog enum for better code abstraction
Usually, when talking about enum, we might just think that enumeration in Systemverilog is for improving readability. However, by using enumeration, we can replace any strong-typed value with enum type. Thus, it will be easier for update the strong-typed value later, making the code more abstract. In this post, let’s look at examples where using the enumeration can simplify the modification steps when the requirements of the environment changed.
Basic of Systemverilog enumeration
Define an enum type
Let take an example of defining an enum type represent the index of each UART module instances in the env.
Some important points from the above example:
- If we do not define the explicit type, the default data type for an enum constant is
integer
. - We can use range to define an enum and it’s very helpful when using with compiler directive as the above example.
- By default, the first enum name constant will be assign to the value of
0
, but we can override that default, as in the example, the initial value is1
.
Enum methods
Systemverilog enumeration provide a useful set of methods as below:
first()
: returns the value of the first member of the enumeration.last()
: returns the value of the last member of the enumeration.next()
: returns the next enumeration value.prev()
: returns the previous enumeration value.num()
: returns the number of elements in the given enumeration.name()
: returns the string representation of the given enumeration label.
We can not call these functions directly on an enum type, but on the variable has it’s type as an enum.
Iterating through an enum
Now with all of the supported methods, we can iterate through all the label in an enum.
Let’s look at an example below. Assuming we have the base address of each UART instances, and we want to create an associative array using ip_idx_e
as index, and the value is the base address of each UART module instances. Also, the range of address of each uart instance will be 16'h100
.
Enumeration examples
Creating associative array of base addresses
Let’s look at the associative array with enum as index example in above section.
- Assuming that the design has been changed, instead of 4 UARTs, the SoC now supports up to 10 UART instances, and we need to update the associative array of base addresses (in the above example).
- All we need to update in this case is the compiler directive
NUM_OF_UART
, theip_idx_e
enum will automatically have constant label fromUART1
toUART10
, thus expected associative array of base addresses is created.
Constructing configure obj for each ip instances
For this example, let’s assume that we’re creating an uvm env with several different types of ip. Each of those ip instances will need a configuration object, and provided with a base address of that instance.
- In this example, we will create an enum of base address directly.
- We will use
uvm_pkg::uvm_re_match()
to perform string pattern matching. - Assuming we already have these cfg class
uart_cfg
,spi_cfg
andi2c_cfg
. And these class are extended formbase_cfg
class. - Also this
base_cfg
will haveadd_base_address()
method to add the base address of ip instance.
- The
uvm_re_match()
is actually a DPI-C function. It will return 0 if the input string matches the pattern. - Instead of using
base_cfg m_cfg_obj[$]
, we can create an associative array as the first example to store the configuration object.
Benefit of using enumeration
As those above examples, by using the enumeration, we can easily update the environment when the design specification updated.
- In the first example, if the number of UART instances is changed, we just need to update the compiler directive
NUM_OF_UART
. - In the second example, when either the number of UART/SPI/I2C instances or the base address of those ip instances changed, we just need to update the
ip_base_addr_e
enum.
Thus, it’s a good practice to put all compiler directive and enum in one file, so that when the environment need to update, we just need modify that file only.
Finding more information
To have more understanding as well as more examples, you can check the IEEE Standard for Systemverilog, chapter.6.19 Enumeration.
[Tags
systemverilog
]