////////////////////////////////////////////////////////////////////////////////
///
/// Template for LSU EE 3755 Spring 2002 Homework 1
///

 /// Instructions:
  //
  // Copy this to a file named hw01.v to directory ~/hw in your
  // class account. (~ is your home directory.)  Use this
  // file for your solution.  Your entire solution should be in
  // this file.
  //
  // Do not rename the modules in this file and be sure to use the
  // directory and filename given above.

  // Assignment:"http://www.ee.lsu.edu/ee3755/2002/hw01.pdf

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


////////////////////////////////////////////////////////////////////////////////
/// Problem 0
///

module hello();

   initial begin
      $display("Hello, world!");
   end

endmodule


////////////////////////////////////////////////////////////////////////////////
/// Problem 1
///

// Complete the 2-to-4 decoder.  See assignment for ports.

// Explicit Structural: Use gates only on assign or operators.

// Test using test_decoder.

module decode_2_to_4();

   // Don't forget to add ports.
   
endmodule


////////////////////////////////////////////////////////////////////////////////
/// Problem 2
///

// Convert a two-digit hex number in ASCII (12, af, 03) on "s" to binary
// on "i"

// Implicit Structural: assign and operators okay.

// Test using test_atoi.


module atoi_implicit(i,s);
   input [15:0] s;
   output [7:0] i;

   // Solution goes here.  Can be done in two lines, but more are okay.

   
endmodule


////////////////////////////////////////////////////////////////////////////////
/// Problem 3
///

// Convert a two-digit hex number in ASCII (12, af, 03) on "s" to binary
// on "i"

// Explicit Structural: Use gates and modules only no assign or operators.

// Can instantiate the following modules: and4, sub4, and8, sub8, see module
// definitions below.

// Test using test_atoi.

module atoi_explicit(i,s);
   input [15:0] s;
   output [7:0] i;

   // Solution goes here.  Can be done in two lines, but more are okay.

   
   
endmodule


//
// Modules for use in Problem 3
//
// DO NOT modify these modules.

module sub4(d,a,b);
   input [3:0] a, b;
   output [3:0] d;

   assign       d = a - b;
   
endmodule

module add4(d,a,b);
   input [3:0] a, b;
   output [3:0] d;

   assign       d = a + b;
   
endmodule

module sub8(d,a,b);
   input [7:0] a, b;
   output [7:0] d;

   assign       d = a - b;
   
endmodule

module add8(d,a,b);
   input [7:0] a, b;
   output [7:0] d;

   assign       d = a + b;
   
endmodule

////////////////////////////////////////////////////////////////////////////////
/// Testbenches
///

module test_decoder();

   parameter stop_on_error = 1;
   
   reg [1:0] a;
   wire      x0, x1, x2, x3;
   reg [3:0] x;

   decode_2_to_4 your_decoder(x0,x1,x2,x3,a);

   integer   i, err;

   initial begin

      err = 0;

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

         a = i[1:0];
         #1;
         x = 1 << a;
         if( {x3,x2,x1,x0} !== x )
           begin
              $display("FAIL: Demux wrong output for input %d",a);
              err = err + 1;
              if( stop_on_error ) $stop;
           end
      end

      if( !err ) $write("PASS: ");
      $write("Tests completed, ");
      if( err )
        $display("encountered %d errors.",err);
      else
        $display("no errors found.\n");

      $display("Thank you for using the decode testbench.");

   end
   
endmodule

module test_atoi();

   wire [7:0] ie, ii;
   reg [15:0] s;

   parameter  stop_on_error = 1;
   parameter  ascii_0 = 48;
   parameter  ascii_a = 97;
   
   atoi_explicit our_atoi_explicit(ie,s);
   atoi_implicit our_atoi_implict(ii,s);

   integer    i, err_i, err_e;

   integer    d0, d1;

   initial begin

      err_i = 0;  err_e = 0;

      for(i=0; i<256; i=i+1)
        begin

           d0 = i & 15;
           d1 = i >> 4;
           s[7:0]  = d0 < 10 ? d0 + ascii_0 : d0 + ascii_a - 10;
           s[15:8] = d1 < 10 ? d1 + ascii_0 : d1 + ascii_a - 10;
           #1;
           if( ie !== i ) begin
              $display("FAIL: Explicit, wrong output, 0x%h (correct) != 0x%h",
                       i,ie);
              err_e = err_e + 1;
              if( stop_on_error ) $stop;
           end
           if( ii !== i ) begin
              $display("FAIL: Implicit, wrong output, 0x%h (correct) != 0x%h",
                       i,ii);
              err_i = err_i + 1;
              if( stop_on_error ) $stop;
           end

        end
      if( !err_i ) $write("PASS: ");
      $write("Implicit tests completed, ");
      if( err_i )
        $display("encountered %d errors.",err_i);
      else
        $display("no errors found.\n");

      if( !err_e ) $write("PASS: ");
      $write("Explicit tests completed, ");
      if( err_e )
        $display("encountered %d errors.",err_e);
      else
        $display("no errors found.\n");

   end

endmodule