jtag: Apply Martin Strubel JTAG implementation for ZPU
[zpu.git] / zpu / hdl / tap / jtagx.vhd
blob89c2075caac11a3a91fb0c067288a118d039b528
1 ----------------------------------------------------------------------------
2 -- Simple JTAG controller, enhanced version
3 --
4 -- $Id: jtag.vhdl 35 2008-09-05 23:31:00Z strubi $
5 --
6 -- (c) 2005, 2006, 2011
7 -- Martin Strubel // <hackfin@section5.ch>
8 ----------------------------------------------------------------------------
10 -- Functionality:
12 -- This module implements a JTAG controller with a instruction register (IR)
13 -- and a data register (DR).
14 -- Data is clocked into the IR register MSB first,
15 -- into the DR register LSB first.
17 -- The reason for this inconsistent behaviour is, that this controller
18 -- allows variable sizes of data registers, depending on the IR value.
19 --
20 -- (Actually, the Blackfin CPU JTAG controller does it the same odd way)
22 -- The IR and DR register size is specified in the parameters:
24 -- IRSIZE (default 4)
25 -- DRSIZE (default 8)
27 -- All special functionality must be encoded outside this module, using
28 -- the IR values.
29 -- There is one exception: The Instruction "1111" is reserved for the
30 -- IR_BYPASS mode. In this mode, the TDI bit is passed onto TDO with a delay
31 -- of one bit, according to the JTAG standard.
33 -- The design is tested using the JTAG library coming with the ICEbear
34 -- USB JTAG adapter.
37 library ieee;
38 use ieee.std_logic_1164.all;
39 use IEEE.std_logic_unsigned.all;
40 use IEEE.numeric_std.all; -- TO_INTEGER
42 library work;
43 use work.jtag.all;
45 entity JtagController is
46 generic (IRSIZE : natural := 4;
47 DRSIZE : natural := 8);
48 port (
49 tck, -- Tap Clock
50 trst, -- Tap Reset
51 tms, -- Tap mode select
52 tdi : in std_logic; -- Tap data in
53 tdo : out std_logic; -- Tap data out
54 state : out jtag_state_type; -- JTAG machine state
55 -- Data register input:
56 dr_in : in std_logic_vector (DRSIZE-1 downto 0);
57 -- Configureable DR size:
58 msbpos : in bitpos_type;
59 -- Data register output:
60 dr_out : out std_logic_vector (DRSIZE-1 downto 0);
61 -- Instruction register:
62 ir_out : out std_logic_vector (IRSIZE-1 downto 0)
64 end JtagController;
66 architecture behaviour of JtagController is
68 -- The only fixed instruction: All ones. Reserved for bypassing.
69 constant IR_BYPASS : std_logic_vector (IRSIZE-1 downto 0) :=
70 (others => '1');
72 signal mystate : jtag_state_type := TEST_LOGIC_RESET;
73 signal next_state : jtag_state_type;
75 signal s_dr : std_logic_vector (DRSIZE-1 downto 0);
76 signal s_ir : std_logic_vector (IRSIZE-1 downto 0) :=
77 (others => '1');
79 signal msb : bitpos_type;
81 -- Disabled: Buffered register
82 -- signal ir : std_logic_vector (IRSIZE-1 downto 0);
84 begin
86 nextstate_decode:
87 process (mystate, tms)
88 begin
89 case mystate is
90 when CAPTURE_DR =>
91 if (tms = '1') then
92 next_state <= EXIT1_DR;
93 else
94 next_state <= SHIFT_DR;
95 end if;
96 when CAPTURE_IR =>
97 if (tms = '1') then
98 next_state <= EXIT1_IR;
99 else
100 next_state <= SHIFT_IR;
101 end if;
102 when EXIT1_DR =>
103 if (tms = '1') then
104 next_state <= UPDATE_DR;
105 else
106 next_state <= PAUSE_DR;
107 end if;
108 when EXIT1_IR =>
109 if (tms = '1') then
110 next_state <= UPDATE_IR;
111 else
112 next_state <= PAUSE_IR;
113 end if;
114 when EXIT2_DR =>
115 if (tms = '1') then
116 next_state <= UPDATE_DR;
117 else
118 next_state <= SHIFT_DR;
119 end if;
120 when EXIT2_IR =>
121 if (tms = '1') then
122 next_state <= UPDATE_IR;
123 else
124 next_state <= SHIFT_IR;
125 end if;
126 when PAUSE_DR =>
127 if (tms = '1') then
128 next_state <= EXIT2_DR;
129 else
130 next_state <= PAUSE_DR;
131 end if;
132 when PAUSE_IR =>
133 if (tms = '1') then
134 next_state <= EXIT2_IR;
135 else
136 next_state <= PAUSE_IR;
137 end if;
138 when RUN_TEST_IDLE =>
139 if (tms = '1') then
140 next_state <= SELECT_DR;
141 else
142 next_state <= RUN_TEST_IDLE;
143 end if;
144 when SELECT_DR =>
145 if (tms = '1') then
146 next_state <= SELECT_IR;
147 else
148 next_state <= CAPTURE_DR;
149 end if;
150 when SELECT_IR =>
151 if (tms = '1') then
152 next_state <= TEST_LOGIC_RESET;
153 else
154 next_state <= CAPTURE_IR;
155 end if;
156 when SHIFT_DR =>
157 if (tms = '1') then
158 next_state <= EXIT1_DR;
159 else
160 next_state <= SHIFT_DR;
161 end if;
162 when SHIFT_IR =>
163 if (tms = '1') then
164 next_state <= EXIT1_IR;
165 else
166 next_state <= SHIFT_IR;
167 end if;
168 when TEST_LOGIC_RESET =>
169 if (tms = '1') then
170 next_state <= TEST_LOGIC_RESET;
171 else
172 next_state <= RUN_TEST_IDLE;
173 end if;
174 when UPDATE_DR =>
175 if (tms = '1') then
176 next_state <= SELECT_DR;
177 else
178 next_state <= RUN_TEST_IDLE;
179 end if;
180 when UPDATE_IR =>
181 if (tms = '1') then
182 next_state <= SELECT_DR;
183 else
184 next_state <= RUN_TEST_IDLE;
185 end if;
186 when others =>
187 end case;
188 end process;
190 -- When we're in BYPASS, use MSB 0
191 msb <= 0 when s_ir = IR_BYPASS else msbpos;
193 tdo_encode:
194 process (mystate, s_ir, s_dr)
195 begin
196 case mystate is
197 when SHIFT_IR =>
198 tdo <= s_ir(0); -- Shift out LSB
199 when SHIFT_DR =>
200 tdo <= s_dr(msb); -- Take MSB
201 when others =>
202 tdo <= '1';
203 end case;
204 end process;
206 state_advance:
207 process (tck, trst)
208 begin
209 if (trst = '0') then
210 mystate <= TEST_LOGIC_RESET;
211 elsif rising_edge(tck) then
212 mystate <= next_state; -- Advance to next state
213 end if;
214 end process;
216 process_ir_dr:
217 process (tck)
218 begin
219 if rising_edge(tck) then
220 -- takes effect when entering the concerning state
221 case next_state is
222 -- When resetting, go into BYPASS mode
223 when TEST_LOGIC_RESET =>
224 s_ir <= (others => '1');
225 s_dr <= (others => '0');
226 when others =>
227 end case;
229 -- Mystate is the current state, process takes effect on rising TCK when IN
230 -- the concerning state.
231 case mystate is
232 when SHIFT_IR =>
233 s_ir <= tdi & s_ir(IRSIZE-1 downto 1); -- Shift in from MSB
234 when SHIFT_DR =>
235 s_dr <= s_dr(DRSIZE-2 downto 0) & tdi; -- likewise from LSB
236 when CAPTURE_DR =>
237 -- We could move this BYPASS check to a higher level module. But since
238 -- it's a reserved command, we leave it in here.
239 if (s_ir /= IR_BYPASS) then
240 s_dr <= dr_in; -- Latch!
241 end if;
242 when others =>
243 end case;
244 end if;
245 end process;
247 -- always assign state to output
248 -- We assign nextstate which is valid on the rising_edge of tck
249 state <= next_state;
251 ir_out <= s_ir;
252 dr_out <= s_dr;
254 end behaviour;