ebba63a9 |
1 | --+-------------------------------------------------------------------------------------------------+\r |
2 | --| |\r |
3 | --| File: pciwbsequ.vhd |\r |
4 | --| |\r |
5 | --| Project: pci32tlite_oc |\r |
6 | --| |\r |
7 | --| Description: FSM controlling PCI to Whisbone sequence. |\r |
8 | --| |\r |
9 | --+-------------------------------------------------------------------------------------------------+\r |
10 | --| |\r |
11 | --| Revision history : |\r |
12 | --| Date Version Author Description |\r |
13 | --| 2005-05-13 R00A00 PAU First alfa revision (eng) |\r |
14 | --| 2006-01-09 MS added debug signals debug_init, debug_access | |\r |
15 | --| |\r |
16 | --| To do: |\r |
17 | --| |\r |
18 | --+-------------------------------------------------------------------------------------------------+\r |
19 | --+-----------------------------------------------------------------+\r |
20 | --| |\r |
21 | --| Copyright (C) 2005 Peio Azkarate, peio@opencores.org | \r |
22 | --| |\r |
23 | --| This source file may be used and distributed without |\r |
24 | --| restriction provided that this copyright statement is not |\r |
25 | --| removed from the file and that any derivative work contains |\r |
26 | --| the original copyright notice and the associated disclaimer. |\r |
27 | --| |\r |
28 | --| This source file is free software; you can redistribute it |\r |
29 | --| and/or modify it under the terms of the GNU Lesser General |\r |
30 | --| Public License as published by the Free Software Foundation; |\r |
31 | --| either version 2.1 of the License, or (at your option) any |\r |
32 | --| later version. |\r |
33 | --| |\r |
34 | --| This source is distributed in the hope that it will be |\r |
35 | --| useful, but WITHOUT ANY WARRANTY; without even the implied |\r |
36 | --| warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |\r |
37 | --| PURPOSE. See the GNU Lesser General Public License for more |\r |
38 | --| details. |\r |
39 | --| |\r |
40 | --| You should have received a copy of the GNU Lesser General |\r |
41 | --| Public License along with this source; if not, download it |\r |
42 | --| from http://www.opencores.org/lgpl.shtml |\r |
43 | --| |\r |
44 | --+-----------------------------------------------------------------+ \r |
45 | \r |
46 | \r |
47 | --+-----------------------------------------------------------------------------+\r |
48 | --| LIBRARIES |\r |
49 | --+-----------------------------------------------------------------------------+\r |
50 | \r |
51 | library ieee;\r |
52 | use ieee.std_logic_1164.all;\r |
53 | \r |
54 | \r |
55 | --+-----------------------------------------------------------------------------+\r |
56 | --| ENTITY |\r |
57 | --+-----------------------------------------------------------------------------+\r |
58 | \r |
59 | entity pciwbsequ is\r |
60 | port (\r |
61 | \r |
62 | -- General \r |
63 | clk_i : in std_logic;\r |
64 | nrst_i : in std_logic;\r |
65 | -- pci \r |
66 | --adr_i\r |
67 | cmd_i : in std_logic_vector(3 downto 0);\r |
68 | cbe_i : in std_logic_vector(3 downto 0);\r |
69 | frame_i : in std_logic;\r |
70 | irdy_i : in std_logic;\r |
71 | devsel_o : out std_logic;\r |
72 | trdy_o : out std_logic;\r |
73 | -- control\r |
74 | adrcfg_i : in std_logic;\r |
75 | adrmem_i : in std_logic;\r |
76 | pciadrLD_o : out std_logic;\r |
77 | pcidOE_o : out std_logic;\r |
78 | parOE_o : out std_logic;\r |
79 | wbdatLD_o : out std_logic;\r |
80 | wbrgdMX_o : out std_logic;\r |
81 | wbd16MX_o : out std_logic; \r |
82 | wrcfg_o : out std_logic;\r |
83 | rdcfg_o : out std_logic;\r |
84 | -- whisbone\r |
85 | wb_sel_o : out std_logic_vector(1 downto 0);\r |
86 | wb_we_o : out std_logic;\r |
87 | wb_stb_o : inout std_logic; \r |
88 | wb_cyc_o : out std_logic;\r |
89 | wb_ack_i : in std_logic;\r |
90 | wb_err_i : in std_logic; \r |
91 | -- debug signals\r |
92 | debug_init : out std_logic;\r |
93 | debug_access : out std_logic \r |
94 | ); \r |
95 | end pciwbsequ;\r |
96 | \r |
97 | \r |
98 | architecture rtl of pciwbsequ is\r |
99 | \r |
100 | \r |
101 | --+-----------------------------------------------------------------------------+\r |
102 | --| COMPONENTS |\r |
103 | --+-----------------------------------------------------------------------------+\r |
104 | --+-----------------------------------------------------------------------------+\r |
105 | --| CONSTANTS |\r |
106 | --+-----------------------------------------------------------------------------+\r |
107 | --+-----------------------------------------------------------------------------+\r |
108 | --| SIGNALS |\r |
109 | --+-----------------------------------------------------------------------------+\r |
110 | \r |
111 | type PciFSM is ( PCIIDLE, B_BUSY, S_DATA1, S_DATA2, TURN_AR ); \r |
112 | signal pst_pci : PciFSM;\r |
113 | signal nxt_pci : PciFSM;\r |
114 | \r |
115 | signal sdata1 : std_logic;\r |
116 | signal sdata2 : std_logic;\r |
117 | signal idleNX : std_logic;\r |
118 | signal sdata1NX : std_logic;\r |
119 | signal sdata2NX : std_logic;\r |
120 | signal turnarNX : std_logic;\r |
121 | signal idle : std_logic;\r |
122 | signal devselNX_n : std_logic;\r |
123 | signal trdyNX_n : std_logic;\r |
124 | signal devsel : std_logic;\r |
125 | signal trdy : std_logic;\r |
126 | signal adrpci : std_logic;\r |
127 | signal acking : std_logic;\r |
128 | signal rdcfg : std_logic;\r |
129 | signal targOE : std_logic;\r |
130 | signal pcidOE : std_logic;\r |
131 | \r |
132 | \r |
133 | begin\r |
134 | \r |
135 | --+-------------------------------------------------------------------------+\r |
136 | --| PCI-Whisbone Sequencer |\r |
137 | --+-------------------------------------------------------------------------+\r |
138 | \r |
139 | \r |
140 | --+-------------------------------------------------------------+\r |
141 | --| FSM PCI-Whisbone |\r |
142 | --+-------------------------------------------------------------+\r |
143 | \r |
144 | PCIFSM_CLOCKED: process( nrst_i, clk_i, nxt_pci )\r |
145 | begin\r |
146 | \r |
147 | if( nrst_i = '0' ) then\r |
148 | pst_pci <= PCIIDLE;\r |
149 | elsif( rising_edge(clk_i) ) then\r |
150 | pst_pci <= nxt_pci; \r |
151 | end if;\r |
152 | \r |
153 | end process PCIFSM_CLOCKED;\r |
154 | \r |
155 | \r |
156 | PCIFSM_COMB: process( pst_pci, frame_i, irdy_i, adrcfg_i, adrpci, acking )\r |
157 | begin\r |
158 | \r |
159 | devselNX_n <= '1';\r |
160 | trdyNX_n <= '1'; \r |
161 | case pst_pci is\r |
162 | \r |
163 | when PCIIDLE =>\r |
164 | if ( frame_i = '0' ) then \r |
165 | nxt_pci <= B_BUSY; \r |
166 | else\r |
167 | nxt_pci <= PCIIDLE;\r |
168 | end if; \r |
169 | \r |
170 | when B_BUSY =>\r |
171 | if ( adrpci = '0' ) then\r |
172 | nxt_pci <= TURN_AR;\r |
173 | else\r |
174 | nxt_pci <= S_DATA1;\r |
175 | devselNX_n <= '0'; \r |
176 | end if;\r |
177 | \r |
178 | when S_DATA1 =>\r |
179 | if ( acking = '1' ) then \r |
180 | nxt_pci <= S_DATA2;\r |
181 | devselNX_n <= '0'; \r |
182 | trdyNX_n <= '0'; \r |
183 | else\r |
184 | nxt_pci <= S_DATA1;\r |
185 | devselNX_n <= '0'; \r |
186 | end if; \r |
187 | \r |
188 | when S_DATA2 => \r |
189 | if ( frame_i = '1' and irdy_i = '0' ) then \r |
190 | nxt_pci <= TURN_AR;\r |
191 | else\r |
192 | nxt_pci <= S_DATA2;\r |
193 | devselNX_n <= '0'; \r |
194 | trdyNX_n <= '0'; \r |
195 | end if; \r |
196 | \r |
197 | when TURN_AR =>\r |
198 | if ( frame_i = '1' ) then\r |
199 | nxt_pci <= PCIIDLE;\r |
200 | else\r |
201 | nxt_pci <= TURN_AR;\r |
202 | end if;\r |
203 | \r |
204 | end case;\r |
205 | \r |
206 | end process PCIFSM_COMB; \r |
207 | \r |
208 | \r |
209 | --+-------------------------------------------------------------+\r |
210 | --| FSM control signals |\r |
211 | --+-------------------------------------------------------------+\r |
212 | \r |
213 | adrpci <= adrmem_i or adrcfg_i;\r |
214 | acking <= '1' when ( wb_ack_i = '1' or wb_err_i = '1' ) or ( adrcfg_i = '1' and irdy_i = '0')\r |
215 | else '0'; \r |
216 | \r |
217 | \r |
218 | --+-------------------------------------------------------------+\r |
219 | --| FSM derived Control signals |\r |
220 | --+-------------------------------------------------------------+\r |
221 | idle <= '1' when ( pst_pci = PCIIDLE ) else '0';\r |
222 | sdata1 <= '1' when ( pst_pci = S_DATA1 ) else '0';\r |
223 | sdata2 <= '1' when ( pst_pci = S_DATA2 ) else '0';\r |
224 | idleNX <= '1' when ( nxt_pci = PCIIDLE ) else '0';\r |
225 | sdata1NX <= '1' when ( nxt_pci = S_DATA1 ) else '0'; \r |
226 | sdata2NX <= '1' when ( nxt_pci = S_DATA2 ) else '0';\r |
227 | turnarNX <= '1' when ( nxt_pci = TURN_AR ) else '0';\r |
228 | \r |
229 | \r |
230 | \r |
231 | --+-------------------------------------------------------------+\r |
232 | --| PCI Data Output Enable |\r |
233 | --+-------------------------------------------------------------+\r |
234 | \r |
235 | PCIDOE_P: process( nrst_i, clk_i, cmd_i(0), sdata1NX, turnarNX )\r |
236 | begin\r |
237 | \r |
238 | if ( nrst_i = '0' ) then \r |
239 | pcidOE <= '0';\r |
240 | elsif ( rising_edge(clk_i) ) then \r |
241 | \r |
242 | if ( sdata1NX = '1' and cmd_i(0) = '0' ) then\r |
243 | pcidOE <= '1';\r |
244 | elsif ( turnarNX = '1' ) then\r |
245 | pcidOE <= '0';\r |
246 | end if; \r |
247 | \r |
248 | end if;\r |
249 | \r |
250 | end process PCIDOE_P;\r |
251 | \r |
252 | pcidOE_o <= pcidOE;\r |
253 | \r |
254 | \r |
255 | --+-------------------------------------------------------------+\r |
256 | --| PAR Output Enable |\r |
257 | --| PCI Read data phase |\r |
258 | --| PAR is valid 1 cicle after data is valid |\r |
259 | --+-------------------------------------------------------------+\r |
260 | \r |
261 | PAROE_P: process( nrst_i, clk_i, cmd_i(0), sdata2NX, turnarNX )\r |
262 | begin\r |
263 | \r |
264 | if ( nrst_i = '0' ) then \r |
265 | parOE_o <= '0';\r |
266 | elsif ( rising_edge(clk_i) ) then \r |
267 | \r |
268 | if ( ( sdata2NX = '1' or turnarNX = '1' ) and cmd_i(0) = '0' ) then\r |
269 | parOE_o <= '1';\r |
270 | else\r |
271 | parOE_o <= '0';\r |
272 | end if; \r |
273 | \r |
274 | end if;\r |
275 | \r |
276 | end process PAROE_P;\r |
277 | \r |
278 | \r |
279 | --+-------------------------------------------------------------+\r |
280 | --| Target s/t/s signals OE control |\r |
281 | --+-------------------------------------------------------------+\r |
282 | \r |
283 | -- targOE <= '1' when ( idle = '0' and adrpci = '1' ) else '0';\r |
284 | TARGOE_P: process( nrst_i, clk_i, sdata1NX, idleNX )\r |
285 | begin\r |
286 | \r |
287 | if ( nrst_i = '0' ) then \r |
288 | targOE <= '0';\r |
289 | elsif ( rising_edge(clk_i) ) then \r |
290 | \r |
291 | if ( sdata1NX = '1' ) then\r |
292 | targOE <= '1';\r |
293 | elsif ( idleNX = '1' ) then\r |
294 | targOE <= '0';\r |
295 | end if; \r |
296 | \r |
297 | end if;\r |
298 | \r |
299 | end process TARGOE_P;\r |
300 | \r |
301 | \r |
302 | --+-------------------------------------------------------------------------+\r |
303 | --| WHISBONE outs |\r |
304 | --+-------------------------------------------------------------------------+\r |
305 | \r |
306 | wb_cyc_o <= '1' when ( adrmem_i = '1' and sdata1 = '1' ) else '0';\r |
307 | wb_stb_o <= '1' when ( adrmem_i = '1' and sdata1 = '1' and irdy_i = '0' ) else '0';\r |
308 | \r |
309 | -- PCI(Little endian) to WB(Big endian)\r |
310 | wb_sel_o(1) <= (not cbe_i(0)) or (not cbe_i(2));\r |
311 | wb_sel_o(0) <= (not cbe_i(1)) or (not cbe_i(3)); \r |
312 | -- \r |
313 | wb_we_o <= cmd_i(0);\r |
314 | \r |
315 | \r |
316 | --+-------------------------------------------------------------------------+\r |
317 | --| Syncronized PCI outs |\r |
318 | --+-------------------------------------------------------------------------+\r |
319 | \r |
320 | PCISIG: process( nrst_i, clk_i, devselNX_n, trdyNX_n)\r |
321 | begin\r |
322 | \r |
323 | if( nrst_i = '0' ) then \r |
324 | devsel <= '1';\r |
325 | trdy <= '1';\r |
326 | elsif( rising_edge(clk_i) ) then \r |
327 | \r |
328 | devsel <= devselNX_n;\r |
329 | trdy <= trdyNX_n;\r |
330 | \r |
331 | end if;\r |
332 | \r |
333 | end process PCISIG;\r |
334 | \r |
335 | devsel_o <= devsel when ( targOE = '1' ) else 'Z';\r |
336 | trdy_o <= trdy when ( targOE = '1' ) else 'Z';\r |
337 | \r |
338 | \r |
339 | --+-------------------------------------------------------------------------+\r |
340 | --| Other outs |\r |
341 | --+-------------------------------------------------------------------------+\r |
342 | \r |
343 | -- rd/wr Configuration Space Registers\r |
344 | wrcfg_o <= '1' when ( adrcfg_i = '1' and cmd_i(0) = '1' and sdata2 = '1' ) else '0';\r |
345 | rdcfg <= '1' when ( adrcfg_i = '1' and cmd_i(0) = '0' and ( sdata1 = '1' or sdata2 = '1' ) ) else '0';\r |
346 | rdcfg_o <= rdcfg;\r |
347 | \r |
348 | -- LoaD enable signals\r |
349 | pciadrLD_o <= not frame_i;\r |
350 | wbdatLD_o <= wb_ack_i;\r |
351 | \r |
352 | -- Mux control signals\r |
353 | wbrgdMX_o <= not rdcfg;\r |
354 | wbd16MX_o <= '1' when ( cbe_i(3) = '0' or cbe_i(2) = '0' ) else '0';\r |
355 | \r |
356 | --+-------------------------------------------------------------------------+\r |
357 | --| debug outs |\r |
358 | --+-------------------------------------------------------------------------+\r |
359 | \r |
360 | process (nrst_i, clk_i)\r |
361 | begin\r |
362 | if ( nrst_i = '0' ) then\r |
363 | debug_init <= '0';\r |
364 | elsif clk_i'event and clk_i = '1' then\r |
365 | if devsel = '0' then\r |
366 | debug_init <= '1';\r |
367 | end if;\r |
368 | end if;\r |
369 | end process; \r |
370 | \r |
371 | process (nrst_i, clk_i)\r |
372 | begin\r |
373 | if ( nrst_i = '0' ) then\r |
374 | debug_access <= '0';\r |
375 | elsif clk_i'event and clk_i = '1' then\r |
376 | if wb_stb_o = '1' then\r |
377 | debug_access <= '1';\r |
378 | end if;\r |
379 | end if;\r |
380 | end process; \r |
381 | \r |
382 | end rtl;\r |