0% found this document useful (0 votes)
12 views

Introduction To VERILOG - VLSI

Uploaded by

nasiharameez03
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

Introduction To VERILOG - VLSI

Uploaded by

nasiharameez03
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 28

UNIT V

INTRODUCTION TO VERILOG

Verilog is a Hardware Description Language (HDL). It is a language used for describing a digital
system such as a network switch, a microprocessor, a memory, or a flip-flop. We can describe any digital
hardware by using HDL at any level. Designs described in HDL are independent of technology, very easy for
designing and debugging, and are normally more useful than schematics, particularly for large circuits.

What is Verilog?

Verilog is a HARDWARE DESCRIPTION LANGUAGE (HDL), which is used to describe a digital system
such as a network switch or a microprocessor or a memory a flip-flop.

Verilog was developed to simplify the process and make the HDL more robust and flexible. Today, Verilog
is the most popular HDL used and practiced throughout the semiconductor industry.

HDL was developed to enhance the design process by allowing engineers to describe the desired hardware's
functionality and let automation tools convert that behavior into actual hardware

elements like combinational gates and sequential logic.


10.4M
390
Java Tricky Program 23 - Main method signature

Verilog is like any other hardware description language. It permits the designers to design the designs in
either Bottom-up or Top-down methodology.
o Bottom-Up Design: The traditional method of electronic design is bottom-up. Each design is

performed at the gate-level using the standards gates. This design gives a way to design new

structural, hierarchical design methods.

o Top-Down Design: It allows early testing, easy change of different technologies, and structured

system design and offers many other benefits.

Verilog Abstraction Levels

Verilog supports a design at many levels of abstraction, such as:

o Behavioral level

o Register-transfer level

o Gate level

Behavioral level

The behavioral level describes a system by concurrent algorithms behavioral. Every algorithm is sequential,
which means it consists of a set of executed instructions one by one. Functions, tasks, and blocks are the
main elements. There is no regard for the structural realization of the design.

Register-Transfer Level

Designs using the Register-Transfer Level specify a circuit's characteristics using operations and the transfer
of data between the registers.

The modern definition of an RTL code is "Any code that is synthesizable is called RTL code".

Gate Level

The characteristics of a system are described by logical links and their timing properties within the logical
level. All signals are discrete signals. They can only have definite logical values (`0', `1', `X', `Z`).

The usable operations are predefined logic primitives (basic gates). Gate level modeling may not be the right
idea for logic design. Gate level code is generated using tools such as synthesis tools, and his netlist is used
for gate-level simulation and backend.
Verilog Data Types

Verilog introduces several new data types. These data types make RTL descriptions easier to write and
understand.

The data storage and transmission elements found in digital hardware are represented using a set of Verilog
Hardware Description Language (HDL) data types.

In Verilog, data types are divided into NETS and Registers. These data types differ in the way that they are
assigned and hold values, and also they represent different hardware structures.

The Verilog HDL value set consists of four basic values:

Value Description

0 Logic zero or false

1 Logic one or true

X Unknown logical value

Z The high impedance of the tri-state gate

Integer and Real Data Types

Many data types will be familiar to C programmers. The idea is that algorithms modeled in C can be
converted to Verilog if the two languages have the same data types.

Verilog introduces new two-state data types, where each bit is 0 or 1 only. Using two-state variables in RTL
models may enable simulators to be more efficient. And they are not affecting the synthesis results.

Types Description

bit user-defined size

byte 8 bits, signed

shortint 16 bits, signed


int 32 bits, signed

longint 64 bits, signed

o Two-state integer types

Unlike in C, Verilog specifies the number of bits for the fixed-width types.

Types Description

reg user-defined size

logic identical to reg in every way

integer 32 bits, signed

o Four-state integer types

We preferred logic because it is better than reg. We can use logic where we have used reg or wire.

Type Description

time 64-bit unsigned

shortreal like a float in C

shortreal like double in C

realtime identical to real

Non-Integer Data Types

Arrays

In Verilog, we can define scalar and vector nets and variables. We can also define memory arrays, which are
one-dimensional arrays of a variable type.
Verilog allowed multi-dimensioned arrays of both nets and variables and removed some of the restrictions on
memory array usage.

Verilog takes this a stage further and refines the concept of arrays and permits more operations on arrays.

In Verilog, arrays may have either packed or unpacked dimensions, or both.

Packed dimensions

o Are guaranteed to be laid out contiguously in memory.


o It can be copied on to any other packed object.
o Can be sliced ("part-selects").
o Are restricted to the "bit" types (bit, logic, int, etc.), some of which (e.g., int) have a fixed size.

Unpacked dimensions

It can be arranged in memory in any way that the simulator chooses. We can reliably copy an array on to
another array of the same type.

For arrays with different types, we have to use a cast, and there are rules for how an unpacked type is cast to
a packed type.

Verilog permits several operations on complete unpacked arrays and slices of unpacked arrays.

For these, the arrays or slices involved must have the same type and shape, i.e., the same number and lengths
of unpacked dimensions.

The packed dimensions may differ, as long as the array or slice elements have the same number of bits. The
permitted operations are:

o Reading and writing the whole array.


o Reading and writing array slices.
o Reading and writing array elements.
o Equality relations on arrays, slices, and elements

Verilog also includes dynamic arrays (the number of elements may change during simulation)
and associative arrays (which have a non-contiguous range).

Verilog includes several arrays of querying functions and methods to support all these array types.

Nets

Nets are used to connect between hardware entities like logic gates and hence do not store any value.
The net variables represent the physical connection between structural entities such as logic gates. These
variables do not store values except trireg. These variables have the value of their drivers, which changes
continuously by the driving circuit.

Some net data types are wire, tri, wor, trior, wand, triand, tri0, tri1, supply0, supply1, and trireg. A net data
type must be used when a signal is:

o The output of some devices drives it.


o It is declared as an input or in-out port.
o On the left-hand side of a continuous assignment.

1. Wire
A wire represents a physical wire in a circuit and is used to connect gates or modules. The value of a wire
can be read, but not assigned to, in a function or block.
2. A wire does not store its value but must be driven by a continuous assignment statement or by
connecting it to the output of a gate or module.
3. Wand(wired-AND)
The value of a wand depends on logical AND of all the drivers connected to it.
4. Wor (wired-OR)
The value of wor depends on the logical OR of all the drivers connected to it.
5. Tri (three-state)
All drivers connected to a tri must be z, except one that determines the tri's value.
6. Supply0 and Supply1
Supply0 and supply1 define wires tied to logic 0 (ground) and logic 1 (power).

Registers

A register is a data object that stores its value from one procedural assignment to the next. They are used only
in functions and procedural blocks.

An assignment statement in a procedure acts as a trigger that changes the value of the data storage element.

Reg is a Verilog variable type and does not necessarily imply a physical register. In multi-bit registers, data is
stored as unsigned numbers, and no sign extension is done for what the user might have thought were two's
complement numbers.

Some register data types are reg, integer, time, and real.reg is the most frequently used type.

o Reg is used for describing logic.


o An integer is general-purpose variables. They are used mainly loops-indices, parameters, and
constants. They store data as signed numbers, whereas explicitly declared reg types store them as
unsigned. If they hold numbers that are not defined at compile-time, their size will default to 32-bits.
If they hold constants, the synthesizer adjusts them to the minimum width needed at compilation.
o Real in system modules.
o Time and realtime for storing simulation times in test benches. Time is a 64-bit quantity that can be
used in conjunction with the $time system task to hold simulation time.

Note: A reg need not always represent a flip-flop because it can also represent combinational logic.

o The reg variables are initialized to x at the start of the simulation. Any wire variable not connected to
anything has the x value.
o The size of a register or wire may be specified during the declaration.
o When the reg or wire size is more than one bit, then register and wire are declared vectors.

Verilog String

Strings are stored in reg, and the width of the reg variable has to be large enough to hold the string.

Each character in a string represents an ASCII value and requires 1 byte. If the variable's size is smaller than
the string, then Verilog truncates the leftmost bits of the string. If the variable's size is larger than the string,
then Verilog adds zeros to the left of the string.

Behavioral Modelling and Timing

In Verilog, Behavioral models contain procedural statements, which control the simulation and manipulate
variables of the data types.

These statements are contained within the procedures. Each of the procedures has an activity flow associated
with it.

During the behavioral model simulation, all the flows defined by the always and initial statements start
together at simulation time zero.

The initial statements are executed once, and the always statements are executed repetitively.1.1K

Example

The register variables a and b are initialized to binary 1 and 0 respectively at simulation time zero.

The initial statement is completed and not executed again during that simulation run. This initial statement is
containing a begin-end block of statements. In this begin-end type block, a is initialized first, followed by b.

module behave;
reg [1:0]a,b;
initial
begin
a = 'b1;
b = 'b0;
end

always
begin
#50 a = ~a;
end

always
begin
#100 b = ~b;
end
End module

Procedural Assignments

Procedural assignments are for updating integer, reg, time, and memory variables. There is a significant
difference between a procedural assignment and continuous assignment, such as:

1. Continuous assignments drive net variables, evaluated, and updated whenever an input operand changes
value.

The procedural assignments update the value of register variables under the control of the procedural flow
constructs that surround them.

2. The right-hand side of a procedural assignment can be any expression that evaluates to a value. However,
part-selects on the right-hand side must have constant indices. The left-hand side indicates the variable that
receives the assignment from the right-hand side. The left-hand side of a procedural assignment can take one
of the following forms:

o Register, integer, real, or time variable: An assignment to the name reference of one of these data
types.
o Bit-select of a register, integer, real, or time variable: An assignment to a single bit that leaves the
other bits untouched.
o Part-select of a register, integer, real, or time variable: A part-select of two or more contiguous bits
that leave the rest of the bits untouched. For the part-select form, only constant expressions are legal.
o Memory element: A single word of memory. Bit-selects and part-selects are illegal on memory
element references.
o Concatenation of any of the above: A concatenation of any of the previous four forms can be
specified, which effectively partitions the result of the right-hand side expression and then assigns
the partition parts, in order, to the various parts of the concatenation.

Delay in Assignment

In a delayed assignment, Δt time units pass before the statement is executed, and the left-hand assignment is
made. With an intra-assignment delay, the right side is evaluated immediately, but there is a delay
of Δt before the result is placed in the left-hand assignment.

If another procedure changes a right-hand side signal during Δt, it does not affect the output. Synthesis tools
do not support delays.

Syntax

An assignment has the following syntax, such as:

1. Procedural Assignmentvariable = expression


2. Delayed assignment#Δt variable = expression;
3. Intra-assignment delayvariable = #Δt expression;

Blocking Assignments

A blocking procedural assignment statement must be executed before executing the statements that follow it
in a sequential block.

The statement does not prevent the execution of statements that follow it in a parallel block.

Syntax

The following syntax is for a blocking procedural assignment, such as:

1. <lvalue> = <timing_control> <expression>


o An lvalue is a data type that is valid for a procedural assignment statement.
o = is the assignment operator, and timing control is the optional intra -assignment delay. The timing
control delay can either be a delay control or event control. The expression is the right-hand side
value the simulator assigns to the left-hand side.
Continuous procedural assignments and continuous assignments also use the = assignment operator
used by blocking procedural assignments.
Non-blocking (RTL) Assignments

The non-blocking procedural assignment is used to schedule assignments without blocking the procedural
flow.

We can use the non-blocking procedural statement whenever we want to make several register assignments
within the same time step without regard to order or dependence upon each other.

Syntax

The following syntax is for a non-blocking procedural assignment:

<lvalue> <= <timing_control> <expression>


o An lvalue is a data type that is valid for a procedural assignment statement.
o <= is the non-blocking assignment operator, and timing control is the optional intra-assignment
timing control.
The timing control delay can be either a delay control or event control. The expression is the right-
hand side value the simulator assigns to the left-hand side. The non-blocking assignment operator is
the same operator the simulator uses for the less-than-or equal relational operator.
o The simulator interprets the <= operator as a relational operator when we use it in an expression and
interprets the <= operator as an assignment operator when you use it in a non-blocking procedural
assignment construct.

When the simulator encounters a non-blocking procedural assignment, the simulator evaluates and executes
the non-blocking procedural assignment in two steps:

Step 1: The simulator evaluates the right-hand side and schedules the new value assignment at a time
specified by a procedural timing control.

Step 2: At the end of the time step, when the given delay has expired, or the appropriate event has taken
place, the simulator executes the assignment by assigning the value to the left-hand side.

Conditions: (if else,case)

The conditional statement or if-else statement is used to decide whether a statement is executed.

Syntax

The syntax is as follows:

<statement>

::= if ( <expression> ) <statement_or_null>


||= if ( <expression> ) <statement_or_null>
else <statement_or_null>
<statement_or_null>

::= <statement>
||= ;
o The <expression> is evaluated. If it is true (non-zero known value), then the first statement executes.
If it is false (zero value or the value is x or z), then the first statement does not execute.
o If there is an else statement and <expression> is false, then the else statement executes.
o Since the numeric value of the, if expression is tested for being zero, specific shortcuts are possible.

Case Statement

The case statement is a unique multi-way decision statement that tests whether an expression matches several
other expressions, and branches accordingly.

The case statement is useful for describing, for example, the decoding of a microprocessor instruction.

Syntax

The case statement has the following syntax:

<statement>
::= case ( <expression> ) <case_item>+ endcase
||= casez ( <expression> ) <case_item>+ endcase
||= casex ( <expression> ) <case_item>+ endcase
<case_item>
::= <expression> <,<expression>>* : <statement_or_null>
||= default : <statement_or_null>
||= default <statement_or_null>
o The case expressions are evaluated and compared in the exact order in which they are given.
o During the linear search, if one of the case item expressions matches the expression in parentheses,
then the statement associated with that case item is executed.
o If all comparisons fail, and the default item is given, then the default item statement is executed.
o If the default statement is not given, and all of the comparisons fail, none of the case item statements
are executed.

The case statement differs from the multi-way if-else-if construct in two essential ways, such as:

1. The conditional expressions in the if-else-if construct are more general than comparing one expression
with several others, as in the case statement.

2. The case statement provides a definitive result when there are x and z values in an expression.

Looping Statements (for, while, repeat, forever)


There are four types of looping statements. They are used to controlling the execution of a statement zero,
one, or more times.

1. Forever continuously executes a statement.

2. Repeat executes a statement a fixed number of times.

3. While executes a statement until expression becomes false, if the expression starts false, the statement is
not executed at all.

4. For controls execution of its associated statements by a three-step process are:

Step 1: Executes an assignment normally used to initialize a variable that controls the number of loops
executed.

Step 2: Evaluates an expression. Suppose the result is zero, then the for loop exits. And if it is not zero, for
loop executes its associated statements and then performs step 3.

Step 3: Executes an assignment normally used to modify the loop control variable's value, then repeats step
2.

Syntax

The following are the syntax rules for the looping statements, such as:

<statement>
::= forever <statement>
||=forever
begin
<statement>+
end

<Statement>
::= repeat ( <expression> ) <statement>
||=repeat ( <expression> )
begin
<statement>+
end

<statement>
::= while ( <expression> ) <statement>
||=while ( <expression> )
begin
<statement>+
end

<statement>
::= for ( <assignment> ; <expression> ; <assignment> )
<statement>
||=for ( <assignment> ; <expression> ; <assignment> )
begin
<statement>+
end

Delay Controls

Verilog handles the delay controls in the following ways, such as:

1. Delay Control

The execution of a procedural statement can be delay-controlled by using the following syntax:

<statement>
::= <delay_control> <statement_or_null>
<delay_control>
::= # <NUMBER>
||= # <identifier>
||= # ( <mintypmax_expression> )

The following example delays the execution of the assignment by 10-time units.

1. #10 rega = regb;

Execution of the assignment delays by the amount of simulation time specified by the value of the
expression.

2. Event Control

The execution of a procedural statement can be synchronized with a value change on a net or register, or the
occurrence of a declared event, by using the following event control syntax:

<statement>
::= <event_control> <statement_or_null>

<event_control>
::= @ <identifier>
||= @ ( <event_expression> )

<event_expression>
::= <expression>
||= posedge <SCALAR_EVENT_EXPRESSION>
||= negedge <SCALAR_EVENT_EXPRESSION>
||= <event_expression> <or <event_expression>>

*<SCALAR_EVENT_EXPRESSION> is an expression that resolves to a one-bit value.

Value changes on nets and registers can be used as events to trigger the execution of a statement. This is
known as detecting an implicit event.

Verilog syntax also used to detect change based on the direction of the change, which is toward the value 1
(posedge) or the value 0 (negedge).

The behavior of posedge and negedge for unknown expression values are:

o A negedge is detected on the transition from 1 to unknown and from unknown to 0.


o And a posedge is detected on the transition from 0 to unknown and from unknown to 1.

Procedures (tasks and function)

All procedures in Verilog are specified within one of the following four Blocks.

1. Initial blocks
2. Always blocks
3. Task
4. Function

Initial Blocks

The initial and always statements are enabled at the beginning of the simulation. The initial blocks execute
only once, and its activity dies when the statement has finished.

Syntax

The following syntax is for the initial statement:

<initial_statement>
::= initial <statement>

Example
The following example illustrates the use of the initial statement for the initialization of variables it the
starting of simulation.

Initial
Begin
Areg = 0; // initialize a register
For (index = 0; index < size; index = index + 1)
Memory [index] = 0; //initialize a memory
Word
End

Another usage of the initial Blocks is the specification of waveform descriptions that execute once to provide
stimulus to the central part of the circuit being simulated.

Initial
Begin
Inputs = 'b000000;
// initialize at time zero
#10 inputs = 'b011001; // first pattern
#10 inputs = 'b011011; // second pattern
#10 inputs = 'b011000; // third pattern
#10 inputs = 'b001000; // last pattern
End

Always Blocks

The always blocks repeatedly executes. Its activity dies only when the simulation is terminated. There is no
limit to the number of initial and always blocks defined in a module.

Syntax

The always statement repeats continuously throughout the whole simulation run. The syntax for the always
statement is given below

<always_statement>
::= always <statement>

The always statement is only useful when used in conjunction with some form of timing control because of
its looping nature.

Task and Function

Tasks and functions are procedures that are enabled by one or more places in other procedures.
Verilog Blocking and Non-blocking

Verilog supports blocking and non-blocking assignments statements within the always block with their
different behaviors.

The blocking assignment is similar to software assignment statements found in most popular programming
languages. The non-blocking assignment is the more natural assignment statement to describe many
hardware systems, especially for synthesis.

The blocking assignments can only be used in a few situations, such as modeling combinational logic,
defining functions, or implementing testbench algorithms. All IEEE P1364.1 compliant synthesis tools are
required to support both blocking and non-blocking assignments in explicit-style code, with the restriction
that each variable and each block may use only one or the other kind of assignment.

Blocking Assignment

Blocking assignment statements are assigned using (=) operator and are executed one after the other in a
procedural block. But, it will not prevent the execution of statements that run in a parallel block.rogram for

module Block;
reg [7:0] a, b, c, d, e;

initial begin
a = 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b = 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end

initial begin
d = 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e = 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule

There are two initial blocks which are executed in parallel. Statements are executed sequentially in each
block and both blocks finish at time 0ns.

To be more specific, variable is assigned first, that followed by the display statement which is then followed
by all other statements.
This is visible in the output where variable b and c are 8'hxx in the first display statement. This is because
variable b and c assignments have not been executed yet when the first $display is called.

ncsim> run
[0] a=0xda b=0xx c=0xx
[0] a=0xda b=0xf1 c=0xx
[0] a=0xda b=0xf1 c=0x30
[0] d=0xaa e=0xx
[0] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.

In the below example, we'll add a few delays into the same set of statements to see how it reacts and behaves.

module Block;
reg [7:0] a, b, c, d, e;
initial begin
a = 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
#10 b = 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
#5 d = 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
#5 e = 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule

After execution, it gives the following data.

ncsim> run
[0] a=0xda b=0xx c=0xx
[5] d=0xaa e=0xx
[10] a=0xda b=0xf1 c=0xx
[10] a=0xda b=0xf1 c=0x30
[10] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.

Non-blocking Assignment
Non-blocking assignment statements are allowed to be scheduled without blocking the execution of the
following statements and is specified by a (<=) symbol.

The same symbol is used as a relational operator in expressions, and as an assignment operator in the context
of a non-blocking assignment.

Take the same example as above, replace all (=) symbols with a non-blocking assignment operator (<=), we'll
get the difference in the output.

module Block;
reg [7:0] a, b, c, d, e;
initial begin
a <= 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b <= 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c <= 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
d <= 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e <= 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule

Now, all the $display statements printed 'h'x. The reason for this behavior is the execution of the non-
blocking assignment statements.

The RHS of every non-blocking statement of a particular time-step is captured and moves onto the next
statement.

The captured RHS value is assigned to the LHS variable only at the end of the time-step.

ncsim> run
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] d=0xx e=0xx
[0] d=0xx e=0xx
ncsim: *W,RNQUIE: Simulation is complete.
Verilog Operators

Operators perform an operation on one or more operands within an expression. An expression combines
operands with appropriate operators to produce the desired functional expression.

1. Arithmetic Operators

For the FPGA, division and multiplication are very expensive, and sometimes we cannot synthesize division.
If we use Z or X for values, the result is unknown. The operations treat the values as unsigned.

Character Operation performed Example

+ Add b + c = 11

- Subtrac b - c = 9, -b=-10

/ Divide b/a=2

* Multiply a * b = 50

% Modulus b%a=0

2. Bitwise Operators

Each bit is operated, the result is the size of the largest operand, and the smaller operand is left extended with
zeroes to the bigger operand's size.

Character Operation performed Example

~ Invert each bit ~a = 3'b010

& And each bit b & c = 3'b010

| Or each bit a | b = 3'b111

^ Xor each bit a ^ b = 3'b011


^~ or ~^ Xnor each bit a ^~ b = 3'b100

3. Reduction Operators

These operators reduce the vectors to only one bit. If there are the characters z and x, the result can be a
known value.

41.3M

732

Prime Ministers of India | List of Prime Minister of India (1947-2020)

Character Operation performed Example

& And all bits &a = 1'b0, &d = 1'b0

~& Nand all bits ~&a = 1'b1

| Or all bits |a = 1'b1, |c = 1'bX

~| Nor all bits ~|a= 1'b0

^ Xor all bits ^a = 1'b1

^~ or ~^ Xnor all bits ~^a = 1'b0

4. Relational Operators

These operators compare operands and results in a 1-bit scalar Boolean value. The case equality and
inequality operators can be used for unknown or high impedance values (z or x), and if the two operands are
unknown, the result is a 1.

Character Operation performed Example

> Greater than a > b = 1'b0

< Smaller than a < b = 1'b1


>= Greater than or equal a >= d = 1'bX

<= Smaller than or equal a <= e = 1'bX

== Equality a == b = 1'b0

!= Inequality a != b = 1'b1

=== Case equality e === e = 1'b1

!=== Case inequality a !== d = 1'b1

5. Logical Operators

These operators compare operands and results in a 1-bit scalar Boolean value.

Character Operation performed Example

! Not true !(a && b) = 1'b1

&& Both expressions true a && b = 1'b0

|| One ore both expressions true a || b = 1'b1

6. Shift Operators

These operators shift operands to the right or left, the size is kept constant, shifted bits are lost, and the vector
is filled with zeroes.

Character Operation performed Example

>> Shift right b >> 1 results 4?b010X

<< Shift left a << 2 results 4?b1000

7. Assignment Operators
There are three assignment operators, each of which performs different tasks, and are used with different data
types:

o assign (continuous assignment)


o <= (non-blocking assignment)
o = (blocking assignment)

8. Other Operators

These are operators used for condition testing and to create vectors.

Character Operation performed Example

?: Conditions testing test cond. ? if true do this or if not do this

{} Concatenate c = {a,b} = 8'101010x0

{{}} Replicate {3{2'b10}}= 6'b101010

9. Operators Precedence

The order of the table tells what operation is made first. The first one has the highest priority. The () can be
used to override the default.

Operators precedence

+, -, !, ~ (Unary)

+,- (Binary)

<<, >>

<,>,<=,>=

==, !=

&
^, ^~ or ~^

&&

||

?:

Verilog Assignments

Placing values onto variables and nets are called assignments. There are three necessary forms:

1. Procedural
2. Continuous
3. Procedural continuous

Legal LHS values

An assignment has two parts, right-hand side (RHS) and left-hand side (LHS) with an equal symbol (=) or a
less than-equal symbol (<=) in between.

Assignment Type Left-hand Side

Procedural o Variables (vector or scalar)


o Bit-select or part-select of an integer, vector reg, or time variable.
o Memory word.
o Concatenation of any of the above.

Continuous o Net (vector or scalar)


o Bit-select or part-select of a vector net.
o Concatenation of bit-selects and part-selects.

Procedural Continuous o Variable or net (scalar/vector)


o Part-select or bit-select of a vector net.

The RHS can contain any expression that evaluates to a final value while the LHS indicates a variable or net
to which RHS's value is being assigned.

Procedural Assignment

Procedural assignments occur within procedures such as initial, always, task, and functions are used to place
values onto variables. The variable will hold the value until the next assignment to the same variable.

The value will be placed onto the variable when the simulation executes this statement during simulation
time. This can be modified and controlled the way we want by using control flow statements such as if-else-
if, looping, and case statement mechanisms.

reg [7:0] data;


integer count;
real period;

initial begin
data = 8'h3e;
period = 4.23;
count = 0;
end

always @ (posedge clk)


count++;

Variable Declaration Assignment

An initial value can be placed onto a variable at the time of its declaration. The assignment does not have the
duration and holds the value until the next assignment to the same variable happens.

Continuous Assignment

This is used to assign values onto scalar and vector nets. And it happens whenever there is a change in the
RHS.

It provides a way to model combinational logic without specifying an interconnection of gates and makes it
easier to drive the net with logical expressions.

// Example model of an AND gate


wire a, b, c;
assign a = b & c;

Whenever b or c changes its value, the whole expression in RHS will be evaluated and updated with the new
value.

Verilog Timing Control

Timing control statements are required in simulation to advance time. The time at which procedural
statements will get executed shall be specified using timing controls.

There are the following types of timing controls in Verilog:

o Edge sensitive event control


o Level sensitive event control

The delay control is a way of adding a delay between when the simulator encounters the statement and when
it executes.

The event expression allows the statement to be delayed until the occurrence of some simulation event,
which can change of value on a net or variable or an explicitly named event triggered in another procedure.

Edge Sensitive Event Control

In Verilog, the @ character specifies an edge-sensitive event control that blocks until there is a transition in
value (an edge) for one of the event's identifiers.

The edge events are queued and then serviced by @(...) guards, rather than @(?) being a guard that waits on
edge events, blocking until an edge event happens.

The only edge events that matter to an @(...) guard are those that happen while it is waiting. Edge events that
happen before reaching the guard are irrelevant to the guard.

Level Sensitive Event Control

A procedural statement's execution can be delayed until a condition becomes true and accomplished with
the wait keyword. And it is a level-sensitive control.

The wait statement evaluates a condition, and if it is false, the procedural statements remain blocked until the
condition becomes true.

module tb;
reg [3:0] ctr;
reg clk;

initial begin
{ctr, clk} <= 0;
wait (ctr);
$display ("T=%0t Counter reached non-zero value 0x%0h", $time, ctr);
wait (ctr == 4) $display ("T=%0t Counter reached 0x%0h", $time, ctr);
$finish;
end
always #10 clk = ~clk;
always @ (posedge clk)
ctr <= ctr + 1;
endmodule

After completion the execution, it produces the following output:

ncsim> run
T=10 Counter reached non-zero value 0x1
T=70 Counter reached 0x4
T=90 Counter reached 0x5
T=170 Counter reached 0x9
Simulation complete via $finish(1) at time 170 NS + 1

Verilog Gate Delay

Verilog gate delays specify how values propagate through nets or gates. The gate delay declaration specifies
a time needed to propagate a signal change from the gate input to its output.

The gate delay declaration can be used in gate instantiations. The delays can also be used for delay control in
procedural statements.

Digital elements are binary entities and only hold either of the two values, 0 and 1. The transition from 0 to 1
and 1 to 0 has a transitional delay, and therefore each gate element propagates the value from input to its
output.

For example, a two-input AND gate has to switch the output to 1 if both inputs become 1 and back to 0 when
inputs become 0.Elon Musk Faces SEC Investigation and Lawsuit by Twitter Investors for Delayed
Disclosure

The net delay declaration specifies a time needed to propagate values from drivers through the net. It can be
used in continuous assignments and net declarations.

This gate and pin to pin delays can be specified in Verilog when instantiating logic primitives.

Rise, Fall, and Turn-Off Delays

The delays declaration can contain up to three values, such as rise, fall, and turn-off delays.
o The time taken for the output of a gate to change from some value to 1 is called a rise delay.
o The time taken for the output of a gate to change form some value to 0 is called a fall delay.
o The time taken for the output of a gate to change from some value to high impedance is called turn-
off delay.

If only one delay value is specified, then it is used for all signal changes. The default delay is zero.

If two delays are specified, then the first delay specifies the rise delay, and the second delay specifies the fall
delay.

If the signal changes to high-impedance or unknown, then the smaller value will be used.

If three values are given, then the first value specifies the rise delay, the second specifies the fall delay, and
the third specifies the turn-off delay. If the signal changes to an unknown value, then the smallest of these
three values will be used.
Min, Typ, and Max Delays

Delays are neither the same in different parts of the fabricated chip nor the same for different temperatures
and other variations. So Verilog also provides an extra level of control for each of the delay types mentioned
above.

Every digital gate and transistor cell has a minimum, typical, and maximum delay specified based on process
node and is typically provided by libraries from fabrication foundry.

For rise, fall, and turn-off delays, the three values min, typ, and max can be specified and stand for minimum,
typical and maximum delays.

This is another level of delay control in Verilog. Only one of the min, typ, and max values can be used in the
entire simulation run.

It is specified at the start of the simulation and depends on the simulator used. The typ is the default value.

The min value is the minimum delay value that the gate is expected to have.

The typ value is the typical delay value that the gate is expected to have.

The max value is the maximum delay value that the gate is expected to have.

You might also like