// program ancienttimes_tb
module ancienttimes_tb
     #(parameter DATA_WIDTH = 12)
      (input    logic                    clk,
       output   logic                    reset,
       output   logic                    start,
       output   logic [DATA_WIDTH-1:0]   p,
       output   logic [DATA_WIDTH-1:0]   q,
       input    logic [2*DATA_WIDTH-1:0] result,
       input    logic                    ready) ;
      
	
      int num_tests ;
      int num_passed ; 

      // start ancienttimes and make sure it asserts ready
      task startMultiply() ;
        int i ;
        num_tests = num_tests + 1 ;
        $display("Reseting test module") ;
        start = 0 ;
        p = 0 ;
        q = 0 ;
        reset = 0 ;
	repeat (4) @(posedge clk) ;
	@(negedge clk) ;
	reset = 1 ;
	repeat (4) @(posedge clk);
	@(negedge clk) ;
	reset = 0 ;
	repeat (10) @(negedge clk);
        assert (ready == 1) else $error("Test module did not assert ready") ;
      endtask 
      
      // Test a multiplication
      task doMultiply(int unsigned pt, int unsigned qt) ;
        int i ;
        // These are silly names
        int unsigned ptt, qtt, rtt ;
        num_tests = num_tests + 1 ;
        ptt = pt[DATA_WIDTH-1:0] ;
        qtt = qt[DATA_WIDTH-1:0] ;
        rtt = ptt*qtt ;
        assert (ready == 1) else $error("ready must be asserted before calling multiply") ;
        // load p, q, and start
        $display("Multiplying %d by %d, expecting %d", ptt, qtt, rtt) ;
        @(negedge clk)
        p = ptt ;
        q = qtt ;
        start = 1 ;
        // leave start asserted for three cycles
	repeat (3) @(negedge clk) ;
        // now deassert start and wait
        start = 0 ;
        i = 0;
        while (i<1000 && !ready)
        begin
          @(negedge clk) ;
          ++i ;
        end
        assert (ready == 1) else $error("ready not asserted") ;
        assert (rtt == result) else $error("wrong result") ;
        $display("result = %d", result) ;
      endtask
      
      initial
      begin
        int i ;
        num_tests = 0 ;
        num_passed = 0 ;
        startMultiply() ;
        // the case from the homework description
        doMultiply(42, 255) ;
        // 4 fencepost cases
        doMultiply(0, 0) ;
        doMultiply(0, ~0) ;
        doMultiply(~0, 0) ;
        doMultiply(~0, ~0) ;
        // And 94 random cases
        for (i=6; i<100; ++i)
          doMultiply($urandom(), $urandom()) ;
        $display("Number tests  %3d", num_tests);
        $display("Number passed %3d", num_passed) ;
        if (num_tests == num_passed)
           $display("All tests passed!") ;
        $stop ;
      end

endmodule
// endprogram // end of program

