/// Sample Code for LSU EE 3755 Fall 2013
///
/// Population Modules and Testbench
///

 // Includes live classroom code, pop_live_n.

 /// Input:       a,  an 8-bit vector.
 /// Output:    pop, the number of 1's in a's binary representation.

 /// Three descriptions:  behavioral, implicit structural, and explicit structural.


module pop_implicit_structural_8(pop,a);
   input a;
   output pop;

   wire [7:0] a;
   wire [3:0] pop = a[7] + a[6] + a[5] + a[4] + a[3] + a[2] + a[1] + a[0];

endmodule // pop_implicit_structural

// And what if a is 128-bits?
// (loop for i from 0 to 127 concat (format " + a[%d]" i))"


module pop_live_n(pop,a);
   parameter n = 8;
   input [n-1:0] a;
   output      pop;
   reg [7:0]   pop;
   integer     i;

   always @ ( a ) begin

      pop = 0;
      for ( i = 0; i < n; i = i + 1 ) pop = pop + a[i];

   end

endmodule;


module pop_behavioral_8(pop,a);
   input [7:0] a;
   output [3:0] pop;

   reg [3:0]  pop;
   integer    i;

   always @ ( a ) begin

      pop = 0;

      for (i=0; i<8; i=i+1)
        pop = pop + a[i];

   end

endmodule

module pop_behavioral_32(pop,a);
   input [31:0] a;
   output [5:0] pop;

   reg [5:0]  pop;
   integer    i;

   always @ ( a ) begin

      pop = 0;

      for (i=0; i<32; i=i+1)
        pop = pop + a[i];

   end

endmodule


// cadence translate_off

module test_pop();

   wire [3:0] pb, pis;
   integer    i;
   wire [7:0] a = i[7:0];
   integer    check;

   pop_behavioral_8 p_b(pb,a);
   pop_implicit_structural_8 p_is(pis,a);

   initial begin

      check = 0;

      for(i=0; i<256; i=i+1)
        begin
           #1;
           if( (^pb) === 1'bx ) begin
              $display("Behavioral has unknown value.");
              $stop;
           end

           check = check + pb;

           if( (^pis) === 1'bx ) begin
              $display("Implicit structural has unknown value.");
              $stop;
           end

           if( pis != pb ) begin
              $display("Behavioral and implicit str don't match.");
              $stop;
           end

        end // for (i=0; i<255; i=i+1)

      if( check != 256 * 4 ) begin
         $display("Incorrect check.");
         $stop;
      end

      $display("Passed all tests.");
      $stop;

   end


endmodule


// cadence translate_on