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

AVLSI_MODULE4

Uploaded by

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

AVLSI_MODULE4

Uploaded by

parvati.patil
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 93

Module-4

• Procedural Statements and Routines


• Procedural statements,
• Tasks, Functions and void functions,
• Task and function overview,
• Routine arguments,
• returning from a routine,
• Local data storage,
• time values.
• Connecting the test bench and design:
• Separating the test bench and design,
• The interface construct,
• Stimulus timing,
• Interface driving and sampling,
• System Verilog assertions.
• As you verify your design,you need to write a great deal of code,
most of which is in tasks and functions.

• System Verilog introduces many incremental improvements to make


this easier by making the language look more like C especially around
argument passing.
3.1 Procedural Statements
• SystemVerilog adopts many operators and statements from C and C++.
• You can declare a loop variable inside a for-loop that then restricts the
scope of the loop variable and can prevent some coding bugs.
• The auto-increment + + and auto-decrement -- operators are available
in both pre- and post-forms.
• If you have a label on a begin or fork statement, you can put the same
label on the matching end or join statement.
• This makes it easier to match the start and finish of a block.
• You can also put a label on other SystemVerilog end statements such
as endmodule. endtask. end function.
• SampIe 3.1 demonstrates some of the new constructs.
do while loop
• A do while loop is a control flow statement that allows code to be
executed repeatedly based on a given condition.
• do while loop syntax

In do-while,

•the condition will be checked after the execution of statements inside the
loop
•the condition can be any expression.
do-while is similar to while loop but in case of while loop execution of statements happens
only if the condition is true. In a do while, statements inside the loop will be executed at least
once even if the condition is not satisfied.
do while loop example
while loop SystemVerilog

• A while loop is a control flow statement that allows code to be


executed repeatedly based on a given condition.
• while loop syntax
In a while,
•Execution of statements within the loop happens
only if the condition is true

In do-while,

•the condition will be checked after the execution of


statements inside the loop
•the condition can be any expression.
while loop example
SystemVerilog foreach loop

• SystemVerilog foreach specifies iteration over the elements of an


array. the loop variable is considered based on elements of an array
and the number of loop variables must match the dimensions of an
array.
• foreach loop syntax

Foreach loop iterates through each index


starting from index 0.
foreach loop example
foreach multidimensional array
SystemVerilog For loop

• SystemVerilog for loop allows,


• declaration of a loop variable within the for loop
• one or more initial declaration or assignment within the for loop
• one or more step assignment or modifier within the for loop
• for loop syntax

Initialization: executed first, and only once.


This allows the user to declare and initialize
loop control variables.
• Condition: the condition is evaluated. If it is true, the body of the loop
is executed, else the flow jumps to the statement after the ‘for’ loop.
• Modifier: at the end of each iteration it will be executed, and
execution moves to Condition.
• for loop example
multiple initializations in for loop
SystemVerilog repeat and forever loop

• repeat loop
• repeat will execute the statements within the loop for a loop variable
number of times.
• repeat loop syntax
repeat loop example
forever loop
• As the name says forever loop will execute the statements inside the
loop forever.
It can be said as indefinite iteration.
• forever loop syntax
forever loop example
SystemVerilog break and continue

• Two new statements help with loops.


• First, if you are in a loop, but want to skip over the rest of the
statements and do the next iteration, use continue.
• If you want to leave the loop immediately, use break.
break:
• The execution of a break statement leads to the end of the loop.
• break shall be used in all the loop constructs (while, do-while,
foreach, for, repeat and forever).

• Syntax
break in while loop
Continue in SystemVerilog
• Execution of continue statement leads to skip the execution of
statements followed by continue and jump to next loop or iteration
value.
• syntax

• Continue example
• In below example,
• when ever the loop value is with in 3 to 6, continue statement will be
executed, this leads to skip the execution of display statement after
the continue.
3.2 Tasks, Functions, and Void Functions
• A function or task is a group of statements that performs some specific action.
• Both of them can be called at various points to perform a certain operation.
• They are also used to break large code into smaller pieces to make it easier to read and
debug.
• Verilog makes a very clear differentiation between tasks and functions.
• The most important difference is that a task can consume time, whereas a function cannot.
• A function cannot have a delay, #100, a blocking statement such as @ (posedge clock) or
wait (ready), or call a task.
• Additionally, a Verilog function must return a value and the value must be used, as in an
assignment statement.
• Functions in Verilog
• A function that does not consume simulation time, returns a single value or an expression,
and may or may not take arguments.
• Keywords used: function and endfunction.
• If you have a SystemVerilog task that does not consume time, you
should make it a void function, which is a function that does not
return a value.
• Now it can be called from any task or function.
• For maximum flexibility, any debug routine should be a void function
rather than a task so that it can be called from any task or function.
• Sample 3.3 prints values from a state machine.
• In SystemVerilog, if you want to call a function and ignore its return
value, cast the result to void, as shown in Sample 3.4.
• Some simulators, such as VCS, allow you to ignore the return value
without using the above void syntax.
Task and Function Overview
Task and Function Overview
Task and Function Overview
• SystemVerilog makes several small improvements to tasks and functions to
make them look more like C or C++ routines.
• In general, a routine definition or call with no arguments does not need the
empty parentheses ().
• This book includes them for added clarity.
• 3.3.1 Routine begin ••• end Removed
• The first improvement you may notice in SystemVerilog routines is that
begin ... end blocks are optional, while Verilog-1995 required them on all but
single-line routines.

• The task / endtask and function / endfunction keywords are enough to define
the routine boundaries, as show in Sample 3.5.
3.4 Routine Arguments
Many of the System Verilog improvements for routines make it easier to declare
arguments and expand the ways you can pass values to and from a routine.
3.4.1 C-Style Routine Arguments
SystemVerilog and Verilog-2001 allow you to declare task and function
arguments more cleanly and with less repetition. The following Verilog task
requires you to declare some arguments twice: once for the direction. and
once for the type. as shown in Sample 3.6.
With System Verilog, you can use the less verbose C-style, shown in Sample 3.7.
Note that you should use the universal input type of logic.

3.4.2 Argument Direction


• You can take even more shortcuts with declaring routine arguments. The direction
and type default to "input logic" and are sticky, and so you don't have to repeat
these for similar arguments.
• Sample 3.8 shows a routine header written using the Verilog 1995 style and
SystemVerilog data types.
You could rewrite this as shown in Sample 3.9.
• The arguments a and b are input logic, I-bit wide. The arguments u and v are
16-bit output bit types. Now that you know this, don't depend on the defaults,
as your code will be infested with subtle and hard to find bugs, as explained in
Section 3.4.6.
• Always declare the type and direction for every routine argument.
• 3.4.3 Advanced Argument Types
• Verilog had a simple way to handle arguments: an input or inout was copied to
a local variable at the start of the routine, whereas an output or inout was
copied when the routine exited.
• In System Verilog, you can specifying that an argument is passed by reference,
rather than copying its value.
• This argument type, ref, has several benefits over input, output, and inout.
More about functions
• A Function can contain declarations of range, returned type, parameters, input arguments,
registers, and events.
• A function without a range or return type declaration returns a one-bit value
• Any expression can be used as a function call argument
• Functions cannot contain any time-controlled statements, and they cannot enable tasks
• Functions can return only one value

• SystemVerilog function can be,


• static
• Automatic
• Static Function
• Static functions share the same storage space for all function calls.
• Automatic Function
• Automatic functions allocate unique, stacked storage for each function call.
Basic syntax of functions
function examples
function with return value with the return keyword
• In the below example,
arguments in declarations and directions, return value is specified using the
return statement.
void function
• The example below shows usage of void function, void function,(function with
no return value)
discarding function return value
The function return value must be assigned to a variable or used in an expression.
Calling a function without return value assigned to a variable can result in a warning message. SystemVerilog void
data type is used to discard a function’s return value without any warning message.
function call as an expression
Task and Function argument passing
SystemVerilog provides below means for passing arguments to functions and
tasks,
• argument pass by value
• argument pass by reference
• argument pass by name
• argument pass by position
also, functions and tasks can have default argument values.
• argument pass by value
• In argument pass by value,
• the argument passing mechanism works by copying each
argument into the subroutine area.
• if any changes to arguments within the subroutine, those changes
will not be visible outside the subroutine.
argument pass by value example
• Variables x and y are passed as an argument in the function call sum,
changes to the argument x within the function is not visible outside.
argument pass by reference
In pass by reference, a reference to the original argument is passed to
the subroutine.
• As the argument within a subroutine is pointing to an original argument, any
changes to the argument within subroutine will be visible outside.
• To indicate argument pass by reference, the argument declaration is preceded
by keyword ref.
• Any modifications to the argument value in a pass by reference can
be avoided by using const keyword before ref, any attempt in changing the
argument value in subroutine will lead to a compilation error.
argument pass by reference example

• variables x and y are passed as an argument in the function call sum,


changes to the argument x within the function, is visible outside.
• Any modifications to the argument value in a pass by reference can be avoided
by using const keyword before ref, any attempt in changing the argument value
in subroutine will lead to a compilation error.

ARGUMENT PASS BY REFERENCE WITH THE CONST KEYWORD


variables x and y are passed as an argument in the function call sum, as
arguments are mentioned as const, changes to the argument x within the function
leads to a compilation error.
default argument values
• The default value can be specified to the arguments of the subroutine.
• In the subroutine call, arguments with a default value can be omitted from the
call.
• if any value is passed to an argument with a default value, then the new value
will be considered.
an argument with default value example
• variables x, y and z of the subroutine has a default value of 5,10 and 20
respectively, in the function call value is passed only for z. x and y will take the
default value.
argument pass by name
• In argument pass by name, arguments can be passed in any order by
specifying the name of the subroutine argument.
argument pass by name example
• value to the second argument is passed first by specifying the
argument name.
Tasks in Verilog
• A task that may or may not consume simulation time, returns values
as output or inout argument type, and may or may not take
arguments.
• Keywords used: task and endtask.
• Tasks and Functions provide a means of splitting code into small
parts.
• A Task can contain a declaration of parameters, input arguments,
output arguments, in-out arguments, registers, events, and zero or
more behavioral statements.
• SystemVerilog task can be,
• static
• automatic
Static tasks
• Static tasks share the same storage space for all task calls.

Automatic tasks
• Automatic tasks allocate unique, stacked storage for each task
call.
task examples
task arguments in parentheses
task arguments in declarations and mentioning directions
• Similarities between function and task
• Both are static in nature by default. Refer to System Verilog tasks and
functions for more details.
• Both support default arguments and arguments have input direction
by default unless it is specified.
• Multiple statements can be written without using a begin .. end block.
Examples from book

Systemverilog allows you to pass array arguments without the ref direction, but the array
is copied onto the stack, an expensive operation for all but the smallest arrays.
The System Verilog LRM states that ref arguments can only be used in routines with
automatic storage.
If you specify the automatic attribute for programs and module, all the routines inside are
automatic.
• Sample 3.10 also shows the const modifier.
• As a result, the array a points to the array in the routine call, but the
contents of the array cannot be modified.
• If you try to change the contents the compiler prints an error.
• Always use ref when passing arrays to a routine for best performance.
• If you don't want the routine to change the array values, use the const ref
type, which causes the compiler to check that your routine does not modify
the array.
Benefits of the argument type ref
1. We can now pass an array into a routine.(see sample 3.10)
2. The second benefit of ref arguments is that a task can modify a
variable and is instantly seen by the calling function.
• This is useful when you have several threads executing concurrently and
want a simple way to pass information.
• In Sample 3.11, the thread2 block in the initial block can access the data
from memory as soon as bus enable is asserted, even though the bus_read
task does not return until the bus transaction completes, which could be
several cycles later. The data argument is passed as ref, and as a result, the
@data statement triggers as soon as data changes in the task. If you had
declared data as output, the @data statement would not trigger until the end
of the bus transaction.
3.4.4 Default Value for an Argument

• As your testbench grows in sophistication, you may want to add


additional controls to your code but not break existing code.
• For the function in Sample 3.10. you might want to print a
checksum of just the middle values of the array.
• However, you don't want to go back and rewrite every call to add
extra arguments.
• In SystemVerilog you can specify a default value that is used if
you leave out an argument in the call.
• Sample 3.12 adds low and high arguments to the print_checksum
function so that you can print a checksum of a range of values.
• You can call this function in the following ways, as shown in Sample
3.13. Note that the first call is compatible with both versions of the
print_checksum routine.
• Using a default value of -I (or any out-of-range value) is a good way to
see if the call specified a value.
• A Verilog for-loop always executes the initialization (int i=low), and
test (i < =high) before starting the loop.
• Thus, if you accidently passed a low value that was larger than high or
the array size, the for-loop would never execute the body.
3.4.5 Passing Arguments by Name
• You may have noticed in the SystemVerilog LRM that the arguments
to a task or function are sometimes called "ports," just like the
connections for a module.
• If you have a task or function with many arguments, some with
default values, and you only want to set a few of those arguments,
you can specify a subset by specifying the name of the routine
argument with a port-like syntax, as shown in Sample 3.14.
3.4.6 Common Coding Errors
• The most common coding mistake that you are likely to make with a
routine is forgetting that the argument type is sticky with respect to
the previous argument and that the default type for the first
argument is a single-bit input.
• Start with the simple task header in Sample 3.15.
3.5 Returning from a Routine
• Verilog had a primitive way to end a routine; after you executed the last statement in a routine, it
returned to the calling code.
• In addition, a function returned a value by assigning that value to a variable with the same name as
the function.
• 3.5.1 The Return Statement
• System Verilog adds the return statement to make it easier for you to control the flow in your
routines. The task in Sample 3.18 needs to return early because of error checking. Otherwise, it
would have to put the rest of the task in an else clause,which would cause more indentation and
be more difficult to read.
The return statement in Sample 3.19 can simplify your
functions.

3.5.2 Returning an Array from a Function

Verilog routines could only return a simple value such as a bit, integer, or vector.
If you wanted to compute and return an array, there was no simple way.
In SystemVerilog, a function can return an array, using several techniques.
The first way is to define a type for the array and then use that in the function declaration.
Sample 3.20 uses the array type from Sample 2.35. and creates a function to initialize the array.
• One problem with the preceding code is that the function init creates an array,
which is copied into the array f5.
• If the array was large, this could be a large performance problem.
• The alternative is to pass the routine by reference. T
• he easiest way is to pass the array into the function as a ref argument, as shown
in Sample 3.21.
3.6 Local Data Storage
• When Verilog was created in the 1980s, it was tightly tied to
describing hardware.
• As a result, all objects in the language were statically allocated.
• In particular, routine arguments and local variables were stored in a
fixed location, rather than pushing them on a stack like other
programming languages.
• Why try to model dynamic code such as a recursive routine when
there is no way to build this in silicon?
• However, software engineers verifying the designs, who were used to
the behavior of stack based languages such as C, were bitten by these
subtle bugs, and were thus limited in their ability to create complex
testbenches with libraries of routines.
3.6.1 Automatic Storage
• In Verilog-I 995, if you tried to call a task from multiple places in your
testbench, the local variables shared common, static storage, and so
the different threads stepped on each other's values.
• In Verilog-2001 you can specify that tasks, functions, and modules use
automatic storage, which causes the simulator to use the stack for
local variables. threads.
• In SystemVerilog, routines still use static storage by default, for both
modules and program blocks.
• You should always make program blocks (and their routines) use
automatic storage by putting the automatic keyword in the program
statement.
You can call this task multiple times concurrently, as the addr and expect_data arguments are
stored separately for each call.
Without the automatic modifier, if you called wait_for_mem a second time while the first was still
waiting, the second call would overwrite the two arguments.
• 3.6.2 Variable Initialization
• A similar problem occurs when you try to initialize a local variable in a
declaration, as it is actually initialized before the start of simulation.
• The general solution is to avoid initializing a variable in a declaration to
anything other than a constant.
• Use a separate assignment statement to give you better control over when
initialization is done.
• The task in Sample 3.23 looks at the bus after five cycles and then creates a
local variable and attempts to initialize it to the current value of the address
bus.
The bug is that the variable local_addr is statically allocated. and so it is actually initialized at
the start of simulation. not when the begin ... end block is entered.
Once again the solution is to declare the program as automatic as shown in Sample 3.14.
Additionally. you can avoid this by never initializing a variable in the declaration. but this is
harder to remember, especially for C programmers.
Sample 3.25 show the recommended style of separating the declaration and initialization.
3.7 Time Values
SystemVerilog has several new constructs to allow you to unambiguously specify time
values in your system.
3.7.1 Time Units and Precision
• When you rely on the' timescale compiler directive. you must compile the files
in the proper order to be sure all the delays use the proper scale and precision.
• The timeunit and timeprecision declarations eliminate this ambiguity by
precisely specifying the values for every module.
• Sample 3.16 shows these declarations. Note that if you use these instead of'
timescale, you must put them in every module that has a delay.
3.7.2 Time Literals
• SystemVerilog allows you to unambiguously specify a time value plus units.
Your code can use delays such as 0 .Ins or 20ps.
• Just remember to use timeunit and timeprecision or 'timescale. You can make
your code even more time aware by using the classic Verilog $timeformat (),
$time, and $realtime system tasks.
• The four arguments to $timefonnat are the scaling factor (-9 for nanoseconds, -
12 for picoseconds), the number of digits to the right of the decimal point, a
string to print after the time value, and the minimum field width.
• Sample 3.26 shows various delays and the result from printing the time when it
is for matting by $timeformat () and the %t specifier.
• 3.7.3 Time and Variables
• You can store time values in variables and use them in calculations and delays.
The values are scaled and rounded according to the current time scale and
precision.
• Variables of type time cannot hold fractional delays as they are just 64-bit
integers, and so delays will be rounded.
• You should use real variables if this is a problem.
• Sample 3.27 shows how real variables are able to retain accurate values and are
only rounded when used as a delay.
3.7.4 $time vs. $realtime
The system task $time returns an integer scaled to the time precision of the current module, but
missing any fractional units, while $real time returns a real number with the complete time value,
including fractions.
This book uses $time in the exam ples for brevity, but your testbenches may need to use $real
time.

You might also like