// Solution to EE 4702-1 Spring 2000 HW 1

//
// Problem 1
//

module number_detect_es(found,number);
   input number;
   output found;
   wire [3:0] number;
   wire       b1001,b0010,n0,n1,n2,n3;

   or (found,b1001,b0010);

   and (b1001,number[3],n2,n1,number[0]);
   and (b0010,n3,n2,number[1],n0);

   not (n0,number[0]);
   not (n1,number[1]);
   not (n2,number[2]);
   not (n3,number[3]);
   
endmodule // number_detect

module number_detect_is(found,number);
   input number;
   output found;
   wire [3:0] number;

   assign     found = number === 4'b1001 || number === 4'b0010;

   // Also works:
   // assign found = ~| ( number ^ 4'b1001 ) | ~| ( number ^ 4'b010 );

   // Works, but is unnecessarily complicated.
//   assign found =               
  //      number[3] & ~number[2] & ~number[1] & number[0] |
    //      ~number[3] & ~number[2] & number[1] & ~number[0];
   
endmodule // number_detect_is

//
// Problem 2
//

module test_number_detect();

   integer   n;
   reg       expected_output;
   wire      fes, fis;     

   // Instantiate implicit and explicit structural descriptions.
   number_detect_es ndes(fes,n[3:0]);
   number_detect_is ndis(fis,n[3:0]);

   initial
     begin
        for(n=0; n<16; n=n+1)
        begin
           #1;
           // Compute expected output using comparison operators.
           // It's important NOT to use the same expression that
           // was used in the implicit structural code.
           expected_output = ( n === 9 || n === 2 ) ? 1 : 0;

           // Check that output is correct for all inputs (not just 2
           // and 9).
           
           if( fes !== expected_output )
             $display("Wrong output for explicit str, n=%d",n);
           
           if( fis !== expected_output )
             $display("Wrong output for implicit str, n=%d",n);
        end
        $display("Done testing.");
     end
   
   
endmodule // test_number_detect


//
// Problem 3
//

module pos_edge_trigger(o,i);
   input i;
   output o;
   wire   i;
   wire   o;
   wire   noti;
   wire   #2 preout;

   assign    o = preout;

   not #2 (noti,i);
   and #(2,3) (preout,i,noti);

endmodule // pos_edge_trigger


module test_pos_edge();
   reg i;
   wire o;

   pos_edge_trigger et(o,i);

   initial
     begin
        i=0;
        #10;
        i=1;
        #1;
        i=0;
        #5;
        i=1;
        #2;
        i=0;
        #7;
        i=1;
        #9;
        i=0;
        #5;
     end
   
endmodule