module testbench(); timeunit 10ns; timeprecision 1ns; logic clk; logic rw; logic clk_50; logic rst; logic [2:0] addr; logic [7:0] data; logic cs; logic i_sd_cmd; logic o_sd_cmd; logic i_sd_data; logic o_sd_data; logic cpu_phi2; always @(posedge clk) begin cpu_phi2 <= cpu_phi2 === '0; end sd_controller dut( .sd_clk(cpu_phi2), .*); always #1 clk_50 = clk_50 === 1'b0; always #100 clk = clk === 1'b0; task write_reg(logic [3:0] _addr, logic [7:0] _data); @(posedge clk); cs = '1; addr = _addr; rw = '0; data = '1; @(posedge clk); data = _data; @(posedge clk); cs = '0; rw = '1; endtask task verify_cmd(logic [5:0] cmd, logic [31:0] arg, logic [47:0] verify); write_reg(0, arg[7:0]); write_reg(1, arg[15:8]); write_reg(2, arg[23:16]); write_reg(3, arg[31:24]); write_reg(4, cmd); $display("arg: %x", dut.arg); $display("dut.cmd: %x", dut.cmd); @(posedge clk); @(posedge clk); while (dut.state.macro == dut.TXCMD) begin assert(o_sd_cmd == verify[47-dut.state.count]) else begin $error("cmd output error: Expected %h:%b, got %h:%b", 47-dut.state.count, verify[47-dut.state.count], 47-dut.state.count, o_sd_cmd); end @(negedge clk); end endtask localparam cmd0 = 48'h400000000095; localparam cmd8 = 48'h48000001aa87; localparam cmd55 = 48'h770000000065; localparam cmd41 = 48'h694018000019; initial begin rst <= '1; repeat(5) @(posedge clk); rst <= '0; verify_cmd(0, 0, cmd0); verify_cmd(8, 'h1aa, cmd8); verify_cmd('d55, 0, cmd55); verify_cmd('d41, 'h40180000, cmd41); $finish(); end endmodule