AVLSI_MODULE4
AVLSI_MODULE4
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
In do-while,
• 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
• 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.
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
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.