0% found this document useful (0 votes)
15 views58 pages

Behavioral Model 2

Uploaded by

Anika
Copyright
© © All Rights Reserved
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)
15 views58 pages

Behavioral Model 2

Uploaded by

Anika
Copyright
© © All Rights Reserved
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/ 58

Timing Controls

• Various behavioral timing control constructs are


available in Verilog.
• In Verilog, if there are no timing control statements,
the simulation time does not advance.
• Timing controls provide a way to specify the
simulation time at which procedural statements will
execute.
• There are three methods of timing control:
– delay-based timing control,
– event-based timing control, and
– level-sensitive timing control.
Delay-based timing control
• Syntax for the delay-based timing control statement
is shown below.
delay3 ::= # delay_value | # ( delay_value [ ,
delay_value [ , delay_value ] ] )
delay2 ::= # delay_value | # ( delay_value [ ,
delay_value ] )
delay_value ::=
unsigned_number |
parameter_identifier |
specparam_identifier |
mintypmax_expression
Delay-based timing control
• Delay-based timing control in an expression specifies the
time duration between when the statement is
encountered and when it is executed.
• Delays are specified by the symbol #.
• Delay-based timing control can be specified by a
number, identifier, or a min/typ/max_expression.
• There are three types of delay control for procedural
assignments:
– Regular delay control
– Intra-assignment delay control
– Zero delay control.
Delay-based timing control
• Regular delay control
– Regular delay control is used when a non-zero delay is specified to the left of a
procedural assignment.
//define parameters
parameter latency = 20;
parameter delta = 2;
//define register variables
reg x, y, z, p, q;
initial
begin
x = 0; // no delay control
#10 y = 1; // delay control with a number.
#latency z = 0; // Delay control with identifier.
#(latency + delta) p = 1; // Delay control with
expression
Delay-based timing control
• Intra-assignment delay control
– Instead of specifying delay control to the left
of the assignment, it is possible to assign a
delay to the right of the assignment operator.
– Such delay specification alters the flow of
activity in a different manner.
Delay-based timing control
• Intra-assignment delay control

//define register variables


reg x, y, z;
//intra assignment delays
initial
begin
x = 0; z = 0;
y = #5 x + z;
//Take value of x and z at the time=0, evaluate x + z
//and then wait 5 time units to assign value to y.
end
Delay-based timing control
• Intra-assignment delay control
– Note the difference between intra-assignment delays
and regular delays.
– Regular delays defer the execution of the entire
assignment.
– Intra-assignment delays compute the right-hand-side
expression at the current time and defer the
assignment of the computed value to the left-hand-
side variable.
– Intra-assignment delays are like using regular delays
with a temporary variable to store the current value
of a right-hand-side expression.
Delay-based timing control
• Zero delay control
– Procedural statements in different always-initial blocks may be
evaluated at the same simulation time.

– The order of execution of these statements in different always-


initial blocks is non-deterministic.

– Zero delay control is a method to ensure that a statement is


executed last, after all other statements in that simulation time
are executed.

– This is used to eliminate race conditions.

– However, if there are multiple zero delay statements, the order


between them is non-deterministic.
Delay-based timing control
• Zero delay control

initial
begin
x = 0; y = 0;
end
initial
begin
#0 x = 1; //zero delay control
#0 y = 1;
end
Event-Based Timing Control
• An event is the change in the value on a
register or a net.
• Events can be utilized to trigger execution of a
statement or a block of statements.
• There are 3 types of event-based timing
control:
– Regular event control
– Named event control
– Event OR control
Event-Based Timing Control
• Regular event control
– The @ symbol is used to specify an event control.
– Statements can be executed on changes in signal
value or at a positive or negative transition of the
signal value.
– The keyword posedge is used for a positive
transition.
– The keyword negedge is used for a negative
transition.
Event-Based Timing Control
• Regular event control
@(clock) q = d;
//q = d is executed whenever signal clock changes value

@(posedge clock) q = d;
//q = d is executed whenever signal clock does a positive
//transition ( 0 to 1,x or z, // x to 1, z to 1 )

@(negedge clock) q = d;
//q = d is executed whenever signal clock does a
//negative transition ( 1 to 0,x or z, //x to 0, z to 0)
Event-Based Timing Control
• Named event control
– VerilogHDL provides the capability to declare an
event and then trigger and recognize the
occurrence of that event.
– The event does not hold any data.
– A named event is declared by the keyword event.
– An event is triggered by the symbol ->.
– The triggering of the event is recognized by the
symbol @.
Event-Based Timing Control
• Named event control
//This is an example of a data buffer storing data after the
//last packet of data has arrived.
event received_data; //Define an event called received_data
always @(posedge clock) //check at each positive clock edge
begin
if(last_data_packet) //If this is the last data packet
->received_data; //trigger the event received_data end
always @(received_data)
//Await triggering of event received_data.
//When event is triggered, store all four packets of received data in data
//buffer use concatenation operator { }
data_buf = {data_pkt[0], data_pkt[1], data_pkt[2], data_pkt[3]};
Event-Based Timing Control
• Event OR control
– Sometimes a transition on any one of multiple
signals or events can trigger the execution of a
statement or a block of statements.
– This is expressed as an OR of events or signals.
– The list of events or signals expressed as an OR is
also known as a sensitivity list.
– The keyword or is used to specify multiple
triggers,
Event-Based Timing Control
• Event OR control
//A level-sensitive latch with asynchronous reset
always @( reset or clock or d)

//Wait for reset or clock or d to change


begin
if (reset)
//if reset signal is high, set q to 0.
q = 1'b0;
else if(clock)
//if clock is high, latch input
q = d;
end
Event-Based Timing Control
• Event OR control
– Sensitivity lists can also be specified using the "," (comma)
operator instead of the or operator.
//A level-sensitive latch with asynchronous reset

always @( reset, clock, d)


//Wait for reset or clock or d to change
begin
if (reset) //if reset signal is high, set q to 0.
q = 1'b0;
else if(clock) //if clock is high, latch input
q = d;
end
Event-Based Timing Control
• Event OR control (Use of @* Operator)
– When the number of input variables to a combination
logic block are very large, sensitivity lists can become
very cumbersome to write.
– Moreover, if an input variable is missed from the
sensitivity list, the block will not behave like a
combinational logic block.
– To solve this problem, VerilogHDL contains two
special symbols: @* and @(*).
– Both symbols exhibit identical behavior.
– These special symbols are sensitive to a change on
any signal that may be read by the statement group
that follows this symbol
Event-Based Timing Control
• Event OR control (Use of @* Operator)
//Combination logic block using the or operator
//Cumbersome to write and it is easy to miss one input to the block

always @(a or b or c or d or e or f or g or h or p or m)
begin
out1 = a ? b+c : d+e; out2 = f ? g+h : p+m;
end
//Instead of the above method, use @(*) symbol. Alternately, the
//@* symbol can be used. All input variables are automatically
//included in the sensitivity list.

always @(*)
begin
out1 = a ? b+c : d+e; out2 = f ? g+h : p+m;
end
Level-Based Timing Control
• Level-sensitive timing control.
– Event control discussed earlier waited for the change of a
signal value or the triggering of an event.

– The symbol @ provided edge-sensitive control.

– VerilogHDL also allows level-sensitive timing control, that


is, the ability to wait for a certain condition to be true
before a statement or a block of statements is executed.
– The keyword wait is used for level-sensitive constructs.
always wait (count_enable) #20 count = count + 1;
Conditional Statements
• Conditional statements are used for making
decisions based upon certain conditions.

• These conditions are used to decide whether or not a


statement should be executed.

• There are three types of conditional statements.


Conditional Statements
//Type 1 conditional statement. No else statement.
if (<expression>) true_statement ;

//Type 2 conditional statement. One else statement


//Either true_statement or false_statement is evaluated
if (<expression>) true_statement ;
else false_statement ;

//Type 3 conditional statement. Nested if-else-if.


//Choice of multiple statements. Only one is executed.
if (<expression1>) true_statement1 ;
else if (<expression2>) true_statement2 ;
else if (<expression3>) true_statement3 ;
else default_statement ;
Conditional Statements
• The <expression> is evaluated.
• If it is true (1 or a non-zero value), the true_statement
is executed.
• However, if it is false (zero) or ambiguous (x), the
false_statement is executed.
• The <expression> can contain any operators.
• Each true_statement or false_statement can be a
single statement or a block of multiple statements.
• A block must be grouped, typically by using
keywords begin and end.
• A single statement need not be grouped.
Conditional Statements
//Type 1 statements
if(!lock) buffer = data;
if(enable) out = in;

//Type 2 statements
if (number_queued < MAX_Q_DEPTH)
begin
data_queue = data;
number_queued = number_queued + 1;
end
else
$display("Queue Full. Try again");
Conditional Statements
//Type 3 statements
//Execute statements based on ALU control signal.
if (alu_control == 0)
y = x + z;
else if(alu_control == 1)
y = x - z;
else if(alu_control == 2)
y = x * z;
else
$display("Invalid ALU control signal");
Multiway Branching
• The nested if-else-if can become unwieldy if there are too
many alternatives. A shortcut to achieve the same result is to
use the case statement.
• The keywords case, endcase, and default are used in the case
statement.
case (expression)
alternative1: statement1;
alternative2: statement2;
alternative3: statement3;
...
...
default: default_statement;
endcase
Multiway Branching
• Each of statement1, statement2 …, default_statement can
be a single statement or a block of multiple statements.
• A block of multiple statements must be grouped by
keywords begin and end.
• The expression is compared to the alternatives in the
order they are written.
• For the first alternative that matches, the corresponding
statement or block is executed.
• If none of the alternatives matches, the default_statement
is executed.
• The default_statement is optional.
• Placing of multiple default statements in one case
statement is not allowed.
• The case statements can be nested.
Multiway Branching
//Execute statements based on the ALU control signal reg
[1:0] alu_control;
...
...
case (alu_control)
2'd0 : y = x + z;
2'd1 : y = x - z;
2'd2 : y = x * z;
default : $display("Invalid ALU control signal");
endcase
4-to-1 Multiplexer (case)
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);
// Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
reg out;
always @(s1 or s0 or i0 or i1 or i2 or i3)
case ({s1, s0}) //Switch based on concatenation of control signals
2'd0 : out = i0;
2'd1 : out = i1;
2'd2 : out = i2;
2'd3 : out = i3;
default: $display("Invalid control signals");
endcase
endmodule
casex, casez Keywords
• casez treats all z values in the case
alternatives or the case expression as don't
cares. All bit positions with z can also
represented by ? in that position.
• casex treats all x and z values in the case item
or the case expression as don't cares.
reg [3:0] encoding;
integer state;
casex (encoding) //logic value x represents a don't care bit.
4'b1xxx : next_state = 3;
4'bx1xx : next_state = 2;
4'bxx1x : next_state = 1;
4'bxxx1 : next_state = 0;
default : next_state = 0;
endcase
Loops
• There are four types of looping statements in
Verilog:
– while, for, repeat, and forever.
• The syntax of these loops is very similar to the
syntax of loops in the C programming
language.
• All looping statements can appear only inside
an initial or always block.
• Loops may contain delay expressions.
while loop
• The keyword while is used to specify this loop.
• The while loop executes until the while-expression is not true.
• If the loop is entered when the while-expression is not true, the
loop is not executed at all.
• Each expression can contain the operators discussed already.
• Any logical expression can be specified with these operators.
• If multiple statements are to be executed in the loop, they must
be grouped typically using keywords begin and end.
while loop
//Illustration 1: Increment count from 0 to 127.
//Exit at count 128.
//Display the count variable.
integer count;
initial
begin
count = 0;
while (count < 128)
//Execute loop till count is 127. Exit at count 128
begin
$display("Count = %d", count);
count = count + 1;
end
end
while loop
//Illustration 2: Find the first bit with a value 1 in flag (vector variable)
'define TRUE 1'b1';
'define FALSE 1'b0;
reg [15:0] flag;
integer i; //integer to keep count
reg continue;
initial
begin
flag = 16'b 0010_0000_0000_0000;
i = 0;
continue = 'TRUE;
while((i < 16) && continue ) //Multiple conditions using operators.
begin
if (flag[i])
begin
$display("Encountered a TRUE bit at element number %d", i);
continue = 'FALSE;
end
i = i + 1;
end
end
for loop
• The keyword for is used to specify this loop. The for loop
contains three parts:
– An initial condition
– A check to see if the terminating condition is true
– A procedural assignment to change value of the control variable
• The initialization condition and the incrementing procedural
assignment are included in the for loop and do not need to be
specified separately.
• Thus, the for loop provides a more compact loop structure
than the while loop.
– The while loop is more general-purpose than the for loop.
– The for loop cannot be used in place of the while loop in all situations.
for loop
//Initialize array elements
'define MAX_STATES 32
integer state [0: 'MAX_STATES-1];
//Integer array state with elements 0:31
integer i;
initial
begin
for(i = 0; i < 32; i = i + 2)
//initialize all even locations with 0
state[i] = 0;
for(i = 1; i < 32; i = i + 2)
//initialize all odd locations with 1
state[i] = 1;
end
repeat loop
• The keyword repeat is used for this loop.
• The repeat construct executes the loop a fixed number
of times.
• A repeat construct cannot be used to loop on a
general logical expression.
• A while loop is used for that purpose. A repeat
construct must contain a number, which can be a
constant, a variable or a signal value.
• However, if the number is a variable or signal value,
it is evaluated only when the loop starts and not
during the loop execution.
repeat loop
//Illustration 1 : increment and display count
//from 0 to 127 integer count;
initial
begin
count = 0;
repeat(128)
begin
$display("Count = %d", count);
count = count + 1;
end
end
forever loop
• The keyword forever is used for this loop.
• The repeat construct executes the loop a fixed number
of times.
• A repeat construct cannot be used to loop on a
general logical expression.
• A while loop is used for that purpose. A repeat
construct must contain a number, which can be a
constant, a variable or a signal value.
• However, if the number is a variable or signal value,
it is evaluated only when the loop starts and not
during the loop execution.
forever loop
//Example 1: Clock generation
//Use forever loop instead of always block
reg clock;
initial
begin
clock = 1'b0;
forever #10 clock = ~clock;
//Clock with period of 20 units end
//Example 2: Synchronize two register values at every
//positive edge of clock
reg clock;
reg x, y;
initial
forever @(posedge clock) x = y;
Sequential and Parallel Blocks
• There are two types of blocks: sequential blocks and parallel
blocks.
Sequential blocks
• The keywords begin and end are used to group statements
into sequential blocks. Sequential blocks have the following
characteristics:
• The statements in a sequential block are processed in the
order they are specified. A statement is executed only after its
preceding statement completes execution (except for
nonblocking assignments with intra-assignment timing
control).
• If delay or event control is specified, it is relative to the
simulation time when the previous statement in the block
completed execution
reg x, y;
reg [1:0] z, w;
initial

begin

x = 1'b0; //completes at simulation time 0


#5 y = 1'b1; //completes at simulation time 5
#10 z = {x, y}; //completes at simulation time 15
#20 w = {y, x}; //completes at simulation time 35

end
Parallel blocks:

•Parallel blocks, specified by keywords fork and join,


provide interesting simulation features.
•Statements in a parallel block are executed
concurrently.
•Ordering of statements is controlled by the delay
or event control assigned to each statement.
•If delay or event control is specified, it is relative to
the time the block was entered.
reg x, y;
reg [1:0] z, w;
initial

fork

x = 1'b0; //completes at simulation time 0


#5 y = 1'b1; //completes at simulation time 5
#10 z = {x, y}; //completes at simulation time 10
#20 w = {y, x}; //completes at simulation time 20

join
Full Adder
module fa_bhv (A, B, CI, S, CO) ;

input A, B, CI;
output S, CO;
reg S, CO;
// explained in later lecture – “holds” values
// use procedural assignments
always@(A or B or CI)
begin
S = A ^ B ^ CI;
CO = (A & B) | (A & CI) | (B & CI);
end
endmodule
4-to-1 Multiplexer
// 4-to-1 multiplexer.
//Port list is taken exactly from the I/O diagram.
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);
//Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
//output declared as register
reg out;
//recompute the signal out if any input signal changes.
4-to-1 Multiplexer
//All input signals that cause a recomputation of out to
//occur must go into the always @(...) sensitivity list.
always @(s1 or s0 or i0 or i1 or i2 or i3)
begin
case ({s1, s0})
2'b00: out = i0;
2'b01: out = i1;
2'b10: out = i2;
2'b11: out = i3;
default: out = 1'bx;
endcase
end
endmodule
8-to-3 Encoder
module encoder (output reg [2:0] Code, input [7:0] Data);
always @ (Data)
begin
// encode the data
if (Data == 8'b00000001) Code = 3’d0;
else if (Data == 8'b00000010) Code = 3’d1;
else if (Data == 8'b00000100) Code = 3’d2;
else if (Data == 8'b00001000) Code = 3’d3;
else if (Data == 8'b00010000) Code = 3’d4;
else if (Data == 8'b00100000) Code = 3’d5;
else if (Data == 8'b01000000) Code = 3’d6;
else if (Data == 8'b10000000) Code = 3’d7;
else Code = 3'bxxx; // invalid, so don’t care
end
endmodule
Seven Segment Display
module Seven_Seg_Display (Display, BCD, Blanking);
output reg [6: 0] Display; // abc_defg
input [3: 0] BCD;
input Blanking;
parameter BLANK = 7'b111_1111; // active low
parameter ZERO = 7'b000_0001; // h01
parameter ONE = 7'b100_1111; // h4f
parameter TWO = 7'b001_0010; // h12
parameter THREE = 7'b000_0110; // h06
parameter FOUR = 7'b100_1100; // h4c
parameter FIVE = 7'b010_0100; // h24 a
parameter SIX = 7'b010_0000; // h20 f b
parameter SEVEN = 7'b000_1111; // h0f g
parameter EIGHT = 7'b000_0000; // h00 c
e
parameter NINE = 7'b000_0100; // h04
d

Defined constants – can make code more understandable!


Seven Segment Display
always @ (BCD or Blanking)
if (Blanking) Display = BLANK;
else
case (BCD)
4’d0: Display = ZERO;
4’d1: Display = ONE;
4’d2: Display = TWO;
4’d3: Display = THREE;
4’d4: Display = FOUR;
4’d5: Display = FIVE;
4’d6: Display = SIX;
4’d7: Display = SEVEN;
4’d8: Display = EIGHT;
4’d9: Display = NINE;
default: Display = BLANK;
endcase
endmodule
D - FF
module dff(q, d, clk);
output q;
reg q,
input d, clk;
always @(posedge clk)
begin
q <= d;
end
endmodule
D - FF
module dff(q, d, clk);
output q;
reg q,
input d, clk;
always @(posedge clk, posedge reset)
begin
if (reset)
q <= d;
else
q <= 0;
end
endmodule
4-bit Shift Register

E D C B A
D Q D Q D Q D Q

R R R R

clk
rst
4-bit Shift Register
module shiftreg(E, A, clk, rst);
output A;
input E;
input clk, rst;
reg A, B, C, D;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
A <= 0; B <= 0; C <= 0; D <= 0;
end
else
begin
D = E; C = D; B = C; A = B;
end
endmodule
4-bit Counter
//4-bit Binary counter
module counter(Q , clock, clear);
// I/O ports
output [3:0] Q;
input clock, clear;
//output defined as register
reg [3:0] Q;
always @( posedge clear or negedge clock)
begin
if (clear)
Q <= 4'd0;
4-bit Counter
//Nonblocking assignments are recommended
//for creating sequential logic such as flipflops
else
Q <= Q + 1;
// Modulo 16 is not necessary because Q is a
//4-bit value and wraps around.
end
endmodule

You might also like