1 -- Example Test Access Port (TAP) controller implementation
2 -- (c) 2005-2011 Martin Strubel <hackfin@section5.ch>
4 -- General behaviour summary:
6 -- * JtagController entity decodes the TMS and TDI sequences
7 -- * IR and DR are decoded by this TAP controller
8 -- * Signals to a CPU core are generated by the TAP. See
9 -- "Core emulation signals" below. These are mapped into a control register:
11 -- * Signals from a CPU core are mapped into a status register:
14 -- Note: Fixed size IR register is clocked in LSB first,
15 -- Variable size DR register is clocked in MSB first.
17 -- The default EMUIR value on a state machine reset is set to
18 -- INS_NOP, which should be defined properly by the parent module.
19 -- This is necessary for the core to not run any spurious command when
20 -- a breakpoint was hit and the JTAG state machine enters Run-Test-Idle.
22 -- This TAP is supported by a generic software library as part of the
23 -- ICEbear software suite.
26 use ieee.std_logic_1164.
all;
27 use ieee.numeric_std.
all;
31 -- TAP register definitions (generated):
32 use work.tap_registers.
all;
35 generic (EMUDAT_SIZE
: natural
:= 32;
36 EMUIR_SIZE
: natural
:= 8;
37 IDCODE
: std_logic_vector(32-1 downto 0) := x"deadbeef"
;
38 INS_NOP
: std_logic_vector(8-1 downto 0) := x"
00"
);
41 tck
, trst
, tms
, tdi
: in std_logic;
43 -- Core <-> TAP signals:
44 core_reset
: out std_logic; -- Reset core logic
45 emuexec
: out std_logic; -- Execute opcode on rising edge
46 emurequest
: out std_logic; -- Emulation request to core
47 emuack
: in std_logic; -- Core has acknowledged EMULATION request
48 emurdy
: in std_logic; -- Core ready to execute next instruction
49 pulse
: in std_logic; -- Pulse event counter
50 -- PC of possibly running core. Allows to access PC without
51 -- entering emulation.
52 dbgpc
: in std_logic_vector(EMUDAT_SIZE
-1 downto 0); -- PC
54 -- Extra status bits, core dependent
55 exstat
: in std_logic_vector(7 downto 0);
57 emudata_i
: in std_logic_vector(EMUDAT_SIZE
-1 downto 0);
58 emudata_o
: out std_logic_vector(EMUDAT_SIZE
-1 downto 0);
59 -- Not implemented in this version
60 -- emudat_wr : in std_logic;
61 -- emudat_rd : in std_logic;
62 emuir
: out std_logic_vector(EMUIR_SIZE
-1 downto 0)
66 architecture behaviour
of tap
is
68 -- Use generated registers from tap_pkg.vhd
70 -- Note: all ones is always reserved for BYPASS
71 -- all zeros is normally reserved for EXTEST
73 signal jtag_state
: jtag_state_type
;
75 signal exec
: std_logic := '0';
77 -- Emulation control/status registers:
78 signal emustat
: std_logic_vector(16-1 downto 0);
79 signal emuctl
: std_logic_vector(16-1 downto 0) := x"
0000"
;
81 -- Core emulation signals:
83 signal dr_in
: std_logic_vector(EMUDAT_SIZE
-1 downto 0);
84 signal dr_out
: std_logic_vector(EMUDAT_SIZE
-1 downto 0);
86 signal count1
: unsigned
(32-1 downto 0);
87 signal count1_reset
: std_logic;
88 signal count2
: unsigned
(16-1 downto 0);
90 signal ir
: std_logic_vector(4-1 downto 0);
92 -- Position of MSB of data register when not in BYPASS
93 -- (defines length of DR register). See also jtag_config.vhd
94 signal msbpos
: bitpos_type
:= 31;
96 -- Emulation auxiliaries:
98 -- Emulation data register for exchange between core and JTAG:
99 signal emudat_i
: std_logic_vector(EMUDAT_SIZE
-1 downto 0);
100 signal emudat_o
: std_logic_vector(EMUDAT_SIZE
-1 downto 0);
101 -- These signals are just stubs. Not implemented in this version.
102 -- signal emudat_rxf : std_logic; -- Receive full
103 -- signal emudat_txe : std_logic := '0'; -- Transmit empty
104 -- signal emudat_ovr : std_logic := '0'; -- Overrun
105 -- signal emudat_unr : std_logic := '0'; -- Underrun
108 i_jtag
: JtagController
122 -- Select DR register according to supported IRs
123 -- We sample this with tck to avoid gated clock issues
128 if rising_edge
(tck
) then
135 msbpos
<= emudata_i
'length - 1;
137 dr_in
(emustat
'length-1 downto 0) <= emustat
;
138 msbpos
<= emustat
'length - 1;
141 msbpos
<= dbgpc
'length - 1;
143 dr_in
(count1
'length-1 downto 0) <= std_logic_vector(count1
);
144 msbpos
<= count1
'length - 1;
146 dr_in
(count2
'length-1 downto 0) <= std_logic_vector(count2
);
147 msbpos
<= count2
'length - 1;
149 dr_in
<= (others => 'X');
156 -- NOTE: action is being taken when ENTERING the concerning state
157 -- on rising edge of tck.
159 -- exec is the signal sent to the core. It is like an IRQ event, thus
160 -- it must be properly treated as an exception (edge sensitive)
161 -- inside the core logic.
166 if rising_edge
(tck
) then
171 if ir
= TAP_EMUCTRL
then
172 emuctl
<= dr_out
(15 downto 0);
173 elsif ir
= TAP_EMUDATA
then
175 elsif ir
= TAP_EMUIR
then
176 emuir
<= dr_out
(EMUIR_SIZE
-1 downto 0);
178 when TEST_LOGIC_RESET
=>
180 count2
<= (others => '0');
181 emuctl
<= (others => '0');
182 emudat_o
<= (others => '0');
183 -- Important to reset the EMUIR to NOP for sane JTAG operation:
185 when RUN_TEST_IDLE
=>
186 count2
<= count2
+ 1;
194 process (count1_reset
, pulse
)
196 if count1_reset
= '1' then
197 count1
<= (others => '0');
198 elsif rising_edge
(pulse
) then
199 count1
<= count1
+ 1;
204 emurequest
<= emuctl
(0);
205 core_reset
<= emuctl
(15);
208 emudata_o
<= emudat_o
;
211 -- These mappings should probably move to glue between TAP and core
212 -- to be more generic.
215 "
0000"
& "
00"
& emurdy
& emuack
;