sim_jtag.vhdl 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. library work;
  5. use work.sim_jtag_socket.all;
  6. library unisim;
  7. use unisim.vcomponents.all;
  8. entity sim_jtag is
  9. end sim_jtag;
  10. architecture behaviour of sim_jtag is
  11. begin
  12. jtag: process
  13. -- Global JTAG signals (used by BSCANE2 inside dmi_dtm
  14. alias j : glob_jtag_t is glob_jtag;
  15. -- Super fast JTAG clock for sim. For debugging the JTAG module,
  16. -- change this to something much larger, for example 60ns, to reflect
  17. -- more realistic conditions.
  18. constant jclk_period : time := 1 ns;
  19. -- Polling the socket... this could be made slower when nothing
  20. -- is connected once we have that indication from the C code.
  21. constant poll_period : time := 100 ns;
  22. -- Number of dummy JTAG clocks to inject after a command. (I haven't
  23. -- got that working with UrJtag but at least with sim, having the
  24. -- right number here allows the synchronizers time to complete a
  25. -- command on the first message exchange, thus avoiding the need
  26. -- for two full shifts for a response.
  27. constant dummy_clocks : integer := 80;
  28. procedure clock(count: in INTEGER) is
  29. begin
  30. for i in 1 to count loop
  31. j.tck <= '0';
  32. wait for jclk_period/2;
  33. j.tck <= '1';
  34. wait for jclk_period/2;
  35. end loop;
  36. end procedure clock;
  37. procedure clock_command(cmd: in std_ulogic_vector;
  38. rsp: out std_ulogic_vector) is
  39. begin
  40. j.capture <= '1';
  41. clock(1);
  42. j.capture <= '0';
  43. clock(1);
  44. j.shift <= '1';
  45. for i in 0 to cmd'length-1 loop
  46. j.tdi <= cmd(i);
  47. rsp := rsp(1 to rsp'length-1) & j.tdo;
  48. clock(1);
  49. end loop;
  50. j.shift <= '0';
  51. j.update <= '1';
  52. clock(1);
  53. j.update <= '0';
  54. clock(1);
  55. end procedure clock_command;
  56. variable cmd : std_ulogic_vector(0 to 247);
  57. variable rsp : std_ulogic_vector(0 to 247);
  58. variable msize : std_ulogic_vector(7 downto 0);
  59. variable size : integer;
  60. begin
  61. -- init & reset
  62. j.reset <= '1';
  63. j.sel <= "0000";
  64. j.capture <= '0';
  65. j.update <= '0';
  66. j.shift <= '0';
  67. j.tdi <= '0';
  68. j.tms <= '0';
  69. j.runtest <= '0';
  70. clock(5);
  71. j.reset <= '0';
  72. clock(5);
  73. -- select chain USER2
  74. -- XXX TODO: Send that via protocol instead
  75. -- XXX TODO: Also maybe have the C code tell us if connected or not
  76. -- and clock when connected.
  77. j.sel <= "0010";
  78. clock(1);
  79. rsp := (others => '0');
  80. while true loop
  81. wait for poll_period;
  82. sim_jtag_read_msg(cmd, msize);
  83. size := to_integer(unsigned(msize));
  84. if size /= 0 and size < 248 then
  85. clock_command(cmd(0 to size-1),
  86. rsp(0 to size-1));
  87. sim_jtag_write_msg(rsp, msize);
  88. clock(dummy_clocks);
  89. end if;
  90. end loop;
  91. end process;
  92. end;