`timescale 1ns / 1ps

module tb_hardmax_onehot;

    // Inputs to DUT
    reg signed [7:0] x0, x1, x2, x3, x4, x5;
    
    // Output from DUT
    wire [5:0] y_onehot;
    
    // Instantiate DUT
    hardmax_onehot uut (
        .x0(x0), .x1(x1), .x2(x2), .x3(x3), .x4(x4), .x5(x5),
        .y_onehot(y_onehot)
    );
    
    // ==============================================
    // Golden Vectors
    // ==============================================
    localparam NUM_TESTS = 36;
    
    // Input vectors (8-bit signed, stored as unsigned)
    reg [7:0] tb_x0 [0:35];
    reg [7:0] tb_x1 [0:35];
    reg [7:0] tb_x2 [0:35];
    reg [7:0] tb_x3 [0:35];
    reg [7:0] tb_x4 [0:35];
    reg [7:0] tb_x5 [0:35];
    
    // Expected output (6-bit one-hot)
    reg [5:0] expected_y [0:35];
    
    integer i;
    integer errors = 0;

    initial begin
        // Test 0: all_zeros (Inputs: [0, 0, 0, 0, 0, 0], Max Index: 0)
        tb_x0[0] = 8'd0;     tb_x1[0] = 8'd0;     tb_x2[0] = 8'd0;     tb_x3[0] = 8'd0;     tb_x4[0] = 8'd0;     tb_x5[0] = 8'd0; 
        expected_y[0] = 6'b000001;

        // Test 1: max_x0 (Inputs: [100, 0, 0, 0, 0, 0], Max Index: 0)
        tb_x0[1] = 8'd100;     tb_x1[1] = 8'd0;     tb_x2[1] = 8'd0;     tb_x3[1] = 8'd0;     tb_x4[1] = 8'd0;     tb_x5[1] = 8'd0; 
        expected_y[1] = 6'b000001;

        // Test 2: max_x1 (Inputs: [0, 100, 0, 0, 0, 0], Max Index: 1)
        tb_x0[2] = 8'd0;     tb_x1[2] = 8'd100;     tb_x2[2] = 8'd0;     tb_x3[2] = 8'd0;     tb_x4[2] = 8'd0;     tb_x5[2] = 8'd0; 
        expected_y[2] = 6'b000010;

        // Test 3: max_x2 (Inputs: [0, 0, 100, 0, 0, 0], Max Index: 2)
        tb_x0[3] = 8'd0;     tb_x1[3] = 8'd0;     tb_x2[3] = 8'd100;     tb_x3[3] = 8'd0;     tb_x4[3] = 8'd0;     tb_x5[3] = 8'd0; 
        expected_y[3] = 6'b000100;

        // Test 4: max_x3 (Inputs: [0, 0, 0, 100, 0, 0], Max Index: 3)
        tb_x0[4] = 8'd0;     tb_x1[4] = 8'd0;     tb_x2[4] = 8'd0;     tb_x3[4] = 8'd100;     tb_x4[4] = 8'd0;     tb_x5[4] = 8'd0; 
        expected_y[4] = 6'b001000;

        // Test 5: max_x4 (Inputs: [0, 0, 0, 0, 100, 0], Max Index: 4)
        tb_x0[5] = 8'd0;     tb_x1[5] = 8'd0;     tb_x2[5] = 8'd0;     tb_x3[5] = 8'd0;     tb_x4[5] = 8'd100;     tb_x5[5] = 8'd0; 
        expected_y[5] = 6'b010000;

        // Test 6: max_x5 (Inputs: [0, 0, 0, 0, 0, 100], Max Index: 5)
        tb_x0[6] = 8'd0;     tb_x1[6] = 8'd0;     tb_x2[6] = 8'd0;     tb_x3[6] = 8'd0;     tb_x4[6] = 8'd0;     tb_x5[6] = 8'd100; 
        expected_y[6] = 6'b100000;

        // Test 7: all_negative (Inputs: [-10, -20, -30, -40, -50, -60], Max Index: 0)
        tb_x0[7] = 8'd246;     tb_x1[7] = 8'd236;     tb_x2[7] = 8'd226;     tb_x3[7] = 8'd216;     tb_x4[7] = 8'd206;     tb_x5[7] = 8'd196; 
        expected_y[7] = 6'b000001;

        // Test 8: max_x5_neg (Inputs: [-60, -50, -40, -30, -20, -10], Max Index: 5)
        tb_x0[8] = 8'd196;     tb_x1[8] = 8'd206;     tb_x2[8] = 8'd216;     tb_x3[8] = 8'd226;     tb_x4[8] = 8'd236;     tb_x5[8] = 8'd246; 
        expected_y[8] = 6'b100000;

        // Test 9: tie_0_1 (Inputs: [50, 50, 0, 0, 0, 0], Max Index: 0)
        tb_x0[9] = 8'd50;     tb_x1[9] = 8'd50;     tb_x2[9] = 8'd0;     tb_x3[9] = 8'd0;     tb_x4[9] = 8'd0;     tb_x5[9] = 8'd0; 
        expected_y[9] = 6'b000001;

        // Test 10: tie_0_2 (Inputs: [50, 0, 50, 0, 0, 0], Max Index: 0)
        tb_x0[10] = 8'd50;     tb_x1[10] = 8'd0;     tb_x2[10] = 8'd50;     tb_x3[10] = 8'd0;     tb_x4[10] = 8'd0;     tb_x5[10] = 8'd0; 
        expected_y[10] = 6'b000001;

        // Test 11: tie_3_4_5 (Inputs: [0, 0, 0, 50, 50, 50], Max Index: 3)
        tb_x0[11] = 8'd0;     tb_x1[11] = 8'd0;     tb_x2[11] = 8'd0;     tb_x3[11] = 8'd50;     tb_x4[11] = 8'd50;     tb_x5[11] = 8'd50; 
        expected_y[11] = 6'b001000;

        // Test 12: tie_all (Inputs: [50, 50, 50, 50, 50, 50], Max Index: 0)
        tb_x0[12] = 8'd50;     tb_x1[12] = 8'd50;     tb_x2[12] = 8'd50;     tb_x3[12] = 8'd50;     tb_x4[12] = 8'd50;     tb_x5[12] = 8'd50; 
        expected_y[12] = 6'b000001;

        // Test 13: close_x1 (Inputs: [10, 11, 10, 10, 10, 10], Max Index: 1)
        tb_x0[13] = 8'd10;     tb_x1[13] = 8'd11;     tb_x2[13] = 8'd10;     tb_x3[13] = 8'd10;     tb_x4[13] = 8'd10;     tb_x5[13] = 8'd10; 
        expected_y[13] = 6'b000010;

        // Test 14: descending (Inputs: [10, 9, 8, 7, 6, 5], Max Index: 0)
        tb_x0[14] = 8'd10;     tb_x1[14] = 8'd9;     tb_x2[14] = 8'd8;     tb_x3[14] = 8'd7;     tb_x4[14] = 8'd6;     tb_x5[14] = 8'd5; 
        expected_y[14] = 6'b000001;

        // Test 15: ascending (Inputs: [5, 6, 7, 8, 9, 10], Max Index: 5)
        tb_x0[15] = 8'd5;     tb_x1[15] = 8'd6;     tb_x2[15] = 8'd7;     tb_x3[15] = 8'd8;     tb_x4[15] = 8'd9;     tb_x5[15] = 8'd10; 
        expected_y[15] = 6'b100000;

        // Test 16: random_0 (Inputs: [23, 61, -36, 104, 39, 89], Max Index: 3)
        tb_x0[16] = 8'd23;     tb_x1[16] = 8'd61;     tb_x2[16] = 8'd220;     tb_x3[16] = 8'd104;     tb_x4[16] = 8'd39;     tb_x5[16] = 8'd89; 
        expected_y[16] = 6'b001000;

        // Test 17: random_1 (Inputs: [39, -38, -14, -46, -44, -56], Max Index: 0)
        tb_x0[17] = 8'd39;     tb_x1[17] = 8'd218;     tb_x2[17] = 8'd242;     tb_x3[17] = 8'd210;     tb_x4[17] = 8'd212;     tb_x5[17] = 8'd200; 
        expected_y[17] = 6'b000001;

        // Test 18: random_2 (Inputs: [-119, 6, 54, -38, -105, 24], Max Index: 2)
        tb_x0[18] = 8'd137;     tb_x1[18] = 8'd6;     tb_x2[18] = 8'd54;     tb_x3[18] = 8'd218;     tb_x4[18] = 8'd151;     tb_x5[18] = 8'd24; 
        expected_y[18] = 6'b000100;

        // Test 19: random_3 (Inputs: [1, -101, -35, -122, -106, -14], Max Index: 0)
        tb_x0[19] = 8'd1;     tb_x1[19] = 8'd155;     tb_x2[19] = 8'd221;     tb_x3[19] = 8'd134;     tb_x4[19] = 8'd150;     tb_x5[19] = 8'd242; 
        expected_y[19] = 6'b000001;

        // Test 20: random_4 (Inputs: [66, -23, -24, 75, -63, -68], Max Index: 3)
        tb_x0[20] = 8'd66;     tb_x1[20] = 8'd233;     tb_x2[20] = 8'd232;     tb_x3[20] = 8'd75;     tb_x4[20] = 8'd193;     tb_x5[20] = 8'd188; 
        expected_y[20] = 6'b001000;

        // Test 21: random_5 (Inputs: [87, 19, 110, -47, -17, -37], Max Index: 2)
        tb_x0[21] = 8'd87;     tb_x1[21] = 8'd19;     tb_x2[21] = 8'd110;     tb_x3[21] = 8'd209;     tb_x4[21] = 8'd239;     tb_x5[21] = 8'd219; 
        expected_y[21] = 6'b000100;

        // Test 22: random_6 (Inputs: [51, -71, 67, 20, -120, -56], Max Index: 2)
        tb_x0[22] = 8'd51;     tb_x1[22] = 8'd185;     tb_x2[22] = 8'd67;     tb_x3[22] = 8'd20;     tb_x4[22] = 8'd136;     tb_x5[22] = 8'd200; 
        expected_y[22] = 6'b000100;

        // Test 23: random_7 (Inputs: [-67, -57, -6, -37, 9, 68], Max Index: 5)
        tb_x0[23] = 8'd189;     tb_x1[23] = 8'd199;     tb_x2[23] = 8'd250;     tb_x3[23] = 8'd219;     tb_x4[23] = 8'd9;     tb_x5[23] = 8'd68; 
        expected_y[23] = 6'b100000;

        // Test 24: random_8 (Inputs: [95, 97, -52, 6, 68, 116], Max Index: 5)
        tb_x0[24] = 8'd95;     tb_x1[24] = 8'd97;     tb_x2[24] = 8'd204;     tb_x3[24] = 8'd6;     tb_x4[24] = 8'd68;     tb_x5[24] = 8'd116; 
        expected_y[24] = 6'b100000;

        // Test 25: random_9 (Inputs: [-14, 117, 46, 119, -108, -110], Max Index: 3)
        tb_x0[25] = 8'd242;     tb_x1[25] = 8'd117;     tb_x2[25] = 8'd46;     tb_x3[25] = 8'd119;     tb_x4[25] = 8'd148;     tb_x5[25] = 8'd146; 
        expected_y[25] = 6'b001000;

        // Test 26: random_10 (Inputs: [-102, 67, -23, 34, 42, 68], Max Index: 5)
        tb_x0[26] = 8'd154;     tb_x1[26] = 8'd67;     tb_x2[26] = 8'd233;     tb_x3[26] = 8'd34;     tb_x4[26] = 8'd42;     tb_x5[26] = 8'd68; 
        expected_y[26] = 6'b100000;

        // Test 27: random_11 (Inputs: [123, -120, -50, 102, 3, -40], Max Index: 0)
        tb_x0[27] = 8'd123;     tb_x1[27] = 8'd136;     tb_x2[27] = 8'd206;     tb_x3[27] = 8'd102;     tb_x4[27] = 8'd3;     tb_x5[27] = 8'd216; 
        expected_y[27] = 6'b000001;

        // Test 28: random_12 (Inputs: [-35, 8, -81, -57, 4, 99], Max Index: 5)
        tb_x0[28] = 8'd221;     tb_x1[28] = 8'd8;     tb_x2[28] = 8'd175;     tb_x3[28] = 8'd199;     tb_x4[28] = 8'd4;     tb_x5[28] = 8'd99; 
        expected_y[28] = 6'b100000;

        // Test 29: random_13 (Inputs: [-110, 61, -119, 113, -36, -51], Max Index: 3)
        tb_x0[29] = 8'd146;     tb_x1[29] = 8'd61;     tb_x2[29] = 8'd137;     tb_x3[29] = 8'd113;     tb_x4[29] = 8'd220;     tb_x5[29] = 8'd205; 
        expected_y[29] = 6'b001000;

        // Test 30: random_14 (Inputs: [-78, -52, 48, -83, 51, 56], Max Index: 5)
        tb_x0[30] = 8'd178;     tb_x1[30] = 8'd204;     tb_x2[30] = 8'd48;     tb_x3[30] = 8'd173;     tb_x4[30] = 8'd51;     tb_x5[30] = 8'd56; 
        expected_y[30] = 6'b100000;

        // Test 31: random_15 (Inputs: [114, 33, 45, -128, -79, -55], Max Index: 0)
        tb_x0[31] = 8'd114;     tb_x1[31] = 8'd33;     tb_x2[31] = 8'd45;     tb_x3[31] = 8'd128;     tb_x4[31] = 8'd177;     tb_x5[31] = 8'd201; 
        expected_y[31] = 6'b000001;

        // Test 32: random_16 (Inputs: [-44, 127, -83, 98, 48, 112], Max Index: 1)
        tb_x0[32] = 8'd212;     tb_x1[32] = 8'd127;     tb_x2[32] = 8'd173;     tb_x3[32] = 8'd98;     tb_x4[32] = 8'd48;     tb_x5[32] = 8'd112; 
        expected_y[32] = 6'b000010;

        // Test 33: random_17 (Inputs: [27, 124, 71, -67, -108, -10], Max Index: 1)
        tb_x0[33] = 8'd27;     tb_x1[33] = 8'd124;     tb_x2[33] = 8'd71;     tb_x3[33] = 8'd189;     tb_x4[33] = 8'd148;     tb_x5[33] = 8'd246; 
        expected_y[33] = 6'b000010;

        // Test 34: random_18 (Inputs: [85, -90, -20, 51, -64, -112], Max Index: 0)
        tb_x0[34] = 8'd85;     tb_x1[34] = 8'd166;     tb_x2[34] = 8'd236;     tb_x3[34] = 8'd51;     tb_x4[34] = 8'd192;     tb_x5[34] = 8'd144; 
        expected_y[34] = 6'b000001;

        // Test 35: random_19 (Inputs: [116, 82, 5, 105, 89, 48], Max Index: 0)
        tb_x0[35] = 8'd116;     tb_x1[35] = 8'd82;     tb_x2[35] = 8'd5;     tb_x3[35] = 8'd105;     tb_x4[35] = 8'd89;     tb_x5[35] = 8'd48; 
        expected_y[35] = 6'b000001;

        // Wait for inputs to settle
        #100;
        
        // Run tests
        for (i = 0; i < NUM_TESTS; i = i + 1) begin
            x0 = tb_x0[i];
            x1 = tb_x1[i];
            x2 = tb_x2[i];
            x3 = tb_x3[i];
            x4 = tb_x4[i];
            x5 = tb_x5[i];
            
            #10;
            
            if (y_onehot !== expected_y[i]) begin
                $display("ERROR [Test %0d]: Inputs=[%d %d %d %d %d %d], Expected=%b, Got=%b", 
                         i, x0, x1, x2, x3, x4, x5, expected_y[i], y_onehot);
                errors = errors + 1;
            end
        end
        
        // Final Results
        $display("");
        $display("===========================================");
        $display("  Tests Run: %0d", NUM_TESTS);
        $display("===========================================");
        
        if (errors == 0) begin
            $display("TEST_RESULT: PASS");
        end else begin
            $display("TEST_RESULT: FAIL (%0d errors)", errors);
        end
        
        $finish;
    end

endmodule
