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

  1. Simulator (uniprocessor) conditions for process interruption:
  • Delay control (#) is encountered
  • A wait with a false condition is encountered
  1. An event control (@) operator is encountered
  1. The simulator stops the process that is being executed
  1. 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