0% found this document useful (0 votes)
75 views93 pages

Special Language Tokens: System Tasks and Functions

- Special language tokens in Verilog begin with $ or # and are used to define system tasks and delay specifications. - There are two main data types in Verilog: nets, which are physical connections between devices, and registers, which implicitly store values. - Nets include wire, wand, wor, tri, trireg and supply nets. Registers include integer, time, and real variables.

Uploaded by

Vamsee Krishna
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
75 views93 pages

Special Language Tokens: System Tasks and Functions

- Special language tokens in Verilog begin with $ or # and are used to define system tasks and delay specifications. - There are two main data types in Verilog: nets, which are physical connections between devices, and registers, which implicitly store values. - Nets include wire, wand, wor, tri, trireg and supply nets. Registers include integer, time, and real variables.

Uploaded by

Vamsee Krishna
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 93

Special Language Tokens

• $<identifier>: System tasks and functions


– $time
– $stop
– $finish
– $monitor
– $ps_waves
– $gr_waves
– $gr_regs
• #<delay specification>
– used in
• gate instances and procedural statements
• unnecessary in RTL specification
Data Types
• Nets
– Nets are physical connections between devices
– Nets always reflect the logic value of the driving device
– Many types of nets, but all we care about is wire
• Registers
– Implicit storage – unless variable of this type is
modified it retains previously assigned value
– Does not necessarily imply a hardware register
– Register type is denoted by reg
- int is also used
Class of Signals

• Nets: physical
connection between
hardware elements

• Registers: Store
value even if
disconnected
Nets

• wire/tri
• wand/triand
• wor/trior
• Supply0,supply1,tri
0,tri1,trireg
Data types
• Net
– physical wire between devices
– the default data type
– used in structural modeling and continuous assignment
– types of nets
• wire, tri : default Simpler than VHDL
• wor, trior : wire-ORed
Only Syntactical
• wand, triand : wire-ANDed
Difference
• trireg : with capacitive storage
• tri1 : pull high
• tri0 ; pull low
• supply1 ; power
• supply0 ; ground
Ports and Data Types
• Correct data types for ports

Module

Register/net net register/net net


input output

net

inout

net
Lexical Conventions in
Verilog
Type of lexical tokens :
•Operators ( * )
•White space
•Comment
•Number ( * )
•String
•Identifier
•Keyword ( * ) Note : * will be discussed
System Tasks
Always
Alwayswritten
writteninside
insideprocedures
procedures

• $display(“..”, arg2, arg3, ..);  much like printf(), displays formatted


string in std output when encountered
• $monitor(“..”, arg2, arg3, ..);  like $display(), but .. displays string each
time any of arg2, arg3, .. Changes
• $stop;  suspends sim when encountered
• $finish;  finishes sim when encountered
• $fopen(“filename”);  returns file descriptor (integer); then, you can use
$fdisplay(fd, “..”, arg2, arg3, ..); or $fmonitor(fd, “..”, arg2, arg3, ..); to
write to file
• $fclose(fd);  closes file
• $random(seed);  returns random integer; give her an integer as a seed
Reg and Parameters
• Reg
– variables used in RTL description
– a wire, a storage device or a temporary variable
– reg : unsigned integer variables of varying bit width
– integer : 32-bit signed integer
– real : signed floating-point
– time : 64-bit unsigned integer
• Parameters
– run-time constants
Nets (ii)
A wire Y; // declaration
Y
B assign Y = A & B;

wand Y; // declaration
assign Y = A;
A assign Y = B;
Y
B
wor Y; // declaration
assign Y = A;
assign Y = B;

dr
tri Y; // declaration
A Y
assign Y = (dr) ? A : z;
Registers

• Variables that store values


• Do not represent real hardware but ..
• .. real hardware can be implemented with registers
• Only one type: reg
reg A, C; // declaration
// assignments are always done inside a procedure
A = 1;
C = A; // C gets the logical value 1
A = 0; // C is still 1
C = 0; // C is now 0
• Register values are updated explicitly!!
Integer & Real Data Types

• Declaration
integer i, k;
real r;
• Use as registers (inside procedures)
i = 1; // assignments occur inside procedure
r = 2.9;
k = r; // k is rounded to 3
• Integers are not initialized!!
• Reals are initialized to 0.0
Time Data Type

• Special data type for simulation time measuring


• Declaration
time my_time;

• Use inside procedure


my_time = $time; // get current sim time

• Simulation runs at simulation time, not real time


Arrays (i)

• Syntax
integer count[1:5]; // 5 integers
reg var[-15:16]; // 32 1-bit regs
reg [7:0] mem[0:1023]; // 1024 8-bit regs
• Accessing array elements
– Entire element: mem[10] = 8’b 10101010;
– Element subfield (needs temp storage):
reg [7:0] temp;
..
temp = mem[10];
var[6] = temp[2];
Arrays (ii)

• Limitation: Cannot access array subfield or entire


array at once
var[2:9] = ???; // WRONG!!
var = ???; // WRONG!!

• No multi-dimentional arrays
reg var[1:10] [1:100]; // WRONG!!

• Arrays don’t work for the Real data type


real r[1:10]; // WRONG !!
Strings
• Implemented with regs:
reg [8*13:1] string_val; // can hold up to 13 chars
..
string_val = “Hello Verilog”;
string_val = “hello”; // MS Bytes are filled with 0
string_val = “I am overflowed”; // “I ” is truncated

• Escaped chars:
– \n newline
– \t tab
– %% %
– \\ \
– \“ “
Logical Operators
• &&  logical AND
• ||  logical OR
• !  logical NOT
• Operands evaluated to ONE bit value: 0, 1 or x
• Result is ONE bit value: 0, 1 or x
A = 6; A && B  1 && 0  0
B = 0; A || !B  1 || 1  1
C = x; C || B  x || 0  x but
butC&&B=0
C&&B=0
Bitwise Operators (i)
•&  bitwise AND
•|  bitwise OR
•~  bitwise NOT
•^  bitwise XOR
• ~^ or ^~  bitwise XNOR

• Operation on bit by bit basis


Bitwise Operators (ii)

c = ~a; c = a & b;

• a = 4’b1010;
b = 4’b1100;

c = a ^ b;

• a = 4’b1010;
b = 2’b11;
Reduction Operators

• &  AND
• |  OR
• ^  XOR
• ~&  NAND
• ~|  NOR
• ~^ or ^~  XNOR

• One multi-bit operand  One single-bit result


a = 4’b1001;
..
c = |a; // c = 1|0|0|1 = 1
Shift Operators
• >>  shift right
• <<  shift left

• Result is same size as first operand, always zero filled


a = 4’b1010;
...
d = a >> 2; // d = 0010
c = a << 1; // c = 0100
Concatenation Operator
• {op1, op2, ..}  concatenates op1, op2, .. to single number
• Operands must be sized !!
reg a;
reg [2:0] b, c;
..
a = 1’b 1;
b = 3’b 010;
c = 3’b 101;
catx = {a, b, c}; // catx = 1_010_101
caty = {b, 2’b11, a}; // caty = 010_11_1
catz = {b, 1}; // WRONG !!
• Replication ..
catr = {4{a}, b, 2{c}}; // catr = 1111_010_101101
Relational Operators

•>  greater than


•<  less than
• >=  greater or equal than
• <=  less or equal than

• Result is one bit value: 0, 1 or x


1 > 0 1
’b1x1 <= 0 x
10 < z x
Equality Operators

• ==  logical equality
Return 0, 1 or x
• !=  logical inequality
• ===  case equality
Return 0 or 1
• !==  case inequality

– 4’b 1z0x == 4’b 1z0x x


– 4’b 1z0x != 4’b 1z0x  x
– 4’b 1z0x === 4’b 1z0x  1
– 4’b 1z0x !== 4’b 1z0x  0
Conditional Operator
• cond_expr ? true_expr : false_expr

• Like a 2-to-1 mux ..

A
1
Y
B Y = (sel)? A : B;
0
sel
Arithmetic Operators (i)

• +, -, *, /, %

• If any operand is x the result is x


• Negative registers:
– regs can be assigned negative but are treated as unsigned
reg [15:0] regA;
..
regA = -4’d12; // stored as 216-12 = 65524

regA/3 evaluates to 21861


Arithmetic Operators (ii)

• Negative integers:
– can be assigned negative values
– different treatment depending on base specification or not
reg [15:0] regA;
integer intA;
..
intA = -12/3; // evaluates to -4 (no base spec)
intA = -’d12/3; // evaluates to 1431655761 (base spec)
Operator Precedence

Use parentheses to
enforce your
priority
Hierarchical Design

Top
TopLevel
Level E.g.
Module
Module

Full
FullAdder
Adder
Sub-Module
Sub-Module Sub-Module
Sub-Module
11 22

Half
HalfAdder
Adder Half
HalfAdder
Adder
Basic
BasicModule
Module Basic
BasicModule
Module Basic
BasicModule
Module
11 22 33
Module

module my_module(out1, .., inN);

in1 my_module out1 output out1, .., outM;

in2 out2 input in1, .., inN;

f .. // declarations
inN outM .. // description of f (maybe
.. // sequential)

endmodule

Everything you write in Verilog must be inside a module


exception: compiler directives
Structural Modeling

• Execution: Concurrent
• Format (Primitive Gates):
and G2(Carry, A, B);
• First parameter (Carry) – Output
• Other Inputs (A, B) - Inputs
Verilog Built-in Primitives

Ideal Resistive
MOS switch gates

and buf nmos rnmos pullup


nand not pmos rpmos pulldown
or bufif0 cmos rcmos
nor bufif1 tran rtran
xor notif0 tranif0 rtranif0
xnor notif1 tranif1 rtranif1
Example: Half Adder

A module half_adder(S, C, A, B);


S
output S, C;
B input A, B;
C
wire S, C, A, B;

A S assign S = A ^ B;
Half assign C = A & B;
Half
B Adder
Adder C
endmodule
Example: Full Adder
in1 A Half S I1 A Half S sum
Half Half
Adder
Adder11 I2 Adder
Adder
in2 B C B C I3
ha1
ha1 ha2
ha2 cout

cin
module full_adder(sum, cout, in1, in2, cin);
output sum, cout;
input in1, in2, cin;

wire sum, cout, in1, in2, cin;


Module wire I1, I2, I3; Instance
name name
half_adder ha1(I1, I2, in1, in2);
half_adder ha2(sum, I3, I1, cin);

assign cout = I2 || I3;

endmodule
Structural Model (Gate Level)

• Built-in gate primitives:


and, nand, nor, or, xor, xnor, buf, not, bufif0,
bufif1, notif0, notif1

• Usage:
nand (out, in1, in2); 2-input NAND without delay
and #2 (out, in1, in2, in3); 3-input AND with 2 t.u. delay
not #1 N1(out, in); NOT with 1 t.u. delay and instance name
xor X1(out, in1, in2); 2-input XOR with instance name

• Write them inside module, outside procedures


Example: Half Adder,
2nd Implementation

A module half_adder(S, C, A, B);


S
output S, C;
B input A, B;
C
wire S, C, A, B;

xor #2 (S, A, B);


and #1 (C, A, B);
Assuming:
• XOR: 2 t.u. delay endmodule
• AND: 1 t.u. delay
Gate Level Modeling
• A logic circuit can be designed by use of logic gates.
• Verilog supports basic logic gates as predefined primitives.
These primitives are instantiated like modules except that
they are predefined in Verilog and do not need a module
definition.
Gate gate_name(out,in1,in2…)
Design of 4:1 Multiplexer
Contd..
4 bit full adder
Declaration:
Code contd..
Quiz

• Write Verilog code to implement the following circuit


using the gate level primitives.

Figure 2.25 b
Behavioral Modeling
Initial and Always Blocks

• Basic components for behavioral modeling


initial always
begin begin
… imperative statements … … imperative statements …
end end

Runs when simulation starts Runs when simulation starts


Terminates when control Restarts when control reaches
reaches the end the end
Good for providing stimulus Good for modeling/specifying
hardware
Procedural Blocks
• Procedural Blocks are constructed from the
following components.
– Procedural Assignment Statements
– High-Level Constructs
“Always” Blocks

• Start execution at sim time zero and


continue until sim finishes
Events (i)
• @
always @(signal1 or signal2 or ..) begin
..
end execution
executiontriggers
triggersevery
every
time
timeany
anysignal
signalchanges
changes

always @(posedge clk) beginexecution triggers every


execution triggers every
.. time
timeclk
clkchanges
changes
end from 0 to 1
from 0 to 1

execution triggers every


always @(negedge clk) beginexecution triggers every
..
time
timeclk
clkchanges
changes
end
from
from11toto00
Examples
• 3rd half adder implem • Behavioral edge-triggered
module half_adder(S, C, A, DFF implem
B); module dff(Q, D, Clk);
output S, C; output Q;
input A, B; input D, Clk;

reg S,C; reg Q;


wire A, B; wire D, Clk;

always @(A or B) begin always @(posedge Clk)


S = A ^ B; Q = D;
C = A && B;
end endmodule

endmodule
Example

always @(res or posedge clk) begin


res if (res) begin
a Y = 0;
b Y W = 0;
end
else begin
c W Y = a & b;
W = ~c;
clk end
end
Initial and Always
• Run until they encounter a delay

initial begin
#10 a = 1; b = 0;
#10 a = 0; b = 1;
end

• or a wait for an event


always @(posedge clk) q = d;
always begin wait(i); a = 0; wait(~i); a = 1; end
Procedural Assignment
• Inside an initial or always block:

sum = a + b + cin;

• Just like in C: RHS evaluated and assigned to LHS


before next statement executes

• RHS may contain wires and regs


– Two possible sources for data
• LHS must be a reg
– Primitives or cont. assignment may set wire values
Procedural Assignments
Procedural Execution Control
• Execution of Procedural Blocks can be specified in
different ways
– Simple Delays: #<delay>
• Specify delay before and after execution for a number of time
steps.
– Edge-Sensitive Controls: always @ (<edge><signal>)
• Execution occurs only at a signal edge. Optional keywords
“posedge” or “negedge” can be used to specify signal edge for
execution.
Conditional Statements: if else
Procedural Statements: if
E.g. 4-to-1 mux:
module mux4_1(out, in, sel);
output out;
if (expr1) input [3:0] in;
true_stmt1; input [1:0] sel;

reg out;
else if (expr2) wire [3:0] in;
wire [1:0] sel;
true_stmt2;
.. always @(in or sel)
if (sel == 0)
else out = in[0];
def_stmt; else if (sel == 1)
out = in[1];
else if (sel == 2)
out = in[2];
else
out = in[3];
endmodule
Conditional Statements: case
Procedural Statements: case
E.g. 4-to-1 mux:
module mux4_1(out, in, sel);
case (expr) output out;
input [3:0] in;
input [1:0] sel;
item_1, .., item_n: stmt1;
reg out;
item_n+1, .., item_m: stmt2; wire [3:0] in;
.. wire [1:0] sel;

default: def_stmt; always @(in or sel)


case (sel)
0: out = in[0];
endcase 1: out = in[1];
2: out = in[2];
3: out = in[3];
endcase
endmodule
casex and casez
Looping Statements: repeat
Procedural Statements: repeat

E.g.
module count(Y, start);
output [3:0] Y;
input start;

repeat (times) stmt; reg [3:0] Y;


wire start;

initial
Can
Canbebeeither
eitheran
an Y = 0;
integer
integeror
oraavariable
variable
always @(posedge start)
repeat (4) #10 Y = Y + 1;
endmodule
Looping Statements: while
While Loops

• A increasing sequence of values on an output

reg [3:0] i, output;

i = 0;
while (I <= 15) begin
output = i;
#10 i = i + 1;
end
Procedural Statements: while
E.g.
module count(Y, start);
output [3:0] Y;
input start;

reg [3:0] Y;
wire start;
integer i;
while (expr) stmt;
initial
Y = 0;

always @(posedge start) begin


i = 0;
while (i < 3) begin
#10 Y = Y + 1;
i = i + 1;
end
end
endmodule
Looping Statements: for
For Loops

• A increasing sequence of values on an output

reg [3:0] i, output;

for ( i = 0 ; i <= 15 ; i = i + 1 ) begin


output = i;
#10;
end
Procedural Statements: for
for (init_assignment; cond; step_assignment)
stmt;
E.g.
module count(Y, start);
output [3:0] Y;
input start;

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: forever

Typical example:
clock generation in test modules
module test;

reg clk; TTclk ==20


20time
timeunits
units
clk
forever stmt;
initial begin
clk = 0;
forever #10 clk = ~clk;
Executes
Executesuntil
untilsim
sim end
finishes
finishes other_module1 o1(clk, ..);
other_module2 o2(.., clk, ..);

endmodule
Blocking vs. Nonblocking

• Verilog has two types of procedural assignment

• Fundamental problem:
– In a synchronous system, all flip-flops sample
simultaneously
– In Verilog, always @(posedge clk) blocks run in some
undefined sequence
Non-blocking Assignments
Nonblocking rule:
RHS evaluated when
• This version does work: assignment runs

reg d1, d2, d3, d4;

always @(posedge clk) d2 <= d1;


always @(posedge clk) d3 <= d2;
LHS updated only after
always @(posedge clk) d4 <= d3;
all events for the current
instant have run
Nonblocking Can Behave Oddly

• A sequence of nonblocking assignments don’t


communicate a <= 1;
a = 1; b <= a;
b = a; c <= b;
c = b;
Nonblocking assignment:
Blocking assignment: a=1
a=b=c=1 b = old value of a
c = old value of b
Nonblocking Looks Like Latches

• RHS of nonblocking taken from latches


• RHS of blocking taken from wires
a = 1;
“ 1
a b c ”
b = a;
c = b;
1 a
a <= 1;
b <= a; “ b ”
c <= b;
c
Dataflow Modeling

• In complex designs the number of gates is very


large

• Currently, automated tools are used to create a


gate-level circuit from a dataflow design
description. This process is called logic synthesis
Dataflow Modeling

• Uses continuous assignment statement


– Format: assign [ delay ] net = expression;
– Example: assign sum = a ^ b;

• Delay: Time duration between assignment from


RHS to LHS

• All continuous assignment statements execute


concurrently

• Order of the statement does not impact the design


Dataflow Modeling (cont.)

• Example:

`timescale 1ns/100ps
module HalfAdder (A, B, Sum, Carry);
input A, B;
output Sum, Carry;
assign #3 Sum = A ^ B;
assign #6 Carry = A & B;
endmodule
Restrictions on Data Types

• Data Flow and Structural Modeling


– Can use only wire data type
– Cannot use reg data type

• Behavioral Modeling
– Can use only reg data type (within initial and always
constructs)
– Cannot use wire data type
Mixed Model
Code that contains various both structure and behavioral styles
module simple(Y, c, clk, res);
output Y;
input c, clk, res;

reg Y;
wire c, clk, res;
res wire n;
c n Y not(n, c); // gate-level
clk
always @(res or posedge clk)
if (res)
Y = 0;
else
Y = n;
endmodule
Example: Half Adder

A module half_adder(S, C, A, B);


S
output S, C;
B input A, B;
C
wire S, C, A, B;

A S assign S = A ^ B;
Half assign C = A & B;
Half
B Adder
Adder C
endmodule
Sample Design
module fadder ( sum, cout, a, b , ci ); Full adder sum
// port declaration a
b
output sum, cout; ci
input a, b, ci;
//reg sum, cout;
cout
// behavior description
//always @( a or b or ci )
//begin
assign sum = a ^ b ^ ci;
Simpler than VHDL
assign cout = ( a&b ) | ( b&ci ) | ( ci&a);
end
Only Syntactical
Difference
Test Bench
module main;
reg a, b, c;
wire sum, carry;

fulladder add(a,b,c,sum,carry);
initial
begin
a = 0; b = 0; c = 0;
#5
a = 0; b = 1; c = 0;
#5
a = 1; b = 0; c = 1;
#5
a = 1; b = 1; c = 1;
#5
end
endmodule
Multiplexor
• Net-list (gate-level)
module mux2_1 (out,a,b,sel) ;
output out ;
input a,b,sel ;
not (sel_, sel) ;
and (a1, a, sel_) ;
and (b1, b, sel) ;
or (out, a1, b1) ;
endmodule
Decoder
• 3-to 8 decoder with an
case(sel)
enable control 3'b000 : o = 8'b1111_1110 ;
module decoder(o,enb_,sel) ; 3'b001 : o = 8'b1111_1101 ;
output [7:0] o ; 3'b010 : o = 8'b1111_1011 ;
3'b011 : o = 8'b1111_0111 ;
input enb_ ;
3'b100 : o = 8'b1110_1111 ;
input [2:0] sel ; 3'b101 : o = 8'b1101_1111 ;
reg [7:0] o ; 3'b110 : o = 8'b1011_1111 ;
always @ (enb_ or sel) 3'b111 : o = 8'b0111_1111 ;
if(enb_) default : o = 8'bx ;
endcase
o = 8'b1111_1111 ;
endmodule
else
Priority Encoder
always @ (d0 or d1 or d2 or d3)
if (d3 == 1)
{x,y,v} = 3’b111 ;
else if (d2 == 1)
{x,y,v} = 3’b101 ;
else if (d1 == 1)
{x,y,v} = 3’b011 ;
else if (d0 == 1)
{x,y,v} = 3’b001 ;
else
{x,y,v} = 3’bxx0 ;
Parity Checker
module parity_chk(data, parity); always @ (data)
input [0:7] data; begin: check_parity
output parity; reg partial;
integer n;
reg parity;
partial = data[0];
for ( n = 0; n <= 7; n = n + 1)
begin
partial = partial ^ data[n];
end
parity <= partial;
end
endmodule
Tri-State
• The value z assign out = (sela)? a: 1’bz ;
always @ (sela or a)
if (sela)
out = a ;
else
out = 1’bz ;

• Another block
always @(selb or b)
if(selb)
out =b ;
else
out = 1’bz ;
Example: Full Adder
in1 A Half S I1 A Half S sum
Half Half
Adder
Adder11 I2 Adder
Adder
in2 B C B C I3
ha1
ha1 ha2
ha2 cout

cin
module full_adder(sum, cout, in1, in2, cin);
output sum, cout;
input in1, in2, cin;

wire sum, cout, in1, in2, cin;


Module wire I1, I2, I3; Instance
name name
half_adder ha1(I1, I2, in1, in2);
half_adder ha2(sum, I3, I1, cin);

assign cout = I2 || I3;

endmodule
Counter
module bcd_counter(count,ripple_out,clr,clk) ;
output [3:0] count ;
output ripple_out ;
reg [3:0] count ;
input clr,clk ;
wire ripple_out = (count == 4'b1001) ? 0:1 ; // combinational
always @ (posedge clk or posedge clr) // combinational + sequential
if (clr) ;
count = 0 ;
else if (count == 4'b1001)
count = 0 ;
else
count = count + 1 ;
endmodule
Register
module register (q,d,clk,clr_, set_) ;
output [7:0] q ;
input [7:0] d ;
input clk,clr_, set_ ;
reg [7:0] q ;
always @ (posedge clk or negedge clr_ or negedge set_)
if (~clr_)
q=0;
else if (~set_)
q = 8’b1111_1111 ;
else
q=d;
endmodule
A Flawed Shift Register

• This doesn’t work as you’d expect:

reg d1, d2, d3, d4;

always @(posedge clk) d2 = d1;


always @(posedge clk) d3 = d2;
always @(posedge clk) d4 = d3;

• These run in some order, but you don’t know which


Shifter
module shifter (so,si,d,clk,ld_,clr_) ;
output so ;
input [7:0] d ;
input si,clk,ld_,clr_ ; // asynchronous clear and synchronous load
reg [7:0] q ;
assign so = q[7] ;
always @ (posedge clk or negedge clr_)
if (~clr_)
q=0; ld_ d
else if (~ld_)
q=d; si so
else shifter
clk
q[7:0] = {q[6:0],si} ;
endmodule
Memory
module memory (data, addr, read, write);
input read, write;
input [4:0] addr;
inout [7:0] data;
reg [7:0] data_reg;
reg [7:0] memory [0:8'hff];
parameter load_file = "cput1.txt";
assign data = (read) ? memory [addr] : 8'hz;
always @ (posedge write)
memory[addr] = data;
initial
$readmemb (load_file, memory);
endmodule

You might also like