1.
Introduction
Verilog 1995 version
has been in market for a very long time. IEEE extended the features of
Verilog 1995 and released it as Verilog 2001. But this was no good for
verification engineers, so verification engineers had to use languages
like "e", VERA, Testbuider. It was rather painfull to have two languages,
one for design and other for verification. SystemVerilog combines the
Verification capabilties of HVL (Hardware Verification Language) with ease
of Verilog to provide a single platform for both design and verification.
Some of the new
features in SystemVerilog are as listed below.
-
C
type data types like int, typedef, struct, union, enum.
-
Dynamic data types: struct, classes, dynamic queues, dynamic arrays.
-
New
operators and built in methods.
-
Enhanced flow control like, foreach, return, break and continue.
-
Semaphores, mailboxes, event extensions.
-
Classes for object oriented programming.
-
Assertions.
-
Coverage.
-
VPI
extensions.
Now IEEE has accepted
the SystemVerilog and it will be official intergrated into Verilog 2005,
which is suppose to be released in year 2005.

Anyone with background
of C++, or OO programming language will feel at home with SystemVerilog.
But on other hand if you have been thinking C or C++ is not required, then
you may be shocked to know that SystemVerilog is very much like C++.
This document
specifies the Accellera extensions for a higher level of abstraction for
modeling and verification with the Verilog Hardware Description Language.
These additions extend Verilog into the systems space and the verification
space. SystemVerilog is built on top of the work of the IEEE Verilog 2001
committee.
Throughout this
document:
— “Verilog” or
“Verilog-2001” refers to the IEEE Std. 1364-2001 standard for the Verilog
Hardware Description Language
— “SystemVerilog”
refers to the Accellera extensions to the Verilog-2001 standard.
This document numbers
the generations of Verilog as follows:
— “Verilog 1.0”
is the IEEE Std. 1364-1995 Verilog standard, which is also called
Verilog-1995
— “Verilog 2.0”
is the IEEE Std. 1364-2001 Verilog standard, commonly called Verilog-2001;
this generation of Verilog contains the first significant enhancements to
Verilog since its release to the public in 1990
— “SystemVerilog
3.x” is Verilog-2001 plus an extensive set of high-level abstraction
extensions, as defined in this document
— SystemVerilog 3.0,
approved as an Accellera standard in June 2002, includes enhancements
primarily directed at high-level architectural modeling
— SystemVerilog 3.1,
approved as an Accellera standard in May 2003, includes enhancements
primarily directed at advanced verification and C language integration
— SystemVerilog 3.1a,
approved as an Accellera standard in April 2004, includes corrections and
clarifications to the SystemVerilog 3.1 manual, as well as some additional
enhancements to Verilog such as VCD and PLI specifications for
SystemVerilog construct.
SystemVerilog is built
on top of Verilog 2001. SystemVerilog improves the productivity,
readability, and reusability of Verilog based code. The language
enhancements in SystemVerilog provide more concise hardware Descriptions,
while still providing an easy route with existing tools into current
hardware implementation Flows. The enhancements also provide extensive
support for directed and constrained-random testbench development,
coverage driven verification, and assertion based verification.
SystemVerilog adds
extended and new constructs to Verilog-2001, including:
—
Extensions to
data types for better encapsulation and compactness of code and for
tighter specification
—
C data types:
int, typedef, struct, union, enum
—
Other data
types: bounded queues, logic (0, 1, X, Z) and bit (0, 1), tagged unions
for safety
—
Dynamic data
types: string, classes, dynamic queues, dynamic arrays, associative arrays
including automatic memory management freeing users from de-allocation
issues
—
Dynamic casting
and bit-stream casting
—
Automatic/static specification on a per variable instance basis
—
Extended
operators for concise description
—
Wild equality
and inequality
—
Built-in
methods to extend the language
—
Operator
overloading
—
streaming
operators
—
set membership
—
Extended
procedural statements
—
Pattern
matching on selection statements for use with tagged unions
—
enhanced loop
statements plus the foreach statement
—
C like jump
statements: return, break, continue
—
Final blocks
that executes at the end of simulation (inverse of initial)
—
extended event
control and sequence events
—
Enhanced
process control
—
Extensions to
always blocks to include synthesis consistent simulation semantics
—
Extensions to
fork…join to model pipelines and for enhanced process control
—
Fine-grain
process control
—
Enhanced tasks
and functions
—
C like void
functions
—
pass by
reference
—
default
arguments
—
pass by name
—
Optional
arguments
—
import/export
functions for DPI (Direct Programming Interface)
—
Classes:
Object-Oriented mechanism that provides abstraction, encapsulation, and
safe pointer capabilities
—
Automated
testbench support with random constraints
—
Interprocess
communication synchronization
—
semaphores
—
Mailboxes
Event extensions,
event variables, and event sequencing
—
Clarification
and extension of the scheduling semantics
—
Cycle-Based
Functionality: Clocking blocks and cycle-based attributes that help reduce
development ease maintainability, and promote reusability:
—
cycle-based
signal drives and samples
—
Synchronous
samples
—
race-free
program context
—
Assertion
mechanism for verifying design intent and functional coverage intent.
—
Property and
sequence declarations
—
Assertions and
Coverage statements with action blocks
—
Extended
hierarchy support
—
Packages for
declaration encapsulation with import for controlled access
—
compilation-unit scope nested modules and extern modules for separate
compilation support
—
Extension of
port declarations to support interfaces, events, and variables.
—
$root to
provide unambiguous access using hierarchical references
—
Interfaces to
encapsulate communication and facilitate “Communication Oriented” design
—
Functional
coverage
—
Direct
Programming Interface (DPI) for clean, efficient interoperation with other
languages (C provided)
—
Assertion API
—
Coverage API
—
Data Read API
—
VPI extensions
for SystemVerilog constructs
—
Concurrent
assertion formal semantics
2. Operators
•
System
verilog adds the following operators ++ and – increment and decrement
operators similar to C
•
Loop
variables can be declared inside a loop. In verilog, the variable has to
be declared and then used within a loop
|
Operator Type |
Operator Symbol |
Operation Performed |
|
Arithmetic |
* |
Multiply |
|
|
/ |
Division |
|
|
+ |
Add |
|
|
- |
Subtract |
|
|
% |
Modulus |
|
|
+ |
Unary plus |
|
|
- |
Unary minus |
|
Logical |
! |
Logical negation |
|
|
&& |
Logical and |
|
|
|| |
Logical or |
|
Relational |
> |
Greater than |
|
|
< |
Less than |
|
|
>= |
Greater than or equal |
|
|
<= |
Less than or equal |
|
Equality |
== |
Equality |
|
|
!= |
inequality |
|
Reduction |
~ |
Bitwise negation |
|
|
~& |
nand |
|
|
| |
or |
|
|
~| |
nor |
|
|
^ |
xor |
|
|
^~ |
xnor |
|
|
~^ |
xnor |
|
Shift |
>> |
Right shift |
|
|
<< |
Left shift |
|
Concatenation |
{ } |
Concatenation |
|
Conditional |
? |
conditional |
|
Assignment operator |
=,
+=, -=,
*=
, /=,
%=,
&=,
|=,
^=,
<<=,
>>=,
<<<=,
>>>=
|
|
Conditional_Expression |
cond_predicate
?
{ attribute_instance } expression
:
expression |
|
Unary_operator |
+,
-, !, ~, &, ~&, |, ~|, ^, ~^, ^~ |
|
Binary_operator |
+,-, *, /, %, ==, !=, ===,!==, =?=, !?=, &&, ||, **
<,
>, <=, >=, &, |, ^, ~^, ^~, >>, <<, <<<, >>> |
|
Increment, decrement operators |
++,
-- |
|
Unary_module_path_operator |
!,
~, &, ~&, |, ~|, ^, ~^, ^~ |
|
Binary_module_path_operator |
==,
!=, &&, ||, &, |, ^, ~^, ^~ |
Concatenation
Braces ( { } ) are
used to show concatenation, as in Verilog. The concatenation is treated as
a packed vector of bits. It can be used on the left hand side of an
assignment or in an expression.
logic
log1, log2, log3;
{log1, log2, log3} =
3’b111;
{log1, log2, log3} =
{1’b1, 1’b1, 1’b1}; // same effect as 3’b111
SystemVerilog enhances
the concatenation operation to allow concatenation of variables of type
string. In general, if any of the operands is of type
string,
the concatenation is treated as a string, and all other arguments are
implicitly converted to the
string
type. String
concatenation is not allowed on the left hand side of an assignment, only
as an expression.
string
sv = "SystemVerilog";
string
s;
s = {sv, " ", "is
easy”};
$display (“%s\n", s);
// displays 'SystemVerilog is easy’
s = {s, “, enjoy”};
$display (“%s\n", s);
// displays 'SystemVerilog is easy, enjoy’
3. Structures and unions
Structures:
User can create a
logical collection of objects using struct
—
Not restricted
to elements of same size and type as with arrays
—
Can be
referenced as a whole or by individual element

Unions:
Unions also allow the
user to create a collection of objects
—
However, unions
only store a single element
—
![Text Box: typedef struct packed {
opc_t opcode;
reg_t ra, rb, rc;
logic [11:0] c3;
} instr_format_3;
typedef struct packed {
opc_t opcode;
reg_t ra, rb;
logic [16:0] c2;
} instr_format_2;
typedef struct packed {
opc_t opcode;
reg_t ra;
logic [21:0] c1;
} instr_format_1;](datatypes_files/image003.gif)
Advantage: single
element stored with different representations
![Text Box: typedef union packed {
instr_format_1 IW1;
instr_format_2 IW2;
instr_format_3 IW3;
logic [31:0] BITS;
} InstrType;
InstrType IR;
always_comb
if (c1o)
q = {{10{IR.IW1.c1[21]}}, IR.IW1.c1};
else if (c2o)
q = {{15{IR.IW2.c2[16]}}, IR.IW2.c2};
else
q = IR.BITS;](datatypes_files/image004.gif)
4. Control Statements
Wait, what's this? if,
else, repeat, while, for, case - it's Verilog that looks exactly like C
(and probably whatever other language you're used to programming in)! Even
though the functionality appears to be the same as C, Verilog is an HDL,
so the descriptions should translate to hardware. This means you've got to
be careful when using control statements (otherwise your designs might not
be implementable in hardware).
if-else
if-else statements
check a condition to decide whether or not to execute a portion of code.
If a condition is satisfied, the code is executed. Else, it runs this
other portion of code.
// begin and end act like curly braces in C/C++.
if (enable == 1'b1)
begin
data = 10; // Decimal assigned
address = 16'hDEAD; // Hexadecimal
enable = 1'b1; // Binary
end
else
begin
data = 32'b0;
enable = 1'b0;
address = address + 1;
end
One could use any
operators in the condition checking as in the case of C language. If
needed we can have nested if else statements, statements without else is
also ok, but then it has its own problem when modeling combinational
logic, if statement without else results in a Latch (this is not always
true).
case
Case statements are
used where we have one variable which needs to be checked for multiple
values. Like an address decoder, where the input is an address and it
needs to check for all the values that it can take. Instead of using
multiple nested if-else statements, one for each value we're looking for,
we use a single case statement, and this is similar to switch statements
in languages like C++.
Case statements begin
with the reserved word case and end with the reserved word endcase
(Verilog does not use brackets to delimit blocks of code). The cases,
followed with a colon and the statements you wish executed, are listed
within these two delimiters. It's also a good idea to have a default case.
Just like with a finite state machine (FSM), if the Verilog machine enters
into a non-covered statement, the machine hangs. Defaulting the statement
with a return to idle keeps us safe.
case (address)
0: $display ("It is 11:40PM");
1: $display ("I am feeling sleepy");
2: $display ("Let me skip this tutorial");
default : $display ("Need to complete");
endcase
Looks like address
value was 3 and so I am still writing this tutorial. Note: One thing that
is common to if-else and case statement is that, if you don't cover all
the cases (don’t have else in if-else or default in case), and you are
trying to write a combination statement, the synthesis tool will infer
Latch.
While
A while statement
executes the code within it repeatedly if the condition it is assigned to
check returns true. While loops are not normally used for models in real
life, but they are used in test benches. As with other statement blocks,
they are delimited by begin and end.
while(free_time) begin
$display ("Continue with webpage development");
end
As long as free_time
variable is set, code within the begin and end will be executed. i.e.
print "Continue with web development". Lets look at a stranger example,
which uses most of the constructs of Verilog. Well you heard it right.
Verilog has very few reserve words then VHDL, and in this few, we use even
lesser few for actual coding.
module counter (clk,rst,enable,count);
input clk, rst, enable;
output [3:0] count;
reg [3:0] count;
always @ (posedge clk or posedge rst)
if (rst) begin
count <= 0;
end else begin : COUNT
while (enable) begin
count <= count + 1;
disable COUNT;
end
end
endmodule
The example above uses
most of the constructs of Verilog. You'll notice a new block called always
- this illustrates one of the key features of Verilog. Most software
languages, as we mentioned before, execute sequentially - that is,
statement by statement. Verilog programs, on the other hand, often have
many statements executing in parallel. All blocks marked always will run -
simultaneously - when one or more of the conditions listed within it is
fulfilled.
In the example above,
the always block will run when either rst or clk reaches a positive edge -
that is, when their value has risen from 0 to 1. You can have two or more
always blocks in a program going at the same time (not shown here, but
commonly used).
We can disable a block
of code, by using the reserve word disable. In the above example, after
each incrementation of the counter, the COUNT block of code (not shown
here) is disabled.
for loop
For loops in Verilog
are almost exactly like for loops in C or C++. The only difference is that
the ++ and -- operators are not supported in Verilog. Instead of writing i++
as you would in C, you need to write out its full operational equivalent,
i = i + 1.
for (i = 0; i < 16; i = i +1)
begin
$display ("Current value of i is %d", i);
end
This code will print
the numbers from 0 to 15 in order. Be careful when using for loops for
register transfer logic (RTL) and make sure your code is actually sanely
implementable in hardware.. and that your loop is not infinite.
repeat
Repeat is similar to
the for loop we just covered. Instead of explicitly specifying a variable
and incrementing it when we declare the for loop, we tell the program how
many times to run through the code, and no variables are incremented
(unless we want them to be, like in this example).
repeat (16)
|