//=========================================================================
// Behavioral Model of GCD Unit
//
// Author : Christoher Batten
// Date   : February 5, 2005
//
// This module implements Eculid's greated common divisor
// algorithm using a behavioral Verilog style. The test
// harness tests one set of inputs possibly taken from
// the command line and is designed to work with the
// vmodel-tester.pl perl script.
//

//-------------------------------------------------------------------------
// GCD Behavioral Module

module gcd_behavioral #( parameter width = 16 )
                       ( input  [width-1:0] A_in, B_in,
                         output [width-1:0] Y );

  reg [width-1:0] A, B, Y, swap;
  integer         done;
  
  always @( A_in or B_in )
  begin

    done = 0;
    A = A_in;
    B = B_in;

    while ( !done )
    begin

      if ( A < B )
      begin
        swap = A;
        A = B;
        B = swap;
      end

      else if ( B != 0 )
        A = A - B;

      else
        done = 1;

    end
    
    Y = A;
  end

endmodule

//-------------------------------------------------------------------------
// GCD Test Harness

module gcd_test;
  parameter width = 16;

  reg  [width-1:0] A_in, B_in;
  wire [width-1:0] Y;

  gcd_behavioral #( .width(width) ) 
                  gcd_unit( .A_in(A_in), .B_in(B_in), .Y(Y) );

  initial
  begin

    // Default inputs if cmdline args are not provided

    A_in = 27;
    B_in = 15;

    // Read in cmdline args
    
    $value$plusargs("a-in=%d",A_in);
    $value$plusargs("b-in=%d",B_in);

    // Let the simulation run
    
    #10;

    // Output the results
    
    $display(" a-in    = %d", A_in );
    $display(" b-in    = %d", B_in );
    $display(" gcd-out = %d", Y    );	
    $finish;
    
  end    

endmodule