Add Tercel PHY reset synchronization
[microwatt.git] / dmi_dtm_xilinx.vhdl
1 -- Xilinx internal JTAG to DMI interface
2 --
3 -- DMI bus
4 --
5 -- req : ____/------------\_____
6 -- addr: xxxx< >xxxxx
7 -- dout: xxxx< >xxxxx
8 -- wr : xxxx< >xxxxx
9 -- din : xxxxxxxxxxxx< >xxx
10 -- ack : ____________/------\___
11 --
12 -- * addr/dout set along with req, can be latched on same cycle by slave
13 -- * ack & din remain up until req is dropped by master, the slave must
14 -- provide a stable output on din on reads during that time.
15 -- * req remains low at until at least one sysclk after ack seen down.
16 --
17 -- JTAG (tck) DMI (sys_clk)
18 --
19 -- * jtag_req = 1
20 -- (jtag_req_0) *
21 -- (jtag_req_1) -> * dmi_req = 1 >
22 -- *.../...
23 -- * dmi_ack = 1 <
24 -- * (dmi_ack_0)
25 -- * <- (dmi_ack_1)
26 -- * jtag_req = 0 (and latch dmi_din)
27 -- (jtag_req_0) *
28 -- (jtag_req_1) -> * dmi_req = 0 >
29 -- * dmi_ack = 0 <
30 -- * (dmi_ack_0)
31 -- * <- (dmi_ack_1)
32 --
33 -- jtag_req can go back to 1 when jtag_rsp_1 is 0
34 --
35 -- Questions/TODO:
36 -- - I use 2 flip fops for sync, is that enough ?
37 -- - I treat the jtag_reset as an async reset, is that necessary ?
38 -- - Dbl check reset situation since we have two different resets
39 -- each only resetting part of the logic...
40 -- - Look at optionally removing the synchronizer on the ack path,
41 -- assuming JTAG is always slow enough that ack will have been
42 -- stable long enough by the time CAPTURE comes in.
43 -- - We could avoid the latched request by not shifting while a
44 -- request is in progress (and force TDO to 1 to return a busy
45 -- status).
46 --
47 -- WARNING: This isn't the real DMI JTAG protocol (at least not yet).
48 -- a command while busy will be ignored. A response of "11"
49 -- means the previous command is still going, try again.
50 -- As such We don't implement the DMI "error" status, and
51 -- we don't implement DTMCS yet... This may still all change
52 -- but for now it's easier that way as the real DMI protocol
53 -- requires for a command to work properly that enough TCK
54 -- are sent while IDLE and I'm having trouble getting that
55 -- working with UrJtag and the Xilinx BSCAN2 for now.
56
57 library ieee;
58 use ieee.std_logic_1164.all;
59 use ieee.math_real.all;
60
61 library work;
62 use work.wishbone_types.all;
63
64 library unisim;
65 use unisim.vcomponents.all;
66
67 entity dmi_dtm is
68 generic(ABITS : INTEGER:=8;
69 DBITS : INTEGER:=32);
70
71 port(sys_clk : in std_ulogic;
72 sys_reset : in std_ulogic;
73 dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0);
74 dmi_din : in std_ulogic_vector(DBITS - 1 downto 0);
75 dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0);
76 dmi_req : out std_ulogic;
77 dmi_wr : out std_ulogic;
78 dmi_ack : in std_ulogic
79 -- dmi_err : in std_ulogic TODO: Add error response
80 );
81 end entity dmi_dtm;
82
83 architecture behaviour of dmi_dtm is
84
85 -- Signals coming out of the BSCANE2 block
86 signal jtag_reset : std_ulogic;
87 signal capture : std_ulogic;
88 signal update : std_ulogic;
89 signal drck : std_ulogic;
90 signal jtag_clk : std_ulogic;
91 signal sel : std_ulogic;
92 signal shift : std_ulogic;
93 signal tdi : std_ulogic;
94 signal tdo : std_ulogic;
95 signal tck : std_ulogic;
96
97 -- ** JTAG clock domain **
98
99 -- Shift register
100 signal shiftr : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
101
102 -- Latched request
103 signal request : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
104
105 -- A request is present
106 signal jtag_req : std_ulogic;
107
108 -- Synchronizer for jtag_rsp (sys clk -> jtag_clk)
109 signal dmi_ack_0 : std_ulogic;
110 signal dmi_ack_1 : std_ulogic;
111
112 -- ** sys clock domain **
113
114 -- Synchronizer for jtag_req (jtag clk -> sys clk)
115 signal jtag_req_0 : std_ulogic;
116 signal jtag_req_1 : std_ulogic;
117
118 -- ** combination signals
119 signal jtag_bsy : std_ulogic;
120 signal op_valid : std_ulogic;
121 signal rsp_op : std_ulogic_vector(1 downto 0);
122
123 -- ** Constants **
124 constant DMI_REQ_NOP : std_ulogic_vector(1 downto 0) := "00";
125 constant DMI_REQ_RD : std_ulogic_vector(1 downto 0) := "01";
126 constant DMI_REQ_WR : std_ulogic_vector(1 downto 0) := "10";
127 constant DMI_RSP_OK : std_ulogic_vector(1 downto 0) := "00";
128 constant DMI_RSP_BSY : std_ulogic_vector(1 downto 0) := "11";
129
130 attribute ASYNC_REG : string;
131 attribute ASYNC_REG of jtag_req_0: signal is "TRUE";
132 attribute ASYNC_REG of jtag_req_1: signal is "TRUE";
133 attribute ASYNC_REG of dmi_ack_0: signal is "TRUE";
134 attribute ASYNC_REG of dmi_ack_1: signal is "TRUE";
135 begin
136
137 -- Implement the Xilinx bscan2 for series 7 devices (TODO: use PoC to
138 -- wrap this if compatibility is required with older devices).
139 bscan : BSCANE2
140 generic map (
141 JTAG_CHAIN => 2
142 )
143 port map (
144 CAPTURE => capture,
145 DRCK => drck,
146 RESET => jtag_reset,
147 RUNTEST => open,
148 SEL => sel,
149 SHIFT => shift,
150 TCK => tck,
151 TDI => tdi,
152 TMS => open,
153 UPDATE => update,
154 TDO => tdo
155 );
156
157 -- Some examples out there suggest buffering the clock so it's
158 -- treated as a proper clock net. This is probably needed when using
159 -- drck (the gated clock) but I'm using the real tck here to avoid
160 -- missing the update phase so maybe not...
161 --
162 clkbuf : BUFG
163 port map (
164 -- I => drck,
165 I => tck,
166 O => jtag_clk
167 );
168
169 -- dmi_req synchronization
170 dmi_req_sync : process(sys_clk)
171 begin
172 -- sys_reset is synchronous
173 if rising_edge(sys_clk) then
174 if (sys_reset = '1') then
175 jtag_req_0 <= '0';
176 jtag_req_1 <= '0';
177 else
178 jtag_req_0 <= jtag_req;
179 jtag_req_1 <= jtag_req_0;
180 end if;
181 end if;
182 end process;
183 dmi_req <= jtag_req_1;
184
185 -- dmi_ack synchronization
186 dmi_ack_sync: process(jtag_clk, jtag_reset)
187 begin
188 -- jtag_reset is async (see comments)
189 if jtag_reset = '1' then
190 dmi_ack_0 <= '0';
191 dmi_ack_1 <= '0';
192 elsif rising_edge(jtag_clk) then
193 dmi_ack_0 <= dmi_ack;
194 dmi_ack_1 <= dmi_ack_0;
195 end if;
196 end process;
197
198 -- jtag_bsy indicates whether we can start a new request, we can when
199 -- we aren't already processing one (jtag_req) and the synchronized ack
200 -- of the previous one is 0.
201 --
202 jtag_bsy <= jtag_req or dmi_ack_1;
203
204 -- decode request type in shift register
205 with shiftr(1 downto 0) select op_valid <=
206 '1' when DMI_REQ_RD,
207 '1' when DMI_REQ_WR,
208 '0' when others;
209
210 -- encode response op
211 rsp_op <= DMI_RSP_BSY when jtag_bsy = '1' else DMI_RSP_OK;
212
213 -- Some DMI out signals are directly driven from the request register
214 dmi_addr <= request(ABITS + DBITS + 1 downto DBITS + 2);
215 dmi_dout <= request(DBITS + 1 downto 2);
216 dmi_wr <= '1' when request(1 downto 0) = DMI_REQ_WR else '0';
217
218 -- TDO is wired to shift register bit 0
219 tdo <= shiftr(0);
220
221 -- Main state machine. Handles shift registers, request latch and
222 -- jtag_req latch. Could be split into 3 processes but it's probably
223 -- not worthwhile.
224 --
225 shifter: process(jtag_clk, jtag_reset, sys_reset)
226 begin
227 if jtag_reset = '1' or sys_reset = '1' then
228 shiftr <= (others => '0');
229 jtag_req <= '0';
230 request <= (others => '0');
231 elsif rising_edge(jtag_clk) then
232
233 -- Handle jtag "commands" when sel is 1
234 if sel = '1' then
235 -- Shift state, rotate the register
236 if shift = '1' then
237 shiftr <= tdi & shiftr(ABITS + DBITS + 1 downto 1);
238 end if;
239
240 -- Update state (trigger)
241 --
242 -- Latch the request if we aren't already processing one and
243 -- it has a valid command opcode.
244 --
245 if update = '1' and op_valid = '1' then
246 if jtag_bsy = '0' then
247 request <= shiftr;
248 jtag_req <= '1';
249 end if;
250 -- Set the shift register "op" to "busy". This will prevent
251 -- us from re-starting the command on the next update if
252 -- the command completes before that.
253 shiftr(1 downto 0) <= DMI_RSP_BSY;
254 end if;
255
256 -- Request completion.
257 --
258 -- Capture the response data for reads and clear request flag.
259 --
260 -- Note: We clear req (and thus dmi_req) here which relies on tck
261 -- ticking and sel set. This means we are stuck with dmi_req up if
262 -- the jtag interface stops. Slaves must be resilient to this.
263 --
264 if jtag_req = '1' and dmi_ack_1 = '1' then
265 jtag_req <= '0';
266 if request(1 downto 0) = DMI_REQ_RD then
267 request(DBITS + 1 downto 2) <= dmi_din;
268 end if;
269 end if;
270
271 -- Capture state, grab latch content with updated status
272 if capture = '1' then
273 shiftr <= request(ABITS + DBITS + 1 downto 2) & rsp_op;
274 end if;
275
276 end if;
277 end if;
278 end process;
279 end architecture behaviour;
280