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