module JEFF_74x181_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg  [3:0]  A, B, S;
    reg         M, CI_BAR;
    wire [3:0]  F;
    wire        CO_BAR, AEQB, X, Y;

    // FOR TESTING  
    reg             TICK;
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg [3:0]       FEXPECTED;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST (dataflow)
    jeff_74x181 UUT_jeff_74x181(
        .a3(A[3]), .a2(A[2]), .a1(A[1]), .a0(A[0]),
        .b3(B[3]), .b2(B[2]), .b1(B[1]), .b0(B[0]),
        .s3(S[3]), .s2(S[2]), .s1(S[1]), .s0(S[0]),
        .m(M), .ci_bar(CI_BAR),
        .f3(F[3]), .f2(F[2]), .f1(F[1]), .f0(F[0]),
        .co_bar(CO_BAR), .aeqb(AEQB), .x(X), .y(Y)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("jeff_74x181_tb.vcd");
        $dumpvars(0, JEFF_74x181_TB);
    end

    // TICK PERIOD
    localparam TICKPERIOD = 20;

    // TICK
    always begin
        #(TICKPERIOD/2) TICK = ~TICK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("jeff_74x181_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b %4b %4b %4b %4b", COMMENT, M, CI_BAR, S, A, B, FEXPECTED);
        TICK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                       | TIME(ns) | M | CI_BAR |  S   |  A   |  B   |  F   |");
        $display("                       -----------------------------------------------------");
        // $monitor("%4d  %16s | %8d | %1b |   %1b    | %4b | %4b | %4b | %4b |", VECTORCOUNT, COMMENT, $time, M, CI_BAR, S, A, B, F);

    end

    // APPLY TEST VECTORS ON NEG EDGE TICK (ADD DELAY)
    always @(negedge TICK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b %4b %4b %4b %4b", COMMENT, M, CI_BAR, S, A, B, FEXPECTED);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE TICK
    always @(posedge TICK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE TICK
        $display("%4d  %16s | %8d | %1b |   %1b    | %4b | %4b | %4b | %4b |", VECTORCOUNT, COMMENT, $time, M, CI_BAR, S, A, B, F);

        // CHECK EACH VECTOR RESULT
        if (F !== FEXPECTED) begin
            $display("***ERROR (gate) - Expected F = %b", FEXPECTED);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule