blob: 72ab65b56a5dfcdc3cc6d2626cc849e251b577fe [file] [log] [blame]
`timescale 1ns/10ps
module jtag_driver (
output reg tck,
output reg tms,
output reg tdi,
input wire tdo
);
parameter TCK_PERIOD = 250;
parameter IR_LEN = 5;
// TCK free run
reg tck_free;
initial begin
tck_free = 1'b0;
forever #(TCK_PERIOD/2) tck_free = ~tck_free;
end
initial begin
tck = 1'b0;
tms = 1'b0;
tdi = 1'b0;
end
// Drive TMS and TDI
task drive;
input tms_i;
input tdi_i;
output reg tdo_o;
begin
@(negedge tck_free);
tck = 1'b0;
tms = tms_i;
tdi = tdi_i;
@(posedge tck_free);
tdo_o = tdo;
tck = 1'b1;
end
endtask
// Set TCK, TMS and TDI to 0
task stop;
begin
@(negedge tck_free);
tck = 1'b0;
tms = 1'b0;
tdi = 1'b0;
end
endtask
// Test-Loggic-Reset
task test_logic_reset;
reg tdo_o;
begin
repeat (6) drive(1,0,tdo_o);
end
endtask
// Run-Test-Idle
task run_test_idle;
reg tdo_o;
begin
test_logic_reset();
drive(0,0,tdo_o);
end
endtask
// Shift-IR (must be in Run-Teset/Idle state before calling this task)
task shift_ir;
input [IR_LEN-1:0] ir_i;
output reg [IR_LEN-1:0] ir_o;
reg tdo_o;
integer i;
begin
ir_o = 0;
drive(0,0,tdo_o); // Run-Test-Idle -> Run-Test-Idle
drive(1,0,tdo_o); // Run-Test-Idle -> Slect-DR-Scan
drive(1,0,tdo_o); // Select-DR-Scan -> Select-IR-Scan
drive(0,0,tdo_o); // Select-IR-Scan -> Capture-IR
drive(0,0,tdo_o); // Capture-IR -> Shift-IR
for (i = 0; i < IR_LEN-1; i = i + 1) begin
drive(0,ir_i[i],ir_o[i]); // Shift-IR -> Shift-IR
end
drive(1,ir_i[IR_LEN-1],ir_o[IR_LEN-1]); // Shift-IR -> Exit1-IR
drive(1,0,tdo_o); // Exit1-IR -> Update-IR
drive(0,0,tdo_o); // Update-IR -> Run-Test-Idle
stop(); // Run-Test-Idle
end
endtask
// Shift-DR (must be in Run-Teset/Idle state before calling this task)
task shift_dr;
input [5:0] dr_len;
input [63:0] dr_i;
output reg [63:0] dr_o;
reg tdo_o;
integer i;
begin
dr_o = 0;
drive(0,0,tdo_o); // Run-Test-Idle -> Run-Test-Idle
drive(1,0,tdo_o); // Run-Test-Idle -> Slect-DR-Scan
drive(0,0,tdo_o); // Select-DR-Scan -> Capture-DR
drive(0,0,tdo_o); // Capture-DR -> Shift-DR
for (i = 0; i < dr_len-1; i = i + 1) begin
drive(0,dr_i[i],dr_o[i]); // Shift-DR -> Shift-DR
end
drive(1,dr_i[dr_len-1],dr_o[dr_len-1]); // Shift-DR -> Exit1-DR
drive(1,0,tdo_o); // Exit1-DR -> Update-DR
drive(0,0,tdo_o); // Update-DR -> Run-Test-Idle
stop(); // Run-Test-Idle
end
endtask
endmodule