module read_command_tb;
    bit clk;
    logic reset;
    logic listen;
    logic [2:0] response_type;
    logic sd_cmd;
    wire received;
    wire [135:0] out_data;


    read_command dut (.*);

    initial forever #10 clk = ~clk;


    initial begin
        $display("Testing read_command module");
        sd_cmd = 1;
        response_type = 0;
        reset = 1;
        listen = 0;
        repeat (2) @(posedge clk);

        reset = 0;
        listen = 1;
        response_type = 2;
        @(posedge clk);
        listen = 0;
        response_type = 0;
        repeat (5) @(posedge clk);
        send_byte('h01);
        for (int i=0; i<15; i++)
            send_byte('hAA);
        send_byte('h01);
        @(posedge clk);
        // NOTE: the received signal takes an extra cycle to propogate because
        // it is loaded into a register
        @(posedge clk);
        #1;
        assert (received === 1)
            else $error("received signal not high");
        assert (out_data === 'h01AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01)
            else $error("out_dat incorrect, found 0x%x but expected 0x01AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01",out_data);
        

        repeat (7) @(posedge clk);

        listen = 1;
        response_type = 3;
        @(posedge clk);
        listen = 0;
        response_type = 0;
        send_byte('h00);
        send_byte('hAB);
        send_byte('hCD);
        send_byte('hEF);
        send_byte('h12);
        send_byte('h01);
        // Return sd_cmd to inactive state
        @(posedge clk) sd_cmd = 1;

        @(posedge clk);
        #1;
        assert (received === 1)
            else $error("received signal not high");
        assert (out_data === 136'h00ABCDEF1201)
            else $error("out_dat incorrect, found %b but expected 0x00ABCDEF1201",out_data);
        

        @(posedge clk);
        $finish;
    end

    task automatic send_byte(logic [7:0] b);
        for (int i = 8; i != 0; i--) begin
            @(posedge clk) sd_cmd = b[i-1];
        end
    endtask


endmodule
