Verilog and System Verilog (SV) , both are used as HDLs in modern day designs. But there are some differences that one should know, to be able to make a better decision on how to code effectively.
Verilog is an older language, which was introduced in 1984. System Verilog is based on Verilog but has multiple enhancements, and was adopted as IEEE Standard in 2005. In between, there have been multiple extensions of Verilog, which are already used in Verilog we know today.
Verilog is an HDL which is used for design as well as verification. However, in comparison to SV, the verification capabilities of Verilog are limited.
SV is based on Object Oriented Programming concept, similar to software languages, which makes it dynamic and hence, imparts greater verification capabilities. This is only restricted to verification, as this kind of code cannot be synthesized. Some important examples of constructs which come under this category are:
- Classes
- Randomize methods
- Assertions
- Interfaces
- Constraints
- Covergroups and Coverpoints
But in this article, we will not be discussing details of SVs verification capabilities, we will only discuss the SV enhancements which can be used in design development. SV integration into the design process makes the process of code-development more user-friendly and easier. Let us go through some examples for the same:
| Verilog | System Verilog | Remarks | |
| Data Types (Variables) | Data types used in Verilog: -Reg -Integer Both of these data-types have 4 possible states: 0,1,Z and X | SV has additional 2-state data types, which means the value of the variable can either be ‘1’ or ‘0’ (No ‘X’ or ‘Z’). Following are the examples: -Bit (1-bit 2 state) -Byte (8 bit 2 state) -Shortint (16 bit 2 state) -Int (32 bit 2 state) -Longint (64 bit 2 state) -Shortreal (32 bit single precision floating point) -Logic (1 bit 4 state integer) – same as ‘reg’ in verilog The purpose is to make the code more readable at higher abstraction level. | 2-state and 4-state data types are both synthesizable and are treated in the same way by Synthesis Compilers. The difference occurs in simulation as: Pre synthesis : Default value is considered 0 before initialization Post Synthesis: Does not guarantee to power-up with a ‘0’ |
| ‘Always’ block (Procedural Blocks) | ‘Always’ block is used as a general purpose block. This means that the same ‘always’ block can be used to model: -Combinational logic -Latched Logic -Sequential Logic The difference lies in the usage of the block as the tool infers the type of logic created from the code that is written. This makes it tricky to identify mistakes while coding. | Three special ‘always’ blocks are added to reduce the ambiguity that comes with Verilog’s general purpose ‘always’ block. These are: -always_comb -always_latch -always_ff In this case, if you are using ‘always_comb’, the tool understands that you are trying to code a combinational logic, and it will flag any mistake you must have made while coding a combinational logic. The type of block specifies the engineer’s intent, hence tool does not need to infer the type of logic from the code. In addition, it helps the engineer to flag any error he/she might have made while modelling the logic. | There is a significant advantage of using SV over Verilog while using procedural blocks. This article does not discuss the more details on WHY part, as it needs more example cases and study of rules to understand this. The main guidelines are: Use ‘always_comb’ to code a combinational logic Use ‘always_latch’ to code a latch Use ‘always_ff’ to code a flip-flop |
| Combinational logic (always @* vs always_comb) (Example function given in rightmost column) | always @* This is a simpler way of modelling combo-logic as @* does not require the engineer to write all the variables needed in the sensitivity list. Cons: -@* will only be executed if any of the inferred signal in sensitivity list changes. Until any such signal changes, output value might not be valid. -The inferred sensitivity list includes only the variables within the block, and variables passed as arguments to functions called inside the block. Inferred sensitivity list : A,B,C,D,E | always_comb Used for the similar purpose. This does not require an explicit sensitivity list as well. Additional Benefits: -It ensures that other procedural blocks do not write into the same variable. -Automatically executes once at time ‘0’, even if it is not triggered by any of the inferred signals in sensitivity list. This allows output values to be consistent with input values from the beginning. -The inferred sensitivity list includes variables within the blocks, arguments passed to function calls inside the block, and also, variables used inside the function. Inferred sensitivity list : A,B,C,D,E, offset | Assume that the variables have appropriate bit-size for desired functionality in the given example The example function used is: |
| Port Connections (Example module given in rightmost column) | Two ways of connecting ports: –Ordered port connection: This requires the port connections in the same order as it was declared. This is hardly used as we have lots of signals in the design. –Named port connection: This includes writing the name of the port while instantiating the module. This does not need the ports to be in order. | SV provides three enhancements to port connections: .name connection: This is really helpful when port name and the net name (which is used as connection to the port) is same. When the name is not same, it needs to be explicitly connected. .* port connection : This is more flexibility than .name as it removes the need to provide the name of ports which have same name as the net. Interfaces: SV allows the use of interfaces to instantiate and connect modules directly. This is a very useful capability but we will not discuss in detail as it is a lengthy topic. This provides a great advantage over Verilog which doesn’t support the use of interfaces. | Example module: |
There are many more differences as SV offers a lot of improvements over Verilog to improve code’s:
- Readability
- Maintainability
- Reusability
Which language should you start with as a new designer?
If you are completely new to RTL design, starting with Verilog will be a good idea. Since Verilog includes the basics of RTL coding, it has more restrictions and constraints and needs more know-how of hardware logic. Gradually, you can learn SV to simplify the RTL coding and use its extra capabilities to further improve the skills.
However, if you are a verification engineer, SV will be a good start as verification capabilities of SV are far more superior and testbenches do not need synthesizable code. Every industry uses SV based testbenches, which require a different understanding than ‘Verilog’.

Leave a comment