<Previous
TOC
Next>
Introduction
Procedural statements are introduced by one of:
initial // do this statement once
always, always_comb, always_latch, always_ff // loop forever (see
section 9 on processes)
task // do these statements whenever the task is called
function // do these statements whenever the function is called
and return a value
SystemVerilog has the following types of control flow within a process
Verilog procedural statements are in initial or always blocks, tasks or
functions.
Verilog includes most of the statement types of C, except for
do...while, break, continue and goto.
Verilog has the repeat statement which C does not, and the disable. The
use of the Verilog disable to
carry out the functionality of break and continue requires the user to
invent block names, and introduces the
opportunity for error.
SystemVerilog adds C-like break, continue and return functionality,
which do not require the use of block
names.
Loops with a test at the end are sometimes useful to save duplication of
the loop body. SystemVerilog adds a
C-like do...while loop for this capability.
Verilog provides two overlapping methods for procedurally adding and
removing drivers for variables: the
force/release statements and the assign/deassign statements. The
force/release statements can also be
used to add or remove drivers for nets in addition to variables. A force
statement targeting a variable that is
currently the target of an assign will override that assign; however,
once the force is released, the assign�s
effect again will be visible.
The keyword assign is much more commonly used for the somewhat similar,
yet quite different purpose of
defining permanent drivers of values to nets.
statement ::= [
block_identifier : ] statement_item // from Annex A.6.4
statement_item ::=
{ attribute_instance } blocking_assignment ;
| { attribute_instance } nonblocking_assignment ;
| { attribute_instance } procedural_continuous_assignments ;
| { attribute_instance } case_statement
| { attribute_instance } conditional_statement
| { attribute_instance } transition_to_state statement_or_null
| { attribute_instance } inc_or_dec_expression
| { attribute_instance } function_call /* must be void function
*/
| { attribute_instance } disable_statement
| { attribute_instance } event_trigger
| { attribute_instance } loop_statement
| { attribute_instance } jump_statement
| { attribute_instance } par_block
| { attribute_instance } procedural_timing_control_statement
| { attribute_instance } seq_block
| { attribute_instance } system_task_enable
| { attribute_instance } task_enable
| { attribute_instance } wait_statement
| { attribute_instance } process statement
| { attribute_instance } proc_assertion
statement_or_null ::=
statement
| { attribute_instance } ;
procedural_timing_control_statement ::=
delay_or_event_control statement_or_null |
Blocking and nonblocking assignments
blocking_assignment ::= // from Annex
A.6.2
variable_lvalue =
delay_or_event_control expression
| operator_assignment
operator_assignment ::= variable_lvalue assignment_operator
expression
assignment_operator ::=
= | += | -= | *= |
/= | %= | &= | |= | ^= | <<= | >>= | <<<= | >>>=
nonblocking_assignment ::= variable_lvalue <= [
delay_or_event_control ] expression |
The following assignments are allowed in both
Verilog-2001 and SystemVerilog:
#1 r = a;
r = #1 a;
r <= #1 a;
r <= a;
@c r = a;
r = @c a;
r <= @c a;
SystemVerilog also allows a time unit to specified in the assignment
statement, as follows:
#1ns r = a;
r = #1ns a;
r <= #1ns a;
It shall be illegal to make nonblocking assignments to automatic
variables.
The size of the left-hand side of an assignment forms the context for
the right hand side expression. If the lefthand side is smaller than the
right hand side, and information may be lost, a warning can be given.
|