library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; use work.sim_jtag_socket.all; library unisim; use unisim.vcomponents.all; entity sim_jtag is end sim_jtag; architecture behaviour of sim_jtag is begin jtag: process -- Global JTAG signals (used by BSCANE2 inside dmi_dtm alias j : glob_jtag_t is glob_jtag; -- Super fast JTAG clock for sim. For debugging the JTAG module, -- change this to something much larger, for example 60ns, to reflect -- more realistic conditions. constant jclk_period : time := 1 ns; -- Polling the socket... this could be made slower when nothing -- is connected once we have that indication from the C code. constant poll_period : time := 100 ns; -- Number of dummy JTAG clocks to inject after a command. (I haven't -- got that working with UrJtag but at least with sim, having the -- right number here allows the synchronizers time to complete a -- command on the first message exchange, thus avoiding the need -- for two full shifts for a response. constant dummy_clocks : integer := 80; procedure clock(count: in INTEGER) is begin for i in 1 to count loop j.tck <= '0'; wait for jclk_period/2; j.tck <= '1'; wait for jclk_period/2; end loop; end procedure clock; procedure clock_command(cmd: in std_ulogic_vector; rsp: out std_ulogic_vector) is begin j.capture <= '1'; clock(1); j.capture <= '0'; clock(1); j.shift <= '1'; for i in 0 to cmd'length-1 loop j.tdi <= cmd(i); rsp := rsp(1 to rsp'length-1) & j.tdo; clock(1); end loop; j.shift <= '0'; j.update <= '1'; clock(1); j.update <= '0'; clock(1); end procedure clock_command; variable cmd : std_ulogic_vector(0 to 247); variable rsp : std_ulogic_vector(0 to 247); variable msize : std_ulogic_vector(7 downto 0); variable size : integer; begin -- init & reset j.reset <= '1'; j.sel <= "0000"; j.capture <= '0'; j.update <= '0'; j.shift <= '0'; j.tdi <= '0'; j.tms <= '0'; j.runtest <= '0'; clock(5); j.reset <= '0'; clock(5); -- select chain USER2 -- XXX TODO: Send that via protocol instead -- XXX TODO: Also maybe have the C code tell us if connected or not -- and clock when connected. j.sel <= "0010"; clock(1); rsp := (others => '0'); while true loop wait for poll_period; sim_jtag_read_msg(cmd, msize); size := to_integer(unsigned(msize)); if size /= 0 and size < 248 then clock_command(cmd(0 to size-1), rsp(0 to size-1)); sim_jtag_write_msg(rsp, msize); clock(dummy_clocks); end if; end loop; end process; end;