/// LSU EE 3755 Computer Organization
//
/// Verilog Notes 8 -- Procedural Code
& Behavioral Modeling
//�
//
/// Contents
// Event Control (@)
// Syntax and Simulation of if else
// Syntax and Simulation of case
// Syntax and Simulation of for, while,
repeat,forever
// Ripple Adder: Combinational v.
Sequential
// Miscellaneous Examples
/// References
//
// :P:��
Palnitkar, "Verilog HDL"
// :Q:��
Qualis, "Verilog HDL Quick Reference Card Revision 1.0"
// :PH:�
Patterson & Hennessy, "Computer Organization & Design"
////////////////////////////////////////////////////////////////////////////////
/// Event Control (@)
// :P: 7.3.2
// An /event control/ statement pauses the
execution of
// the procedural code in which it appears
// until the specified event occurs.
// The general use of event control
statements will be briefly
// described here.�
// :Syntax: @( EXPR ) STATEMENT;
//
// Evaluate EXPR and resume execution
starting with STATEMENT when
// value of EXPR changes.
// :Syntax: @( EXPR1 or EXPR2 or... )
STATEMENT;
//
// Evaluate EXPR1, EXPR2, ... and resume
execution starting with
// STATEMENT when the value of any of the
EXPR change.
// :Syntax: @( posedge EXPR ) STATEMENT;
//
// Resume execution starting with
STATEMENT when EXPR changes from // 0 to anything or from anything to 1.
// :Syntax: @( negedge EXPR ) STATEMENT;
//
// Resume execution starting with
STATEMENT when EXPR changes from
// anything to 0 or from 1 to anything.
// :Syntax: @( EDGE1 EXPR1 or EDGE1 EXPR2
or ... ) STATEMENT;
//
// EDGE1 can be posedge, negedge, or
nothing.
// Resume execution at STATEMENT when any
of the EXPR change to
// the specified value (nothing, which
means just EXPRx,
// means any change, @(EXPR) Statement;).
//
// The event controls can be used anywhere
a statement can go.� In
// practice they are almost always used
right after "always @,"
// which is the way they will be covered
in the following
// sections.�
////////////////////////////////////////////////////////////////////////////////
�
////////////////////////////////////////////////////////////////////////////////
/// Syntax and Simulation of if else
// :P: 7.4
// Similar to C language.
// :Syntax: if( EXPR ) STATEMENT;
//
// If EXPR evaluates to a non-zero number,
execute STATEMENT.
// Note that STATEMENT could be a
begin/end block.
//
// :Syntax: if( EXPR ) STATEMENT1; else
STATEMENT2
//
// If EXPR evaluates to a non-zero number,
execute STATEMENT1
// otherwise execute STATEMENT2.
// :Example:
//
// Examples of if/else.�
//�
Doing nothing useful.
//�
Focus on usage of if statement..
module if_examples();
��
integer a, b, c, d, x;
��
initial
����
begin
�������
if( a < b ) c = 1;
�������
if( a < b ) c = 2; else d = 3;
�������
// Note: x = 5 is always executed; c = 3 only if a < b.
�������
// This is an example of bad style, x = 5 should be put on
�������
// the next line.
�������
if( a < b ) c = 3;x = 5;
�������
// Unlike the statement above, c=3 and x=5
�������
// are executed only if a < b.
�������
if( a < b ) begin c = 3; x = 5; end
�������
if( a < b )
���������
begin
������������ c = 3;
������������ x = 5;
���������
end
�������
else
���������
begin
������������ c = 7;
������������ x = 2;
���������
end
�������
if( a == 0 )����� d = 7'b1110111;
�������
else if( a == 1 ) d = 7'b0100100;
�������
else if( a == 2 ) d = 7'b1011101;
�������
else if( a == 3 ) d = 7'b1101101;
�������
else if( a == 4 ) d = 7'b0101110;
�������
else d = 7'b1111111;
�������
����
end
endmodule
////////////////////////////////////////////////////////////////////////////////
//Example of event control.
module cond_example2(x,y,a,b,c,clk);
��
input a,b,c;
��
input clk;
��
output x,y;
��
wire [7:0] b, c;
��
reg [8:0]� x, y;
��
always @( posedge clk )
����
begin
�������
if( a ) begin
����������
x = b + c;
����������
y = b - c;
�������
end else begin
����������
x = b - c;
�������
end
����
end
endmodule
// Example of an if/else
module anotherif(x,a);
��
input [7:0] a;
��
output����� x;
��
reg [7:0]�� x;
��
always @( a )
� ���begin
�������
if( a < 10 )
���������
x = 1;��
�������
else
��������
���������
if ( a < 20 )
����������� x = 2;�
���������
else
����������
����������� if ( a < 30 ) x = 3;
����������� else x = 4;
�������
//� x = a < 10 ? 1: a < 20
? 2 : a < 30 ? 3 : 4;
����
end
endmodule
// An example with lots of if's.
// Focus on usage of if.
// Don't have to worry about what the
module is doing.
module andyetanotherif(x,a);
��
input [7:0] a;
��
output����� x;
��
reg [7:0]�� x;
��
always @( a )
����
begin
�������
�������
x = a;
�������
if( a[0] )
���������
begin
������������ x = x + 2;
������������ if( a[1] & a[2] ) x = x + 1;
���������
end
�������
else
���������
begin
������������ if( a[3] ^ a[4] ) x = x + ( a >> 1 );
������������ else x = x + ( a << 1 );
������������ x = 3 * x;
���������
end
�������
if( x[7] ) x = x - 1;
����
end
endmodule
// :Example:
//
//�
ALU.
module alu(result,a,b,add);
��
input [31:0] a, b;
��
input������� add;
��
output������ result;
��
reg [31:0]�� result;
��
always @( a or b or add )
����
begin
�������
if( add ) result = a + b; else result = a - b;
����
end
endmodule
// :Example:
//
// An up/down counter.
module
up_down_counter(count,up,reset,clk);
��
input up, reset, clk;
��
output count;
��
reg [7:0] count;
��
always @( posedge clk )
����
begin
�������
if( reset ) count = 0;
�������
else if( up ) count = count + 1;
�������
else count = count - 1;
�������
����
end
endmodule
//Mux using if statement.We will give mux
// using case statement after this .
// :Example:
//
// A mux, look at how the if/else chain
works.
module mux(x,select,i0,i1,i2,i3);
��
input [1:0] select;
��
input [7:0] i0, i1, i2, i3;
��
output����� x;
��
reg [7:0]�� x;
��
always @( select or i0 or i1 or i2 or i3 )
����
begin
�������
if( select == 0 ) x = i0;
�������
else if( select == 1 ) x = i1;
�������
else if( select == 2 ) x = i2;
�������
else x = i3;
����
end
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Syntax and Simulation of case
// :P: 7.5, 7.5.1 case
// :Syntax: case ( EXPR )
//������������ CEXP1:ST1;��
//������������ CEXP2:ST2;��
//������������ ...
//������������ [default:STD;]�
// Optional
//��������� endcase
//
// EXPR is an expression that evaluates to
a number
// [or physical value].
// CEXP1, CEXP2, etc. are expressions that
evaluate to a number
//[or physical value].
//
// Evaluate EXPR, find the first CEXP that
is equal to EXPR,
// execute the corresponding ST.� If none match and default is
// present execute STD.
// :Example:
//
// Description of a multiplexor using a
case statement.
// Using a case statement is much less
tedious
// than using the conditional operator.
module mux_case(x,select,i0,i1,i2,i3);
��
input [1:0] select;
��
input [7:0] i0, i1, i2, i3;
��
output����� x;
��
reg [7:0]�� x;
��
always @( select or i0 or i1 or i2 or i3 )
����
begin
�������
case ( select )
���������
0: x = i0;
���������
1: x = i1;
���������
2: x = i2;
���������
3: x = i3;
�������
endcase
�������
����
end
endmodule
// :Example:
//
// Module describing a selector.� There are four data inputs,
// i0,i1,i2,i3, four control inputs c0,
c1, c2, c3, c4, and a data
// output, x.� The output is set to the first input with a
// corresponding control input of 1, or
zero if all control inputs
// are zero. See the truth table below.
//
// c3 c2 c1 c0 | x
//
"""""""""""""""
// 0�
0� 0� 0� | 0
// 0�
0� 0� 1� | i0
// 0�
0� 1� 0� | i1
// 0�
0� 1� 1� | i0
// 0�
1� 0� 0� | i2
// 0�
1� 0� 1� | i0
// 0�
1� 1� 0� | i1
// 0�
1� 1� 1� | i0
// 1�
0� 0� 0� | i3
// 1�
0� 0� 1� | i0
// 1�
0� 1� 0� | i1
// 1�
0� 1� 1� | i0
// 1�
1� 0� 0� | i2
// 1�
1� 0� 1� | i0
// 1�
1� 1� 0� | i1
// 1�
1� 1� 1� | i0
module
selector(x,c0,c1,c2,c3,i0,i1,i2,i3);
��
input c0, c1, c2, c3;
��
input [7:0] i0, i1, i2, i3;
��
output����� x;
��
reg� [7:0]� x;
��
always @( c0 or c1 or c2 or c3 or i0 or i1 or i2 or i3 )
����
begin
�������
case( 1 )
���������
c0: x = i0;
���������
c1: x = i1;
���������
c2: x = i2;
���������
c3: x = i3;
���������
default: x = 0;
�������
endcase
�������
����
end
//
//if�
co == 1 then x = i0 else if
//���
c1 == 1 then x = i1 else if
//���
c2 == 1 then x = i2 else if
//���
c3 == 1 then x = i3
// usually in case statement the ordering
of CEXPR(co,c1..)
// is not important.
// but in this case , the ordering of
CEXPR is� important.
//���
//�������
case( 1 )
//��������
c3: x = i3;
//��������
c2: x = i2;
//��������
c1: x = i1;
//��������
c0: x = i0;
//��������
default: x = 0;
//�������
endcase
// this will generate different result..
// c3 c2 c1 c0 | x
//
"""""""""""""""
// 0�
0� 0� 0� | 0
// 0�
0� 0� 1� | i0
// 0�
0� 1� 0� | i1
// 0�
0� 1� 1� | i1�� i0
// 0�
1� 0� 0� | i2
// 0�
1� 0� 1� | i2�� i0
// 0�
1� 1� 0� | i2�� i1
// 0�
1� 1� 1� | i2�� i0
// 1�
0� 0� 0� | i3
// 1�
0� 0� 1� | i3�� i0
// 1�
0� 1� 0� | i3�� i1
// 1�
0� 1� 1� | i3�� i0
// 1�
1� 0� 0� | i3�� i2
// 1�
1� 0� 1� | i3�� i0
// 1�
1� 1� 0� | i3�� i1
// 1�
1� 1� 1� | i3�� i0
��
endmodule
// :Example:
//
// Description of an ALU using case.� This version is more
// readable than the structural
descriptions.
module yet_another_alu(result,a,b,op);
��
input [31:0] a, b;
��
input [2:0]� op;
��
output������ result;
��
reg [31:0]�� result;
��
parameter��� op_add = 0;
��
parameter��� op_sub = 1;
��
parameter��� op_and = 2;
��
parameter��� op_or = 3;
��
parameter��� op_slt = 4;
��
parameter��� op_a = 5;
��
parameter��� op_b = 6;
��
always @( a or b or op )
����
begin
�������
case( op )
���������
op_add� : result = a + b;� // 0 : result = a + b;
������������������������������������ // using parameters is easier
����������������������������������� // than using just numbers.
���������
op_sub� : result = a - b;� // 1 : result = a - b;
���������
op_and� : result = a & b;
���������
op_or�� : result = a | b;
���������
op_slt� : result = a < b;� // evaluate a < b logical
����������������������������������� // operation , so result will
���������������������������������� // be true or false(1,0)
���������
op_a�� �: result = a;
���������
op_b��� : result = b;
���������
default : result = 0;
�������
endcase
�������
����
end
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Syntax and Simulation of for, while,
repeat,forever
// :P: 7.6, 7.6.1, 7.6.2, 7.6.3
// In descriptions below remember
STATEMENT can be
// a single statement or:
//��
STATEMENT -> begin STATEMENT1; STATEMENT2; ... end
//�
multiple statements inside� begin
end block.
// :Syntax: for( INIT_ASSIGN; CONDITION;
STEP_ASSIGN ) STATEMENT
//���
#for(i = 0, j = 0 ; i <=4; j = j+1, i = i +1)// this is C.
//�
Some C programmers might find the for loop disappointing:
//���
INIT_ASSIGN must be an assignment,
// not an arbitrary statement.(not like
...i = 0, j = 0)
//���
STEP_ASSIGN must be an assignment,
// not an arbitrary statement.(not like j
= j+1, i = i +1)
//���
CONDITION is an expression that evaluates to
// an integer.(commonly using logical
operator for condition)
//
//���
1. Execute INIT_ASSIGN.
//���
2. Evaluate CONDITION, if true go to next step, else done.
//���
3. Execute STATEMENT
//���
4. Execute STEP_ASSIGN;
//���
5. Go to step 2.
// :Syntax: while( CONDITION) ) STATEMENT
//
//���
1. Evaluate CONDITION, if false done, else go to next step.
//���
2. Execute STATEMENT.
//���
3. Go to step 1.
// :Syntax: repeat( COUNT ) STATEMENT
//
//���
COUNT is an expression that evaluates to an integer.
//
//���
1. Evaluate COUNT, call result the_count.
//���
2. Execute STATEMENT the_count times.
// :Syntax: forever STATEMENT
//���
Execute STATEMENT forever.
// :Example:
//
// Easy looping (for, while, repeat)
examples.
module for_example();
��
integer i, sum;
��
��
initial
����
begin
�������
sum = 0;
����
���for(i=0; i<10; i=i+1)
���������
begin
������������ $display("So far i=%d and sum=%d",i,sum);
������������ sum = sum + i;
���������
end
�������
$display("Finally i=%d and sum=%d",i,sum);
�������
sum = 0;� i = 0;
�������
while( i < 10 )
�����
����begin
������������ $display("So far i=%d and sum=%d",i,sum);
������������ sum = sum + i;
������������ i = i + 1;
���������
end
�������
$display("Finally i=%d and sum=%d",i,sum);
������������
�������
sum = 0;� i = 0;
�������
repeat( 10 )
�� �������begin
������������ $display("So far i=%d and sum=%d",i,sum);
������������ sum = sum + i;
������������ i = i + 1;
���������
end
�������
$display("Finally i=%d and sum=%d",i,sum);
������������
����
end
endmodule
// :Example:
//
// Looping (for,while,repeat) with
additional information.
module looping_examples();
��
integer a, b, c;
��
integer i, pop, x;
��
reg���� clock, clock2;
��
initial begin
�����
/// for
�����
�����
// Basic for loop.
�����
for(i=0; i<3; i=i+1) $display("Hello");
�����
// There is no postincrement operator.
�����
// for(i=0; i<3; i++) $display("Hello");�
����
�// Syntax error. For C, it is
OK.
�����
// Can only have a single initialization assignment.
�����
//for(i=0, j=0; i<3; i=i+1) $display("Hello");
���
��// Syntax error. For C, it is
OK.
�����
/// while
�����
// Basic while loop.
�����
while( x < 10 ) x = x + 1;
�����
// Assignment (=) is not an operator as in C.
�����
// Verilog does not allow assignment
�����
// inside while loop condidion.
�����
// while( i = i - 1 ) x = x + 1;��
// Syntax error.
�����
/// Three Ways to Iterate Ten Times:
�����
�����
//� The simplest way is the best.
(repeat).
�����
repeat( 10 ) x = x + 1;
�����
for(i=0; i<10; i=i+1) x = x + 1;
�����
i = 10; while( i ) begin i = i - 1; x = x + 1; end
��
��
// while example, count the 1's in b.
�����
pop = 0;
�����
while( b )
�������
begin
����������
pop = pop + b[0];
����������
b = b >> 1;
�������
end
�����
��
end
�
endmodule
// the above module may repeat(while) zero
times
// or upto 32 times maximum.
// :Example:
//
// A module that computes the population
of its integer input.�
//The population of an integer is simply
the number of 1's in its
// binary representation.� (The population of: 1 is 1, 2 is 1,
// 3 is 2, 5 is 2, and 15 is 4.)
module pop_combinational(p,a);
��
input [31:0] a;
��
output������ p;
��
reg [5:0]��� p;
��
integer����� i;
��
always @( a )
����
begin
�������
p = 0;
�������
for(i=0; i<32; i=i+1) p = p + a[i];
����
end
��
endmodule
// the above module repeats( for) 32
times.
//looping forever example.
module forever_loop();
���� reg
clock; // the value stays 0 for a period of time and
��������������� // stays 1 for the other time.
���� initial
begin
�� ������ �����// forever is normally used with a delay
control.
� ������� �����// Example below implements a clock with
�������������� // a period of 20 cycles.
�����
clock = 0;
�����
forever begin #10 clock� =
~clock; end
end
endmodule
//�
There is a mechanism for breaking
//out of these loops(for, while ,
repeat,forever), but it's not
//�
as convenient as C's break.
// students are not responsible for this
material
// [named blocks and disable statement]
// [disabling blocks and breaking out of
loop]
//�
Naming Blocks
/// begin: NAME ...end
//�
Example
//�
begin: BLOCK1
//
//�
end
// disable can be used to exit from loops.
// Example
module disable_example(a,b);
�����
input a,b;
���� integer
i,x;
�����
�����
initial begin
�������������� x = 1;
�������������� begin:BLOCK1 //note:BLOCK1 is outside of for loop.
������������������ for(i =1; i<10; i = i +1) begin
����������������������� x = x*i;����������������
�������������������� ���// =
1* 1 * 2 * 3 * 4 ....
����������������������� //Early exit if x >100.
�����
������������������if (x > 100)
disable BLOCK1;
�������������� // exit when x > 100 actually x = 1*2*3*4*5 = 120
�������������������������������������������������
�
// when disabled, execution goes�
out of the block.**
������������������ end //for begin-end
����������
����end���� //BLOCK1 begin-end
�������������� x =1; i =1;�����
��//** execution comes here
�������������� begin : BLOCK2
������������������ forever begin
���������������������� x = x*i; i = i+ 1;
��������������������� //Exit if x >100.
���������������������� if( x> 100) disable BLOCK2;
������������������ end//forever begin-end
������������� end //BLOCK2 begin-end
������������ end� //initial
begin-end����������
endmodule
//
// :Example:
//
// A comparison module.� Output lt is asserted if a < b
// and gt is asserted if a > b.
module compare(gt, lt, a, b);
��
input [2:0] a, b;
��
output gt, lt;
��
reg������� gt, lt;
��
integer��� i;
��
always @( a or b ) begin
�����
gt = 0; lt = 0;
�����
for(i=2; i>=0; i=i-1)
�������
if( !gt && !lt ) begin
����������
if( a[i] < b[i] ) lt = 1;
����������
if( a[i] > b[i] ) gt = 1;
�������
end
��
end
endmodule // compare
//� Example1
//� a = 101
//� b = 011
//� at the beginnig.
//�� gt = 0, lt =0;
//�� for loop i = 2..
//����������� if statement (condition is true)
//������������� if(a[2] < b[2]).... (1 <
0)�� //.condition not true...
��������������������������������������������� //doing
nothing.lt still zero.
//������������� if(a[2] > b[2]).... (1 >
0)�� //.condition true...�� gt = 1.
//����������� i = 1..
//����������� if statement (condition is not
true)//gt became 1....
�������������������������������������������������
//doing nothing.
//����������� i = 0..
//����������� if statement (condition is not
true)//gt became 1....
�������������������������������������������������
//doing nothing.
//����������� i = -1...End of for loop.....
//� Example2
//� a = 101
//� b = 111
//� at the beginnig.
//�� gt = 0, lt =0;
//�� for loop i = 2..
//����������� if statement (condition is true)
//������������� if(a[2] < b[2]).... (1 <
1)� // .condition not true...
������������������������������������������� //doing
nothing.lt still zero.
//������������� if(a[2] > b[2]).... (1 >
1) //� .condition not true...
������������������������������������������� //doing
nothing gt still zero.
//����������� i = 1..
//����������� if statement (condition is� true)
//������������� if(a[1] < b[1]).... (0 <
1)� // .condition� true... lt = 1
//������������� if(a[1] > b[1]).... (0 >
1)� // .condition not true...
�������������������������������������������� //doing
nothing gt still zero.
//����������� i = 0..
//����������� if statement (condition is not
true)//lt became 1....
�������������������������������������������������
//doing nothing.
//����������� i = -1...End of for loop.....
////////////////////////////////////////////////////////////////////////////////
/// Ripple Adder: Combinational v.
Sequential
///
// Three approaches to ripple adder will
be shown:
//
// (1) Ripple Classic:�
//����
Combinational Logic using structural code.
//
// (2) Ripple Procedural Combinational:
//
// (3) Ripple Sequential:
//����
Uses sequential logic.
//
// :Example:
//
// Classic ripple adder.
module ripple_classic(sum,cout,a,b);
��
input [3:0] a, b;
��
output [3:0] sum;
��
output������ cout;
��
wire������ ��c0, c1, c2;
��
bfa_implicit bfa0(sum[0],c0,a[0],b[0],1'b0);
��
bfa_implicit bfa1(sum[1],c1,a[1],b[1],c0);
��
bfa_implicit bfa2(sum[2],c2,a[2],b[2],c1);
��
bfa_implicit bfa3(sum[3],cout,a[3],b[3],c2);
endmodule
// :Example:
//
// A ripple adder made from binary full
adders, but using
// procedural code.� Except for the number of bits, equivalent
// to the one above.
module ripple_2(sum,a,b);
��
input [31:0] a, b;
��
output������ sum;
��
reg [32:0]�� sum;
��
reg��������� carry;
�� integer�����
i;
��
always @( a or b )
����
begin
�������
carry = 0;
�������
for(i=0; i<32; i=i+1) begin
����������
sum[i] = a[i] ^ b[i] ^ carry;
����������
carry = a[i] & b[i] | a[i] & carry | b[i] & carry;
����������
�������
end
���
����sum[32] = carry;
����
end
��
endmodule
// :Example:
//
// A sequential ripple adder.
module ripple_seq(sum,a,b,clk);
��
input [31:0] a, b;
��
input������� clk;
��
output������ sum;
��
reg [32:0]�� sum;
��
reg��������� carry;
� �reg [4:0]���
i;
��
initial i = 0;
��
always @( posedge clk )
����
begin
�������
if( i == 0 ) begin
����������
sum[32] = carry;//� at the
beginning carry is unknown..
�������������������������� //�
11111 (31)� ----> 00000 (32)
��������������������������� //���������������� changing i value.
��������������� �//� sum[32]�
= carry generated by
��������������� �// a[31]
& b[31] | a[31 & carry | b[31] & carry;
��������������������������
����������
carry = 0;
�������
end
�������
sum[i] = a[i] ^ b[i] ^ carry;
�������
carry� = a[i] & b[i] | a[i]
& carry | b[i] & carry;
����������
�������
i = i + 1;
����
end
��
endmodule
��
////////////////////////////////////////////////////////////////////////////////
/// Miscellaneous Examples
// :Example:
//
//�
Clocked population count module.�
//�
there is no way to tell that the
//�
output is ready.
//so we need a flag to tell when output is
ready.
//�
Example for a = 0000 0000 0000 0000 0000 0000 0000 0001 ,
// output will be available early.
//��������� for a = 1000 0000 0000 0000 0000 0000 0000 0000 ,
// output will be available later.
�
module pop(p,a,clk);
��
input [31:0] a;
��
input������� clk;
��
output������ p;
��
reg [5:0]��� p;
��
reg [31:0]�� acopy;
��
reg [5:0]��� pcopy;
��
��
initial acopy = 0;
��
initial pcopy = 0;
��
always @( posedge clk )
����
begin
�������
if( acopy == 0 )
���������
begin
������������ p = pcopy;
������������ pcopy = 0;
������������ acopy = a;
���������
end
�������
else
���������
begin
������������ pcopy = pcopy + acopy[0];
������������ acopy = acopy >> 1;
���������
end
�����������������
����
end
endmodule
//Example
// a =��
0000 0000 0000 0000 0000 0000 0000 0110
//
//�������
1 cycle..
//���������� doing if.
//���������� p = pcopy =0
//���������� pcopy = 0.
//���������� acopy = a =0000 0000 0000 0000 0000 0000 0000 0110
//�������
2 cycle..
//��������
doing else part.
//��������� pcopy = pcopy + acopy[0] = 0 + 0 =0;
//��������� shift.0.0000 0000 0000 0000 0000 0000 0000 011
//������
3cycle..
//������
���doing else part.
//��������� pcopy = pcopy + acopy[0] = 0 + 1 =1;
//��������� shift.00.0000 0000 0000 0000 0000 0000 0000 01
//������
4cycle..
//��������� doing else part.
//��������� pcopy = pcopy + acopy[0] = 1 + 1 =2;
//��������� shift.000.0000 0000 0000 0000 0000 0000 0000 0� //acopy becomes zero...
//������
5 cycle...
//��������� (acopy became zero at 4cycle)
//��������� doing if part
//��������� p = pcopy =2�
//correct p value..//if the module is
// �smart,the module should say.."ready".
�����
//finished the process or ready to accept new input....
//��������� pcopy = 0.� �// instead,�
the module is repeating
������������������������ // the process over again.
//��������
acopy = a =0000 0000 0000 0000 0000 0000 0000 0110
//�����
6 cycle.....will repeat 2cycle.....
//�������
doing else part.
//�������
pcopy = pcopy + acopy[0] = 0 + 0 =0;
//�������
shift.0.0000 0000 0000 0000 0000 0000 0000 011
//����
7 cycle will repeat� 3cycle...
//����
8 cycle will repeat� 4cycle...
//����
9 cycle will repeat�
5cycle...update p value
//���
10 cycle will repeat 6cycle. which is 2cycle....
//and so on.....
//��
//������
if we have one at 31 bit position ,
// �������p will be available at 34 cycles.
// :Example:
//
// Population count with handshaking.� Handshaking is the use of
// control signals between two modules to
coordinate activities.
//
// In this case:
//��
The external module waits for ready to be 1.
//��
ready is output of the module which tells the module is
//�
ready to accept inputs.
// If ready = 0 , the module is busy(don't
accept inputs).
//��
The external module then puts a number on "a"
// and asserts start.
//��
start is output of external module(input to the module)�
// which tells inputs to the module are
//��
ready, so start to process the inputs.
//��
when start is 1,pop_with_handshaking copies the number and
// sets ready to zero(initialize the
module to compute).
//��
When start goes to zero, pop_with_handshaking� starts
// computing(external module will change
the start value to zero).
//��
When pop_with_handshaking is finished it asserts
//�
ready(telling the module is not busy so
//��
it is ready to accept new inputs to process).
module
pop_with_handshaking(p,ready,a,start,clk);
��
input [31:0] a;
��
input������� start, clk;
��
output������ p, ready;
��
reg [5:0]��� p;
��
reg��������� ready;
��
reg [31:0]�� acopy;
��
��
initial ready = 1;
��
always @( posedge clk )
����
begin
�������
if( start )
���������
begin
������������ acopy = a;
������������ p = 0;
����������
��ready = 0;
���������
end
�������
else if( !ready && acopy )
���������
begin
������������ p = p + acopy[0];
������������ acopy = acopy >> 1;
���������
end
�������
else if( !ready && !acopy )
���������
begin
������������ ready = 1;//output is ready,also means the module is
��������������������� // ready to accept new input.
���������
end
����
end
endmodule
// :Keyword: $stop (System task)
//
// Stops simulation.� Used for testbenches and debugging.
##########################################################
module demo_counter();
��
wire [7:0] count;
��
reg������� up, reset, clk;
��
��
up_down_counter c1(count,up,reset,clk);
��
integer��� i;
��
initial
����
begin
�������
i = 0;
�������
up = 1;����� //up-counting.
�������
reset = 1;�� //reset the counter
to zero
������������� �������//after
posedge clk comes.
�������������������� //see next line(for loop).
�������
for(i=0; i<4; i=i+1) @( posedge clk );
�������
reset = 0;� //now the counter is
ready to count.
�������
for(i=0; i < 255; i=i+1)
���������
begin
������������ if( i != count )// at i = 0 : since we reset
���������������������������� // the counter, no clock occured,
���������������������������� //so count remains zero.
�������������� begin
����������������� $display("Something wrong at i=%d, ����
��������������������������� count=%d",i,count);
����������������� $stop;
�������������� end
������������ @( posedge clk ); #1;//just waiting 1 time unit,
������������� �������������������//so giving the counter sometime
�������������������������������� //to update count value.
���������
end
�������
up = 0;// down counting
�������
for(i=i; i >= 0; i=i-1)�
//from previous for loop,
������������������������������� �//i is now 255.
���������
begin
������������ if( i != count )
�������������� begin
����������������� $display("Something wrong at i=%d,
���������������������������������� count=%d",i,count);
����������������� $stop;
�������������� end
������������ @( posedge clk ); #1;
���������
end
�������
$display("Done with tests.");
�������
���
�end
��
always begin clk = 0; #5; clk = 1; #5; end //clock generator, ������
��������������������������������������������� //cycle of 10.
endmodule