Behavioral Model 2
Behavioral Model 2
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)
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.
//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
end
Parallel blocks:
fork
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
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