Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Verilog HDL Lectuer 5

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 36

VERILOG HARDARE DESCRIPTION

LANGUAGE

LECTUER-5

DIVYA SHAH
03/03/09
Behavioral Modeling:

PROCEDURAL ASSIGNMENT
The procedural block defines
 A region of code containing sequential
statements.
 The statements execute in the order they are
written.

 Two types of procedural blocks in Verilog


• The “always” block
A continuous loop that never terminates.
• The “initial” block
Executed once at the beginning of
simulation (used in Test-benches).
INITIAL BLOCK
Syntax of initial block
initial
begin
… imperative statements …
end
 Runs when simulation starts
 Terminates when control reaches the end
 It cant be nested
 If there are multiple initial blocks,each block starts to
execute concurrently
 Each block finishes execution independently to other block
 Good for providing stimulus
ALWAYS BLOCK
Syntax of always block
Always @(sensitivity variables)
begin
… imperative statements …
end

 Runs when simulation starts


 Restarts when control reaches the end
 It cant be nested
 If there are multiple always blocks, each block starts
to execute concurrently
 Only “reg” type variables can be assigned within an
“always” block.
 Good for modeling/specifying hardware
 Both always and initial statements are concurrent
statements.

 Statements within the body of the always and initial


block may be sequential or concurrent.

 Verilog uses begin .. end block for sequential


modeling and fork .. join block for concurrent
modeling.

 Only “reg” type variables can be assigned within an


“always” block.
Sequential Statements in Verilog
1. begin
sequential_statements
end
//begin...end not required if there is only 1 stmt.

2. if (expression)
sequential_statement
else
sequential_statement
end if
3. case (expression)
expr: sequential_statement
…….
default: sequential_statement
endcase

4. forever
sequential_statement

5. repeat (expression)
sequential_statement
6. while (expression)
sequential_statement

7. for (expr1; expr2; expr3)


sequential_statement

8. # (time_value)
Makes a block suspend for “time_value” time
units.

9. @ (event_expression) Makes a block suspend


until event_expression triggers.
A combinational logic example

module mux21 (in1, in0, s, f);


input in1, in0, s;
output f;
reg f;
always @ (in1 or in0 or s)
if (s)
f = in1;
else
f = in0;
endmodule
A sequential logic example

module dff_negedge (D, clock, Q, Qbar);


input D, clock;
output Q, Qbar;
reg Q, Qbar;
always @ (negedge clock)
begin
Q = D;
Qbar = ~D;
end
endmodule
• //negedge clock is used for negative edge of clock &
//posedge clock is used for positive edge of clock
COUNTER
module simple_counter (clk, rst, count);
input clk, rst;
output count;
reg [31:0] count;
always @(posedge clk)
begin
if (rst)
count = 32’b0;
else
count = count + 1;
end
endmodule
4 BIT ALU
module ALU_4bit (f, a, b, op);
input [1:0] op;
input [3:0] a, b;
output [3:0] f;
reg [3:0] f;
parameter ADD=2’b00, SUB=2’b01,MUL=2’b10, DIV=2’b11;
always @ (a or b or op)
case (op)
ADD : f = a + b;
SUB : f = a – b;
MUL : f = a * b;
DIV : f = a / b;
endcase
endmodule
Blocking & Non-blocking
Assignments
Sequential statements within procedural
blocks (“always” and “initial”) can use
two types of assignments:

• Blocking assignment
Uses the ‘=’ operator

• Non-blocking assignment
Uses the ‘<=’ operator
Blocking Assignment (using ‘=’)

• Most commonly used type.

• The target of assignment gets updated before the


next sequential statement in the procedural block is
executed.

• A statement using blocking assignment blocks the


execution of the statements following it, until it gets
completed.

• Recommended style for modeling combinational


logic.
Non-Blocking Assignment (using
‘<=’)
• The assignment to the target gets scheduled for the
end of the simulation cycle.

• Normally occurs at the end of the sequential block

• Statements subsequent to the instruction under


consideration are not blocked by the assignment.

• Recommended style for modeling sequential logic.

• Can be used to assign several ‘reg’ type variables


synchronously, under the control of a common clock.
Nonblocking Statements are odd!

a = 1; a <= 1;
b = a; b <= a;
c = b; c <= b;
//Blocking assignment: // Nonblocking assignment:
a=b=c=1 a=1
b = old value of a
c = old value of b
• RHS of nonblocking taken from latches
• RHS of blocking taken from wires
Some Rules to be Followed

• Verilog synthesizer ignores the delays


specified in a procedural assignment
statement.
• A variable cannot appear as the target
of both a blocking and a nonblocking
assignment.
• Following is not permissible:
value = value + 1;
value <= init;
Parameterized design:: an N-bit
counter
module counter (clear, clock, count);
parameter N = 7;
input clear, clock;
output [0:N] count;
reg [0:N] count;
always @ (negedge clock)
if (clear)
count <= 0;
else
count <= count + 1;
endmodule
Using more than one clocks in a
module

module multiple_clk (clk1, clk2, a, b, c, f1, f2);


input clk1, clk2, a, b, c;
output f1, f2;
reg f1, f2;
always @ (posedge clk1)
f1 <= a & b;
always @ (negedge clk2)
f2 <= b ^ c;
endmodule
Using multiple edges of the same
clock

module multi_phase_clk (a, b, f, clk);


input a, b, clk;
output f;
reg f,t;
always @ (posedge clk)
f <= t & b;
always @ (negedge clk)
t <= a | b;
endmodule
A Ring Counter Example
module ring_counter (clk, init, count);
input clk, init;
output [7:0] count;
reg [7:0] count;
always @ (posedge clk)
begin
if (init)
count = 8’b10000000;
Else
begin
count = count << 1;
count[0] = count[7];
end
end
Endmodule
//this is a wrong program
A Ring Counter Example
(Modified)
module ring_counter_modi1 (clk, init, count);
input clk, init; output [7:0] count;
reg [7:0] count;
always @ (posedge clk)
begin
if (init)
count = 8’b10000000;
else
begin
count <= count << 1;
count[0] <= count[7];
end
end
endmodule
Example with Multiple Modules

• A simple example showing multiple


module definitions. B

A en
COMPLEMENTOR

BOUT
c_in Add_sub
ADDER

carry sum

PARITY CHECKER P
module complementor (Y, X, comp);
input [7:0] X;
input comp;
output [7:0] Y; reg [7:0] Y;
always @ (X or comp)
if (comp)
Y = ~X;
else
Y = X;
endmodule
module adder (sum, cy_out, in1, in2, cy_in);
input [7:0] in1, in2;
input cy_in;
output [7:0] sum; reg [7:0] sum;
output cy_out; reg cy_out;
always @ (in1 or in2 or cy_in)
{cy_out, sum} = in1 + in2 + cy_in;
endmodule
module parity_checker (out_par, in_word);
input [8:0] in_word;
output out_par;
always @ (in_word)
out_par = ^ (in_word);
endmodule
Top level module
module add_sub_parity (p, a, b, add_sub);
input [7:0] a, b;
input add_sub; // 0 for add, 1 for subtract
output p; // parity of the result
wire [7:0] Bout, sum;
wire carry;
complementor M1 (Bout, B, add_sub);
adder M2 (sum, carry, A, Bout, add_sub);
parity_checker M3 (p, {carry, sum});
endmodule
Verilog Test Bench

What is test bench?


• A Verilog procedural block which
executes only once.
• Used for simulation.
• Testbench generates clock, reset, and
the required test vectors.
How to Write Testbench?

 Create a dummy template


• Declare inputs to the module-under-test (MUT) as
“reg”, and the outputs as “wire”
• Instantiate the MUT.
 Initialization
• Assign some known values to the MUT inputs.
 Clock generation logic
• Various ways to do so.
 May include several simulator directives
• Like $display, $monitor, $dumpfile, $dumpvars,
$finish.
• $display
Prints text or variables to stdout.
Syntax same as “printf”.
• $monitor
Similar to $display, but prints the value whenever
the value of some variable in the given list changes.
• $finish
Terminates the simulation process.
• $dumpfile
Specify the file that will be used for storing the
waveform.
• $dumpvars
Starts dumping all the signals to the specified file.
Example Testbench

module shifter_toplevel;
reg clk, clear, shift;
wire [7:0] data;
shift_register S1 (clk, clear, shift, data);
initial
begin
clk = 0; clear = 0; shift = 0;
end
always
#10 clk = !clk;
endmodule
Testbench: More Complete Version

module shifter_toplevel;
reg clk, clear, shift;
wire [7:0] data;
shift_register S1 (clk, clear, shift, data);
initial
begin
clk = 0; clear = 0; shift = 0;
end
always
#10 clk = !clk;
//contd
initial
begin
$dumpfile (“shifter.vcd”);
$dumpvars;
end
initial
begin
$display (“\ttime, \tclk, \tclr, \tsft, \tdata);
$monitor (“%d, %d, %d, %d, %d”, $time,
clk, reset, clear, shift, data);
end
initial
#400 $finish;
***** REMAINING CODE HERE ******
endmodule
A Complete Example

module testbench;
wire w1, w2, w3;
xyz m1 (w1, w2, w3);
test_xyz m2 (w1, w2, w3);
endmodule
module xyz (f, A, B);
input A, B; output f;
nor #1 (f, A, B);
endmodule
module test_xyz (f, A, B);
input f;
output A, B;
reg A, B;
initial
begin
$monitor ($time, “A=%b”, “B=%b”, f=%b”,A, B, f);
#10 A = 0; B = 0;
#10 A = 1; B = 0;
#10 A = 1; B = 1;
#10 $finish;
end
endmodule

You might also like