Professional Documents
Culture Documents
•HDL
•What is Verilog?
•Scope of Verilog
•Basic Concept of Verilog
•Lexical Convention
•Data Types
•System Task
•Modules
•Module instances
•Compiler Directive
•Modules & ports
•Port Declaration
•Various Modelling in Verilog
HDL AND ITS IMPORTANCE
in1
sum
in2
carry
endmodule
module Module_Name (Port_List) ;
...
...
<Module Internals>
...
...
endmodule
MODULE IN VERILOG
Module is a basic functional unit in Verilog. A module can be
seen as a design block with some inputs and outputs. How
that block works is written inside that module.
All the distinct blocks in design tree corresponds to a module
in Verilog. So module is just like black box with input and
output terminals and that black box interacts with the outside
environment through these terminals only.
The relationship between these input and output terminals is
hidden from the environment.
Every module definition begins with a keyword module and
ends with keyword endmodule.
Only within these two keywords functionality of a module is
specified. Each module has a module name and port list.
Module name is an identifier for that particular module and
port list contains the list of all input and output terminals for
the module.
FULL ADDER
To build a full adder from the half adder defined just now
we have to create an instance of halfadder module in
fulladder module.
This instance is given a name and ports are connected
appropriately.
Certain predefined modules of basic hardware elements
are provided in Verilog and we call them as primitives.
These primitives can be instantiated inside modules in
same way but giving them names is optional.
So a module may contain instances of primitives and
other modules.
Full Adder
a
HALF carry_out
ADDER
b
endmodule
module Module_Name(Port_List) ;
<Port Declarations>
<Internal Signals Declaration>
<Functionality>
endmodule
Blank spaces \b
tabs \t
new lines \n
White spaces have no syntactical significance and can be inserted for
better readability. Whitespace is not ignored in strings.
Comments
// The rest of the line is a comment.
/* Multiple line
comments */
Signal Values
0 Logic Zero
1 Logic One
x or X Unknown
z or Z High Impedance
Representation of Numbers
Decimal d or D
Hex h or H
Octal o or O
Binary b or B
NUMBER FORMAT
If the size is greater than the value of number, the number in the
most significant bit is extended for MSB = 0, x or z
zero extended if MSB = 1.
12'b000111010100
12'b000_111_010_100
12'o07_24
IDENTIFIERS
\5467
\.*.&
\{***}
\a+b-c
\InGate#3
KEYWORDS
Keywords are special words reserved by language, their meaning is
predefined and cannot be used as identifiers. All keywords are in lowercase.
In above circuit n1, m1, x0, x1 are nets. They are declared inside module by keyword wire.
Some other type of nets will be discussed later in advance Verilog concepts. Any undeclared nets
default to type wire.
REGISTERS
integer
The integer data type supports numeric computation in procedural code.
Integers are represented internally to the word length of the host
machine (at least 32 bits). A negative number is stored in 2’s
complement format. Registers declared as data types reg store values
as unsigned quantities,whereas integers store values as signed
quantities.
real
Accurate modeling of delay values might require the use of real data
types. Real objects are stored in double precision, typically a 64-bit
value. Real values can be specified in decimal and exponential
notation. An object of type real may not be connected to a port or
terminal of a primitive.Real numbers cannot have a range declaration
and their default value is 0.
time
The data type time supports time-related computations within
procedural code in Verilog models. Time variables are stored as
unsigned 64-bit quantities. A variable of type time may not be used in a
module port; nor may it be an input or output of a primitive. Data type
realtime stores time values in real number format. The system function
$time is invoked to get the current simulation time.
VECTORS
Nets or reg data types can be declared as vectors (multiple bit
widths). If bit width is not specified, the default is scalar (1-bit).
wire conect ;
wire [7:0] dbus ;
wire [0:15] cbus1, cbus2, cbus3 ;
reg clk ;
reg [31:0] accr ;
\n newline
\t tab
%% %
\\ \
\” “
CONSTANTS
A constant in Verilog is declared with the keyword parameter, which
declares and assigns values to the constant. The value of a constant
may not be changed during simulation but parameters (or constants)
can be changed at module instantiation or by using the defparam
statement.
parameter high_index = 22 ;
parameter av_delay = (min_delay + max_delay) / 2 ;
parameter initial_state = 8’b1011_1000 ;
GATE LEVEL MODELING
PRIMITIVES
Verilog provides a robust set of built-in gate primitives.
Primitives are like predefined modules. A logic circuit is described on gate
to gate basis using these primitives.
Primitives can be instantiated only within modules and use of identifier
name with primitive instantiation is optional.
The port list of a primitive have output(or outputs) written first, followed by
inputs.
endmodule
OPERATORS
Concatenation { } concatenation
{ { } } replication
Arithmetic + add
- subtract
* multiply
/ divide
% modulus
LOGICAL OPERATORS
A = 6 A && B 1 && 0 0
B = 0 A || (!B) 1 || 1 1
C = x C || B x || 0 x
C && B x && 0 0
REDUCTION OPERATORS
|(010x10) 0 | 1 | 0 | x | 1 | 0 1
BITWISE OPERATORS
a = 4’b1010
d = a >> 2 d = 0010
c = a << 1 c = 0100
CONCATENATION OPERATOR
{ op1, op2, … }
This operator concatenates op1, op2, … to a single number. The operand should be sized, no
unsized constant operand is allowed.
If the operand A is bit pattern 1011 and
the operand B is the bit pattern 0001,
then {A, B} is the bit pattern 1011_0001
{0011, {{01}, {10}}} = 0011_0110
Replication of same operand can be expressed by using a replication constant which specifies how
many times to replicate the number inside the brackets ({ }).
a = 1’b1
b = 3’b010
c = 3’b101
catr = { 4{a}, b, 2{c} }
catr = {1, 1, 1, 1, 010, 101, 101}
catr = 1111010101101
RELATIONAL OPERATOR
1 > 0 1
‘b1x1 <= 0 x
10 < z x
EQUALITY OPERATORS
== logical equality
!= logical inequality
=== case equality
!== case inequality
The case equality operators are used to determine whether two operands match identically on a bit
by bit basis, including bits that have values “x” or “z”, so they produce either 0 or 1 result.
The logical equality operators do the same purpose but produce a “x” result if any bit of any
operand is “x” or “z”.
4’b1z0x == 4’b1z0x x
4’b1z0x != 4’b1z0x x
4’b1z0x === 4’b1z0x 1
4’b1z0x !== 4’b1z0x 0
CONDITIONAL OPERATORS
? :
The Verilog conditional operator selects an expression for evaluation based on the value of
a conditional expression.
conditional_expn ? true_expn : false_expn
If the conditional_expn evaluates to Boolean true (logical 1), then true_expn is
evaluated; otherwise if it evaluates to Boolean false (logical 0), then false_expn is
evaluated. In case result is ambiguous (x) then both true_expn and false_expn are
evaluated and their results are compared, bit by bit, to return for each bit position an x if the
bits are different and the value of bit if they are same.
Conditional operators can be nested to any depth.
bus_data = control_data ? Adder_out : 24’bz;
out = (a == 5) ? (cntrl ? m : n) : (cntrl ? S : t);
The action of conditional operator is like a 2:1 multiplexer.
A
Y = (sel)
Y ? A : B ;
sel
ARITHMETIC OPERATORS
+ add - subtract
* Multiply / divide
% modulus
Arithmetic operations are fully implemented in Verilog for scalar and vector
nets and registers as 2’s complement arithmetic. The size of the result of an
arithmetic expression is determined by the largest of the sizes of operands
and left hand side target.
Negative numbers are stored in 2’s complement form. In case of a net, a
reg register and an integer constant in base format notation, stored number
is interpreted as unsigned value. We can store signed value in an integer
register or an integer constant in decimal notation.
If any of the operand is x, the result is also x. the operators + and - can
also work as unary operators for specifying sign of the operand. Modulus
operator which produces remainder from the division of two operands,
takes sign of first operand as sign of the remainder.
PRECEDENCE OF OPERATOR
+ - ! ~ unary HIGHEST PRECEDENCE
* / %
+ - binary
<< >>
< <= => >
== != === !==
& ~&
^ ^~ ~^
| ~|
&&
||
? : conditional LOWEST PRECEDENCE
PROPAGATION DELAYS
Any input pulse should stay for the duration of propagation delay of a
gate so that it could affect the output.
Delay time between the change in a right-hand-side operand and when
the new value is assigned to the left hand side can be specified in
continuous assignment statements similar to specification of gate delays.
•Procedural Statements
• Case, casez and casex statements
• full_case and parellel_case directives
• For, repeat, while and forever loops
• integers
• Self-disabling blocks
• Combinational logic synthesis
• Tasks, Functions and
• Finite State Machines
• Designing state machines
Memories
– Understanding tasks
• State machine architectures – Task arguments
• Verilog code-based FSM strategy – Task synchronization
– Tasks and synthesis
• State encoding – Functions
• Unreachable states & safe design – Memory arrrays
practices – RAM modelling and synthesis
• One-hot machines – $readmemb and $readmemh
OUTPUT = ?
The statements written inside these blocks are called procedural
assignments (statements) and normally they execute sequentially. These
statements assigns values to the register data type variables(reg, integer,
real or time).
Left hand side of procedural assignments can be any of register
variables, their bit select, part select or concatenation, while right hand
side should be an expression that evaluates to a value and may use any
of the operators.
There are two types of procedural assignments : blocking and
non-blocking.
Blocking assignments written inside an always or initial block execute in
the same order in which they are written. A statement that follows a
blocked statement in sequential flow cannot be executed until the
preceding statement has completed execution. These assignment use
the = operator.
target1 = expression1 ; executed 1st
target2 = expression2 ; executed 2nd
target3 = expression3 ; executed 3rd
Non-blocking assignment behave differently than blocked assignments, it
does not block the execution of the statements that follows it in listed code.
Non-blocking are made using <= operator.
The RHS expression of all non-blocking assignments in a block are
evaluated concurrently and independent of their order with respect to each
other, later the assignments are made to LHS.
begin begin
A= 1 ; A= 1 ;
B = 0 ; B = 0 ;
. . . . . .
end end
initial initial
begin begin
A= 1 ; A= 1 ;
B = 0 ; B = 0 ;
. . . . . .
A = B ; // uses B = 0 B = A ; // uses A = 1
B = A ; // uses A = 0 A = B ; // uses B = 1
end end
DELAYS
Three types of delay specification are allowed for procedural assignments.
1. Regular Delay - It is specified by simply placing a non-zero number with # to the left of a
procedural statements. It delays the execution of statement by specified number of time units
relative to the time when statement is encountered in the activity flow.
#3 tran = pas1 & pas2 ;
2. Intra Assignment Delay - If we write delay format (#delaytime) to the right of assignment
operator, then it computes the RHS expression at the same time but delays the assignment
of computed value to LHS target by specified number of time units.
tran = #5 pas1 & pas2 ;
3. Zero Delay - This delay specification is used to ensure that a statement is executed in the
last, after all other statements are executed in that simulation time. It is specified by placing
#0 before the assignment (to left most).
tran1 = pas11 & pas12 ;
#0 tran2 = pas21 & pas22 ; // executed last
tran3 = pas31 & pas32 ;
● How would the following code execute?
module
BLOCK_NONBLOCK(clock,a1,b1,c1,a2,b2,c2,a3,b3,c3,a4,b4,c4,y1,y2,y3,y4);
input clock, a1,b1,c1,a2,b2,c2,a3,b3,c3,a4,b4,c4;
output y1,y2,y3,y4 ;
reg y1,y2,y3,y4;
reg m1,m2,m3,m4;
endmodule
EVENT CONTROL
Frequently, we want to continue execution only when some specified event
(signal transition) occurs. We have two types of event control mechanisms
in Verilog: edge triggered and level sensitive.
1. Edge Triggered - Operator @ is used to delay the execution until occurrence of the specified
edge transition.
@(event) proc_statement ; 1 -> x
1 -> z
@(sig) // continue execution at transition in sig
1 -> 0
@(posedge sig) // continue execution at positive edge transition in sig x -> 0
z -> 0
0 -> x
0 -> z
@(negedge sig) // continue execution at negative edge transition in sig 0 -> 1
if (expr1)
module mux4_1 (out, in, sel);
true_stmt1; output out;
else if (expr2) input [3:0] in;
input [1:0] sel;
true_stmt2;
.. reg out
wire [3:0] in;
else wire [1:0] sel;
reg [3:0] Y;
wire start;
integer I;
initial
Y = 0;
always @ (posedge start)
for (I = 0, I<3; i = i+1)
# 10 Y = Y + 1;
endmodule
PROCEDURAL STATEMENTS : while
module count (Y, start);
while (expr) stmt; output [3:0] Y;
input start;
reg [3:0] Y;
wire start;
integer I;
initial
Y = 0;
always @ (posedge start)
begin
I = 0;
while (I < 3)
begin
# 10 Y = Y + 1;
i =iI + 1;
end
end
end module
PROCEDURAL STATEMENTS : repeat
initial
Y = 0;
always @ (posedge start)
repeat (4) # 10 Y = Y + 1;
end module
PROCEDURAL STATEMENTS : forever
forever stmt;
clock generation in test modules
module test; T = 20 time units
clk
reg clk;
Executes until sim
finishes initial
begin
clk = 0;
forever # 10 clk = ~ clk;
end
other_module1 01 (clk, ..);
other_module2 02 (..,clk,..);
endmodule
Difference between if-else and ternary(X
:) operator
value =1'bx ? B : C;
if (1'bx)
value = B;
else
value = C;
“Case” Statement
always@(sel, a, b, c, d)
case sel is
0: y = A;
1: y =B;
2: y =C;
Default: y = D;
end case;
A 00
B 01
Y
C 10
D 11
SEL
D Flip Flop
T Flip Flop