data/full_repos/permissive/421030651/mdl/jtag_mdl.sv
1: b'%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:1: Cannot find include file: dbgapb_define.h\n`include "dbgapb_define.h" \n         ^~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/421030651/mdl,data/full_repos/permissive/421030651/dbgapb_define.h\n             data/full_repos/permissive/421030651/mdl,data/full_repos/permissive/421030651/dbgapb_define.h.v\n             data/full_repos/permissive/421030651/mdl,data/full_repos/permissive/421030651/dbgapb_define.h.sv\n             dbgapb_define.h\n             dbgapb_define.h.v\n             dbgapb_define.h.sv\n             obj_dir/dbgapb_define.h\n             obj_dir/dbgapb_define.h.v\n             obj_dir/dbgapb_define.h.sv\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:2: Cannot find include file: dbgapb_mmap.h\n`include "dbgapb_mmap.h" \n         ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:50: Unsupported: Verilog 1995 force\n    force test.u_cpu_wrap.u_dap.u_jtag_dp.cur_state = $random() & 4\'hf;\n    ^~~~~\n%Warning-STMTDLY: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:51: Unsupported: Ignoring delay on this delayed statement.\n    #1;\n    ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:52: Unsupported: Verilog 1995 release\n    release test.u_cpu_wrap.u_dap.u_jtag_dp.cur_state;\n    ^~~~~~~\n%Warning-STMTDLY: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:53: Unsupported: Ignoring delay on this delayed statement.\n    repeat(10) #(100);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:405: Unsupported: Ignoring delay on this delayed statement.\n#(100/4);\n^\n%Warning-STMTDLY: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:407: Unsupported: Ignoring delay on this delayed statement.\n#(100/2);\n^\n%Warning-STMTDLY: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:409: Unsupported: Ignoring delay on this delayed statement.\n#(100/4);\n^\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:631: Define or directive not defined: \'`DBGAPB_INST\'\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_STATUS_RD});\n            ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:631: Define or directive not defined: \'`INST_STATUS_RD\'\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_STATUS_RD});\n                                  ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:631: syntax error, unexpected \'}\', expecting TYPE-IDENTIFIER\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_STATUS_RD});\n                                                 ^\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:632: Define or directive not defined: \'`DBGAPB_INST_WR\'\njtag_apb_wr(`DBGAPB_INST_WR, 32\'b1);\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:633: Define or directive not defined: \'`DBGAPB_RDATA_L\'\njtag_apb_rd(`DBGAPB_RDATA_L);\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:635: Define or directive not defined: \'`DBGAPB_RDATA_H\'\njtag_apb_rd(`DBGAPB_RDATA_H);\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:642: Define or directive not defined: \'`DBGAPB_INST\'\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_PC_RD});\n            ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:642: Define or directive not defined: \'`INST_PC_RD\'\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_PC_RD});\n                                  ^~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:642: syntax error, unexpected \'}\', expecting TYPE-IDENTIFIER\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_PC_RD});\n                                             ^\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:643: Define or directive not defined: \'`DBGAPB_INST_WR\'\njtag_apb_wr(`DBGAPB_INST_WR, 32\'b1);\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:644: Define or directive not defined: \'`DBGAPB_RDATA_L\'\njtag_apb_rd(`DBGAPB_RDATA_L);\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:646: Define or directive not defined: \'`DBGAPB_RDATA_H\'\njtag_apb_rd(`DBGAPB_RDATA_H);\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:654: Define or directive not defined: \'`DBGAPB_WDATA_L\'\njtag_apb_wr(`DBGAPB_WDATA_L, inst);\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:655: Define or directive not defined: \'`DBGAPB_WDATA_WR\'\njtag_apb_wr(`DBGAPB_WDATA_WR, 32\'b1);\n            ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:656: Define or directive not defined: \'`DBGAPB_INST\'\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_INSTREG_WR});\n            ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:656: Define or directive not defined: \'`INST_INSTREG_WR\'\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_INSTREG_WR});\n                                  ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:656: syntax error, unexpected \'}\', expecting TYPE-IDENTIFIER\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_INSTREG_WR});\n                                                  ^\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:657: Define or directive not defined: \'`DBGAPB_INST_WR\'\njtag_apb_wr(`DBGAPB_INST_WR, 32\'b1);\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:658: Define or directive not defined: \'`DBGAPB_INST\'\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_EXECUTE});\n            ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:658: Define or directive not defined: \'`INST_EXECUTE\'\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_EXECUTE});\n                                  ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:658: syntax error, unexpected \'}\', expecting TYPE-IDENTIFIER\njtag_apb_wr(`DBGAPB_INST, {20\'b0, `INST_EXECUTE});\n                                               ^\n%Error: data/full_repos/permissive/421030651/mdl/jtag_mdl.sv:659: Define or directive not defined: \'`DBGAPB_INST_WR\'\njtag_apb_wr(`DBGAPB_INST_WR, 32\'b1);\n            ^~~~~~~~~~~~~~~\n%Error: Exiting due to 26 error(s), 5 warning(s)\n'
module jtag_mdl (
    output logic tck,
    output logic tms,
    output logic tdi,
    input        tdo
);

logic [34:0] rdata;
logic [31:0] apb_rdata;
logic [63:0] apb64_rdata;
logic [ 3:0] ir_latch;
logic [ 7:0] apsel_latch;
logic [ 3:0] apaddr_h_latch;
logic [31:0] apbap_tar_latch;
logic [31:0] axi_ap_test_addr;
logic [31:0] axi_ap_test_data;
logic [32*64-1:0] wdata_buf;

initial begin












end

initial begin
    integer i, j;

    tck = 1'b0;
    tms = 1'b0;
    tdi = 1'b0;
    force test.u_cpu_wrap.u_dap.u_jtag_dp.cur_state = $random() & 4'hf;
    #1;
    release test.u_cpu_wrap.u_dap.u_jtag_dp.cur_state;
    repeat(10) #(`TCK_PERIOD);
    jtag_reset;
    jtag_tms(1'b0);
    jtag_dpacc_wr(4'h4, 32'h54000000);

`ifdef DBGAPB_TEST
    jtag_apb_wr(`DBGAPB_DBG_EN, 32'h1);
    jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_ATTACH});
    jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
    while (apb64_rdata != `XLEN'h3) begin
        jtag_dbgapb_status_rd;
    end
    jtag_dbgapb_pc_rd;
    jtag_dbgapb_exec(`ADDI(`GPR_T0_ADDR, `GPR_ZERO_ADDR, 12'hcc));
    jtag_dbgapb_exec(`JALR(`GPR_T0_ADDR));
    jtag_dbgapb_pc_rd;
    repeat(10) jtag_tms_tdi(1'b0, 1'b0);
    jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_RESUME});
    jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
`else

`endif
end

task jtag_tms_tdi;
input tms_i;
input tdi_i;

tck = 1'b0;
tms = tms_i;
tdi = tdi_i;
#(`TCK_PERIOD/4);
tck = 1'b1;
#(`TCK_PERIOD/2);
tck = 1'b0;
#(`TCK_PERIOD/4);
endtask

task jtag_tms;
input tms_i;
jtag_tms_tdi(tms_i, 1'b0);
endtask

task jtag_tdi;
input tdi_i;
jtag_tms_tdi(1'b0, tdi_i);
endtask

task jtag_reset;
integer i;
for (i = 0; i < 5; i = i + 1) begin
    jtag_tms(1'b1);
end
endtask

task jtag_w_ir;
input [4:0] ir;
integer i;
if (ir !== ir_latch) begin
    jtag_tms(1'b1);
    jtag_tms(1'b1);
    jtag_tms(1'b0);
    jtag_tms(1'b0);
    for (i = 0; i < 4; i = i + 1)
        jtag_tdi(ir[i]);
    jtag_tms_tdi(1'b1, ir[i]);
    jtag_tms(1'b1);
    jtag_tms(1'b0);
    ir_latch = ir;
end
endtask

task jtag_wr_wbuf;
input [32*64 - 1:0] wdata;
input int n;
integer i;
jtag_tms(1'b1);
jtag_tms(1'b0);
jtag_tms(1'b0);
for (i = 0; i < 32*n - 1; i = i + 1) begin
    jtag_tdi(wdata[0]);
    wdata = {1'b0, wdata[32*64-1:1]};
end
jtag_tms_tdi(1'b1, wdata[0]);
jtag_tms(1'b1);
jtag_tms(1'b0);
endtask

task jtag_rd_dbuf;
integer i;
jtag_tms(1'b1);
jtag_tms(1'b0);
jtag_tms(1'b0);
for (i = 0; i < 32*64 - 1; i = i + 1) begin
    rdata[31:0] = {tdo, rdata[31:1]};
    if (i % 32 == 31)
        $display("dbuf[0x%2x] = 0x%8x", i / 32, rdata[31:0]);
    jtag_tdi(1'b0);
end
rdata[31:0] = {tdo, rdata[31:1]};
$display("dbuf[0x%2x] = 0x%8x", i / 32, rdata[31:0]);
jtag_tms_tdi(1'b1, 1'b0);
jtag_tms(1'b1);
jtag_tms(1'b0);
endtask

task jtag_rd_rbuf;
integer i;
jtag_tms(1'b1);
jtag_tms(1'b0);
jtag_tms(1'b0);
for (i = 0; i < 2*64 - 1; i = i + 1) begin
    rdata[31:0] = {tdo, rdata[31:1]};
    if (i % 2 == 1)

    jtag_tdi(1'b0);
end
rdata[31:0] = {tdo, rdata[31:1]};

jtag_tms_tdi(1'b1, 1'b0);
jtag_tms(1'b1);
jtag_tms(1'b0);
endtask

task jtag_rw_dr;
input [ 5:0] length;
input [34:0] dr;
integer i;
jtag_tms(1'b1);
jtag_tms(1'b0);
jtag_tms(1'b0);
for (i = 0; i < length-1; i = i + 1) begin
    rdata = {tdo, rdata[34:1]};
    jtag_tdi(dr[i]);
end
rdata = {tdo, rdata[34:1]};
jtag_tms_tdi(1'b1, dr[i]);
for (; i < 34; i = i + 1)
    rdata = {1'b0, rdata[34:1]};
jtag_tms(1'b1);
jtag_tms(1'b0);
endtask

task jtag_dpacc_wr;
input [ 3:0] addr;
input [31:0] wdata;

if (~|addr[1:0]) begin
    if (addr[3:2] !== 2'h2 || apsel_latch !== wdata[31:24] || apaddr_h_latch !== wdata[7:4]) begin
        jtag_w_ir(5'ha);
        do begin
            jtag_rw_dr(35, {wdata, addr[3:2], 1'b0});
        end while (rdata[2:0] == `RESP_WAIT);
        if (addr[3:2] === 2'h2) begin
            apsel_latch    = wdata[31:24];
            apaddr_h_latch = wdata[ 7: 4];
        end
    end
end
endtask

task jtag_dapacc_rdbuff;

jtag_w_ir(5'ha);
do begin
    jtag_rw_dr(35, {32'b0, 2'h3, 1'b1});
end while (rdata[2:0] == `RESP_WAIT);

endtask

task jtag_apbapacc_wr;
input [ 7:0] addr;
input [31:0] wdata;

if (~|addr[1:0]) begin
    jtag_w_ir(5'hb);
    if (addr !== 8'h4 || apbap_tar_latch !== wdata) begin
        jtag_dpacc_wr(4'h8, {8'b0, 16'b0, addr[7:4], 4'b0});
        do begin
            jtag_rw_dr(35, {wdata, addr[3:2], 1'b0});
        end while (rdata[2:0] == `RESP_WAIT);
        if (addr === 8'h4) begin
            apbap_tar_latch = wdata;
        end
    end
end
endtask

task jtag_apbapacc_rd;
input [ 7:0] addr;

if (~|addr[1:0]) begin
    jtag_w_ir(5'hb);
    jtag_dpacc_wr(4'h8, {8'b0, 16'b0, addr[7:4], 4'b0});
    do begin
        jtag_rw_dr(35, {32'b0, addr[3:2], 1'b1});
    end while (rdata[2:0] == `RESP_WAIT);
    jtag_dapacc_rdbuff;
end
endtask

task jtag_apbapacc_rd_cmp;
input [ 7:0] addr;
input [31:0] cmp_data;

if (~|addr[1:0]) begin
    jtag_w_ir(5'hb);
    jtag_dpacc_wr(4'h8, {8'b0, 16'b0, addr[7:4], 4'b0});
    do begin
        jtag_rw_dr(35, {cmp_data, addr[3:2], 1'b1});
    end while (rdata[2:0] == `RESP_WAIT);
    jtag_w_ir(5'ha);
    do begin
        jtag_rw_dr(35, {32'b0, 2'h1, 1'b1});
    end while (rdata[2:0] == `RESP_WAIT);
    jtag_dapacc_rdbuff;
end
endtask

task jtag_apb_wr;
input [31:0] addr;
input [31:0] wdata;

jtag_apbapacc_wr(8'h4, addr);
jtag_apbapacc_wr(8'hc, wdata);

endtask

task jtag_apb_rd;
input [31:0] addr;

jtag_dpacc_wr(4'h4, 32'hf00);
jtag_apbapacc_wr(8'h4, addr);
jtag_apbapacc_rd(8'hc);
apb_rdata = rdata[34:3];
endtask

task jtag_apb_rd_cmp;
input [31:0] addr;
input [31:0] cmp_data;

jtag_dpacc_wr(4'h4, 32'hf08);
jtag_apbapacc_wr(8'h4, addr);
jtag_apbapacc_rd_cmp(8'hc, cmp_data);
endtask

task jtag_apb_rd_verf;
input [31:0] addr;
input [31:0] cmp_data;

jtag_dpacc_wr(4'h4, 32'hf04);
jtag_apbapacc_wr(8'h4, addr);
jtag_apbapacc_rd_cmp(8'hc, cmp_data);
endtask

task jtag_dbgapb_status_rd;

jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_STATUS_RD});
jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
jtag_apb_rd(`DBGAPB_RDATA_L);
apb64_rdata[31: 0] = apb_rdata;
jtag_apb_rd(`DBGAPB_RDATA_H);
apb64_rdata[63:32] = apb_rdata;
$display("[JTAG_MDL][DBGAPB] READ STATUS_REG: %16x", apb64_rdata);
endtask

task jtag_dbgapb_pc_rd;

jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_PC_RD});
jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
jtag_apb_rd(`DBGAPB_RDATA_L);
apb64_rdata[31: 0] = apb_rdata;
jtag_apb_rd(`DBGAPB_RDATA_H);
apb64_rdata[63:32] = apb_rdata;
$display("[JTAG_MDL][DBGAPB] READ PC: %16x", apb64_rdata);
endtask

task jtag_dbgapb_exec;
input [31:0] inst;

jtag_apb_wr(`DBGAPB_WDATA_L, inst);
jtag_apb_wr(`DBGAPB_WDATA_WR, 32'b1);
jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_INSTREG_WR});
jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_EXECUTE});
jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
endtask

endmodule
module jtag_mdl (
    output logic tck,
    output logic tms,
    output logic tdi,
    input        tdo
);


logic [34:0] rdata;
logic [31:0] apb_rdata;
logic [63:0] apb64_rdata;
logic [ 3:0] ir_latch;
logic [ 7:0] apsel_latch;
logic [ 3:0] apaddr_h_latch;
logic [31:0] apbap_tar_latch;
logic [31:0] axi_ap_test_addr;
logic [31:0] axi_ap_test_data;
logic [32*64-1:0] wdata_buf;

initial begin












end

initial begin
    integer i, j;

    tck = 1'b0;
    tms = 1'b0;
    tdi = 1'b0;
    force test.u_cpu_wrap.u_dap.u_jtag_dp.cur_state = $random() & 4'hf;
    #1;
    release test.u_cpu_wrap.u_dap.u_jtag_dp.cur_state;
    repeat(10) #(`TCK_PERIOD);
    jtag_reset;
    jtag_tms(1'b0);
    jtag_dpacc_wr(4'h4, 32'h54000000);

`ifdef DBGAPB_TEST
    jtag_apb_wr(`DBGAPB_DBG_EN, 32'h1);
    jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_ATTACH});
    jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
    while (apb64_rdata != `XLEN'h3) begin
        jtag_dbgapb_status_rd;
    end
    jtag_dbgapb_pc_rd;
    jtag_dbgapb_exec(`ADDI(`GPR_T0_ADDR, `GPR_ZERO_ADDR, 12'hcc));
    jtag_dbgapb_exec(`JALR(`GPR_T0_ADDR));
    jtag_dbgapb_pc_rd;
    repeat(10) jtag_tms_tdi(1'b0, 1'b0);
    jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_RESUME});
    jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
`else

`endif
end

task jtag_tms_tdi;
input tms_i;
input tdi_i;

tck = 1'b0;
tms = tms_i;
tdi = tdi_i;
#(`TCK_PERIOD/4);
tck = 1'b1;
#(`TCK_PERIOD/2);
tck = 1'b0;
#(`TCK_PERIOD/4);
endtask

task jtag_tms;
input tms_i;
jtag_tms_tdi(tms_i, 1'b0);
endtask

task jtag_tdi;
input tdi_i;
jtag_tms_tdi(1'b0, tdi_i);
endtask

task jtag_reset;
integer i;
for (i = 0; i < 5; i = i + 1) begin
    jtag_tms(1'b1);
end
endtask

task jtag_w_ir;
input [4:0] ir;
integer i;
if (ir !== ir_latch) begin
    jtag_tms(1'b1);
    jtag_tms(1'b1);
    jtag_tms(1'b0);
    jtag_tms(1'b0);
    for (i = 0; i < 4; i = i + 1)
        jtag_tdi(ir[i]);
    jtag_tms_tdi(1'b1, ir[i]);
    jtag_tms(1'b1);
    jtag_tms(1'b0);
    ir_latch = ir;
end
endtask

task jtag_wr_wbuf;
input [32*64 - 1:0] wdata;
input int n;
integer i;
jtag_tms(1'b1);
jtag_tms(1'b0);
jtag_tms(1'b0);
for (i = 0; i < 32*n - 1; i = i + 1) begin
    jtag_tdi(wdata[0]);
    wdata = {1'b0, wdata[32*64-1:1]};
end
jtag_tms_tdi(1'b1, wdata[0]);
jtag_tms(1'b1);
jtag_tms(1'b0);
endtask

task jtag_rd_dbuf;
integer i;
jtag_tms(1'b1);
jtag_tms(1'b0);
jtag_tms(1'b0);
for (i = 0; i < 32*64 - 1; i = i + 1) begin
    rdata[31:0] = {tdo, rdata[31:1]};
    if (i % 32 == 31)
        $display("dbuf[0x%2x] = 0x%8x", i / 32, rdata[31:0]);
    jtag_tdi(1'b0);
end
rdata[31:0] = {tdo, rdata[31:1]};
$display("dbuf[0x%2x] = 0x%8x", i / 32, rdata[31:0]);
jtag_tms_tdi(1'b1, 1'b0);
jtag_tms(1'b1);
jtag_tms(1'b0);
endtask

task jtag_rd_rbuf;
integer i;
jtag_tms(1'b1);
jtag_tms(1'b0);
jtag_tms(1'b0);
for (i = 0; i < 2*64 - 1; i = i + 1) begin
    rdata[31:0] = {tdo, rdata[31:1]};
    if (i % 2 == 1)

    jtag_tdi(1'b0);
end
rdata[31:0] = {tdo, rdata[31:1]};

jtag_tms_tdi(1'b1, 1'b0);
jtag_tms(1'b1);
jtag_tms(1'b0);
endtask

task jtag_rw_dr;
input [ 5:0] length;
input [34:0] dr;
integer i;
jtag_tms(1'b1);
jtag_tms(1'b0);
jtag_tms(1'b0);
for (i = 0; i < length-1; i = i + 1) begin
    rdata = {tdo, rdata[34:1]};
    jtag_tdi(dr[i]);
end
rdata = {tdo, rdata[34:1]};
jtag_tms_tdi(1'b1, dr[i]);
for (; i < 34; i = i + 1)
    rdata = {1'b0, rdata[34:1]};
jtag_tms(1'b1);
jtag_tms(1'b0);
endtask

task jtag_dpacc_wr;
input [ 3:0] addr;
input [31:0] wdata;

if (~|addr[1:0]) begin
    if (addr[3:2] !== 2'h2 || apsel_latch !== wdata[31:24] || apaddr_h_latch !== wdata[7:4]) begin
        jtag_w_ir(5'ha);
        do begin
            jtag_rw_dr(35, {wdata, addr[3:2], 1'b0});
        end while (rdata[2:0] == `RESP_WAIT);
        if (addr[3:2] === 2'h2) begin
            apsel_latch    = wdata[31:24];
            apaddr_h_latch = wdata[ 7: 4];
        end
    end
end
endtask

task jtag_dapacc_rdbuff;

jtag_w_ir(5'ha);
do begin
    jtag_rw_dr(35, {32'b0, 2'h3, 1'b1});
end while (rdata[2:0] == `RESP_WAIT);

endtask

task jtag_apbapacc_wr;
input [ 7:0] addr;
input [31:0] wdata;

if (~|addr[1:0]) begin
    jtag_w_ir(5'hb);
    if (addr !== 8'h4 || apbap_tar_latch !== wdata) begin
        jtag_dpacc_wr(4'h8, {8'b0, 16'b0, addr[7:4], 4'b0});
        do begin
            jtag_rw_dr(35, {wdata, addr[3:2], 1'b0});
        end while (rdata[2:0] == `RESP_WAIT);
        if (addr === 8'h4) begin
            apbap_tar_latch = wdata;
        end
    end
end
endtask

task jtag_apbapacc_rd;
input [ 7:0] addr;

if (~|addr[1:0]) begin
    jtag_w_ir(5'hb);
    jtag_dpacc_wr(4'h8, {8'b0, 16'b0, addr[7:4], 4'b0});
    do begin
        jtag_rw_dr(35, {32'b0, addr[3:2], 1'b1});
    end while (rdata[2:0] == `RESP_WAIT);
    jtag_dapacc_rdbuff;
end
endtask

task jtag_apbapacc_rd_cmp;
input [ 7:0] addr;
input [31:0] cmp_data;

if (~|addr[1:0]) begin
    jtag_w_ir(5'hb);
    jtag_dpacc_wr(4'h8, {8'b0, 16'b0, addr[7:4], 4'b0});
    do begin
        jtag_rw_dr(35, {cmp_data, addr[3:2], 1'b1});
    end while (rdata[2:0] == `RESP_WAIT);
    jtag_w_ir(5'ha);
    do begin
        jtag_rw_dr(35, {32'b0, 2'h1, 1'b1});
    end while (rdata[2:0] == `RESP_WAIT);
    jtag_dapacc_rdbuff;
end
endtask

task jtag_apb_wr;
input [31:0] addr;
input [31:0] wdata;

jtag_apbapacc_wr(8'h4, addr);
jtag_apbapacc_wr(8'hc, wdata);

endtask

task jtag_apb_rd;
input [31:0] addr;

jtag_dpacc_wr(4'h4, 32'hf00);
jtag_apbapacc_wr(8'h4, addr);
jtag_apbapacc_rd(8'hc);
apb_rdata = rdata[34:3];
endtask

task jtag_apb_rd_cmp;
input [31:0] addr;
input [31:0] cmp_data;

jtag_dpacc_wr(4'h4, 32'hf08);
jtag_apbapacc_wr(8'h4, addr);
jtag_apbapacc_rd_cmp(8'hc, cmp_data);
endtask

task jtag_apb_rd_verf;
input [31:0] addr;
input [31:0] cmp_data;

jtag_dpacc_wr(4'h4, 32'hf04);
jtag_apbapacc_wr(8'h4, addr);
jtag_apbapacc_rd_cmp(8'hc, cmp_data);
endtask

task jtag_dbgapb_status_rd;

jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_STATUS_RD});
jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
jtag_apb_rd(`DBGAPB_RDATA_L);
apb64_rdata[31: 0] = apb_rdata;
jtag_apb_rd(`DBGAPB_RDATA_H);
apb64_rdata[63:32] = apb_rdata;
$display("[JTAG_MDL][DBGAPB] READ STATUS_REG: %16x", apb64_rdata);
endtask

task jtag_dbgapb_pc_rd;

jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_PC_RD});
jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
jtag_apb_rd(`DBGAPB_RDATA_L);
apb64_rdata[31: 0] = apb_rdata;
jtag_apb_rd(`DBGAPB_RDATA_H);
apb64_rdata[63:32] = apb_rdata;
$display("[JTAG_MDL][DBGAPB] READ PC: %16x", apb64_rdata);
endtask

task jtag_dbgapb_exec;
input [31:0] inst;

jtag_apb_wr(`DBGAPB_WDATA_L, inst);
jtag_apb_wr(`DBGAPB_WDATA_WR, 32'b1);
jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_INSTREG_WR});
jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
jtag_apb_wr(`DBGAPB_INST, {20'b0, `INST_EXECUTE});
jtag_apb_wr(`DBGAPB_INST_WR, 32'b1);
endtask

endmodule