`timescale 1ns/1ps module tb_svf(); wire [7:0] led_out; wire [31:0] update_count; jtag_byte_sink #( .SVF_FILE("sim/other/test.svf"), .TCK_HALF_PERIOD_NS(50) ) dut ( .o_led(led_out), .o_update_count(update_count) ); initial begin // Optional waveform dump. $dumpfile("out.vcd"); $dumpvars; // Timeout for large SVF playback. #20_000; $finish; end endmodule module jtag_byte_sink #( parameter [8*256-1:0] SVF_FILE = "", parameter integer TCK_HALF_PERIOD_NS = 50 )( output reg [7:0] o_led, output reg [31:0] o_update_count ); wire jtag_tck; wire jtag_tdi; wire jtag_drck; wire jtag_capture; wire jtag_shift; wire jtag_update; wire jtag_runtest; wire jtag_reset; wire jtag_sel; wire jtag_tdo; reg [7:0] shift_reg; assign jtag_tdo = shift_reg[0]; jtag_if #( .chain(1), .SVF_FILE(SVF_FILE), .TCK_HALF_PERIOD_NS(TCK_HALF_PERIOD_NS), .USER_IR_OPCODE(32'h0000_0002) ) jtag ( .i_tdo(jtag_tdo), .o_tck(jtag_tck), .o_tdi(jtag_tdi), .o_drck(jtag_drck), .o_capture(jtag_capture), .o_shift(jtag_shift), .o_update(jtag_update), .o_runtest(jtag_runtest), .o_reset(jtag_reset), .o_sel(jtag_sel) ); always @(posedge jtag_drck or posedge jtag_reset) begin if (jtag_reset) begin shift_reg <= 8'h00; end else if (jtag_sel && jtag_capture) begin shift_reg <= o_led; end else if (jtag_sel && jtag_shift) begin shift_reg <= {jtag_tdi, shift_reg[7:1]}; end end always @(posedge jtag_update or posedge jtag_reset) begin if (jtag_reset) begin o_led <= 8'h00; o_update_count <= 32'd0; end else if (jtag_sel) begin o_led <= shift_reg; o_update_count <= o_update_count + 1'b1; end end // Keep lint happy for currently unused outputs. wire _unused_tck; wire _unused_runtest; assign _unused_tck = jtag_tck; assign _unused_runtest = jtag_runtest; endmodule