-
Notifications
You must be signed in to change notification settings - Fork 102
/
sim_jtag.vhdl
105 lines (92 loc) · 2.58 KB
/
sim_jtag.vhdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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;