/// LSU EE 3755 Computer Organization

//

/// Verilog Notes 7 -- Procedural Code & Behavioral Modeling

 

//

//

 

 

/// Contents

//

// Procedural Code Overview

// Procedural Code Basics (initial,always,begin,end,#,$display)

// More Procedural Code Basics(always)

// Variables (reg, integer, etc)

 

/// References

//

// :P:�� Palnitkar, "Verilog HDL"

// :Q:�� Qualis, "Verilog HDL Quick Reference Card Revision 1.0"

// :PH:Patterson & Hennessy, "Computer Organization & Design"

 

////////////////////////////////////////////////////////////////////////////////

/// Procedural Code Overview

 

// :P: 7, 7.1, 7.1.1

 

/// Structural Model

//

// A description of hardware in terms of

// an interconnection of simpler

// components.The Verilog examples presented in class up to this

// point have been structural models.

 

/// Behavioral Model

//

// A description of what hardware does.That is, a description of

// what the outputs should be given some input.

//

 

/// Procedural Verilog Code

//

// Used for writing behavioral models.

//

// Like a Simple C Program:

//�� Statements executed in program order.

//

// Unlike a Simple C Program

//�� Multiple pieces of code can run concurrently.

//�� Need to think about how code starts and stops.

//�� Time (simulated) part of language(think about delay).

//�� when we have /delay/, the /delay/ is unit time

// (simulated time).

 

//This example is NOT a completed code

//Thisshows 3 blocks are running concurrently

// at time 3, each block generates output of and-gate

//each block has its own activity flow(what it does).

 

//module activity_flow( )

/*

initial

�� begin

������� #3

������ and a1(a1,b1,c1);

�� end

 

initial

�� begin

������ #3

����� and a2(a2,b2,c2);

�� end

 

initial

�� begin

������ #3

������ and a3(a3,b3,c3);

end

 

 

endmodule

 

*/

 

 

/// Activity Flow (within procedural code)

//

 

//

// A Verilog description can have many activity flows.

//�� Each "initial" and "always" (see below) block has

//�� its own activity flow.

 

// How Code Starts in an ordinary C Program

//�� Starts with call to "main."

//

// How Procedural Code Starts in Verilog

//�� Code in all "initial" and "always" blocks (see below)

//�� starts at t=0.

 

/// Reminder

//

// Pay attention to how simulated time is handled.

//

// Remember that several pieces of procedural code can execute

// concurrently, and so several activity flows are concurrently

// advancing.

 

 

////////////////////////////////////////////////////////////////////////////////

/// Procedural Code Basics (initial,always,begin,end,#,$display)

 

// :P: 7.1, 7.1.1, 7.1.2initial, always

// :P: 7.7, 7.7.1 begin/end.

// :P: 7.3, 7.3.1 Delay (#)

// :P: 3.3.1 System tasks, including $display.

 

// :Keywords: initial, always, begin, end, #, $display, $stop

 

// Procedural Code

//

// Starts with either "initial" or "always"...

// ... followed by a single statement ...

// ... or a begin / end block [or a fork/join block].

//

// Details follow example.

 

// :Example:

//

// A module using procedural code to print simple messages.

 

module my_first_procedural_module();

 

��

�� integer i;

 

�� initial��� // Indicate start of procedural code.

������������� // Activity flow (execution) starts at t=0.

���� begin��� // begin/end used to bracket code.

 

������� // Lines below execute sequentially,

������� // like an ordinary program.

 

��� ��i = 0;

 

��� $display("Hello,World!, i=%d t=%t", i, $time); //time t = 0;

 

 

��� ��i = 1;

�������

��� $display("Hello,World!, i=%d t=%t",i,$time);//time t = 0;

����

���� end

 

endmodule

 

 

/// Specifying Procedural Code: initial, always

//

// :Syntax: initial STATEMENT;

//

// Start activity flow (start executing) with STATEMENT at t=0.

// STATEMENT may finish at t=0 or later (depending on what it is).

// block of codes inside initial begin-endwill be

// executed ONLY once.

// Note: STATEMENT may be a single statement, a begin/end block, // [or a fork/join block].

//

//

// :Syntax: always STATEMENT;

//

// Start activity flow (start executing) with STATEMENT at t=0.

// STATEMENT may finish at t=0 or later (depending on what it is).

// When STATEMENT finishes start it again. (Loop infinitely.)

 

 

/// Procedural [Sequential] Block: begin, end

//

// :Syntax: begin STATEMENT1; STATEMENT2; ... end

//

// Used to bracket statements.begin, end, and statements between

// treated as a statement.

//

// The entire begin/end block below is treated

// as a single statement.

// :Sample: initial begin a=0; b=2; end

//

// :Sample: initial begin clk = 0; x = 3; end

 

 

/// System Task: $display

//

// :Syntax: $display(FORMAT,EXPR1,EXPR2,...);

//

// Used to display messages on simulator console.Similar to C

// printf.FORMAT specifies what text to print and, using escape

// sequences( %,\) , how expressions should be formatted.

// EXPR1, EXPR2, etc

// are evaluated and their values printed.

//

// Format Escape Sequences

//

// Start with a % and are followed by a format character.

// Format characters: %d (decimal), %h (hex), %o (octal),

// %b (binary),%c (character), %s(string), %t(time), ...

//

// See module for examples.

 

 

/// System Task: $stop

//

// :Syntax: $stop;

//

// Stop simulator.Typically used at the end of a testbench or

// where the testbench discovers an error.

 

 

/// Procedural Delay

//

// :Syntax: # NUM;

//

// DelayNUM time units.See behavioral_2 example.

//

// :Syntax: # ( EXPR );// # (a+b);

���������������������� // for example ,when a =1, b =3,

����� �����������������// # 4;

//

// Delay by value of EXPR;

//

// :Syntax: # NUM STATEMENT;

//��������� # 5 and a1(a,b,c);

// DelayNUM time units then execute STATEMENT. This is

// equivalent to:begin # NUM; STATEMENT; end

����������������� //begin #5; and a1(a,b,c); end

//

// :Syntax: # ( EXPR ) STATEMENT;

//

// Delay by value of EXPR then execute STATEMENT.

// This is equivalent to :

// begin # (EXPR); STATEMENT; end

 

 

 

 

// :Example:

//

// Procedural code using initial.Code below starts at t=0, and

// because there are no delays, finishes at t=0.

//

module behavioral_1(x);

�� output x;

 

�� reg [7:0]x;

 

�� initial

���� // Activity flow starts here at t=0.

���� // Procedural Code Starts Here

���� begin

 

������� x = 1;

������ $display("Hello, x=%d, t=%t",x,$time);

 

������� x = 2;

������� $display("Hello, x=%d, t=%t",x,$time);

 

������� x = 3;

������� $display("Hello, x=%d, t=%t",x,$time);

�������

���� end

 

endmodule

 

// Simulator Output

//

// # Hello, x=1, t=�����������������0

// # Hello, x=2, t=������������������ 0

// # Hello, x=3, t=������������������ 0

 

 

// :Example:

//

// An example of behavioral code using delays.The initial block

// starts at t=0 and finishes at t=3.

 

module behavioral_2(x);

�� output x;

 

�� reg [7:0]x;

��

�� initial

���� begin

 

������� x = 1;

������� $display("Hello, x=%d, t=%t",x,$time);

������� #1;

 

������� x = 2;

������� $display("Hello, x=%d, t=%t",x,$time);

������� #1;

 

������� x = 3;

������� $display("Hello, x=%d, t=%t",x,$time);

������� #1;

�������

���� end

 

endmodule

 

// Simulator Output

//

// # Hello, x=1, t=������������������ 0

// # Hello, x=2, t=������������������ 1

// # Hello, x=3, t=������������������ 2

 

 

// :Example:

//

// Use of two initials in a module.Both start execution at t=0.

 

module behavioral_3(x);

�� output x;

 

�� reg [7:0] x;

 

�� // Initial block A

�� initial

���� // Activity flow starts here at t=0.

���� begin

 

������� x = 1;

������� $display("Hello, x=%d, t=%t",x,$time);

������� #10;

 

������� x = 2;

������� $display("Hello, x=%d, t=%t",x,$time);

������� #10;

 

������� // The two statements below and in the next initial block

������� // execute at t=20.There is no way to tell

������� // for sure whether

������� // the final value of x will be 3 or 30.

 

������� x = 3;

������� $display("Hello, x=%d, t=%t",x,$time);

������� #10;

�������

���� end

 

�� // Initial block B

�� initial

���� // Activity flow starts here at t=0.

���� begin

�� �����#5;

 

������� x = 10;

������� $display("Hello, x=%d, t=%t",x,$time);

������� #10;

 

������� x = 20;

������� $display("Hello, x=%d, t=%t",x,$time);

������� #5;

 

������� // The two statements below and the two in the previous

������� // initial block execute at t=20.There is no way to tell����

������� // for sure whether the final value of x will be 3 or 30.

 

������� x = 30;

������� $display("Hello, x=%d, t=%t",x,$time);

������� #10;

�������

���� end

 

endmodule

 

//t�� 0��� 5��� 10�� 15�� 20

//A�� x=1������ x=2������ x=3

//B������� x=10����� x=20 x=30

//

//Both blocks execute at t=20.One of them will execute before //the other but there is not way to predict which one.

//

// Simulator Output:

//

// # Hello, x=1, t=������������������ 0

// # Hello, x= 10, t=������������������ 5

// # Hello, x=2, t=����������������� 10

// # Hello, x= 20, t=����������������� 15

// # Hello, x=3, t=����������������� 20

// # Hello, x= 30, t=����������������� 20

 

 

// :Example:

//

// The module below is a behavioral description of an xor gate

// that doesn't work.Why not?

 

module this_xor_gate_doesnt_work(x,a,b);

�� input a, b;

�� output x;

 

�� reg��� x;

 

�� initial

���� begin

������� x = a ^ b;

���� end

 

endmodule

 

// Because it sets the output to a xor b only once, at t=0.

// Inputs a and b might change after t=0, but x won't.

// execution starts at t = 0, and executes only once.

 

// :Example:

//

// Testbench for the xor gate above.

 

module demo_xor();

 

�� reg a, b;

�� wire x;

��

�� this_xor_gate_doesnt_work x0(x,a,b);

 

�� integer i;

��

�� initial

���� for(i=0; i<4; i=i+1)

������ begin

��������� a = i[0];

��������� b = i[1];

��������� #1;

������ end

 

endmodule

 

 

////////////////////////////////////////////////////////////////////////////////

/// More Procedural Code Basics(always)

 

// :P: 7.1.2always

 

// :Keyword: always

//

// :Syntax: always STATEMENT;

//

// Execute STATEMENT at t=0.

// When it completes execute it again. And again, and again,...

 

/// Use of initial and always

//

// Use of initial

//�� Testbench code.

//�� Initializing modules for simulation, NOT for synthesis.

 

 

// :Example:

//

// A simple always demo.Message will be printed endlessly

// as simulated time advances.

 

module shouldnt_do_this();

��

�� always

���� begin

������� $display("This is an infinite loop.");

������� #10;

���� end

 

endmodule

 

 

// :Example:

//

// An example of how NOT to use always.It starts at t=0 and

// loops endlessly without advancing time.

// Therefore the code in the

// initial block never gets past the #1 delay.

// Two blocks always and initial running concurrently

// because there is job to finish at time t = 0

//( which never finishes..always block).

// simulated time clock never reaches time t = 1;

// so the initial block's $display will never enter

//(it will be executed at time t =1.)

 

module never_do_this();

 

�� always

���� begin

������� $display("This is an infinite loop too.");

�� ��end

 

�� initial

���� begin

������� #1;

������� $display("The simulator will never print this one.");

���� end

��

endmodule

 

 

// :Example:

//

// An example of how to use always.The code in the initial block

// initializes the clock to 0.

// The code in the always block inverts

// it every ten cycles.

// This sort of code is used by testbenches.

 

module clock_generator(clk);

�� output clk;

�� reg��� clk;

 

�� initial clk = 0;

 

�� always

���� begin

������� #10;

������� clk = ~clk;

��� end

 

endmodule

 

 

// :Example:

//

// Another proper use of always.This generates a clock that is

//high for 90% of the time. (The clock above was a square wave.)

 

module another_clock_generator(clk);

�� output clk;

�� reg��� clk;

 

�� always

���� begin

������� clk = 0;

������� #1;

������� clk = 1;

������� #9;

���� end

 

endmodule

 

 

////////////////////////////////////////////////////////////////////////////////

/// Variables (reg, integer, etc)

 

// :P: 4.2.3 Port connection rules.

// :P: 3.2.3, 3.2.5 Registers (Variables), variable types.

 

/// Variable Types

//

// Hold values, unlike wires (nets)

 

// Variable Types

//

// reg:���� Holds physical values. (Vector of 0, 1, x, z)

//��������� Declared with a specific number of bits.

//��������� Unsigned integer (or x or z).

//

// integer: Signed integer.

//��������� Usually 32 bits (based on host machine).

//

// real:��� Floating-point number.

//

// time:��� At least a 64-bit integer.

//��������� For holding simulated time.

 

module var_usage();

 

�� reg [7:0] r;

�� integer�� i;

�� real����� f;

�� time����� t;

 

�� initial

���� begin

������� r = 5;

������� i = r;��

������� f = 1.0 / i;// Take reciprocal of i.

������� t = $time; // Get current time.

 

������� // Display values in appropriate formats.

������� $display(" r = %h,i = %d,f = %f,t = %t",r,i,f,t);

���� end

 

endmodule

 

 

/// Variable and Net Assignment Rules

//

// Nets and variables are not interchangeable.

// Here is how they can be used:

// Letters refer to example below.

//

// Note: net types: wire.

//������ variable types: reg, integer, real, time.

//

// A:Procedural Code

//�� Can assign to variables.

//�� Cannot assign to nets.

//

// B:Continuous Assignment (assign)

//�� Left-hand side must be a net.

//�� Cannot be used to assign variables.

//

// C:Instantiation Input Connection

//�� Can use net, variable, or expression.

// : bfa bfa1(sum,carryout,a,b)

// : a, b can be net or variable.

//

// D:Instantiation Output Connection

//�� Must use net. (Cannot use variable.)

// : bfa bfa1(sum,carryout,a,b)

// : sum, carryout should be net.

//

 

// E:Module Input Port

//�� Must use net.(Cannot use variable.)

// : module bfa (sum,carryout,a,b)

// : a, b should be net.

 

// F:Module Output Ports

//�� Can use nets or variables.

 

 

// When make a module, inputs should be wires.

// When instantiate a module, outputs should be wires.

 

// :Example:

//

// Examples of how nets and registers used.

 

module reg_v_net();

 

�� reg [7:0] x, y;

�� wire [7:0] a, b;

 

�� // B: Continuous assignment to a net.

�� assign���� a = x;

�� // B: The commented-out line below would be an error

�� // because reg's cannot be assigned using assign.

�� // assign�� ��y = x;

 

�� initial

���� begin

������� // A: Assignment to a variable.

������� x = 1;

������� // A: The commented-out line below would be an error

������� // because

������� // net's cannot be assigned in procedural code.

������� // b = 1;

���� end

 

endmodule

 

 

// :Example:

//

// Examples of how nets and registers used for ports

// and connections.

 

module port_example_1();

�� wire s, co;

 

�� // D: Commented-out line below would be an error

�� //because variables

�� //��� (including reg's) cannot connect to instantiation output

�� //��� connections, in this case sum and carry out.

�� // reg s, co;

 

�� // C: Instantiation input connections

�� //(inputs to an instantiated

�� //��� module, bfa_implicit.b1 below) can be either reg's

�� //or net's.

�� rega, b;

 

�� // C: Input connections to instantiated module

�� //are regs (a,b) and

�� //��� an expression (1'b0).

�� // D: Output connections are nets (s,co),

�� // and cannot be variables (regs).

�� bfa_implicit b1(s,co,a,b,1'b0);

 

�� initial

���� begin

 

���� ���#1; a = 0;b = 0;

������� #1; a = 0;b = 1;

������� #1; a = 1;b = 0;

������� #1; a = 1;b = 1;

������� #1;

 

���� end

 

endmodule

 

 

// :Example:

//

// Additional examples of how to use variables and nets.

// focus on usage of nets and variables,

// not to focus on module's functionality...

module port_example_2(x,s,a);

�� // E: Module inputs must be wires. (The default.)

�� input a;

�� // F: Module outputs can be either variables or nets.

�� //��� Here x is a variable (reg) and s is a net

�� //(wire, by default).

�� output x, s;

�� reg��� x;

 

�� // E: The commented out line below would be an error

�� // since module inputs

�� //��� cannot be variables.

�� // reg a;

��

�� wire co;

�� // D: Commented-out line below is an error because variables

�� //��� (including reg's) cannot connect to output ports,

��� //in this case

�� //��� sum and carry out.

�� //below we intantiate BFA.

�� // When intantiate a module, outputs should be nets

�� // reg co;

 

�� // C: Input connections to

�� //an instantiated module (bfa_implicit.b1

�� //��� below) can be either reg's or net's.

�� // Here, net type wire isused.

�� wireb, ci;

 

�� integer i;

 

�� assign b = i[0];

�� assign ci = i[1];

��

�� bfa_implicit b1(s,co,a,b,ci);

 

�� initial

���� begin

 

������� x = 1; // x is not a very useful output.

 

������� #1; i = 0;

������� #1; i = 1;

������� #1; i = 2;

������� #1; i = 3;

������� #1;

 

���� end

 

endmodule