/// LSU EE 3755 Fall 2009 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