COURSE OVERVIEW
Part 1: Introduction, Modeling, Hierarchical Design
Part 2: Simulation, Module Elements, Data Types, Logic System, Operators
Part 3: User Defined Primitives, Delay Models
Part 4: Behavioral Modeling With Verilog: Assignments
Part 5: Behavioral Modeling With Verilog: Activity Flow Control
Part 6: Behavioral Modeling With Verilog: Code Management
Part 7: ModelingFiniteState Machines
Part 8: HDL-Based Synthesis with Verilog
VERILOG: ACTIVITY FLOW CONTROL
EXAMPLE: MULTIPLEXER USING ‘case’ STATEMENT
module mux4_case (a, b, c, d, select, y_out);// p 204
1
AMDG Copyright M.D. Ciletti
inputa, b, c, d;
input [1:0] select;
outputy_out;
regy_out;
always@ (a or b or c or d or select)
case (select)
0: y_out = a;
1: y_out = b;
2: y_out = c;
3: y_out = d;
default y_out = 1'bx;
endcase
endmodule
1
VERILOG: ‘case’ STATEMENT
The case statement implements multi-way branching of an activity flow.
For the case statement, the case_item is evaluated in order and compared to the expression. The statement associated with the first found exact bitwise match (0, 1, x, z) between the case_item and expression executes. The remaining matches and statements are ignored.
Note: A single expression determines which statement executes (“case” is less general than the “if” statement).
Note: The default is optional; the associated statement executes if no other match is found. Synthesis tools require complete list of case items.
VERILOG: ‘case’ STATEMENT (Cont.)
The case statement requires an exact bitwise match.
EXAMPLE
reg [1:0] sig_A, sig_ones;
...
case(sig_A)
2’b00:$display (“Sig_A has no ones”);
2’b01, 2’b10:$display (“Sig_A has a single one”);
2’b11:$display (“Sig_A has two ones”);
2'bx :$display ("sig_A is unknown value");
2’bz $display ("sig_A is high impedance value");
default:$display ("Value of sig_A is mixed”);
endcase;
VERILOG: ‘case’ STATEMENT OPTIONS
caseComplete bitwise match between expression
and case_item expression
casexTreat 'x' values in expression or case_item as don't-cares
casezTreat 'x' and 'z' values in expression or case_item as don't-cares
Optional: Use ? to specify don’t-care bits.
EXAMPLE: ‘casex’
1
AMDG Copyright M.D. Ciletti
module casex_decoder;
// Ref: Thomas & Moorby
reg[7:0] r, mask;
always
begin
...
mask = 8'bx0x0x0x0;
casex (r ^ mask) // bitwise xor
8'b001100xx:do_task_1;
8'b1100xx00:do_task_2;
8'b00xx0011:do_task_3;
8'bxx001100:do_task_4;
endcase;
end
endmodule
NOTE:
The controlling_expression depends on a match between register bits and the mask word
An 'x' bit in the register mask ignores bits in the register.
1
AMDG Copyright M.D. Ciletti
EXAMPLE: ‘casex’ (Cont.)
x0x0x0x0mask word
^01100110r word
------
x1x0x1x0case_expression
1100xx00case item match
A “don’t care” on the case item or in the case_expression has the same effect in determining the match result.
In this example: do_task_2 is executed.
CASE STATEMENT: DON'T CARES
Table 7.2:
VERILOG: CONDITIONAL BRANCH/ EXECUTION
PURPOSE:Support conditional activity flow within a behavior.
1
AMDG Copyright M.D. Ciletti
if
if ... else
if ... else ... if
1
AMDG Copyright M.D. Ciletti
The “if” statement provides flexibility in the statement of conditions that determine the activity flow.
VERILOG: CONDITIONAL BRANCH/ EXECUTION
- ‘if’ STATEMENT (p. 206)
SYNTAX:if ( Boolean_Condition) statement
EXAMPLE
if (A < B) sum_value = sum_value + 1;
NOTES:
- The statement that is executed may be a block statement (begin … end).
- A zero expression evaluates to Boolean false.
- Any value (numeric) other than zero evaluates to true.
- ‘x’ and ‘z’ are treated as false.
VERILOG: CONDITIONAL BRANCH/ EXECUTION
- ‘if’ STATEMENT
EXAMPLE
if (k==1) // Note use of '=='
begin
sum_out = sum_reg(4);
c_out = c_reg(2);
end
EXAMPLE
if (A == B)
begin
J = 4;
sum = y + z;
end
VERILOG: CONDITIONAL BRANCH/ EXECUTION
- ‘if ... else’ STATEMENT
SYNTAX:if (Boolean_Condition) statement_or_null else statement_or_null
EXAMPLE ( if ... else )
if (C < D)
reg_1 = reg_1 + 1;
else
reg_1 = reg_1 + 2;
VERILOG: CONDITIONAL BRANCH/ EXECUTION
- CONDITIONAL OPERATOR
SYNTAX:
(Control_expression) ? Expression_if_true : Expression_if_false;
EXAMPLE
assign y_out = (bus_enabled) ? register_A : 16'bz;
RULES:
1.A conditional operator may appear in the following:
- An expression in a continuous assignment statement
- An expression in the body of a procedural statement
2.The if ... else statement may appear in
- Body of a procedural statement
- Task, function
EXAMPLE - NESTED CONDITIONAL OPERATOR
module mux_cond (mux_out, a, b, c, d, sel);
inputa, b, c, d;
input[1:0] sel;
outputmux_out;
assign mux_out = (!sel[1] !sel[0]) ? a :
(!sel[1] sel[0]) ? b :
(sel[1] !sel[0]) ? c :
(sel[1] sel[0]) ? d : 1'bx;
endmodule
EXAMPLE -
NESTED CONDITIONAL OPERATOR (Cont.)
1
AMDG Copyright M.D. Ciletti
module test_mux_cond ();
reg a, b, c, d;
reg [1:0] sel;
mux_cond M1 (mux_out, a, b, c, d, sel);
initialfork
begin
sel = 2'd0;
#10 sel = 2'd1;
#10 sel = 2'd2;
#10 sel = 2'd3;
end
begin
#0 a=0; b=0; c=0; d=0;
#2 a = 1;
#2 a = 0;
end
begin
#12 b = 1;
#2 b = 0;
end
begin
#22 c = 1;
#2 c = 0;
end
begin
#32 d = 1;
#2 d = 0;
end
join
1
AMDG Copyright M.D. Ciletti
initial
$monitor($time,,"sel= %d a= %b b= %b c= %b d= %b mux_out = %b",
sel, a, b, c, d, mux_out);
endmodule
EXAMPLE - NESTED CONDITIONAL OPERATOR (Cont.)
0 sel= 0 a= 0 b= 0 c= 0 d= 0 mux_out = 0
2 sel= 0 a= 1 b= 0 c= 0 d= 0 mux_out = 1
4 sel= 0 a= 0 b= 0 c= 0 d= 0 mux_out = 0
10 sel= 1 a= 0 b= 0 c= 0 d= 0 mux_out = 0
12 sel= 1 a= 0 b= 1 c= 0 d= 0 mux_out = 1
14 sel= 1 a= 0 b= 0 c= 0 d= 0 mux_out = 0
20 sel= 2 a= 0 b= 0 c= 0 d= 0 mux_out = 0
22 sel= 2 a= 0 b= 0 c= 1 d= 0 mux_out = 1
24 sel= 2 a= 0 b= 0 c= 0 d= 0 mux_out = 0
30 sel= 3 a= 0 b= 0 c= 0 d= 0 mux_out = 0
32 sel= 3 a= 0 b= 0 c= 0 d= 1 mux_out = 1
34 sel= 3 a= 0 b= 0 c= 0 d= 0 mux_out = 0
Note: consider alternative listing with labels at only the header.
VERILOG: LOOPS (p 208)
PURPOSE: SUPPORT REPEATED EXECUTION OF STATEMENTS IN PROCEDURAL BLOCKS
repeat
for
while
forever
NOTE: VHDL has constructs: 'loop', 'for'.
VERILOG: 'repeat' LOOP STATEMENT
SYNTAX:repeat (count_expression) statement_or_null;
- The count_expression is evaluated once at the beginning of execution of the loop.
- The count_expression determines the number of times the execution is repeated.
- The execution can end prematurely with the ‘disable’ statement.
1
AMDG Copyright M.D. Ciletti
Example
repeat (4)
begin
Sum_out[i] = acc[i];
i = i+1;
end
Example
repeat (register_A)
begin
Sum_out[i] = acc[i];
i = i+1;
end
Example
initial
begin
#start_up repeat (2)
#delay clock = ~clock;
end
1
AMDG Copyright M.D. Ciletti
VERILOG: EXAMPLE - repeat LOOP
…
word_address = 0;
repeat (memory_size)
begin
memory [word_address] = 0;
word_address = word_address + 1;
end
VERILOG: 'for' LOOP STATEMENT
SYNTAX:
for (initial_statement; end_of_loop_expression; loop_update) statement_or_null;
NOTE:
- The initial_statement executes once. (e.g. Initialize loop update variable)
- The end_of_loop_expression is checked. The statement executes if the end_of_loop expressions evaluates ‘TRUE’.
- The end_of_loop_expression executes to determine whether to remain in the loop.
- The body of the loop executes. (Modify the loop-update variable)
- The loop_update expression executes.
- The loop variable may be a reg or integer.
EXAMPLE: 'for' LOOP STATEMENT
for (K=32; K; K = K-1)
begin
...
end
NOTE: The loop_update variable may be changed during execution.
VERILOG: 'while' LOOP STATEMENT
PURPOSE: EXECUTE STATEMENTS WHILE A CONDITION IS TRUE.
SYNTAX: while (expression) statement;
EXAMPLE
begin: count_of_1s// named block// p. 216
reg [7:0] temp_reg;// local declaration
count = 0;
temp_reg = reg_a;
while (temp_reg)
begin
if (temp_reg[0]) count = count + 1;
temp_reg = temp_reg > 1;
end
end
Local variables may be declared within a named procedural block.
VERILOG: 'while' LOOP STATEMENT (Cont.)
ALTERNATIVE DESCRIPTION
begin: count_of_1s// named block// p. 217
reg [7:0] temp_reg;// local declaration
count = 0;
temp_reg = reg_a;
while (temp_reg)
begin
count = count + temp_reg[0];
temp_reg = temp_reg > 1;
end
end
VERILOG: 'while' LOOP STATEMENT (Cont.)
while (expression) statement;
NOTE:
- Execution recycles as long the expression is TRUE.
- Skip execution if expression is FALSE when encountered.
1
AMDG Copyright M.D. Ciletti
for (K=16; K; K=K-1)
begin
...
end
K = 16;
while (K)
begin
...
K = K-1;
end
1
AMDG Copyright M.D. Ciletti
NOTE: THE while LOOP SYNTAX REQUIRES A STATEMENT OR NULL.
VERILOG EXAMPLE: CARRY LOOK-AHEAD ADDER (Behavioral - Combined RTL and ALGORITHM)
See p. 211
1
AMDG Copyright M.D. Ciletti
gi = ai & bi// ai and biGenerate a carry
pi = ai ^ bi// ai xor biPropagate a carry
1
AMDG Copyright M.D. Ciletti
si = (ai ^ bi) ^ ci = pi ^ ci
ci+1 = (ai ^ bi) & ci + ai & bi = pi & ci + gi
VERILOG EXAMPLE: CARRY LOOK-AHEAD (Cont.)
RECURSIVE ALGORITHM:
s0 = p0 ^ c0
c1 = p0 & c0 + g0
s1 = p1 ^ c1
c2 = p1 & c1 + g1
s2 = p2 ^ c2
c3 = p2 & c2 + g2
...
IN SUMMARY:
sum = p ^ (cn-1, ..., c2 ,c1,c0)// Bitwise exclusive-or
c_out = cn
VERILOG EXAMPLE: CARRY LOOK-AHEAD (Cont.)
module Add_prop_gen (sum, c_out, a, b, c_in);// generic 4-bit carry
// look-ahead adder
// behavioral model
output[3:0] sum;// p 214
outputc_out;
input [3:0] a, b;
input c_in;
reg [3:0] carrychain;
wire [3:0] g = a & b; // carry generate, contin assignment, bitwise and
wire [3:0] p = a ^ b; // carry propagate, contin assignment, bitwise xor
VERILOG EXAMPLE: CARRY LOOK-AHEAD (Cont.)
always @(a or b or c_in)// event "or"
begin: carry_generation // usage: block name
integer i;
#0 carrychain[0] = g[0] | (p[0] & c_in); // Eliminate race
for(i = 1; i <= 3; i = i + 1)
begin
carrychain[i] = g[i] | (p[i] & carrychain[i-1]);
end
end
wire [4:0] shiftedcarry = {carrychain, c_in} ; // concatenation
wire [3:0] sum = p ^ shiftedcarry; // summation
wire c_out = shiftedcarry[4]; // carry out bit select
endmodule
Note: #0 is used to prevent a race between assignments to p and g and their use. There are alternatives that don't require #0. See p. 216.
VERILOG EXAMPLE: CARRY LOOK-AHEAD (Cont.)
EXAMPLE: A BLACK HOLE
Ref: Thomas & Moorby .
module Asking_for_Trouble (Some_external_input);// p. 217
input Some_external_input;
always
begin
while (Some_external_input) // Waiting for external signal
begin
// Other statements go here
end
end
endmodule
NOTE:Nothing external to the module can cause this loop to terminate. Use a ‘wait’ statement.
EXAMPLE: A BLACK HOLE (Cont.)
Ref: Thomas & Moorby
- Simulator (uniprocessor) conditions for process interruption:
- Delay control (#) is encountered
- A wait with a false condition is encountered
- An event control (@) operator is encountered
- The simulator stops the process that is being executed
- The simulator begins executing the process that is scheduled next for execution.
CAUTION: A while STATEMENT CANNOT STOP EXECUTION.
VERILOG: 'forever' LOOP STATEMENT
SYNTAX: forever statement;
1
AMDG Copyright M.D. Ciletti
EXAMPLE:module microprocessor;
always
begin
power_on_initialization;
forever
begin
fetch_instruction;
decode_instruction;
execute_instruction;
end
end
endmodule
EXAMPLE: CLOCK GENERATOR
initial
begin
clock = 0;
forever #half_cycle clock = ~ clock;
end
1
AMDG Copyright M.D. Ciletti
VERILOG: EXAMPLE - forever LOOP
1
AMDG Copyright 1999 M.D. Ciletti Page
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
NOTE: Use disable to terminate a named block or task.
1
AMDG Copyright 1999 M.D. Ciletti Page
EXAMPLE: forever LOOP
1
AMDG Copyright 1999 M.D. Ciletti Page
module non_block;
reg a, b, sig_a, sig_b, sig_c;
initial
begin
sig_a = 0;
sig_b = 1;
sig_c = 0;
forever sig_c = #5 ~sig_c;
end
always@ (posedge sig_c)
begin
sig_a <= sig_b;
sig_b <= sig_a;
end
endmodule
timesig_asig_bsig_c
0010
5101
10100
15011
20010
25101
30100
35011
1
AMDG Copyright M.D. Ciletti
VERILOG: COMPARISON OF LOOPS
LOOPFEATURETERMINATION
repeatExpression determines 'end' or 'disable'
constant number of repetitions.
forLoop variable determines'end' or 'disable'
number of repetitions.
whileIterate while expression'end' or 'disable'
evaluates 'true'.
foreverIndefinite iteration'disable'
VERILOG: LOOP EXIT - EXCEPTIONAL CONDITIONS
PURPOSE: DISABLE OR TERMINATE A NAMED BLOCK OR TASK.
SYNTAX:disable name_of_block_or_task;
NOTE:
1.Action is analogous to 'continue' and 'break' in C.
2.The target block or task must be named.
3.Execution resumes with the statement following the block.
EXAMPLE: 'disable' STATEMENT
begin: Outer_Block
for (k = 0; k < Limit; k = k+1)
begin: Inner_Block
if (Flag1 == 0) disable Inner_Block; // Aborts iteration
// other statements go here - proceed
if (Some_Condition) disable Outer_Block; // Aborts for loop
// other statements go here
end
end
VERILOG: EXAMPLE - disable
module stand_alone_digital_machine;
always
begin
Perform_power_up_resets;// User-defined task
forever Perform_machine_tasks;// User-defined task
endmodule
An internal condition can cause Perform_machine_tasks to abort and return control to Perform_power_up_resets.
VERILOG: EXAMPLE - disable
Find the location of the first '1' in a 16-bit word. (p. 220)
module find_first_one( A_word, trigger, index_value);
input [15:0] A_word;
inputtrigger;
output[3:0] index_value;
reg[3:0] index_value;
always @ trigger
begin
index_value = 0;
for (index_value=0; index_value < 15; index_value = index_value + 1);
if (A_word [index_value] == 1) disable;
end
endmodule
Caution: the loop is endless if index_value <= 15 is used.
VERILOG: PARALLEL ACTIVITY FLOW
fork ... join STATEMENT
PURPOSE: PROVIDE SUPPORT FOR PARALLEL THREADS OF ACTIVITY FLOW IN A SINGLE PROCEDURAL BLOCK.
SYNTAX (Single block):
fork
statement_1
statement_2
join
NOTE:
- statement_1 and statement_2 execute in parallel.
- Flow control passes out of the fork-join after all threads of activity are complete.
EXAMPLE: SEQUENTIAL BLOCK
parameterdelay = 50;
reg [7:0]wave_register;
initial
begin
#delay wave_register = 'h35;
# delay wave_register = 'he2;
# delay wave_register = 'h00;
# delay wave_register = 'hf7;
end
NOTE:
1.The execution is sequential.
2.The delay value for each statement is relative to the time of execution of the previous statement.
3.Control passes out of the block after the last statement executes.
EXAMPLE: fork ... join
...
fork
#50r = 'h35;
#100r = 'hE2;
#150r = 'hF7;
#300r = 'h00;
join
...
- The blocking assignment of a statement does not block flow to the other statements in a parallel activity flow.
- Execution is in parallel relative to the entry time.
- The ordering of the statements is insignificant.
- A race condition is possible between assignments in parallel threads.
- fork … join is not equivalent to non-blocking assignment because race is not possible in non-blocking assignment.
EXAMPLE: fork ... join
1
AMDG Copyright M.D. Ciletti
p. 221
...
fork// tsim = 0
#50sig_wave = ‘b1;
#100sig_wave = 'b0;
#150sig_wave = 'b1;
#300sig_wave = 'b0;
join
...
begin
#50 sig_wave = 'b1;
#100sig_wave = 'b0;
#150sig_wave = 'b1;
#300sig_wave = 'b0;
end
1
AMDG Copyright M.D. Ciletti
VERILOG: MULTIPLE fork ... join BLOCKS
1
AMDG Copyright M.D. Ciletti
fork
begin
...
end
begin
fork
begin
...
end
join ...
end
...
begin
...
end
join
1
AMDG Copyright M.D. Ciletti
VERILOG: INTRA-ASSIGNMENT DELAY AND RACES
EXAMPLE- RACE CONDITION IN THE EVENT QUEUE (p. 223)
fork// Parallel activity!
#150register_a = register_b;// Delayed execution of statement
#150register_c = register_a;// Delayed execution of statement
join
EXAMPLE - DATA SWAP / NO RACE
1
AMDG Copyright M.D. Ciletti
fork
register_a = #150 register_b;
register_c = #5 register_a;
join
// Equivalent:
register_a <= #150 register_b;
register_c <= #5 register_a;
1
AMDG Copyright M.D. Ciletti
Note: intra-assignment delay causes immediate sampling and delayed execution of a procedural assignment. The equivalent non-blocking description does not race, with or without intra-assignment delay.
1