/// Example of how not to use functions.

// For LSU EE 4702-1, Spring 2001

// This is how it SHOULD be done:
//
// Output COUNT is number of times since last RESET that SYMBOL is
// equal to TARGET on positive edge of CLK.
//
module match_count(count,reset,symbol,target,clk);
   output       count;
   input        reset, symbol, target, clk;

   reg [9:0]    count;
   wire         reset;
   wire [7:0]   symbol, target;
   wire         clk;

   always @( posedge clk )
     case ( 1 )
       reset             : count <= 0;
       symbol === target : count <= count + 1;
       default           : count <= count;
     endcase 
   
endmodule // match_count


module test_match_count_module();

   reg       clk;
   reg [7:0] symbol;
   reg       reset;
   wire [9:0] s1count;
   match_count mc1(s1count,reset,symbol,8'd1,clk);
   wire [9:0] s2count;
   match_count mc2(s2count,reset,symbol,8'd2,clk);
   
   initial
     begin:I
        integer j;
        reset = 1;
        clk = 0;
        #1;
        clk = 1;
        #1;
        clk = 0;
        reset = 0;
        #1;
        for(j=0;j<8;j=j+1)
        begin
           #1;
           clk = 1;
           #1;
           symbol = {6'b0,j[1:0]};
           #1;
           clk = 0;
           $display("Input is %d, count of 1's is %d",symbol,s1count);
           $display("Input is %d, count of 2's is %d",symbol,s2count);
        end
     end 

endmodule 



 /// WARNING: The following example will show how NOT to use functions.
module test_match_count_function();

   // WARNING: This is an example of how NOT to use functions.
   function [9:0] match_count;
      input reset;
      input [7:0] item,target;
      integer c;  // Static duration. (Its value sticks around.)

      begin
         if( reset ) c = 0;
         else if( item === target ) c = c + 1;
         match_count = c;
      end
   endfunction // match_count

   reg [7:0] symbol;
   reg       reset;
   wire [9:0] s1count;
   assign s1count = match_count(reset,symbol,1);
   wire [9:0] s2count;
   assign s2count = match_count(reset,symbol,2);

   /// WARNING: Within an example showing how NOT to use functions.
   
   initial
     begin:I
        integer j;
        reset = 1;
        #1;
        reset = 0;
        #1;
        for(j=0;j<8;j=j+1)
        begin
           symbol = {6'b0,j[2:1]};
           #1;
           $display("Input is %d, count of 1's is %d",symbol,s1count);
           $display("Input is %d, count of 2's is %d",symbol,s2count);
        end
     end // block: I

   // Problems:
   //   Unsafe use of static variables. (Incorrect behavior.)
   //   "Trick" simulator into executing function on changes.
   
endmodule // test_match_count_function
 /// WARNING: The preceding example showed how NOT to use functions.