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