data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv
1: b'%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:13: Unsupported: Ignoring delay on this delayed statement.\n        forever #5 clk = ~clk;\n                ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:109: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:115: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:120: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:125: Unsupported: Ignoring delay on this delayed statement.\n        #10;  \n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:137: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:182: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:190: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Error: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:194: Unsupported: wait statements\n        wait (tb_rtl_reuleaux.dut.done_draw === 1\'b1);\n        ^~~~\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:202: Unsupported: Ignoring delay on this delayed statement.\n        #20;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:206: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Error: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:214: Unsupported: wait statements\n        wait (tb_rtl_reuleaux.dut.done_draw === 1\'b1);\n        ^~~~\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:222: Unsupported: Ignoring delay on this delayed statement.\n        #20;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:226: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Error: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:234: Unsupported: wait statements\n        wait (tb_rtl_reuleaux.dut.done_draw === 1\'b1);\n        ^~~~\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:242: Unsupported: Ignoring delay on this delayed statement.\n        #20;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:246: Unsupported: Ignoring delay on this delayed statement.\n        #20;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:251: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:259: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:264: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:269: Unsupported: Ignoring delay on this delayed statement.\n        #10;  \n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:281: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:320: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:328: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Error: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:332: Unsupported: wait statements\n        wait (tb_rtl_reuleaux.dut.done_draw === 1\'b1);\n        ^~~~\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:340: Unsupported: Ignoring delay on this delayed statement.\n        #20;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:344: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Error: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:352: Unsupported: wait statements\n        wait (tb_rtl_reuleaux.dut.done_draw === 1\'b1);\n        ^~~~\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:360: Unsupported: Ignoring delay on this delayed statement.\n        #20;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:364: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Error: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:372: Unsupported: wait statements\n        wait (tb_rtl_reuleaux.dut.done_draw === 1\'b1);\n        ^~~~\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:380: Unsupported: Ignoring delay on this delayed statement.\n        #20;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:384: Unsupported: Ignoring delay on this delayed statement.\n        #20;\n        ^\n%Warning-STMTDLY: data/full_repos/permissive/426864978/lab2/task4/tb_rtl_reuleaux.sv:389: Unsupported: Ignoring delay on this delayed statement.\n        #10;\n        ^\n%Error: Exiting due to 6 error(s), 28 warning(s)\n        ... See the manual and https://verilator.org for more assistance.\n'
module tb_rtl_reuleaux();


    logic clk, rst_n, start, done, vga_plot, err;
    logic [2:0] colour, vga_colour;
    logic [7:0] centre_x, diameter, vga_x;
    logic [6:0] centre_y, vga_y;

    reuleaux dut(.*);

    initial begin
        clk = 0;
        forever #5 clk = ~clk;
    end

    task validator;
        input [31:0] index;
        input [3:0] exp_state;
        input [7:0] exp_x;
        input [6:0] exp_y;
        input [2:0] exp_colour;
        input exp_done, exp_plot;
        begin
            $display("CASE %d", index);
            if (tb_rtl_reuleaux.dut.state !== exp_state) begin
                $display("ERROR A: Expected state is %d, actual state is %d", exp_state, tb_rtl_reuleaux.dut.state);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.vga_x !== exp_x) begin
                $display("ERROR B: Expected vga_x is %d, actual vga_x is %d", exp_x, tb_rtl_reuleaux.dut.vga_x);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.vga_y !== exp_y) begin
                $display("ERROR C: Expected vga_y is %d, actual vga_y is %d", exp_y, tb_rtl_reuleaux.dut.vga_y);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.vga_colour !== exp_colour) begin
                $display("ERROR D: Expected vga_colour is %d, actual vga_colour is %d", exp_colour, tb_rtl_reuleaux.dut.vga_colour);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.done !== exp_done) begin
                $display("ERROR E: Expected done is %b, actual done is %b", exp_done, tb_rtl_reuleaux.dut.done);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.vga_plot !== exp_plot) begin
                $display("ERROR F: Expected vga_plot is %b, actual vga_plot is %b", exp_plot, tb_rtl_reuleaux.dut.vga_plot);
                err = 1'b1;
            end
        end
    endtask

    task circle_in_validator;
        input [31:0] index;
        input [7:0] exp_curr_cx, exp_min_x, exp_max_x;
        input [6:0] exp_curr_cy, exp_min_y, exp_max_y;
        $display("CASE %d", index);
        if (tb_rtl_reuleaux.dut.curr_cx !== exp_curr_cx) begin
            $display("C ERROR A: Expected curr_cx is %d, actual curr_cx is %d", exp_curr_cx, tb_rtl_reuleaux.dut.curr_cx);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.min_x !== exp_min_x) begin
            $display("C ERROR C: Expected min_x is %d, actual min_x is %d", exp_min_x, tb_rtl_reuleaux.dut.min_x);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.max_x !== exp_max_x) begin
            $display("C ERROR D: Expected max_x is %d, actual max_x is %d", exp_max_x, tb_rtl_reuleaux.dut.max_x);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.curr_cy !== exp_curr_cy) begin
            $display("C ERROR B: Expected curr_cy is %d, actual curr_cy is %d", exp_curr_cy, tb_rtl_reuleaux.dut.curr_cy);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.min_y !== exp_min_y) begin
            $display("C ERROR E: Expected min_y is %d, actual min_y is %d", exp_min_y, tb_rtl_reuleaux.dut.min_y);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.max_y !== exp_max_y) begin
            $display("C ERROR F: Expected max_y is %d, actual max_y is %d", exp_max_y, tb_rtl_reuleaux.dut.max_y);
            err = 1'b1;
        end
    endtask


    `define BLACK    3'b000
    `define BLUE     3'b001
    `define GREEN    3'b010
    `define CYAN     3'b011
    `define RED      3'b100
    `define MAGENTA  3'b101
    `define YELLOW   3'b110
    `define WHITE    3'b111

    `define IDLE   3'b000
    `define CALC   3'b001
    `define DRAW_1 3'b010
    `define DRAW_2 3'b011
    `define DRAW_3 3'b100
    `define DONE   3'b101

    `define DIAMETER 8'd80
    `define CENTRE_X 8'd80
    `define CENTRE_Y 7'd60

    initial begin
        err = 1'b0;


        rst_n = 1'bx; start = 1'bx;
        #10;
        validator(1, `IDLE, 8'b0, 7'b0, 3'bx, 1'b0, 1'b0);


        rst_n = 1'b0; start = 1'b0;
        colour = `BLUE; centre_x = `CENTRE_X; centre_y = `CENTRE_Y; diameter = `DIAMETER;
        #10;
        validator(2, `IDLE, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);


        rst_n = 1'b1;
        #10;
        validator(3, `IDLE, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);


        start = 1'b1;
        #10;
        validator(4, `CALC, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.c_x !== centre_x) begin
            $display("CASE 4 ERROR: Expected c_x is %b, actual c_x is %b", centre_x, tb_rtl_reuleaux.dut.c_x);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y !== centre_y) begin
            $display("CASE 4 ERROR: Expected c_y is %b, actual c_y is %b", centre_y, tb_rtl_reuleaux.dut.c_y);
            err = 1'b1;
        end


        #10;
        validator(5, `DRAW_1, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.c_x1 !== 8'd120) begin
            $display("CASE 5 ERROR: Expected c_x1 is %d, actual c_x1 is %d", 8'd120, tb_rtl_reuleaux.dut.c_x1);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y1 !== 7'd83) begin
            $display("CASE 5 ERROR: Expected c_y1 is %d, actual c_y1 is %d", 7'd83, tb_rtl_reuleaux.dut.c_y1);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_x2 !== 8'd40) begin
            $display("CASE 5 ERROR: Expected c_x2 is %d, actual c_x2 is %d", 8'd40, tb_rtl_reuleaux.dut.c_x2);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y2 !== 7'd83) begin
            $display("CASE 5 ERROR: Expected c_y2 is %d, actual c_y2 is %d", 7'd83, tb_rtl_reuleaux.dut.c_y2);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_x3 !== 8'd80) begin
            $display("CASE 5 ERROR: Expected c_x3 is %d, actual c_x3 is %d", 8'd80, tb_rtl_reuleaux.dut.c_x3);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y3 !== 7'd14) begin
            $display("CASE 5 ERROR: Expected c_y3 is %d, actual c_y3 is %d", 7'd14, tb_rtl_reuleaux.dut.c_y3);
            err = 1'b1;
        end



















        #10;
        validator(6, `DRAW_1, 8'bx, 7'bx, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 6 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        #10;
        circle_in_validator(7, 8'd120, 8'd40, 8'd80, 7'd83, 7'd14, 7'd83);


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(8, `DRAW_1, 8'd176, 7'd26, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 8 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(9, `DRAW_2, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);


        #10;
        circle_in_validator(10, 8'd40, 8'd80, 8'd120, 7'd83, 7'd14, 7'd83);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 10 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(11, `DRAW_2, 8'd96, 7'd26, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 11 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(12, `DRAW_3, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);


        #10;
        circle_in_validator(13, 8'd80, 8'd40, 8'd120, 7'd14, 7'd83, 7'd119);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 13 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(14, `DRAW_3, 8'd136, 7'd85, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 14 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(15, `DONE, 8'd0, 7'd0, `BLUE, 1'b1, 1'b0);


        #20;
        validator(16, `DONE, 8'd0, 7'd0, `BLUE, 1'b1, 1'b0);


        start = 0;
        #10;
        validator(17, `IDLE, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);




        rst_n = 1'b0; start = 1'b0;
        colour = `MAGENTA; centre_x = 8'd159; centre_y = 7'd119; diameter = 8'd5;
        #10;
        validator(18, `IDLE, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);


        rst_n = 1'b1;
        #10;
        validator(19, `IDLE, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);


        start = 1'b1;
        #10;
        validator(20, `CALC, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.c_x !== centre_x) begin
            $display("CASE 20 ERROR: Expected c_x is %b, actual c_x is %b", centre_x, tb_rtl_reuleaux.dut.c_x);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y !== centre_y) begin
            $display("CASE 20 ERROR: Expected c_y is %b, actual c_y is %b", centre_y, tb_rtl_reuleaux.dut.c_y);
            err = 1'b1;
        end


        #10;
        validator(21, `DRAW_1, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.c_x1 !== 8'd161) begin
            $display("CASE 21 ERROR: Expected c_x1 is %d, actual c_x1 is %d", 8'd161, tb_rtl_reuleaux.dut.c_x1);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y1 !== 7'd120) begin
            $display("CASE 21 ERROR: Expected c_y1 is %d, actual c_y1 is %d", 7'd120, tb_rtl_reuleaux.dut.c_y1);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_x2 !== 8'd157) begin
            $display("CASE 21 ERROR: Expected c_x2 is %d, actual c_x2 is %d", 8'd157, tb_rtl_reuleaux.dut.c_x2);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y2 !== 7'd120) begin
            $display("CASE 21 ERROR: Expected c_y2 is %d, actual c_y2 is %d", 7'd120, tb_rtl_reuleaux.dut.c_y2);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_x3 !== 8'd159) begin
            $display("CASE 21 ERROR: Expected c_x3 is %d, actual c_x3 is %d", 8'd159, tb_rtl_reuleaux.dut.c_x3);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y3 !== 7'd116) begin
            $display("CASE 21 ERROR: Expected c_y3 is %d, actual c_y3 is %d", 7'd116, tb_rtl_reuleaux.dut.c_y3);
            err = 1'b1;
        end













        #10;
        validator(22, `DRAW_1, 8'd85, 7'd14, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 22 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        #10;
        circle_in_validator(23, 8'd161, 8'd157, 8'd159, 7'd120, 7'd116, 7'd120);


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(24, `DRAW_1, 8'd164, 7'd116, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 24 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(25, `DRAW_2, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);


        #10;
        circle_in_validator(26, 8'd157, 8'd159, 8'd161, 7'd120, 7'd116, 7'd120);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 26 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(27, `DRAW_2, 8'd160, 7'd116, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 27 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(28, `DRAW_3, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);


        #10;
        circle_in_validator(29, 8'd159, 8'd157, 8'd161, 7'd116, 7'd120, 7'd119);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 29 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(30, `DRAW_3, 8'd162, 7'd112, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 30 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(31, `DONE, 8'd0, 7'd0, `MAGENTA, 1'b1, 1'b0);


        #20;
        validator(32, `DONE, 8'd0, 7'd0, `MAGENTA, 1'b1, 1'b0);


        start = 0;
        #10;
        validator(33, `IDLE, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);

        if (~err) begin
            $display("SUCCESS: All tests passed.");
        end
        $stop;
    end

endmodule
module tb_rtl_reuleaux();



    logic clk, rst_n, start, done, vga_plot, err;
    logic [2:0] colour, vga_colour;
    logic [7:0] centre_x, diameter, vga_x;
    logic [6:0] centre_y, vga_y;

    reuleaux dut(.*);

    initial begin
        clk = 0;
        forever #5 clk = ~clk;
    end

    task validator;
        input [31:0] index;
        input [3:0] exp_state;
        input [7:0] exp_x;
        input [6:0] exp_y;
        input [2:0] exp_colour;
        input exp_done, exp_plot;
        begin
            $display("CASE %d", index);
            if (tb_rtl_reuleaux.dut.state !== exp_state) begin
                $display("ERROR A: Expected state is %d, actual state is %d", exp_state, tb_rtl_reuleaux.dut.state);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.vga_x !== exp_x) begin
                $display("ERROR B: Expected vga_x is %d, actual vga_x is %d", exp_x, tb_rtl_reuleaux.dut.vga_x);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.vga_y !== exp_y) begin
                $display("ERROR C: Expected vga_y is %d, actual vga_y is %d", exp_y, tb_rtl_reuleaux.dut.vga_y);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.vga_colour !== exp_colour) begin
                $display("ERROR D: Expected vga_colour is %d, actual vga_colour is %d", exp_colour, tb_rtl_reuleaux.dut.vga_colour);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.done !== exp_done) begin
                $display("ERROR E: Expected done is %b, actual done is %b", exp_done, tb_rtl_reuleaux.dut.done);
                err = 1'b1;
            end
            if (tb_rtl_reuleaux.dut.vga_plot !== exp_plot) begin
                $display("ERROR F: Expected vga_plot is %b, actual vga_plot is %b", exp_plot, tb_rtl_reuleaux.dut.vga_plot);
                err = 1'b1;
            end
        end
    endtask

    task circle_in_validator;
        input [31:0] index;
        input [7:0] exp_curr_cx, exp_min_x, exp_max_x;
        input [6:0] exp_curr_cy, exp_min_y, exp_max_y;
        $display("CASE %d", index);
        if (tb_rtl_reuleaux.dut.curr_cx !== exp_curr_cx) begin
            $display("C ERROR A: Expected curr_cx is %d, actual curr_cx is %d", exp_curr_cx, tb_rtl_reuleaux.dut.curr_cx);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.min_x !== exp_min_x) begin
            $display("C ERROR C: Expected min_x is %d, actual min_x is %d", exp_min_x, tb_rtl_reuleaux.dut.min_x);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.max_x !== exp_max_x) begin
            $display("C ERROR D: Expected max_x is %d, actual max_x is %d", exp_max_x, tb_rtl_reuleaux.dut.max_x);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.curr_cy !== exp_curr_cy) begin
            $display("C ERROR B: Expected curr_cy is %d, actual curr_cy is %d", exp_curr_cy, tb_rtl_reuleaux.dut.curr_cy);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.min_y !== exp_min_y) begin
            $display("C ERROR E: Expected min_y is %d, actual min_y is %d", exp_min_y, tb_rtl_reuleaux.dut.min_y);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.max_y !== exp_max_y) begin
            $display("C ERROR F: Expected max_y is %d, actual max_y is %d", exp_max_y, tb_rtl_reuleaux.dut.max_y);
            err = 1'b1;
        end
    endtask


    `define BLACK    3'b000
    `define BLUE     3'b001
    `define GREEN    3'b010
    `define CYAN     3'b011
    `define RED      3'b100
    `define MAGENTA  3'b101
    `define YELLOW   3'b110
    `define WHITE    3'b111

    `define IDLE   3'b000
    `define CALC   3'b001
    `define DRAW_1 3'b010
    `define DRAW_2 3'b011
    `define DRAW_3 3'b100
    `define DONE   3'b101

    `define DIAMETER 8'd80
    `define CENTRE_X 8'd80
    `define CENTRE_Y 7'd60

    initial begin
        err = 1'b0;


        rst_n = 1'bx; start = 1'bx;
        #10;
        validator(1, `IDLE, 8'b0, 7'b0, 3'bx, 1'b0, 1'b0);


        rst_n = 1'b0; start = 1'b0;
        colour = `BLUE; centre_x = `CENTRE_X; centre_y = `CENTRE_Y; diameter = `DIAMETER;
        #10;
        validator(2, `IDLE, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);


        rst_n = 1'b1;
        #10;
        validator(3, `IDLE, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);


        start = 1'b1;
        #10;
        validator(4, `CALC, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.c_x !== centre_x) begin
            $display("CASE 4 ERROR: Expected c_x is %b, actual c_x is %b", centre_x, tb_rtl_reuleaux.dut.c_x);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y !== centre_y) begin
            $display("CASE 4 ERROR: Expected c_y is %b, actual c_y is %b", centre_y, tb_rtl_reuleaux.dut.c_y);
            err = 1'b1;
        end


        #10;
        validator(5, `DRAW_1, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.c_x1 !== 8'd120) begin
            $display("CASE 5 ERROR: Expected c_x1 is %d, actual c_x1 is %d", 8'd120, tb_rtl_reuleaux.dut.c_x1);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y1 !== 7'd83) begin
            $display("CASE 5 ERROR: Expected c_y1 is %d, actual c_y1 is %d", 7'd83, tb_rtl_reuleaux.dut.c_y1);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_x2 !== 8'd40) begin
            $display("CASE 5 ERROR: Expected c_x2 is %d, actual c_x2 is %d", 8'd40, tb_rtl_reuleaux.dut.c_x2);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y2 !== 7'd83) begin
            $display("CASE 5 ERROR: Expected c_y2 is %d, actual c_y2 is %d", 7'd83, tb_rtl_reuleaux.dut.c_y2);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_x3 !== 8'd80) begin
            $display("CASE 5 ERROR: Expected c_x3 is %d, actual c_x3 is %d", 8'd80, tb_rtl_reuleaux.dut.c_x3);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y3 !== 7'd14) begin
            $display("CASE 5 ERROR: Expected c_y3 is %d, actual c_y3 is %d", 7'd14, tb_rtl_reuleaux.dut.c_y3);
            err = 1'b1;
        end



















        #10;
        validator(6, `DRAW_1, 8'bx, 7'bx, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 6 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        #10;
        circle_in_validator(7, 8'd120, 8'd40, 8'd80, 7'd83, 7'd14, 7'd83);


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(8, `DRAW_1, 8'd176, 7'd26, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 8 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(9, `DRAW_2, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);


        #10;
        circle_in_validator(10, 8'd40, 8'd80, 8'd120, 7'd83, 7'd14, 7'd83);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 10 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(11, `DRAW_2, 8'd96, 7'd26, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 11 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(12, `DRAW_3, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);


        #10;
        circle_in_validator(13, 8'd80, 8'd40, 8'd120, 7'd14, 7'd83, 7'd119);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 13 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(14, `DRAW_3, 8'd136, 7'd85, `BLUE, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 14 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(15, `DONE, 8'd0, 7'd0, `BLUE, 1'b1, 1'b0);


        #20;
        validator(16, `DONE, 8'd0, 7'd0, `BLUE, 1'b1, 1'b0);


        start = 0;
        #10;
        validator(17, `IDLE, 8'd0, 7'd0, `BLUE, 1'b0, 1'b0);




        rst_n = 1'b0; start = 1'b0;
        colour = `MAGENTA; centre_x = 8'd159; centre_y = 7'd119; diameter = 8'd5;
        #10;
        validator(18, `IDLE, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);


        rst_n = 1'b1;
        #10;
        validator(19, `IDLE, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);


        start = 1'b1;
        #10;
        validator(20, `CALC, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.c_x !== centre_x) begin
            $display("CASE 20 ERROR: Expected c_x is %b, actual c_x is %b", centre_x, tb_rtl_reuleaux.dut.c_x);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y !== centre_y) begin
            $display("CASE 20 ERROR: Expected c_y is %b, actual c_y is %b", centre_y, tb_rtl_reuleaux.dut.c_y);
            err = 1'b1;
        end


        #10;
        validator(21, `DRAW_1, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.c_x1 !== 8'd161) begin
            $display("CASE 21 ERROR: Expected c_x1 is %d, actual c_x1 is %d", 8'd161, tb_rtl_reuleaux.dut.c_x1);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y1 !== 7'd120) begin
            $display("CASE 21 ERROR: Expected c_y1 is %d, actual c_y1 is %d", 7'd120, tb_rtl_reuleaux.dut.c_y1);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_x2 !== 8'd157) begin
            $display("CASE 21 ERROR: Expected c_x2 is %d, actual c_x2 is %d", 8'd157, tb_rtl_reuleaux.dut.c_x2);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y2 !== 7'd120) begin
            $display("CASE 21 ERROR: Expected c_y2 is %d, actual c_y2 is %d", 7'd120, tb_rtl_reuleaux.dut.c_y2);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_x3 !== 8'd159) begin
            $display("CASE 21 ERROR: Expected c_x3 is %d, actual c_x3 is %d", 8'd159, tb_rtl_reuleaux.dut.c_x3);
            err = 1'b1;
        end
        if (tb_rtl_reuleaux.dut.c_y3 !== 7'd116) begin
            $display("CASE 21 ERROR: Expected c_y3 is %d, actual c_y3 is %d", 7'd116, tb_rtl_reuleaux.dut.c_y3);
            err = 1'b1;
        end













        #10;
        validator(22, `DRAW_1, 8'd85, 7'd14, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 22 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        #10;
        circle_in_validator(23, 8'd161, 8'd157, 8'd159, 7'd120, 7'd116, 7'd120);


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(24, `DRAW_1, 8'd164, 7'd116, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 24 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(25, `DRAW_2, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);


        #10;
        circle_in_validator(26, 8'd157, 8'd159, 8'd161, 7'd120, 7'd116, 7'd120);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 26 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(27, `DRAW_2, 8'd160, 7'd116, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 27 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(28, `DRAW_3, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);


        #10;
        circle_in_validator(29, 8'd159, 8'd157, 8'd161, 7'd116, 7'd120, 7'd119);
        if (tb_rtl_reuleaux.dut.start_draw !== 1'b1) begin
            $display("CASE 29 ERROR: Expected start_draw is %d, actual start_draw is %d", 1'b1, tb_rtl_reuleaux.dut.start_draw);
            err = 1'b1;
        end


        wait (tb_rtl_reuleaux.dut.done_draw === 1'b1);
        validator(30, `DRAW_3, 8'd162, 7'd112, `MAGENTA, 1'b0, 1'b0);
        if (tb_rtl_reuleaux.dut.draw.offset_y <= tb_rtl_reuleaux.dut.draw.offset_x) begin
            $display("CASE 30 ERROR: Expected offset_y to be less than or equal to offset_x.");
            err = 1'b1;
        end


        #20;
        validator(31, `DONE, 8'd0, 7'd0, `MAGENTA, 1'b1, 1'b0);


        #20;
        validator(32, `DONE, 8'd0, 7'd0, `MAGENTA, 1'b1, 1'b0);


        start = 0;
        #10;
        validator(33, `IDLE, 8'd0, 7'd0, `MAGENTA, 1'b0, 1'b0);

        if (~err) begin
            $display("SUCCESS: All tests passed.");
        end
        $stop;
    end

endmodule