0% found this document useful (0 votes)
216 views

Module 3 Complete Notes

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
216 views

Module 3 Complete Notes

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 123

Module 3

Verification Guidelines and


Data types
Module 3 a

Verification
Guidelines:

The
Randomization, verification
process,

constrained basic test


random bench
stimulus, functionality,

methodology directed
basics, testing,
Module 3 b

Data
Types:
Built in
Data
types,
fixed and
dynamic
arrays,

Queues,
associativ
e arrays,

linked lists,

array
methods,

choosing a
type,
Why was System Verilog created?

. Hardware Verification The donation of the OpenVera


Languages (HVL) such as language formed the basis for
Verilog Hardware Description
OpenVera and e were created. the HVL features of
Language (HDL) became the
Companies that did not want SystemVerilog. Accellera’s goal
most widely used language for
to pay for these tools instead was met in November 2005
describing hardware for
spent hundreds of man-years with the adoption of the IEEE
simulation and synthesis.
creating their own custom standard P1800-2005 for
tools SystemVerilog, IEEE (2005).
Verification Guidelines
chapter introduces a set of guidelines and coding styles
for designing and constructing a test bench that meets
your particular needs.

These techniques use some of the same concepts as shown


in the Verification Methodology Manual for System Verilog
(VMM), Bergeron et al. (2006), but without the base classes
Typical features of an HVL that distinguish it from a
Hardware Description Language such as Verilog or
VHDL are

Tight integration
with event-
Support for HDL simulator for
types such as control of the
Verilog’s 4-state design
especially Object values „
Oriented
Programming „
Multi-threading
Higher-level and inter process
structures, communication „

Constrained-
random
stimulus
generation „
Functional
coverage „
The Verification Process
Is it Find
Bugs ?
Yes No
The Verification Process

A designer reads the hardware specification for a block,


interprets the human language description, and creates the
corresponding logic in a machine-readable form, usually RTL
code

he or she needs to understand the input format, the


transformation function, and the format of the output

As a verification engineer, you must also read the hardware


specification, create the verification plan, and then follow it to
build tests showing the RTL code correctly implements the
features.

What types of bugs are lurking in the design? The easiest ones
to detect are at the block level, in modules created by a single
person.

After the block level, the next place to look for discrepancies is
at boundaries between blocks
The Verification Process

To simulate a single design block, you need to create tests that


generate stimuli from all the surrounding blocks

As you start to integrate design blocks, they can stimulate each other,
reducing your workload. These multiple block simulations may uncover more
bugs, but they also run slower.

At the highest level of the DUT, the entire system is tested, but the simulation
performance is greatly reduced.

Once you have verified that the DUT performs its designated
functions correctly, you need to see how it operates when there are
errors.
Can the design handle a partial transaction, or one with corrupted data or control fields?
Just trying to enumerate all the possible problems is difficult, not to mention how the
design should recover from them. Error injection and handling can be the most challenging
part of verification
The Verification Plan

For a more
complete
discussion on
These steps may verification see
include directed Bergeron (2006).
or random
testing,
assertions, HW/
The verification plan SW co-
is closely tied to the verification,
hardware emulation, formal
specification and
contains a proofs, and use of
description of what verification IP.
features need to be
exercised and the
techniques to be
used.
Basic Test bench Functionality
The purpose of a test bench is to determine the correctness of the design under test (DUT).
This is accomplished by the following steps.

Generate stimulus „

Apply stimulus to the DUT „

Capture the response „

Check for correctness „

Measure progress against the overall verification goals


Directed Testing

The task of verifying the correctness of a


design, you may have used directed tests.

Using this approach, you look at the hardware


specification and write a verification plan with
a list of tests, each of which concentrated on
a set of related features.

Armed with this plan, you write stimulus


vectors that exercise these features in the
DUT.

You then simulate the DUT with these vectors


and manually review the resulting log files
and waveforms to make sure the design does
what you expect.

Once the test works correctly, you check off


the test in the verification plan and move to
the next.

Incremental approach makes steady progress,


Incremental approach makes steady progress,

What if you do not have the necessary time or resources to carry


out the directed testing approach? As you can see, while you
may always be making forward progress, the slope remains the
same. When the design complexity doubles, it takes twice as
long to complete or requires twice as many people. Neither of
these situations is desirable. You need a methodology that finds
bugs faster in order to reach the goal of 100% coverage.
Figure 1-2 shows the total design space and the features that get
covered by directed test cases.
In this space are many features, some of which have bugs. You
need to write tests that cover all the features and find the bugs.
Methodology Basics

„Test-specific
„Constrained- „Layered test code kept
random bench using separate from
stimulus transactors test bench

„Functional „Common test


coverage bench for all
tests

All these principles are related.

Random stimulus is crucial for exercising complex designs.

A directed test finds the bugs you expect to be in the design, while a random test can find bugs
you never anticipated.
All these principles are related. Random stimulus is crucial for exercising complex designs. A directed
test finds the bugs you expect to be in the design, while a random test can find bugs you never
anticipated.

When using random stimulus, you need functional coverage to measure verification progress.

once you start using automatically generated stimulus, you need an automated way to predict the
results, generally a scoreboard or reference model.

A layered testbench helps you control the complexity by breaking the problem into manageable
pieces.

Transactors provide a useful pattern for building these pieces.

With appropriate planning, you can build a testbench infrastructure that can be shared by all tests and
does not have to be continually modified.

You just need to leave “hooks” where the tests can perform certain actions such as shaping the
stimulus and injecting disturbances.
 Building this style of testbench takes longer than a traditional directed testbench,
especially the self-checking portions, causing a delay before the first test can be
run. This gap can cause a manager to panic, so make this effort part of your
schedule.
 In Figure 1-3, you can see the initial delay before the first random test runs.
Constrained-Random Stimulus
Figure 1-4 shows the coverage for constrained-random tests over the total
design space. First, notice that a random test often covers a wider space than
a directed one.

This extra coverage may overlap other tests, or may explore new areas that
you did not anticipate.

If these new areas find a bug, you are in luck! If the new area is not legal, you
need to write more constraints to keep away.

Lastly, you may still have to write a few directed tests to find cases not
covered by any other constrained-random tests.
Figure 1-5 shows
the paths to Start at the upper left
with basic
achieve constrained-random
complete tests.
coverage.

Run them with many


Now you make
different seeds. When
minimal code
you look at the
changes, perhaps
functional coverage
with new constraints,
reports, find the
or injecting errors or
holes, where there
delays into the DUT.
are gaps.
What Should You Randomize?
When you think of randomizing the stimulus to a
design, the first thing that you might think of is the
data fields. This stimulus is the easiest to create –
just call $random.

The problem is that this gives a very low payback in


terms of bugs found.

The primary types of bugs found with random data


are data path errors, perhaps with bit-level
mistakes. You need to find bugs in the control logic.
Device and environment configuration
What is the most common reason why bugs are missed during testing of the RTL design?

Not enough different configurations are tried. Most tests


just use the design as it comes out of reset, or ap
fixed set of initialization vectors to put it into a known state

In a real world environment, the DUT’s configuration becomes more random the longer it

To test this device, the engineer had to write several dozen lines of directed testbench cod
configure each channel.

In the real world, your device operates in an environment containing other components.

When you are verifying the DUT, it is connected to a testbench that mimics this environme

You should randomize the entire environment configuration, including the length of the
simulation, number of devices, and how they are configured.

Of course you need to create constraints to make sure the configuration is legal
Input data

When you read about


random stimulus, you
probably thought of taking a
transaction such as a bus
write or ATM cell and filling
the data fields with random
values.

Actually this approach is


fairly straightforward as long
as you carefully prepare your
transaction classes
Protocol exceptions, errors, and violations
• If something can go wrong in the real hardware, you should
try to simulate it. Look at all the errors that can occur.
• What happens if a bus transaction does not complete?
• If an invalid operation is encountered?
• Does the design specification state that two signals are
mutually exclusive? Drive them both and make sure the
device continues to operate.
• Just as you are trying to provoke the hardware with ill-
formed commands, you should also try to catch these
occurrences.
• For example, recall those mutually exclusive signals. You
should add checker code to look for these violations
• Your code should at least print a warning message when this
occurs, and preferably generate an error and wind down the
test.
Delays and synchronization

 A test that uses the shortest delays runs the fastest, but it won’t
create all possible stimulus. You can create a testbench that talks
to another block at the fastest rate, but subtle bugs are often
revealed when intermittent delays are introduced
 You can create a testbench that talks to another block at the
fastest rate, but subtle bugs are often revealed when
intermittent delays are introduced.
 A block may function correctly for all possible permutations of
stimulus from a single interface, but subtle errors may occur
when data is flowing into multiple inputs.
 . What if the inputs arrive at the fastest possible rate, but the
output is being throttled back to a slower rate? What if stimulus
arrives at multiple inputs concurrently? What if it is staggered
with different delays? Use functional coverage to measure what
combinations have been randomly generated
Parallel random testing

 A random test consists of the testbench code plus a random seed. If you run the
same test 50 times, each with a unique seed, you will get 50 different sets of
stimuli. Running with multiple seeds broadens the coverage of your test and
leverages your work
 You need to plan how to organize your files to handle multiple simulations. Each
job creates a set of output files such as log files and functional coverage data.
You can run each job in a different directory, or you can try to give a unique
name to each file.
Functional Coverage

• The previous sections have shown how to create stimuli that can
randomly walk through the entire space of possible inputs. With
this approach, your testbench visits some areas often, but takes
too long to reach all possible states.
• Unreachable states will never be visited, even given unlimited
simulation time. You need to measure what has been verified in
order to check off items in your verification plan.
• The process of measuring and using functional coverage
consists of several steps.
• First, you add code to the testbench to monitor the stimulus
going into the device, and its reaction and response, to
determine what functionality has been exercised.
• Next, the data from one or more simulations is combined into
a report.
• Lastly, you need to analyze the results and determine how to
create new stimulus to reach untested conditions and logic
Feedback from functional coverage to stimulus

 A random test evolves using feedback. The initial test can


be run with many different seeds, creating many unique
input sequences. Eventually the test, even with a new seed,
is less likely to generate stimulus that reaches areas of the
design space.
 As the functional coverage asymptotically approaches its
limit, you need to change the test to find new approaches
to reach uncovered areas of the design. This is known as
“coverage-driven verification.”
3.8 Testbench Components

21EC71
34
Flat Test Bench

21EC71
3.9 Layered Testbench

21EC71
36
22

21E C 71
Module 3 b

Data
Types:
Built in
Data
types,
fixed and
dynamic
arrays,

Queues,
associativ
e arrays,

linked lists,

array
methods,

choosing a
type,
Data Types
System Verilog offers
many improved data
structures compared with

System Verilog
„Strings: built-in string introduces new data
support types with the following
benefits.

„Classes and structures: „Two-state: better


support for abstract performance, reduced
data structures memory usage

„Queues, dynamic and


associative arrays and
„Unions and packed
automatic storage:
structures: allows multiple
reduced memory usage,
views of the same data
built-in support for
searching and sorting
Built In Data types

Logic

Two State Data


type
System Verilog
improves the classic
reg data type so that it
can be driven by
Logic Data Type
continuous
assignments, gates and
modules, in addition to
being a variable

The one limitation is


that a logic variable
It is given the new
cannot be driven by
name logic so that it
multiple drivers such
does not look like a
as when you are
register declaration.
modelling a
bidirectional bus.
Two-state types

System Verilog introduces several two-state data types to improve


simulator performance and reduce memory usage, over four-state types.
The simplest type is the bit, which is always unsigned.
There are four signed types: byte, shortint, int, and longint.
Unpacked Dynamic
Array Array Array

Declaring Packed
Fixed – array
size
arrays
System Verilog offers much flexibility in
building complicated data structures
through the different types of arrays.
Static Arrays or fixed array
Dynamic Arrays
Associative Arrays
Queues
Fixed Array or static Array
SystemVerilog offers several flavors of arrays beyond the single-dimension,
fixed-size Verilog-1995 arrays.
Many enhancements have been made to these classic arrays.
A static array is one whose size is known before compilation time. In the
example shown below, a static array of 8-bit wide is declared, assigned some
value and iterated over to print its value.

Declaring and initializing fixed-size array


Verilog requires that the low and high array limits must be given in the declaration.
Almost all arrays use a low index of 0, so SystemVerilog lets you use the shortcut of
just giving the array size, similar to C
A static array is one whose size is known before compilation time. In the example shown
below, a static array of 8-bit wide is declared, assigned some value and iterated over to
print its value
Multidimensional Array

You can create multidimensional fixed-size arrays by


specifying the dimensions after the variable name.
This is an unpacked array; packed arrays are shown later.
The following creates several two-dimensional arrays of
integers, 8 entries by 4, and sets the last entry to 1.
A multidimensional packed array is still a set of contiguous bits but are also segmented
into smaller groups
Unpacked Array
If the Array Bounds are declared after variable names its called
Unpacked
An unpacked array is used to refer to dimensions declared after the variable
name.
Unpacked arrays may be fixed-size arrays, dynamic arrays, associative
arrays or queues.
Basic array operations — for and foreach

The most common way to


The System Verilog function $size
manipulate an array is with a for or In Example 2-8, the variable i is returns the size of the array.
foreach loop. declared local to the for loop.

In the for each statement, you specify the


array name and an index in square brackets,
and System Verilog automatically steps
through all the elements of the array. The
index variable is local to the loop
Basic array operations – copy and compare

You can perform aggregate compare and copy of arrays


without loops.
(An aggregate operation works on the entire array as opposed
to working on just an individual element.)
Comparisons are limited to just equality and inequality.
Example 2-11 shows several examples of compares. The ? :
operator is a mini if-statement. Here it is choosing between
two strings.
Bit and word subscripts, together at last

A common annoyance in Verilog-1995 is that you cannot use


word and bit subscripts together. Verilog-2001 removes this
restriction for fixed-size arrays.
Example 2-12 prints the first array element (binary 101), its
lowest bit (1), and the next two higher bits (binary 10
Packed Array

For some data types, you may want both to access the entire
value and also divide it into smaller elements.
For example, you may have a 32-bit register that sometimes
you want to treat as four 8-bit values and at other times as a
single, unsigned value.
A System Verilog packed array is treated as both an array and a
single value. It is stored as a contiguous set of bits with no
unused space, unlike an unpacked array.
A packed array is used to refer to dimensions declared before
the variable name.
A packed array is guaranteed to be represented as a
contiguous set of bits. They can be made of only the single bit
data types like bit, logic, and other recursively packed arrays.
Choosing between packed and unpacked arrays

A packed array is handy if you need to convert to and from


scalars. For example, you might need to reference a memory
as a byte or as a longword.

If you need to wait for a change in an array, you have to use a


packed array. Perhaps your testbench might need to wake up
when a memory changes value, so you want to use the @
operator. But this is only legal with scalar values and packed
arrays.

Using the earlier examples, you can block on the variable lw,
and barray[0], but not the entire array barray unless you
expand it: @(barray[0] or barray[1] or barray[2]).
Dynamic Arrays

A dynamic array is declared


The basic Verilog array type with empty word subscripts
shown so far is known as a []. This means that you do not
fixed-size array, as its size is want to give an array size at
set at compile time compile time; instead, you
specify it at run-time.

The array is initially empty, so If you pass the name of an


you must call the new[] array to the new[] operator,
operator to allocate space, the values are copied into the
passing in the number of new elements.
entries in the square brackets.
Queues
System Verilog introduces a new data type, the queue, which provides easy
searching and sorting in a structure that is as fast as a fixed-size array but as
versatile as a linked list.
Like a dynamic array, queues can grow and shrink, but with a queue you can easily
add and remove elements anywhere.
Example 2-17 adds and removes values from a queue
Queues

When you create a queue,


SystemVerilog actually
allocates extra space so you
Adding deleting elements in can quickly add extra
the middle is slower, elements. Note that you do
especially for larger queues, not need to call the new[]
as SystemVerilog has to shift operator for a queue.
up to half of the elements

It is very efficient to
If you add enough
push and pop elements
elements so that the
from the front and back
queue runs out of space,
of a queue, taking a
SystemVerilog
fixed amount of time no
automatically allocates
matter how large the
additional space.
queue

As a result, you can grow and


shrink a queue without the
performance penalty of a
dynamic array.
A SystemVerilog queue is a First In First Out scheme which can have a variable
size to store elements of the same data type.
It is similar to a one-dimensional unpacked array that grows and shrinks
automatically.
They can also be manipulated by indexing, concatenation and slicing operators.
Queues can be passed to tasks/functions as ref or non-ref arguments.
Types of Queues

A bounded queue has a specific size and can


hold a limited number of entries. Shown below
is a bounded queue of depth N and is full with
N items and cannot accept more.
Methods Description
Returns the number of items
function int size ();
in the queue, 0 if empty

function void insert (input


Inserts the given item at the
integer index, input element_t
specified index position
item);

Deletes the element at the


function void delete ( [input specified index, and if not
integer index] ); provided all elements will be
deleted
function element_t pop_front Removes and returns the first
(); element of the queue
function element_t pop_back Removes and returns the last
(); element of the queue
function void push_front Inserts the given element at
(input element_t item); the front of the queue
function void push_back Inserts the given element at
(input element_t item); the end of the queue
Associative Array

When size of a collection is unknown or the data space is sparse, an


associative array is a better option. Associative arrays do not have any
storage allocated until it is used, and the index expression is not
restricted to integral expressions, but can be of any type.
An associative array implements a look-up table of the elements of its
declared type. The data type to be used as an index serves as the lookup
key and imposes an ordering.
Associative Array
Function Description
Returns the number of entries in the
function int num ();
associative array
Also returns the number of entries, if
function int size ();
empty 0 is returned
index when specified deletes the entry at
function void delete ( [input index] );
that index, else the whole array is deleted
Checks whether an element exists at
function int exists (input index);
specified index; returns 1 if it does, else 0
Assigns to the given index variable the
function int first (ref index); value of the first index; returns 0 for empty
array

Assigns to given index variable the value of


function int last (ref index);
the last index; returns 0 for empty array

Finds the smallest index whose value is


function int next (ref index);
greater than the given index
Finds the largest index whose value is
function int prev (ref index);
smaller than the given index
Example 2-18 shows declaring, initializing, and stepping through an associative array. These
arrays are declared with wildcard syntax [*]. You can remember the syntax by thinking that the
array can be indexed with almost any integer
2.8 Array Methods
There are many array methods that you can use on any unpacked array types:
fixed, dynamic, queue, and associative.
These routines can be as simple as giving the current array size to sorting the
elements.

2.8.1 Array reduction methods


• A basic array reduction method takes an array and reduces it to
a scalar.
• The most common reduction method is sum, which adds
together all the values in an array.
• Be careful of SystemVerilog’s rules for handling the width of
operations.
• By default, if you add the values of a single-bit array, the result
is a single bit.
• But if you store the result in a 32-bit variable or compare it to a
32-bit variable, SystemVerilog uses 32-bits when adding up the
values
2.8.2 Array locator methods
What is the largest value in an array?
Does an array contain a certain value?
The array locator methods find data in an unpacked array.
These methods always return a queue

Example 2-22 uses a fixed-size array, f[6], a dynamic array, d[], and a queue, q[$].
The min and max functions find the smallest and largest elements in an array.
Note that they return a queue, not a scalar as you might expect.
These methods also work for associative arrays.
The unique method returns a queue of the unique values from the array — duplicate values
are not included
You could search through an array using a foreach loop, but
SystemVerilog can do this in one operation with a locator method. The
with expression tells System Verilog how to perform the search.
Method name Description

Returns all elements satisfying the given


find()
expression

Returns the indices of all elements


find_index()
satisfying the given expression

Returns the first element satisfying the


find_first()
given expression

Returns the index of the first element


find_first_index()
satisfying the given expression

Returns the last element satisfying the


find_last()
given expression

Returns the index of the last element


find_last_index()
satisfying the given expression
Methods Description
Returns the element with
minimum value or whose
min()
expression evaluates to a
minimum
Returns the element with
maximum value or whose
max()
expression evaluates to a
maximum
Returns all elements with
unique values or whose
unique()
expression evaluates to a
unique value
Returns the indices of all
elements with unique values
unique_index()
or whose expression
evaluates to a unique value
Method Description
Reverses the order of
reverse()
elements in the array
Sorts the array in ascending
sort() order, optionally
using with clause
Sorts the array in descending
rsort() order, optionally
using with clause
Randomizes the order of the
elements in the
shuffle()
array. with clause is not
allowed here.
Array Ordering
Methods Examples
Array Reduction Methods
Method Description
Returns the sum of all array
sum()
elements
Returns the product of all
product()
array elements
Returns the bitwise AND (&)
and()
of all array elements
Returns the bitwise OR (|) of
or()
all array elements
Returns the bitwise XOR (^)
xor()
of all array elements
2.9 Choosing a Storage Type
Here are some guidelines for choosing the right storage type
based on
 flexibility,
 memory usage,
 speed, and sorting.
These are just rules of thumb, and results may vary between
simulators.
2.9.1 Flexibility
• Use a fixed-size or dynamic array if it is accessed with consecutive positive
integer indices: 0, 1, 2, 3…
• Choose a fixed-size array if the array size is known at compile time, or choose
a dynamic array if the size is not known until run-time
• If you are writing routines to manipulate arrays, consider using just dynamic
arrays, as one routine will works for any size dynamic array as long as the
element type (int, string, etc.) matches
• Associative arrays can also be passed regardless of size. However, a routine
with a fixed-size array argument only accepts arrays of the specified length.
• Associative arrays can also be used to model content-addressable memories.
• Queues are a good way to store data where the number of elements grows
and shrinks a lot during simulation, such as a scoreboard that holds expected
values. Lastly, queues are great for searching and sorting.
2.9.2 Memory usage

• If you want to reduce the simulation memory usage, use two-


state elements.
• You should chose data sizes that are multiples of 32 bits to
avoid wasted space.
• Simulators usually store anything smaller in a 32-bit word
• For arrays that hold up to a thousand elements, the type of
array that you choose does not make a big difference in
memory usage
• Queues are slightly less efficient to access than fixed-size or
dynamic arrays because of additional pointers.
• Modeling memories larger than a few megabytes should be
done with an associative array. Note that each element in an
associative array can take several times more memory than a
fixed-size or dynamic memory because of pointer overhead
2.9.3 Speed

Choose your array type based on how many times it is accessed per clock cycle.
For only a few reads and writes, you could use any type, as the overhead is
minor compared with the DUT.
Fixed-size and dynamic arrays are stored in contiguous memory, so any element
can be found in the same amount of time, regardless of array size.
If you need to insert new elements into a large queue, your testbench may slow
down, so consider changing how you store new elements.
When reading and writing associative arrays, the simulator must search for the
element in memory.
The LRM does not specify how this is done, but popular ways are hash tables
and trees. These requires more computation than other arrays, and therefore
associative arrays are the slowest.
2.9.4 Sorting

• System Verilog can sort any single-dimension array (fixed-


size, dynamic, and associative arrays plus queues), you
should pick based on how often the data is added to the
array.
• If the data is received all at once, chose a fixed-size or
dynamic array so that you only have to allocate the array
once.
• If the data slowly dribbles in, chose a queue, as adding
new elements to the head or tail is very efficient
• Using the routines first, next, and prev, you can search an
associative array for a value and find successive values.
2.9.5 Choosing the best data structure
Here are some suggestions on choosing a data structure

Network packets. Properties: fixed size, accessed sequentially. Use a


fixed-size or dynamic array for fixed- or variable-size packets.
Scoreboard of expected values. Properties: variable size, accessed by value
Sorted structures. Use a queue if the data comes out in a predictable
order or an associative array if the order is unspecified.
Modelling very large memories, greater than a million entries. If you do not
need every location, use an associative array as a sparse memory.
Command names and values from a file.
Property: lookup by string. Read the strings from the file, and then look up
the commands in an associative array using the command as a string index
2.10 Creating New Types with typedef
You can create new types using the typedef statement.
For example, you may have an ALU that can be configured at compile-time to use on
8, 16, 24, or 32-bit operands. In Verilog you would define a macro for the operand
width and another for the type
Creating New Types with typedef

In complex testbenches some variable declarations might have


a longer data-type specification or require to be used in
multiple places in the testbench.
In such cases we can use a typedef to give a user-defined name
to an existing data type. The new data-type can then be used
throughout the code and hence avoids the need to edit in
multiple places if required.
Examples Creating New Types with typedef
2.11 Creating User-Defined Structures

One of the biggest limitations of Verilog is the lack of data


structures.
In SystemVerilog you can create a structure using the struct
statement, similar to what is available in C.
But a struct is a degenerate class, so use a class instead,
A typedef just groups data fields together. Without the code
that manipulates the data, you are only creating half of the
solution.
There are several places where a typedef is useful: creating
simple userdefined types, unions, and enumerated types and
virtual interfaces.
2.11.1 Creating a struct and a new type

You can combine several variables into a structure.


Example 2-27 creates a structure called pixel that has three unsigned bytes for red,
green, and blue.
2.11.2 Making a union of several types

In hardware, the interpretation of a set of bits in a register may depend on the value
of other bits.

Use the suffix “_u” when declaring a union

Unions are useful when you frequently need to read and write a
register in several different formats.
However, don’t go overboard, especially just to save memory.
Unions may help squeeze a few bytes out of a structure, but at the
expense of having to create and maintain a more complicated data
structure
2.11.3 Packed structures

• A packed structure is stored as a contiguous set of bits with no unused


space.
• The struct for a pixel, shown above, used three data values, so it is
stored in three longwords, even though it only needs three bytes. You
can specify that it should be packed into the smallest possible space

• Packed structures are used when the underlying bits represent a


numerical value, or when you are trying to reduce memory usage.
• For example, you could pack together several bit-fields to make a single
register. Or you might pack together the opcode and operand fields to
make a value that contains an entire processor instruction.
2.12 Enumerated Types

An enumeration creates a strong variable type that is limited to a set of specified names such as
the instruction opcodes or state machine values.
Using these names, such as ADD, MOVE, or ROTW, makes your code easier to write and maintain
than using literals such as 8’h01.
The simplest enumerated type declaration contains a list of constant names and one or more
variables. This creates an anonymous enumerated type.

Enumerated
types are stored
as int unless you
specify
otherwise. .
Be careful when
assigning values
to enumerated
constants, as
the default
value of an int is
2.13 Constants

 In SystemVerilog, parameters can be declared at the $root level so they


can be global. This approach can replace many Verilog macros that were
just being used as constants.
 You can use a typedef to replace those clunky macros. The next choice is
a parameter. A Verilog parameter was loosely typed and was limited in
scope to a single module.
 SystemVerilog also supports the const modifier that allows you to make a
variable that can be initialized in the declaration but not written by
procedural code.
 Types of Contants parameter, localparam, specparam, type parameter,
and const constants.
Localparam Constants in Verilog and
SystemVerilog

 Localparam constants are constants that cannot be modified by defparam statements or instance
parameter value assignments.
 They are defined using the localparam keyword followed by the name and value of the constant.
 Localparam constants are helpful when you need to set a value that should not be altered by the
user.
 For instance, consider the following code that defines a Memory module with a parameter
named EntryNum and a localparam named AddrWidth.
 The localparam is utilized to set the width of the address bus based on the value of
the EntryNum parameter, which should be calculated, and the user should not modify it.
Specparam Constants in Verilog and SystemVerilog

• Specparam constants are used to provide timing and delay values for
Verilog and SystemVerilog simulations.
• They are declared within a module or a specify block and are used
to override the timing and delay values.
• Specparam constants are defined using the specparam keyword
followed by the name and value of the constant.
2.14 Strings

 The SystemVerilog string type holds variable-length strings. An


individual character is of type byte. The elements of a string of length
N are numbered 0 to N-1.
 Note that, unlike C, there is no null character at the end of a string,
and any attempt to use the character “\0” is ignored.
 Strings use dynamic memory allocation, so you do not have to worry
about running out of space to store the string

The string data-type is an ordered collection of characters. The length of


a string variable is the number of characters in the collection which can have
dynamic length and vary during the course of a simulation. A string variable does
not represent a string in the same way as a string literal. No truncation occurs
when using the string variable.
How are strings Represented
A single ASCII character requires 8-bits (1 byte) and to store a string we would need as
many bytes as there are number of characters in the string.
String Operators

Semantics
Operator
Returns 1 if the two strings are
Equality Str1 == Str2
equal and 0 if they are not
Returns 1 if the two strings are not
Inequality Str1 != Str2
equal and 0 if they are
Str1 < Str2
Str1 <= Str2 Returns 1 if the correspondig
Comparison
Str1 > Str2 condition is true and 0 if false
Str1 >= Str2
{Str1, Str2, ..., All strings will be concatenated into
Concatenation
StrN} one resultant string
Replicates the string N number of
Replication {multiplier{Str}} times, where N is specified by the
multiplier
Returns a byte, the ASCII code at
Indexing Str[index] the given index. If given index is
out of range, it returns 0
The dot(.) operator is used to call
Methods Str.method([args])
string functions
Basic String Methods
SystemVerilog also includes a number of special methods to work with strings,
which use built-in method notation.
Usage Definition Comments

Returns the number of


str.len() function int len()
characters in the string

Replaces the ith character in the


str.putc() function void putc (int i, byte c);
string with the given character

Returns the ASCII code of the


str.getc() function byte getc (int i);
ith character in str

Returns a string with characters


str.tolower() function string tolower();
in str converted to lowercase

Compares str and s, as in the


str.compare(s) function int compare (string s);
ANSI C strcmp function

Compares str and s, like the ANSI


str.icompare(s) function int icompare (string s);
C strcmp function

Returns a new string that is a


str.substr (i, j) function string substr (int i, int j); substring formed by characters
in position i through j of str
Example 2-39 shows various string operations.
• The function getc(N) returns the byte at location N, while toupper returns
an upper-case copy of the string and tolower returns a lowercase copy.
• The curly braces {} are used for concatenation.
• The task putc(M) writes a byte into a string at location M, that must be
between 0 and the length as given by len.
• The substr(start,end) function extracts characters from location start to end
Previous Year VTU Questions
1. Explain the verification process of system Verilog. (10 Marks)
2. Explain the different phases of simulation. (10 Marks)
3. Explain different types of array methods used in unpacked
arrays. (10 Marks)
4. Discuss the guidelines associated to choose a storage type. (10
Marks)
5. Explain the factors in randomizing the stimulus to design (10M)
6. Describe the various array methods with examples (10M)
7. Write a Short note on User defined Data types with examples
(10M)
8. Explain the Constants and Strings in System Verilog with
examples (10M)

You might also like