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

System Verilog I

The document discusses the evolution of verification languages from Verilog to SystemVerilog. It describes how SystemVerilog addressed limitations in Verilog for verification by adding capabilities for object-oriented programming, extended data types, and assertions. It also explains the components of a SystemVerilog testbench and how they work together to verify a design.

Uploaded by

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

System Verilog I

The document discusses the evolution of verification languages from Verilog to SystemVerilog. It describes how SystemVerilog addressed limitations in Verilog for verification by adding capabilities for object-oriented programming, extended data types, and assertions. It also explains the components of a SystemVerilog testbench and how they work together to verify a design.

Uploaded by

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

1

• In the late 1990s, the Verilog Hardware Description Language (HDL) became the most
widely used language for describing hardware for simulation and synthesis.
• The first two versions standardized by the IEEE (1364-1995 and 1364- 2001) had only
simple constructs for creating tests.
• As design sizes outgrew a productivity crisis happened.
• Companies spent hundreds of man-years creating their own custom verification tools.
• As an initiative, a consortium of EDA companies and users created an entity called
Accellera with the purpose to create the next generation of Verilog with verification
capabilities.
• This effort led to the adoption of the IEEE standard P1800-2005 for SystemVerilog,
IEEE (2005).

2
• Verification is generally viewed as a fundamentally different activity from design.
• This split has led to dividing engineers into two groups, one specialized in design, and
the other specialized in verification, and this created bottlenecks in communication
between them.
• SystemVerilog being both a design language, and a verification language at the same
time improved the communication bottlenecks, enabling both the design and verification
engineers to work together to identify and fix problems.
• SystemVerilog is based on the Verilog constructs that engineers have used for decades.
• SystemVerilog enables designers, who understand the inner workings of their blocks, to
write assertions about it. At the same time it allows verification engineers, who may have
a broader view, to create assertions between blocks.
• The value of an HVL (Hardware Verification Language) is its ability to create high level,
flexible tests.

3
• The purpose of a testbench 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
• Some steps are accomplished automatically by the testbench, while others are manually
determined by you. The methodology you choose determines how the preceding steps
are carried out.

4
5
• Generator: Generates different input stimulus to test the DUT. These signals can be
predetermined or generated randomly to cover various design features.
• Interface: Contains design signals that can be driven or monitored. It allows engineers to
monitor and debug the behavior of he DUT and the testbench during testing.
• Driver: The driver is a component responsible for applying input signals or stimuli to the
device under test (DUT). The driver ensures that the DUT receives the appropriate inputs
for testing its functionality.
• Monitor: The monitor, observes or monitors the outputs of the DUT during the test
execution. It captures the output responses produced by the DUT in response to the input
stimuli applied by the driver.
• Scoreboard: The scoreboard maintains a record of expected values for various signals or
outputs based on the input stimuli provided to the device under test (DUT). As the
simulation or testing progresses, the scoreboard compares the actual outputs produced by
the DUT with the expected values.
If there is a mismatch between the expected and actual results, the scoreboard flags an
error, indicating a potential issue in the hardware design or test environment.
This helps verification engineers identify and debug problems more efficiently, ensuring
the correctness and reliability of the hardware system.
• Environment: Contains all the verification components mentioned above
• Test: Contains the environment that can be tweaked with different configuration settings
• All these components will be implemented using SystemVerilog.

6
• Datatypes in Verilog are not sufficient to develop efficient testbenches and testcases.
Hence SystemVerilog has extended Verilog by adding more data-types for better
encapsulation and compactness.

7
• So what are the 4 states mentioned above ?
• 0: variable/net is at 0 volts
• 1: variable/net is at some value > 0.7 volts
• x: or X: variable/net has either 0/1 - we just don't know
• z or Z: net has high impedance - may be the wire is not connected and is floating.

8
• The one thing in verilog that always leaves new users scratching their heads is the
difference between a reg and a wire.
• When driving a port, which should you use? How about when you are connecting
blocks?
 reg <= reg or wire (non-blocking assignment)
 reg = reg or wire (blocking assignment)
 assign wire = reg or wire (continuous)
• System Verilog improves the classic reg data type so that it can be driven by continuous
assignments, gates, and modules, in addition to being a variable. It is given the synonym
logic so that it does not look like a register declaration.
• A logic type is a 4-state type (1,0,x,z)
• A logic signal can be used anywhere a net is used,
• A logic variable cannot be driven by multiple structural drivers, such as when you are
modeling a bidirectional bus. In this case, the variable needs to be a net-type such as wire
so that System Verilog can resolve the multiple values to determine the final value.
• Names are case sensitive so CYCLE is the same is cycle
• Sometimes the waveform is not displayed due to the popup blocker. (Settings -> Privacy
& Security -> Site Settings -> Pop-ups & Redirects -> add edaplayground.com to
Allowed to send pop-ups

9
• System Verilog introduces several 2-state data types to improve simulator
performance and reduce memory usage compared with variables declared as 4-
state types.
• The simplest type is the bit , which is always unsigned. There are four signed 2-
state types: byte, shortint, int, and longint.

• byte versus logic [7: 0]:


You may think, why should I write logic [7: 0], while I can simply write byte to
declare signals?
You should be careful as these new types are signed variables, and so a byte
variable can only count up to 127, not the 255 as you may think.
Signed variables can cause unexpected results with randomization, as will be
discussed later.
• From the figure note the following:
 Uninitialized 2-state signals are set to 0, while 4-state signals are set to x.
 In line 18, b32 is set to (a5bfx1z7)16 but in the waveform it is (a5bf0107)16
that is because 2-state type can take only the 2 values; 1 or 0.
 In line 19, s is set to (80,000)10 but s is of type shortint which is only 16
bits long, so the range of values it can represent is (– 215 to 215 – 1) i.e.
(–32768 to 32767), so only the least 16 bits are taken.
(80000)10 = (1 0011 1000 1000 000)2 that is why in the waveform we see
(0011 1000 1000 000)2 which is (3880)16.

10
• Datatypes in Verilog are not sufficient to develop efficient
testbenches and testcases. Hence SystemVerilog has extended Verilog
by adding more data-types for better encapsulation and compactness.

11
• SystemVerilog offers several flavors of arrays beyond the single-dimension,
fixed size Verilog-1995 arrays, as many enhancements have been made to these
classic arrays.
• Verilog requires that the low and high array limits must be given in the
declaration. Since almost all arrays use a low index of 0, SystemVerilog lets you
use the shortcut of just giving the array size, which is similar to C’s style.
• You can create multidimensional fixed-size arrays by specifying the dimensions
after the variable name. Multidimensional arrays were introduced in Verilog-
2001, but the compact declaration style is new.
• If your code accidently tries to read from an out-of-bounds address,
SystemVerilog will return the default value for the array element type:
 That just means that an array of 4-state types, such as logic, will return X’s.
 whereas an array of 2-state types, such as int or bit, will return 0.
This applies also if your address has an X or Z.

12
• You can initialize an array using an array literal, which is an apostrophe followed
by the values in curly braces. ‘{}
 You can set some or all elements at once.
 You are able to replicate values by putting a count before the curly braces.
 Lastly, you might specify a default value for any element that does not have
an explicit value.

13
• The most common way to manipulate an array is with a for or foreach loop.
• The SystemVerilog function $size returns the size of the array.
• In the foreach-loop, you specify the array name and an index in square brackets,
and SystemVerilog automatically steps through all the elements of the array. The
index variable is automatically declared for you and is local to the loop.

14
• Note that using foreach for a two-dimensional array, it must be written as
follows: array_name[i,j], not array_name[i][j].
• In the normal use of the multi-dimensional array, each index must be written in a
separate pair of square brackets. i.e. array_name[i][j].

15
• 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.
• In line 15, line 18, The “? :” conditional operator is a mini if-statement. In the
above code it is used to choose between two strings.
• The final compare uses an array slice, src[1:4], which creates a temporary array
with four elements.
• You cannot perform aggregate arithmetic operations such as addition on arrays.
Instead, you can use loops. For logical operations such as xor, you have to either
use a loop or use packed arrays as we will see later.

16
• A common annoyance in Verilog-1995 is that you cannot use array and bit
subscripts together.
• Verilog-2001 removes this restriction for fixed-size arrays.
• The above code prints the first array element (binary 101), its lowest bit (1), and
the next two higher bits (binary 10).
• Although this change is not new to SystemVerilog, many users may not know
about this useful improvement in Verilog-2001
• Remarks:
 Note that $displayb is used to display in binary format.
 Not that you can use two comas “, ,” in the arguments of the display function
to leave a blank space.

17
• A fixed-size array, has its size set a priori. What if the size of the array isn’t known yet?
• For example, you may want to generate a random number of transactions at the start of simulation. If
you stored the transactions in an fixed-size array, it would have to be large enough to hold the
maximum number of transactions, but would typically hold fewer transactions, thus wasting memory.
• A dynamic array can be allocated and resized during simulation, so your simulation will consume a
minimal amount of memory.
• A dynamic array is declared with empty word square brackets [ ] (see line 2). This means that you do
not specify the array size in advance; instead, you give it at run-time.
• The array is initially empty, and so you must call the new[ ] constructor to allocate space, passing in the
number of entries in the square brackets.
• When you copy a fixed-size array to a dynamic array, SystemVerilog calls the new[ ] constructor to
allocate space, and then copies the values.
 Line A calls new[5] to allocate 5 array elements.
 Line B sets the value of each element of the array to its index value.
 Line C allocates another array and copies the contents of dyn into it.
 Lines D and E show that the arrays dyn and d2 are separate.
 Line F allocates 20 new elements, and copies the existing 5 elements of dyn to the beginning of the
array. The old 5-element array is deallocated. The result is that dyn points to a 20-element array.
 Line G allocates 40 elements, but the existing values are not copied. The old 20-element array is
deallocated.
 Finally, line H deletes the dyn array.
 The $size function returns the size of an array. Dynamic arrays have several built-in routines, such
as delete and size.

18
• Unlike a regular array, where the indices are integers, (e.g dyn[3]), associative
arrays allow any data type to be used as the index.
• In SystemVerilog, an associative array is a data structure that associates a unique
key with a value.
• An associative array is declared with a data type in square brackets, such as
[string].
• In the shown example, scoreboard is an associative array where strings are used
as keys, and integers are used as values. The keys “alu", “ecu", “storage”, and
“cpu" are associated with the values 10, 50, 100, and 150 respectively.
• The foreach loop iterates through each key-value pair in the associative array,
displaying the key and its corresponding value.

19
• Dynamic arrays are good if you want to occasionally create a big array, but what
if you want something really large?
• Perhaps you are modeling a processor that has a multi-gigabyte address range.
• During a typical test, the processor may only touch a few hundred or thousand
memory locations, so allocating and initializing gigabytes of storage is wasteful.
• Associative arrays that store entries in a sparse matrix. This means that while you
can address a very large address space, SystemVerilog only allocates memory for
an element when you write to it.
• In the shown figure, the associative array holds values in locations 0, 3, 42, 1000,
4521, and 200,000. The memory used to store these is far less than would be
needed to store a fixed or dynamic array with 200,000 entries.

20
• The shown code shows declaring, initializing, and stepping through an
associative array.
• In the above code we have an associative array, “assoc”, with very scattered
elements: 1, 2, 4, 8, 16, etc.
• A simple for-loop cannot step through them; you need to use a foreach loop.

21
• If you want finer control, you can use the first and next functions in a do...while
loop. These functions modify the index argument, and return 0 or 1 depending on
whether any elements are left in the array.
• Used methods in the above code: first(<index>), next(<index>),
delete(<index>).

22
• Associative arrays can also be addressed with a string index, similar to Perl’s
hash arrays.
• The above code reads a file with strings and builds the associative array so that
you can quickly map from a string value to a number.
• Strings are explained later. You can use the function exists() to check if an
element exists.
• If you try to read an element that has not been written, SystemVerilog returns the
default value for the array type, such as 0 for 2- state types, or X for 4-state
types.
• Used methods in the above code: exists(<index>).

23
• SystemVerilog introduces a new data type, the queue, which combines the best
of a linked lists and arrays.
• Like a linked list, you can add or remove elements anywhere in a queue, without
the performance hit of a dynamic array that has to allocate a new array and copy
the entire contents.
• Like an array, you can directly access any element with an index, without linked
list’s overhead of stepping through the preceding elements.
• A queue is declared with square brackets containing a dollar sign: [$].
• The code above shows how you can add and remove values from a queue using
methods.
• Note that queue literals only have curly braces, and are missing the initial
apostrophe of array literals.
• If you add enough elements that the queue runs out of that extra space,
SystemVerilog automatically allocates more. As a result, you can grow and
shrink a queue without the performance penalty of a dynamic array, and
SystemVerilog keeps track of the free space for you.
• Note that you never call the new[ ] constructor for a queue.
• Used methods in the above code: insert(<index>,<value>), delete(<index>),
delete(), push_front(<value>), push_back(<value>), pop_front(<value>),
pop_back(<value>),

24
• You can use concatenation instead of methods.
• As a shortcut, if you put a $ on the left side of a range, such as [$:2], the $ stands
for the minimum value, [0:2].
• If you put $ on the right side, as in [1:$], stands for the maximum value, [1:2], in
first line of the initial block shown above.
• The queue elements are stored in contiguous locations, and so it is efficient to
push and pop elements from the front and back. This takes a fixed amount of
time no matter how large the queue.
• Adding and deleting elements in the middle of a queue requires shifting the
existing data to make room. The time to do this grows linearly with the size of
the queue.
• You can also copy the contents of a fixed or dynamic array into a queue.

25
• System Verilog provides a linked list data-structure.
• Now that you know there is a linked list in SystemVerilog, avoid using it.
• SystemVerilog's queues are more efficient and easier to use.

26
• 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 or as
complex as sorting the elements.

27
• A basic array reduction method takes an array and reduces it to a single value.
• 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.
• However, if you use the proper with expression, System Verilog uses 32-bits
when adding up the values. The with expression is described in full details later.
• Other array reduction methods are product, and, or, and xor.

28
• The code above shows various ways to total up a subset of the values in the
array.
• When you combine an array reduction such as sum using the with clause, the
results may surprise you.
• The sum operator totals the number of times that the expression is true. For the
first statement there are two array elements that are greater than 7 (9 and 8) and
so count is set to 2.
• The first total compares the item with 7. This relational returns a 1 (true) or 0
(false) and multiplies this with the array. So the sum of {9,0,8,0,0,0} is 17.
• The second total is computed using the ? : conditional operator.

29
• 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.
• The shown code 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.

30
• You could search through an array using a foreach-loop.
• SystemVerilog can do this in one operation with a locator method.
• The with expression tells SystemVerilog how to perform the search, as shown
above.
• In a with clause, the name item is called the iterator argument and represents a
single element of the array.
• You can specify your own name by putting it in the argument list of the array
method. For example:
tq = d.find_first(x) with (x>4);

• The array locator methods that return an index, such as find_index, return a
queue of type int, not integer. Your code may not compile if you use the wrong
queue type with these statements.

31
• SystemVerilog has several methods for changing the order of elements in an
array.
• You can sort the elements, reverse their order, or shuffle the order.
• Notice that these methods change the original array, unlike the array locator
methods which create a queue to hold the results.

32
• The array locator methods can be used to build a scoreboard.
• Here we define a packet structure, then create a scoreboard made from a queue
of these structures.
• Note that in defining struct, we use “;” to separate the different items. Even the
last item has a “;” after it inside the curly braces “}”.
• The check_addr () function looks up an address in the scoreboard.
• The find_index () method returns an int queue.
• If the queue is empty (size==0), no match was found.
• If the queue has one member (size== 1), a single match was found, which the
check_addr () function deletes.
• If the queue has multiple members (size > 1), there are multiple packets in the
scoreboard whose address matches the requested one.

33

You might also like