[Edit of Image1]
Hey it's a me again @drifter1!
Today we continue with the Logic Design series on SystemVerilog in order to cover some of the additional Control Flow that it provides. Many are directly derived from Verilog. Therefore, only those that are unique to SystemVerilog will be covered rigorously.
So, without further ado, let's dive straight into it!
Let's start off with the procedural blocks, which are similar to Verilog's.
Procedural statements can only be specified within procedural blocks, which in SystemVerilog are the following:
initial : Executes once at the beginning of the simulationfinal : Executes once at the end of the simulation (unique to SystemVerilog)always_comb, always_latch, always_ff (unique to SystemVerilog)task : Executed whenever the task is calledfunction : Executed whenever the function is called, and also returns an optional valueA final block is defined using the final keyword. It specifies a procedural block of statements which is executed at the end of the simulation without delays. So, it's common to use it in order to display statistics about the simulation.
The syntax is:
final begin
// statements to execute at
// the end of the simulation
end
The always block in Verilog can be used for both combinational and sequential logic. This may lead to some unintended latches and design mistakes in general. In order to fix this issue SystemVerilog adds specialized always blocks that indicate the exact type of always block that is intented for simulation, synthesis and verification:
always_comb : combinational logicalways_latch : latch logicalways_ff : sequential logicFor all of them keep in mind that:
When specifying combinational logic the sensitivity list can be omitted as it is inferred automatically from the expressions defined.
In order execute a section of code for more than once, loops are defined. It's also typical to specify a termination condition, so that the simulation doesn't run indefinitely.
SystemVerilog provides the following looping blocks:
forever : Executes the statements foreverrepeat : Executes / repeats the statements for a given number of timeswhile : Executes the statements as long as a specified condition is truefor : Similar to a while loop, but it allows specifying the starting value and incremental expression.do while : Executes the statements at least once and then loops as long as a specified condition is trueforeach : Iterates through all the elements of an arrayThe loops that are unique to SystemVerilog are thus the do while and foreach loops. Additionally, the for loop is enhanced allowing the for loop control variable to be declared within the for loop.
The enhanced SystemVerilog for loop is exactly like a C for loop:
for (int i = 0; i < 4; i++) begin
// loop code
end
A do while loop is defined as:
do begin
// loop code
end while ([condition]);
A foreach loop has the following syntax:
foreach (array[index]) begin
// what to execute on each element
end
For example, initializing each element of a 1D array arr, to the value of their index can be done as follows:
foreach (arr[i]) begin
arr[i] = i;
end
SystemVerilog also adds the C-like jump statements:
break : break out of loopcontinue : skip current and move to next loop iterationreturn expression : exit from a function with a return valuereturn : exit from a task or a void functionAll of these are statements and thus must be followed by an semicolon (;) to be syntactically correct.
In addition to the usual if and case conditional statements that Verilog provides, SystemVerilog also adds some additional forms that can report violations. Those are the unique, unique0 and priority versions, which operate as follows:
unique : reports an error if none of the conditions match (and there is no explicit else) or more than one of the conditions match.unique0 : reports an error if more than one of the conditions match.priority : reports an error if none of the conditions match (which are evaluated in sequential order). In the case of the if statement there's no else clause to the final if.The syntax is simple. Add these keywords before the if and case keyword respectively:
unique if ([condition])
unique case ([var])
// error when no condition matches
// OR
// more than one conditions match
unique0 if ([condition])
unique0 case ([var])
// error when more than one conditions match
priority if ([condition])
priority case ([var])
// error when no condition matches
Functions and Tasks in SystemVerilog are the same as in Verilog, but some additional features are added, such as:
In Verilog the only way of passing a variable was by value, which basically meant that the argument's value was copied to the task or function memory space. In SystemVerilog this is done by simply specifying the name of the variable as the argument in both the definition and the call of the function or task:
function func_name;
input var_name;
// main body
endfunction
...
func_name (arg_name);
SystemVerilog also adds passing by reference, which is done by adding the keyword ref in the argument definition:
function func_name(ref var_name)
// main body
endfunction
With this we also showcased the module-like definition of functions.
Next up is, SystemVerilog also allows passing arguments by name or by position. This is the same as connecting module ports using explicit mapping when instantiating them, allowing us to mix up the position and name of the arguments in the task or function call. So, this is basically done using the familiar . notation.
function func_name(ref var1, ref var2)
// main body
endfunction
func_name(.var2(arg2), .var1(arg1));
Specifying a default value for each argument is as simple as adding an assigment statement to its definition:
function func_name(ref var_name = value)
// main body
endfunction
When there is such a default value specified then the argument can be omitted, basically becoming optional. It's also possible to have just empty parentheses () when all arguments have defaults specified.
func_name();
Block diagrams and other visualizations were made using draw.io
And this is actually it for today's post!
Of course, there are more features in SystemVerilog that can be used to control the flow of the program, but these are the most common ones.
Next up are Processes, and maybe even Events...
See Ya!

Keep on drifting!