Special Language Tokens: System Tasks and Functions
Special Language Tokens: System Tasks and Functions
• 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
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
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
• 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
• 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)
• No multi-dimentional arrays
reg var[1:10] [1:100]; // WRONG!!
• 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
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
• == logical equality
Return 0, 1 or x
• != logical inequality
• === case equality
Return 0 or 1
• !== case inequality
A
1
Y
B Y = (sel)? A : B;
0
sel
Arithmetic Operators (i)
• +, -, *, /, %
• 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
f .. // declarations
inN outM .. // description of f (maybe
.. // sequential)
endmodule
• 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
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;
endmodule
Structural Model (Gate Level)
• 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
Figure 2.25 b
Behavioral Modeling
Initial and Always Blocks
endmodule
Example
initial begin
#10 a = 1; b = 0;
#10 a = 0; b = 1;
end
sum = a + b + cin;
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;
E.g.
module count(Y, start);
output [3:0] Y;
input 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
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;
reg [3:0] Y;
wire start;
integer i;
initial
Y = 0;
Typical example:
clock generation in test modules
module test;
endmodule
Blocking vs. Nonblocking
• 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
• 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
• 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 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;
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