`timescale 1ns / 1ps

// =============================================================================
// Testbench for fixed-method softmax approximation (Problem 012)
// - Signed Q4.4 inputs
// - Unsigned Q0.8 outputs
// - Exact match against golden vectors generated by generate_golden.py
// =============================================================================

module tb_softmax_approx;
    reg  [7:0] x0, x1, x2, x3;
    wire [7:0] y0, y1, y2, y3;

    integer i;
    integer errors;

// Golden vectors for 012_softmax_approx
// Generated by: python3 generate_golden.py
// Algorithm: fixed piecewise softmax from spec.yaml

localparam NUM_TESTS = 48;

reg [7:0] test_x0 [0:47];
reg [7:0] test_x1 [0:47];
reg [7:0] test_x2 [0:47];
reg [7:0] test_x3 [0:47];

reg [7:0] exp_y0 [0:47];
reg [7:0] exp_y1 [0:47];
reg [7:0] exp_y2 [0:47];
reg [7:0] exp_y3 [0:47];

initial begin
    // Test 0: all_zero
    test_x0[0] = 8'd0; test_x1[0] = 8'd0; test_x2[0] = 8'd0; test_x3[0] = 8'd0;
    exp_y0[0] = 8'd64; exp_y1[0] = 8'd64; exp_y2[0] = 8'd64; exp_y3[0] = 8'd64;
    // Test 1: all_equal_pos
    test_x0[1] = 8'd64; test_x1[1] = 8'd64; test_x2[1] = 8'd64; test_x3[1] = 8'd64;
    exp_y0[1] = 8'd64; exp_y1[1] = 8'd64; exp_y2[1] = 8'd64; exp_y3[1] = 8'd64;
    // Test 2: all_equal_neg
    test_x0[2] = 8'd224; test_x1[2] = 8'd224; test_x2[2] = 8'd224; test_x3[2] = 8'd224;
    exp_y0[2] = 8'd64; exp_y1[2] = 8'd64; exp_y2[2] = 8'd64; exp_y3[2] = 8'd64;
    // Test 3: single_dominant_pos
    test_x0[3] = 8'd127; test_x1[3] = 8'd0; test_x2[3] = 8'd0; test_x3[3] = 8'd0;
    exp_y0[3] = 8'd255; exp_y1[3] = 8'd0; exp_y2[3] = 8'd0; exp_y3[3] = 8'd0;
    // Test 4: single_dominant_pos_1
    test_x0[4] = 8'd0; test_x1[4] = 8'd127; test_x2[4] = 8'd0; test_x3[4] = 8'd0;
    exp_y0[4] = 8'd0; exp_y1[4] = 8'd255; exp_y2[4] = 8'd0; exp_y3[4] = 8'd0;
    // Test 5: single_dominant_pos_2
    test_x0[5] = 8'd0; test_x1[5] = 8'd0; test_x2[5] = 8'd127; test_x3[5] = 8'd0;
    exp_y0[5] = 8'd0; exp_y1[5] = 8'd0; exp_y2[5] = 8'd255; exp_y3[5] = 8'd0;
    // Test 6: single_dominant_pos_3
    test_x0[6] = 8'd0; test_x1[6] = 8'd0; test_x2[6] = 8'd0; test_x3[6] = 8'd127;
    exp_y0[6] = 8'd0; exp_y1[6] = 8'd0; exp_y2[6] = 8'd0; exp_y3[6] = 8'd255;
    // Test 7: close_cluster_high
    test_x0[7] = 8'd127; test_x1[7] = 8'd126; test_x2[7] = 8'd125; test_x3[7] = 8'd124;
    exp_y0[7] = 8'd70; exp_y1[7] = 8'd66; exp_y2[7] = 8'd61; exp_y3[7] = 8'd57;
    // Test 8: close_cluster_mid
    test_x0[8] = 8'd16; test_x1[8] = 8'd15; test_x2[8] = 8'd14; test_x3[8] = 8'd13;
    exp_y0[8] = 8'd70; exp_y1[8] = 8'd66; exp_y2[8] = 8'd61; exp_y3[8] = 8'd57;
    // Test 9: boundary_exact
    test_x0[9] = 8'd0; test_x1[9] = 8'd252; test_x2[9] = 8'd248; test_x3[9] = 8'd240;
    exp_y0[9] = 8'd95; exp_y1[9] = 8'd71; exp_y2[9] = 8'd53; exp_y3[9] = 8'd34;
    // Test 10: boundary_just_above
    test_x0[10] = 8'd0; test_x1[10] = 8'd253; test_x2[10] = 8'd249; test_x3[10] = 8'd241;
    exp_y0[10] = 8'd93; exp_y1[10] = 8'd76; exp_y2[10] = 8'd57; exp_y3[10] = 8'd29;
    // Test 11: boundary_just_below
    test_x0[11] = 8'd0; test_x1[11] = 8'd251; test_x2[11] = 8'd247; test_x3[11] = 8'd239;
    exp_y0[11] = 8'd99; exp_y1[11] = 8'd70; exp_y2[11] = 8'd52; exp_y3[11] = 8'd33;
    // Test 12: wide_negative_span
    test_x0[12] = 8'd0; test_x1[12] = 8'd224; test_x2[12] = 8'd192; test_x3[12] = 8'd128;
    exp_y0[12] = 8'd225; exp_y1[12] = 8'd30; exp_y2[12] = 8'd0; exp_y3[12] = 8'd0;
    // Test 13: mixed_signed_values
    test_x0[13] = 8'd32; test_x1[13] = 8'd240; test_x2[13] = 8'd48; test_x3[13] = 8'd224;
    exp_y0[13] = 8'd67; exp_y1[13] = 8'd0; exp_y2[13] = 8'd188; exp_y3[13] = 8'd0;
    // Test 14: negative_close_cluster
    test_x0[14] = 8'd255; test_x1[14] = 8'd254; test_x2[14] = 8'd253; test_x3[14] = 8'd252;
    exp_y0[14] = 8'd70; exp_y1[14] = 8'd66; exp_y2[14] = 8'd61; exp_y3[14] = 8'd57;
    // Test 15: descending_positive
    test_x0[15] = 8'd127; test_x1[15] = 8'd63; test_x2[15] = 8'd31; test_x3[15] = 8'd0;
    exp_y0[15] = 8'd255; exp_y1[15] = 8'd0; exp_y2[15] = 8'd0; exp_y3[15] = 8'd0;
    // Test 16: ascending_positive
    test_x0[16] = 8'd0; test_x1[16] = 8'd16; test_x2[16] = 8'd32; test_x3[16] = 8'd48;
    exp_y0[16] = 8'd0; exp_y1[16] = 8'd22; exp_y2[16] = 8'd61; exp_y3[16] = 8'd171;
    // Test 17: ascending_negative
    test_x0[17] = 8'd128; test_x1[17] = 8'd144; test_x2[17] = 8'd160; test_x3[17] = 8'd176;
    exp_y0[17] = 8'd0; exp_y1[17] = 8'd22; exp_y2[17] = 8'd61; exp_y3[17] = 8'd171;
    // Test 18: alternating_extremes
    test_x0[18] = 8'd127; test_x1[18] = 8'd128; test_x2[18] = 8'd127; test_x3[18] = 8'd128;
    exp_y0[18] = 8'd128; exp_y1[18] = 8'd0; exp_y2[18] = 8'd128; exp_y3[18] = 8'd0;
    // Test 19: three_similar_one_low
    test_x0[19] = 8'd80; test_x1[19] = 8'd79; test_x2[19] = 8'd78; test_x3[19] = 8'd16;
    exp_y0[19] = 8'd90; exp_y1[19] = 8'd85; exp_y2[19] = 8'd79; exp_y3[19] = 8'd0;
    // Test 20: three_similar_permuted
    test_x0[20] = 8'd80; test_x1[20] = 8'd16; test_x2[20] = 8'd79; test_x3[20] = 8'd78;
    exp_y0[20] = 8'd90; exp_y1[20] = 8'd0; exp_y2[20] = 8'd85; exp_y3[20] = 8'd79;
    // Test 21: three_similar_permuted2
    test_x0[21] = 8'd16; test_x1[21] = 8'd80; test_x2[21] = 8'd79; test_x3[21] = 8'd78;
    exp_y0[21] = 8'd0; exp_y1[21] = 8'd90; exp_y2[21] = 8'd85; exp_y3[21] = 8'd79;
    // Test 22: neg_to_zero
    test_x0[22] = 8'd128; test_x1[22] = 8'd192; test_x2[22] = 8'd224; test_x3[22] = 8'd0;
    exp_y0[22] = 8'd0; exp_y1[22] = 8'd0; exp_y2[22] = 8'd30; exp_y3[22] = 8'd225;
    // Test 23: mixed_seed_like
    test_x0[23] = 8'd8; test_x1[23] = 8'd89; test_x2[23] = 8'd52; test_x3[23] = 8'd129;
    exp_y0[23] = 8'd0; exp_y1[23] = 8'd234; exp_y2[23] = 8'd21; exp_y3[23] = 8'd0;
    // Test 24: random_00
    test_x0[24] = 8'd213; test_x1[24] = 8'd5; test_x2[24] = 8'd152; test_x3[24] = 8'd188;
    exp_y0[24] = 8'd0; exp_y1[24] = 8'd255; exp_y2[24] = 8'd0; exp_y3[24] = 8'd0;
    // Test 25: random_01
    test_x0[25] = 8'd99; test_x1[25] = 8'd138; test_x2[25] = 8'd223; test_x3[25] = 8'd82;
    exp_y0[25] = 8'd191; exp_y1[25] = 8'd0; exp_y2[25] = 8'd0; exp_y3[25] = 8'd64;
    // Test 26: random_02
    test_x0[26] = 8'd191; test_x1[26] = 8'd63; test_x2[26] = 8'd221; test_x3[26] = 8'd133;
    exp_y0[26] = 8'd0; exp_y1[26] = 8'd255; exp_y2[26] = 8'd0; exp_y3[26] = 8'd0;
    // Test 27: random_03
    test_x0[27] = 8'd89; test_x1[27] = 8'd95; test_x2[27] = 8'd181; test_x3[27] = 8'd46;
    exp_y0[27] = 8'd101; exp_y1[27] = 8'd154; exp_y2[27] = 8'd0; exp_y3[27] = 8'd0;
    // Test 28: random_04
    test_x0[28] = 8'd211; test_x1[28] = 8'd85; test_x2[28] = 8'd75; test_x3[28] = 8'd105;
    exp_y0[28] = 8'd0; exp_y1[28] = 8'd52; exp_y2[28] = 8'd8; exp_y3[28] = 8'd194;
    // Test 29: random_05
    test_x0[29] = 8'd39; test_x1[29] = 8'd97; test_x2[29] = 8'd174; test_x3[29] = 8'd164;
    exp_y0[29] = 8'd0; exp_y1[29] = 8'd255; exp_y2[29] = 8'd0; exp_y3[29] = 8'd0;
    // Test 30: random_06
    test_x0[30] = 8'd12; test_x1[30] = 8'd234; test_x2[30] = 8'd173; test_x3[30] = 8'd13;
    exp_y0[30] = 8'd117; exp_y1[30] = 8'd13; exp_y2[30] = 8'd0; exp_y3[30] = 8'd125;
    // Test 31: random_07
    test_x0[31] = 8'd212; test_x1[31] = 8'd1; test_x2[31] = 8'd3; test_x3[31] = 8'd83;
    exp_y0[31] = 8'd0; exp_y1[31] = 8'd0; exp_y2[31] = 8'd0; exp_y3[31] = 8'd255;
    // Test 32: random_08
    test_x0[32] = 8'd91; test_x1[32] = 8'd146; test_x2[32] = 8'd50; test_x3[32] = 8'd212;
    exp_y0[32] = 8'd242; exp_y1[32] = 8'd0; exp_y2[32] = 8'd13; exp_y3[32] = 8'd0;
    // Test 33: random_09
    test_x0[33] = 8'd54; test_x1[33] = 8'd93; test_x2[33] = 8'd192; test_x3[33] = 8'd119;
    exp_y0[33] = 8'd0; exp_y1[33] = 8'd30; exp_y2[33] = 8'd0; exp_y3[33] = 8'd225;
    // Test 34: random_10
    test_x0[34] = 8'd168; test_x1[34] = 8'd20; test_x2[34] = 8'd118; test_x3[34] = 8'd61;
    exp_y0[34] = 8'd0; exp_y1[34] = 8'd0; exp_y2[34] = 8'd255; exp_y3[34] = 8'd0;
    // Test 35: random_11
    test_x0[35] = 8'd255; test_x1[35] = 8'd110; test_x2[35] = 8'd95; test_x3[35] = 8'd131;
    exp_y0[35] = 8'd0; exp_y1[35] = 8'd194; exp_y2[35] = 8'd61; exp_y3[35] = 8'd0;
    // Test 36: random_12
    test_x0[36] = 8'd222; test_x1[36] = 8'd66; test_x2[36] = 8'd21; test_x3[36] = 8'd84;
    exp_y0[36] = 8'd0; exp_y1[36] = 8'd61; exp_y2[36] = 8'd0; exp_y3[36] = 8'd194;
    // Test 37: random_13
    test_x0[37] = 8'd154; test_x1[37] = 8'd4; test_x2[37] = 8'd76; test_x3[37] = 8'd117;
    exp_y0[37] = 8'd0; exp_y1[37] = 8'd0; exp_y2[37] = 8'd13; exp_y3[37] = 8'd242;
    // Test 38: random_14
    test_x0[38] = 8'd179; test_x1[38] = 8'd175; test_x2[38] = 8'd80; test_x3[38] = 8'd197;
    exp_y0[38] = 8'd0; exp_y1[38] = 8'd0; exp_y2[38] = 8'd255; exp_y3[38] = 8'd0;
    // Test 39: random_15
    test_x0[39] = 8'd165; test_x1[39] = 8'd6; test_x2[39] = 8'd25; test_x3[39] = 8'd31;
    exp_y0[39] = 8'd0; exp_y1[39] = 8'd22; exp_y2[39] = 8'd92; exp_y3[39] = 8'd140;
    // Test 40: random_16
    test_x0[40] = 8'd227; test_x1[40] = 8'd40; test_x2[40] = 8'd198; test_x3[40] = 8'd91;
    exp_y0[40] = 8'd0; exp_y1[40] = 8'd0; exp_y2[40] = 8'd0; exp_y3[40] = 8'd255;
    // Test 41: random_17
    test_x0[41] = 8'd5; test_x1[41] = 8'd188; test_x2[41] = 8'd110; test_x3[41] = 8'd62;
    exp_y0[41] = 8'd0; exp_y1[41] = 8'd0; exp_y2[41] = 8'd255; exp_y3[41] = 8'd0;
    // Test 42: random_18
    test_x0[42] = 8'd246; test_x1[42] = 8'd31; test_x2[42] = 8'd7; test_x3[42] = 8'd251;
    exp_y0[42] = 8'd10; exp_y1[42] = 8'd192; exp_y2[42] = 8'd34; exp_y3[42] = 8'd18;
    // Test 43: random_19
    test_x0[43] = 8'd166; test_x1[43] = 8'd215; test_x2[43] = 8'd103; test_x3[43] = 8'd186;
    exp_y0[43] = 8'd0; exp_y1[43] = 8'd0; exp_y2[43] = 8'd255; exp_y3[43] = 8'd0;
    // Test 44: random_20
    test_x0[44] = 8'd61; test_x1[44] = 8'd76; test_x2[44] = 8'd40; test_x3[44] = 8'd253;
    exp_y0[44] = 8'd57; exp_y1[44] = 8'd180; exp_y2[44] = 8'd17; exp_y3[44] = 8'd0;
    // Test 45: random_21
    test_x0[45] = 8'd84; test_x1[45] = 8'd171; test_x2[45] = 8'd118; test_x3[45] = 8'd104;
    exp_y0[45] = 8'd19; exp_y1[45] = 8'd0; exp_y2[45] = 8'd174; exp_y3[45] = 8'd61;
    // Test 46: random_22
    test_x0[46] = 8'd83; test_x1[46] = 8'd83; test_x2[46] = 8'd147; test_x3[46] = 8'd76;
    exp_y0[46] = 8'd98; exp_y1[46] = 8'd98; exp_y2[46] = 8'd0; exp_y3[46] = 8'd59;
    // Test 47: random_23
    test_x0[47] = 8'd46; test_x1[47] = 8'd1; test_x2[47] = 8'd75; test_x3[47] = 8'd1;
    exp_y0[47] = 8'd16; exp_y1[47] = 8'd0; exp_y2[47] = 8'd240; exp_y3[47] = 8'd0;
end

// Summary:
//  0. all_zero               x=[  0.00,  0.00,  0.00,  0.00] -> y=[0.250,0.250,0.250,0.250] sum=256
//  1. all_equal_pos          x=[  4.00,  4.00,  4.00,  4.00] -> y=[0.250,0.250,0.250,0.250] sum=256
//  2. all_equal_neg          x=[ -2.00, -2.00, -2.00, -2.00] -> y=[0.250,0.250,0.250,0.250] sum=256
//  3. single_dominant_pos    x=[  7.94,  0.00,  0.00,  0.00] -> y=[0.996,0.000,0.000,0.000] sum=255
//  4. single_dominant_pos_1  x=[  0.00,  7.94,  0.00,  0.00] -> y=[0.000,0.996,0.000,0.000] sum=255
//  5. single_dominant_pos_2  x=[  0.00,  0.00,  7.94,  0.00] -> y=[0.000,0.000,0.996,0.000] sum=255
//  6. single_dominant_pos_3  x=[  0.00,  0.00,  0.00,  7.94] -> y=[0.000,0.000,0.000,0.996] sum=255
//  7. close_cluster_high     x=[  7.94,  7.88,  7.81,  7.75] -> y=[0.273,0.258,0.238,0.223] sum=254
//  8. close_cluster_mid      x=[  1.00,  0.94,  0.88,  0.81] -> y=[0.273,0.258,0.238,0.223] sum=254
//  9. boundary_exact         x=[  0.00, -0.25, -0.50, -1.00] -> y=[0.371,0.277,0.207,0.133] sum=253
// 10. boundary_just_above    x=[  0.00, -0.19, -0.44, -0.94] -> y=[0.363,0.297,0.223,0.113] sum=255
// 11. boundary_just_below    x=[  0.00, -0.31, -0.56, -1.06] -> y=[0.387,0.273,0.203,0.129] sum=254
// 12. wide_negative_span     x=[  0.00, -2.00, -4.00, -8.00] -> y=[0.879,0.117,0.000,0.000] sum=255
// 13. mixed_signed_values    x=[  2.00, -1.00,  3.00, -2.00] -> y=[0.262,0.000,0.734,0.000] sum=255
// 14. negative_close_cluster x=[ -0.06, -0.12, -0.19, -0.25] -> y=[0.273,0.258,0.238,0.223] sum=254
// 15. descending_positive    x=[  7.94,  3.94,  1.94,  0.00] -> y=[0.996,0.000,0.000,0.000] sum=255
// 16. ascending_positive     x=[  0.00,  1.00,  2.00,  3.00] -> y=[0.000,0.086,0.238,0.668] sum=254
// 17. ascending_negative     x=[ -8.00, -7.00, -6.00, -5.00] -> y=[0.000,0.086,0.238,0.668] sum=254
// 18. alternating_extremes   x=[  7.94, -8.00,  7.94, -8.00] -> y=[0.500,0.000,0.500,0.000] sum=256
// 19. three_similar_one_low  x=[  5.00,  4.94,  4.88,  1.00] -> y=[0.352,0.332,0.309,0.000] sum=254
// 20. three_similar_permuted x=[  5.00,  1.00,  4.94,  4.88] -> y=[0.352,0.000,0.332,0.309] sum=254
// 21. three_similar_permuted2 x=[  1.00,  5.00,  4.94,  4.88] -> y=[0.000,0.352,0.332,0.309] sum=254
// 22. neg_to_zero            x=[ -8.00, -4.00, -2.00,  0.00] -> y=[0.000,0.000,0.117,0.879] sum=255
// 23. mixed_seed_like        x=[  0.50,  5.56,  3.25, -7.94] -> y=[0.000,0.914,0.082,0.000] sum=255
// 24. random_00              x=[ -2.69,  0.31, -6.50, -4.25] -> y=[0.000,0.996,0.000,0.000] sum=255
// 25. random_01              x=[  6.19, -7.38, -2.06,  5.12] -> y=[0.746,0.000,0.000,0.250] sum=255
// 26. random_02              x=[ -4.06,  3.94, -2.19, -7.69] -> y=[0.000,0.996,0.000,0.000] sum=255
// 27. random_03              x=[  5.56,  5.94, -4.69,  2.88] -> y=[0.395,0.602,0.000,0.000] sum=255
// 28. random_04              x=[ -2.81,  5.31,  4.69,  6.56] -> y=[0.000,0.203,0.031,0.758] sum=254
// 29. random_05              x=[  2.44,  6.06, -5.12, -5.75] -> y=[0.000,0.996,0.000,0.000] sum=255
// 30. random_06              x=[  0.75, -1.38, -5.19,  0.81] -> y=[0.457,0.051,0.000,0.488] sum=255
// 31. random_07              x=[ -2.75,  0.06,  0.19,  5.19] -> y=[0.000,0.000,0.000,0.996] sum=255
// 32. random_08              x=[  5.69, -6.88,  3.12, -2.75] -> y=[0.945,0.000,0.051,0.000] sum=255
// 33. random_09              x=[  3.38,  5.81, -4.00,  7.44] -> y=[0.000,0.117,0.000,0.879] sum=255
// 34. random_10              x=[ -5.50,  1.25,  7.38,  3.81] -> y=[0.000,0.000,0.996,0.000] sum=255
// 35. random_11              x=[ -0.06,  6.88,  5.94, -7.81] -> y=[0.000,0.758,0.238,0.000] sum=255
// 36. random_12              x=[ -2.12,  4.12,  1.31,  5.25] -> y=[0.000,0.238,0.000,0.758] sum=255
// 37. random_13              x=[ -6.38,  0.25,  4.75,  7.31] -> y=[0.000,0.000,0.051,0.945] sum=255
// 38. random_14              x=[ -4.81, -5.06,  5.00, -3.69] -> y=[0.000,0.000,0.996,0.000] sum=255
// 39. random_15              x=[ -5.69,  0.38,  1.56,  1.94] -> y=[0.000,0.086,0.359,0.547] sum=254
// 40. random_16              x=[ -1.81,  2.50, -3.62,  5.69] -> y=[0.000,0.000,0.000,0.996] sum=255
// 41. random_17              x=[  0.31, -4.25,  6.88,  3.88] -> y=[0.000,0.000,0.996,0.000] sum=255
// 42. random_18              x=[ -0.62,  1.94,  0.44, -0.31] -> y=[0.039,0.750,0.133,0.070] sum=254
// 43. random_19              x=[ -5.62, -2.56,  6.44, -4.38] -> y=[0.000,0.000,0.996,0.000] sum=255
// 44. random_20              x=[  3.81,  4.75,  2.50, -0.19] -> y=[0.223,0.703,0.066,0.000] sum=254
// 45. random_21              x=[  5.25, -5.31,  7.38,  6.50] -> y=[0.074,0.000,0.680,0.238] sum=254
// 46. random_22              x=[  5.19,  5.19, -6.81,  4.75] -> y=[0.383,0.383,0.000,0.230] sum=255
// 47. random_23              x=[  2.88,  0.06,  4.69,  0.06] -> y=[0.062,0.000,0.938,0.000] sum=256

    softmax_approx uut (
        .x0(x0), .x1(x1), .x2(x2), .x3(x3),
        .y0(y0), .y1(y1), .y2(y2), .y3(y3)
    );

    initial begin
        errors = 0;
        x0 = 0;
        x1 = 0;
        x2 = 0;
        x3 = 0;

        $display("===========================================");
        $display("  Softmax Approximation Testbench (Fixed)");
        $display("  Tests: %0d", NUM_TESTS);
        $display("===========================================");

        #1;

        for (i = 0; i < NUM_TESTS; i = i + 1) begin
            x0 = test_x0[i];
            x1 = test_x1[i];
            x2 = test_x2[i];
            x3 = test_x3[i];
            #1;

            if (y0 !== exp_y0[i]) begin
                $display("ERROR [Test %0d]: y0 expected=%0d got=%0d", i, exp_y0[i], y0);
                errors = errors + 1;
            end
            if (y1 !== exp_y1[i]) begin
                $display("ERROR [Test %0d]: y1 expected=%0d got=%0d", i, exp_y1[i], y1);
                errors = errors + 1;
            end
            if (y2 !== exp_y2[i]) begin
                $display("ERROR [Test %0d]: y2 expected=%0d got=%0d", i, exp_y2[i], y2);
                errors = errors + 1;
            end
            if (y3 !== exp_y3[i]) begin
                $display("ERROR [Test %0d]: y3 expected=%0d got=%0d", i, exp_y3[i], y3);
                errors = errors + 1;
            end
        end

        $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
