Verilog HDL
HDLs
 Hardware Description Languages
 Widely used in logic design
 Verilog and VHDL
 Describe hardware using code
 Document logic functions
 Simulate logic before building
 Synthesize code into gates and layout
 Requires a library of standard cells
Taste of Verilog
Module name
Module ports
module Add_half ( sum, c_out, a, b );
input
a, b;
Declaration of port
modes
output
sum, c_out;
wire
c_out_bar;
Declaration of internal
signal
xor (sum, a, b);
nand (c_out_bar, a, b);
not (c_out, c_out_bar);
endmodule
Verilog keywords
Instantiation of primitive
gates
a
b
sum
c_out_bar
c_out
Behavioral Description
module Add_half ( sum, c_out, a, b );
input
a, b;
output
sum, c_out;
a
Add_half
reg sum, c_out;
always @ ( a or b )
b
begin
sum = a ^ b;
// Exclusive or
c_out = a & b;
// And
end
endmodule
sum
c_out
Example of Flip-flop
module Flip_flop ( q, data_in, clk, rst );
input
data_in, clk, rst;
output
q;
reg q;
always @ ( posedge clk )
begin
if ( rst == 1) q = 0;
else q = data_in;
end
endmodule
rst
data_in
q
clk
Declaration of synchronous behavior
Procedural statement
Gate Delay
 and (yout, x1, x2);





// default, zero gate delay
and #3 (yout, x1, x2);
// 3 units delay for all transitions
and #(2,3) G1(yout, x1, x2); // rising, falling delay
and #(2,3) G1(yout, x1, x2), G2(yout2, x3, x4);
// Multiple instances
a_buffer #(3,5,2) (yout, x); // UDP, rise, fall, turnoff
bufif1 #(3:4:5, 6:7:9, 5:7:8) (yout, xin, enable);
// min:typ:max / rise, fall, turnoff
•Simulators simulate with only one of min, typ and max delay values
•Selection is made through compiler directives or user interfaces
•Default delay is typ delay
Time Scales
 Time scale directive: ‘ timescale <time_unit>/<time_precision>
 time_unit -> physical unit of measure, time scale of delay
 time_precision -> time resolution/minimum step size during
simulation
 time_unit  time_precision
Unit/precision Delay
specification
Simulator time Delay value in
step
simulation
1ns / 100ps
#4
0.1ns
4.0ns
100ns / ns
#4
1ns
400ns
10ns / 100ps
#4.629
0.1ns
46.3ns
Net Delay
……
wire #2 y_tran;
and #3 (y_tran, x1, x2);
buf #1 (buf_out, y_tran);
and #3 (y_inertial, x1, x2);
……
x1
2
4
6
8
10
2
4
6
8
10
2
4
6
8
10
2
4
6
8
10
2
4
6
8
10
x2
y_inertial
x1
y_tran
x2
buf_out
y_tran
y_inertial
buf_out
Structural vs. Behavioral Descriptions
module my_module(…);
…
assign …; // continuous assignment
and (…); // instantiation of primitive
adder_16 M(…); // instantiation of module
always @(…)
begin … end
initial
begin … end
endmodule
Structural, no order
Behavior, in order in each procedure
Behavioral Statements
initial | always
single_statement; |
begin
block_of_statements;
end
 initial
 Activated from tsim = 0
 Executed once
 Initialize a simulation
 always
 Activated from tsim = 0
 Executed cyclically
 Continue till simulation
terminates
Example of Behavioral Statement
module clock1 ( clk );
parameter half_cycle = 50;
parameter max_time = 1000;
output clk;
reg clk;
initial
clk = 0;
always
begin
#half_cycle clk = ~clk;
end
initial
#max_time $finish;
endmodule
clk
50
100 150 200
tsim
Assignment
 Continuous assignment
 Values are assigned to net variables due to some
input variable changes
 “assign …=… “
 Procedural assignment
 Values are assigned to register variables when
certain statement is executed in a behavioral
description
 Procedural assignment, “=“
 Procedural continuous assignment, “assign …=…
[deassign] “
 Non-blocking assignment, “<=“
Procedural Continuous Assignment
 Continuous assignment establishes static binding for
net variables
 Procedural continuous assignment (PCA) establishes
dynamic binding for variables
 “assign … deassign” for register variables only
“assign … deassign” PCA
 Binding takes effect
when PCA statement is
executed
 Can be overridden by
another PCA statement
 “deassign” is optional
 “assign” takes control,
“deassign” release
control
module flop ( q, qbar, preset,
clear, clock, data );
…
assign qbar = ~q;
initial
q = 0;
always @ ( negedge clk )
q = data;
always @ ( clear or preset )
begin
if ( !preset ) assign q = 1;
else if ( !clear ) assign q = 0;
else deassign q;
end
endmodule
Example of assign
module mux4_PCA(a, b, c, d, select, y_out);
input a, b, c, d; input [1:0] select;
output y_out; reg y_out;
always @(select)
y_out changes with a;
begin
if (select == 0) assign y_out=a;
else if (select == 1) assign y_out=b;
else if (select == 2) assign y_out=c;
else if (select == 3) assign y_out=d;
else assign y_out=1’bx;
end
endmodule
Alternative
module mux4_PCA(a, b, c, d, select, y_out);
input a, b, c, d; input [1:0] select;
output y_out; reg y_out;
always @(select or a or b or c or d)
begin
Value of ‘a’ is assigned to
if (select == 0) y_out=a;
y_out at this time
else if (select == 1) y_out=b;
else if (select == 2) y_out=c;
else if (select == 3) y_out=d;
else y_out=1’bx;
end
endmodule
Blocking and Non-blocking Assignment
initial
begin
a = 1;
b = 0;
a = b; // a = 0;
b = a; // b = 0;
end
initial
begin
a = 1;
b = 0;
a <= b; // a = 0;
b <= a; // b = 1;
end
 Blocking assignment “=“
 Statement order matters
 A statement has to be executed
before next statement
 Non-blocking assignment “<=“
 Concurrent assignment
 If there are multiple non-
blocking assignments to same
variable in same behavior,
latter overwrites previous
Delay Control Operator (#)
initial
begin
#0 in1 = 0; in2 = 1;
#10 in3 = 1;
#40 in4 = 0; in5 = 1;
#60 in3 = 0;
end
Event Control Operator (@)
…
@ ( eventA or eventB ) begin
…
@ ( eventC ) begin
…
end
end
 Event -> identifier or expression
 When [email protected] is reached
 Activity flow is suspended
 The event is monitored
 Other processes keep going
 posedge: 0->1, 0->x, x->1
 negedge: 1->0, 1->x, x->0
The “wait” Construct
module modA (…);
…
always
begin
…
wait ( enable ) ra = rb;
…
end
endmodule
 Activity flow is
suspended if expression
is false
 It resumes when the
expression is true
 Other processes keep
going
Intra-assignment Delay: Blocking Assignment
// B = 0 at time 0
// B = 1 at time 4
…
#5 A = B; // A = 1
C = D;
…
A = #5 B; // A = 0
C = D;
…
A = @(enable) B;
C = D;
…
A = @(named_event) B;
C= D;
…
 If timing control operator(#,@)
on LHS
 Blocking delay
 RHS evaluated at (#,@)
 Assignment at (#,@)
 If timing control operator(#,@)
on RHS
 Intra-assignment delay
 RHS evaluated immediately
 Assignment at (#,@)
Indeterminate Assignment
module multi_assign();
reg a, b, c, d;
initial begin
#5 a = 1; b = 0; end
always @ ( posedge a ) begin
c = a;
end
always @ ( posedge a ) begin
c = b;
end
always @ ( posedge a ) begin
d = b;
end
always @ ( posedge a ) begin
d = a;
end
endmodule
 Multiple assignments
are made to same
variable in different
behaviors
 Value depends on
code order or vendor
specifications
 Similar to race-
conditions in
hardware
Activity Flow Control ( if … else )
if ( A == B ) P = d;
if ( B < C );
if ( a >= b )
begin
…
end
if ( A < B ) P = d;
else P = k;
if ( A > B ) P = d;
else if ( A < B ) P = k;
else P = Q;
 Syntax: if ( expression )
statement [ else statement ]
 Value of expression
 0, x or z => false
 Non-zero number => true
Conditional Operator ( ? … : )
always @ ( posedge clock )
yout = ( sel ) ? a + b : a – b;
Conditional operator can be applied in
• either continuous assignments
• or behavioral descriptions
The case Statement
module mux4 ( a, b, c, d, select, yout );
input a, b, c, d;
input [1:0] select;
output yout;
reg yout;
always @( a or b or c or d or select )
begin
case ( select )
0: yout = a;
1: yout = b;
2: yout = c;
3: yout = d;
default yout = 1`bx;
endcase
endmodule
 Case items are examined in
order
 Exact match between case
expression and case item
 casez – treats “z” as don’t
cares
 casex – treats both “x” and “z”
as don’t cares
The repeat Loop
…
word_address = 0;
repeat ( memory_size )
begin
memory [word_address] = 0;
word_address = word_address + 1;
end
…
The for Loop
reg [15:0] regA;
integer k;
…
for ( k = 4; k; k = k – 1 )
begin
regA [ k+10 ] = 0;
regA [ k+2 ] = 1;
end
…
Loop variables have to be either
integer or reg
The while Loop
begin cnt1s
reg [7:0] tmp;
cnt = 0;
tmp = regA;
while ( tmp )
begin
cnt = cnt + tmp[0];
tmp = tmp >> 1;
end
end
Loop activities suspend external activities
module sth ( externalSig );
input externalSig;
always
begin
while ( externalSig );
end
endmodule
The disable Statement
begin
k = 0;
for ( k = 0; k <= 15; k = k + 1 )
if ( word[ k ] == 1 ) disable ;
end
Terminate prematurely in a block of procedural statements
The forever Loop
parameter half_cycle = 50;
initial
begin : clock_loop
clock = 0;
forever
begin
#half_cycle clock = 1;
#half_cycle clock = 0;
end
end
initial
#350 disable clock_loop;
Task
module bit_counter (data, count);
input [7:0] data;
output [3:0] count; reg [3:0] count;
always @(data) t(data, count);
task t;
input [7:0] a; output [3:0] c; reg [3:0] c;
reg [7:0] tmp;
begin c = 0; tmp = a;
while (tmp)
begin
c = c + tmp[0];
tmp = tmp >> 1;
end
end
endtask
endmodule
Function
module word_aligner (w_in, w_out);
input [7:0] w_in;
output [7:0] w_out;
assign w_out = align (w_in);
function [7:0] align;
input [7:0] word;
begin
align = word;
if (align != 0)
while (align[7] == 0)
align = align << 1;
end
endfunction
endmodule
Switch Level NAND Gate
module nand_2 ( Y, A, B );
output Y;
input A, B;
supply0 GND;
supply1 PWR;
wire w;
pmos ( Y, PWR, A );
pmos ( Y, PWR, B );
nmos ( Y, w, A );
nmos ( w, GND, B );
endmodule
Vdd
B
A
Y
A
B
Assign Drive Strengths
nand ( pull1, strong0 ) G1( Y, A, B );
wire ( pull0, weak1 ) A_wire = net1 || net2;
assign ( pull1, weak0 ) A_net = reg_b;
 Drive strength is specified through an unordered pair
 one value from { supply0, strong0, pull0, weak0 , highz0 }
 the other from { supply1, strong1, pull1, weak1, highz1 }
 Only scalar nets may receive strength assignment
Latch Resulted from Unspecified Input State
module myMux( y, selA, selB, a, b );
input selA, selB, a, b;
output y;
reg y;
always @ ( selA or selB or a or b )
case ( {selA, selB} )
2’b10: y = a;
2’b01: y = b;
endcase
endmodule
b
selA’
selB
selA
selB’
a
en
latch
y
Synthesis of Loops
 repeat, for, while, forever
 Depends on
 Venders
 Timing control
 Data dependencies
 A loop is static or data-independent if the number of
iterations can by determined by the complier before
simulation
Static Loops without Internal Timing Controls –>
Combinational Logic
module count1sA ( bit_cnt, data, clk, rst );
parameter data_width = 4; parameter cnt_width = 3;
output [cnt_width-1:0] bit_cnt;
input [data_width-1:0] data; input clk, rst;
reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp;
always @ ( posedge clk )
if ( rst ) begin cnt = 0; bit_cnt = 0; end
else begin cnt = 0; tmp = data;
for ( i = 0; i < data_width; i = i + 1 )
begin
if ( tmp[0] ) cnt = cnt + 1;
tmp = tmp >> 1; end
bit_cnt = cnt;
end
endmodule
Static Loops with Internal Timing
Controls –> Sequential Logic
module count1sB ( bit_cnt, data, clk, rst );
parameter data_width = 4; parameter cnt_width = 3;
output [cnt_width-1:0] bit_cnt;
input[data_width-1:0] data; input clk, rst;
reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0]
tmp;
always @ ( posedge clk )
if ( rst ) begin cnt = 0; bit_cnt = 0; end
else begin
cnt = 0; tmp = data;
for ( i = 0; i < data_width; i = i + 1 )
@ ( posedge clk )
begin if ( tmp[0] ) cnt = cnt + 1;
tmp = tmp >> 1; end
bit_cnt = cnt;
end
endmodule
Non-Static Loops without Internal Timing Controls –>
Not Synthesizable
module count1sC ( bit_cnt, data, clk, rst );
parameter data_width = 4; parameter cnt_width = 3;
output [cnt_width-1:0] bit_cnt;
input [data_width-1:0] data; input clk, rst;
reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp;
always @ ( posedge clk )
if ( rst ) begin cnt = 0; bit_cnt = 0; end
else begin
cnt = 0; tmp = data;
for ( i = 0; tmp; i = i + 1 )
begin if ( tmp[0] ) cnt = cnt + 1;
tmp = tmp >> 1; end
bit_cnt = cnt;
end
endmodule
Non-Static Loops with Internal Timing
Controls –> Sequential Logic
module count1sD ( bit_cnt, data, clk, rst );
parameter data_width = 4; parameter cnt_width = 3;
output [cnt_width-1:0] bit_cnt;
input [data_width-1:0] data; input clk, rst;
reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp;
always @ ( posedge clk )
if ( rst ) begin cnt = 0; bit_cnt = 0; end
else begin: bit_counter
cnt = 0; tmp = data;
while ( tmp )
@ ( posedge clk ) begin
if ( rst ) begin cnt = 0; disable bit_counter; end
else begin cnt = cnt + tmp[0]; tmp = tmp >> 1; end
bit_cnt = cnt;
end
end
endmodule
Descargar

Document