123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- 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;
|