]>
Commit | Line | Data |
---|---|---|
40a1f26c | 1 | ////////////////////////////////////////////////////////////////////// |
2 | //// //// | |
3 | //// File name "pci_master32_sm.v" //// | |
4 | //// //// | |
5 | //// This file is part of the "PCI bridge" project //// | |
6 | //// http://www.opencores.org/cores/pci/ //// | |
7 | //// //// | |
8 | //// Author(s): //// | |
9 | //// - Miha Dolenc (mihad@opencores.org) //// | |
10 | //// //// | |
11 | //// All additional information is avaliable in the README //// | |
12 | //// file. //// | |
13 | //// //// | |
14 | //// //// | |
15 | ////////////////////////////////////////////////////////////////////// | |
16 | //// //// | |
17 | //// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// | |
18 | //// //// | |
19 | //// This source file may be used and distributed without //// | |
20 | //// restriction provided that this copyright statement is not //// | |
21 | //// removed from the file and that any derivative work contains //// | |
22 | //// the original copyright notice and the associated disclaimer. //// | |
23 | //// //// | |
24 | //// This source file is free software; you can redistribute it //// | |
25 | //// and/or modify it under the terms of the GNU Lesser General //// | |
26 | //// Public License as published by the Free Software Foundation; //// | |
27 | //// either version 2.1 of the License, or (at your option) any //// | |
28 | //// later version. //// | |
29 | //// //// | |
30 | //// This source is distributed in the hope that it will be //// | |
31 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// | |
32 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// | |
33 | //// PURPOSE. See the GNU Lesser General Public License for more //// | |
34 | //// details. //// | |
35 | //// //// | |
36 | //// You should have received a copy of the GNU Lesser General //// | |
37 | //// Public License along with this source; if not, download it //// | |
38 | //// from http://www.opencores.org/lgpl.shtml //// | |
39 | //// //// | |
40 | ////////////////////////////////////////////////////////////////////// | |
41 | // | |
42 | // CVS Revision History | |
43 | // | |
44 | // $Log: pci_master32_sm.v,v $ | |
45 | // Revision 1.1 2007-03-20 17:50:56 sithglan | |
46 | // add shit | |
47 | // | |
48 | // Revision 1.5 2003/01/27 16:49:31 mihad | |
49 | // Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. | |
50 | // | |
51 | // Revision 1.4 2003/01/21 16:06:56 mihad | |
52 | // Bug fixes, testcases added. | |
53 | // | |
54 | // Revision 1.3 2002/02/01 15:25:12 mihad | |
55 | // Repaired a few bugs, updated specification, added test bench files and design document | |
56 | // | |
57 | // Revision 1.2 2001/10/05 08:14:29 mihad | |
58 | // Updated all files with inclusion of timescale file for simulation purposes. | |
59 | // | |
60 | // Revision 1.1.1.1 2001/10/02 15:33:46 mihad | |
61 | // New project directory structure | |
62 | // | |
63 | // | |
64 | ||
65 | // module includes pci master state machine and surrounding logic | |
66 | ||
67 | // synopsys translate_off | |
68 | `include "timescale.v" | |
69 | // synopsys translate_on | |
70 | `include "pci_constants.v" | |
71 | ||
72 | module pci_master32_sm | |
73 | ( | |
74 | // system inputs | |
75 | clk_in, | |
76 | reset_in, | |
77 | // arbitration | |
78 | pci_req_out, | |
79 | pci_gnt_in, | |
80 | // master in/outs | |
81 | pci_frame_in, | |
82 | pci_frame_out, | |
83 | pci_frame_out_in, | |
84 | pci_frame_load_out, | |
85 | pci_frame_en_in, | |
86 | pci_frame_en_out, | |
87 | pci_irdy_in, | |
88 | pci_irdy_out, | |
89 | pci_irdy_en_out, | |
90 | ||
91 | // target response inputs | |
92 | pci_trdy_in, | |
93 | pci_trdy_reg_in, | |
94 | pci_stop_in, | |
95 | pci_stop_reg_in, | |
96 | pci_devsel_in, | |
97 | pci_devsel_reg_in, | |
98 | ||
99 | // address, data, bus command, byte enable in/outs | |
100 | pci_ad_reg_in, | |
101 | pci_ad_out, | |
102 | pci_ad_en_out, | |
103 | pci_cbe_out, | |
104 | pci_cbe_en_out, | |
105 | ||
106 | // other side of state machine | |
107 | address_in, | |
108 | bc_in, | |
109 | data_in, | |
110 | data_out, | |
111 | be_in, | |
112 | req_in, | |
113 | rdy_in, | |
114 | last_in, | |
115 | next_data_in, | |
116 | next_be_in, | |
117 | next_last_in, | |
118 | ad_load_out, | |
119 | ad_load_on_transfer_out, | |
120 | wait_out, | |
121 | wtransfer_out, | |
122 | rtransfer_out, | |
123 | retry_out, | |
124 | rerror_out, | |
125 | first_out, | |
126 | mabort_out, | |
127 | latency_tim_val_in | |
128 | ) ; | |
129 | ||
130 | // system inputs | |
131 | input clk_in, | |
132 | reset_in ; | |
133 | ||
134 | /*================================================================================================================== | |
135 | PCI interface signals - bidirectional signals are divided to inputs and outputs in I/O cells instantiation | |
136 | module. Enables are separate signals. | |
137 | ==================================================================================================================*/ | |
138 | // arbitration | |
139 | output pci_req_out ; | |
140 | ||
141 | input pci_gnt_in ; | |
142 | ||
143 | // master in/outs | |
144 | input pci_frame_in ; | |
145 | input pci_frame_en_in ; | |
146 | input pci_frame_out_in ; | |
147 | ||
148 | output pci_frame_out, | |
149 | pci_frame_en_out ; | |
150 | ||
151 | output pci_frame_load_out ; | |
152 | ||
153 | input pci_irdy_in ; | |
154 | output pci_irdy_out, | |
155 | pci_irdy_en_out; | |
156 | ||
157 | // target response inputs | |
158 | input pci_trdy_in, | |
159 | pci_trdy_reg_in, | |
160 | pci_stop_in, | |
161 | pci_stop_reg_in, | |
162 | pci_devsel_in, | |
163 | pci_devsel_reg_in ; | |
164 | ||
165 | // address, data, bus command, byte enable in/outs | |
166 | input [31:0] pci_ad_reg_in ; | |
167 | output [31:0] pci_ad_out ; | |
168 | ||
169 | reg [31:0] pci_ad_out ; | |
170 | ||
171 | output pci_ad_en_out ; | |
172 | ||
173 | output [3:0] pci_cbe_out ; | |
174 | ||
175 | reg [3:0] pci_cbe_out ; | |
176 | ||
177 | output pci_cbe_en_out ; | |
178 | ||
179 | input [31:0] address_in ; // current request address input | |
180 | ||
181 | input [3:0] bc_in ; // current request bus command input | |
182 | ||
183 | input [31:0] data_in ; // current dataphase data input | |
184 | ||
185 | output [31:0] data_out ; // for read operations - current request data output | |
186 | ||
187 | reg [31:0] data_out ; | |
188 | ||
189 | input [3:0] be_in ; // current dataphase byte enable inputs | |
190 | ||
191 | input req_in ; // initiator cycle is requested | |
192 | input rdy_in ; // requestor indicates that data is ready to be sent for write transaction and ready to | |
193 | // be received on read transaction | |
194 | input last_in ; // last dataphase in current transaction indicator | |
195 | ||
196 | // status outputs | |
197 | output wait_out, // wait indicates to the backend that dataphases are not in progress on PCI bus | |
198 | wtransfer_out, // on any rising clock edge that this status is 1, data is transferred - heavy constraints here | |
199 | rtransfer_out, // registered transfer indicator - when 1 indicates that data was transfered on previous clock cycle | |
200 | retry_out, // retry status output - when target signals a retry | |
201 | rerror_out, // registered error output - when 1 indicates that error was signalled by a target on previous clock cycle | |
202 | first_out , // indicates whether or not any data was transfered in current transaction | |
203 | mabort_out; // master abort indicator | |
204 | ||
205 | reg wait_out ; | |
206 | ||
207 | // latency timer value input - state machine starts latency timer whenever it starts a transaction and last is not | |
208 | // asserted ( meaning burst transfer ). | |
209 | input [7:0] latency_tim_val_in ; | |
210 | ||
211 | // next data, byte enable and last inputs | |
212 | input [31:0] next_data_in ; | |
213 | input [3:0] next_be_in ; | |
214 | input next_last_in ; | |
215 | ||
216 | // clock enable for data output flip-flops - whenever data is transfered, sm loads next data to those flip flops | |
217 | output ad_load_out, | |
218 | ad_load_on_transfer_out ; | |
219 | ||
220 | // parameters - states - one hot | |
221 | // idle state | |
222 | parameter S_IDLE = 4'h1 ; | |
223 | ||
224 | // address state | |
225 | parameter S_ADDRESS = 4'h2 ; | |
226 | ||
227 | // transfer state - dataphases | |
228 | parameter S_TRANSFER = 4'h4 ; | |
229 | ||
230 | // turn arround state | |
231 | parameter S_TA_END = 4'h8 ; | |
232 | ||
233 | // change state - clock enable for sm state register | |
234 | wire change_state ; | |
235 | // next state for state machine | |
236 | reg [3:0] next_state ; | |
237 | // SM state register | |
238 | reg [3:0] cur_state ; | |
239 | ||
240 | // variables for indicating which state state machine is in | |
241 | // this variables are used to reduce logic levels in case of heavily constrained PCI signals | |
242 | reg sm_idle ; | |
243 | reg sm_address ; | |
244 | reg sm_data_phases ; | |
245 | reg sm_turn_arround ; | |
246 | ||
247 | // state machine register control logic with clock enable | |
248 | always@(posedge reset_in or posedge clk_in) | |
249 | begin | |
250 | if (reset_in) | |
251 | cur_state <= #`FF_DELAY S_IDLE ; | |
252 | else | |
253 | if ( change_state ) | |
254 | cur_state <= #`FF_DELAY next_state ; | |
255 | end | |
256 | ||
257 | // parameters - data selector - ad and bc lines switch between address/data and bus command/byte enable respectively | |
258 | parameter SEL_ADDR_BC = 2'b01 ; | |
259 | parameter SEL_DATA_BE = 2'b00 ; | |
260 | parameter SEL_NEXT_DATA_BE = 2'b11 ; | |
261 | ||
262 | reg [1:0] wdata_selector ; | |
263 | ||
264 | wire u_dont_have_pci_bus = pci_gnt_in || ~pci_frame_in || ~pci_irdy_in ; // pci master can't start a transaction when GNT is deasserted ( 1 ) or | |
265 | // bus is not in idle state ( FRAME and IRDY both 1 ) | |
266 | wire u_have_pci_bus = ~pci_gnt_in && pci_frame_in && pci_irdy_in ; | |
267 | ||
268 | // decode count enable - counter that counts cycles passed since address phase | |
269 | wire sm_decode_count_enable = sm_data_phases ; // counter is enabled when master wants to transfer | |
270 | wire decode_count_enable = sm_decode_count_enable && pci_trdy_in && pci_stop_in && pci_devsel_in ; // and target is not responding | |
271 | wire decode_count_load = ~decode_count_enable ; | |
272 | reg [2:0] decode_count ; | |
273 | ||
274 | wire decode_to = ~( decode_count[2] || decode_count[1]) ; | |
275 | ||
276 | always@(posedge reset_in or posedge clk_in) | |
277 | begin | |
278 | if ( reset_in ) | |
279 | // initial value of counter is 4 | |
280 | decode_count <= #`FF_DELAY 3'h4 ; | |
281 | else | |
282 | if ( decode_count_load ) | |
283 | decode_count <= #`FF_DELAY 3'h4 ; | |
284 | else | |
285 | if ( decode_count_enable ) | |
286 | decode_count <= #`FF_DELAY decode_count - 1'b1 ; | |
287 | end | |
288 | ||
289 | // Bus commands LSbit indicates whether operation is a read or a write | |
290 | wire do_write = bc_in[0] ; | |
291 | ||
292 | // latency timer | |
293 | reg [7:0] latency_timer ; | |
294 | ||
295 | wire latency_time_out = ~( | |
296 | (latency_timer[7] || latency_timer[6] || latency_timer[5] || latency_timer[4]) || | |
297 | (latency_timer[3] || latency_timer[2] || latency_timer[1] ) | |
298 | ) ; | |
299 | ||
300 | wire latency_timer_enable = (sm_address || sm_data_phases) && ~latency_time_out ; | |
301 | wire latency_timer_load = ~sm_address && ~sm_data_phases ; | |
302 | ||
303 | always@(posedge clk_in or posedge reset_in) | |
304 | begin | |
305 | if (reset_in) | |
306 | latency_timer <= #`FF_DELAY 8'h00 ; | |
307 | else | |
308 | if ( latency_timer_load ) | |
309 | latency_timer <= #`FF_DELAY latency_tim_val_in ; | |
310 | else | |
311 | if ( latency_timer_enable) // latency timer counts down until it expires - then it stops | |
312 | latency_timer <= #`FF_DELAY latency_timer - 1'b1 ; | |
313 | end | |
314 | ||
315 | // master abort indicators - when decode time out occurres and still no target response is received | |
316 | wire do_master_abort = decode_to && pci_trdy_in && pci_stop_in && pci_devsel_in ; | |
317 | reg mabort1 ; | |
318 | always@(posedge reset_in or posedge clk_in) | |
319 | begin | |
320 | if (reset_in) | |
321 | mabort1 <= #`FF_DELAY 1'b0 ; | |
322 | else | |
323 | mabort1 <= #`FF_DELAY do_master_abort ; | |
324 | end | |
325 | ||
326 | reg mabort2 ; | |
327 | always@(posedge reset_in or posedge clk_in) | |
328 | begin | |
329 | if ( reset_in ) | |
330 | mabort2 <= #`FF_DELAY 1'b0 ; | |
331 | else | |
332 | mabort2 <= #`FF_DELAY mabort1 ; | |
333 | end | |
334 | ||
335 | // master abort is only asserted for one clock cycle | |
336 | assign mabort_out = mabort1 && ~mabort2 ; | |
337 | ||
338 | // register indicating when master should do timeout termination (latency timer expires) | |
339 | reg timeout ; | |
340 | always@(posedge reset_in or posedge clk_in) | |
341 | begin | |
342 | if (reset_in) | |
343 | timeout <= #`FF_DELAY 1'b0 ; | |
344 | else | |
345 | timeout <= #`FF_DELAY (latency_time_out && ~pci_frame_out_in && pci_gnt_in || timeout ) && ~wait_out ; | |
346 | end | |
347 | ||
348 | wire timeout_termination = sm_turn_arround && timeout && pci_stop_reg_in ; | |
349 | ||
350 | // frame control logic | |
351 | // frame is forced to 0 (active) when state machine is in idle state, since only possible next state is address state which always drives frame active | |
352 | wire force_frame = ~sm_idle ; | |
353 | // slow signal for frame calculated from various registers in the core | |
354 | wire slow_frame = last_in || (latency_time_out && pci_gnt_in) || (next_last_in && sm_data_phases) || mabort1 ; | |
355 | // critical timing frame logic in separate module - some combinations of target signals force frame to inactive state immediately after sampled asserted | |
356 | // (STOP) | |
357 | pci_frame_crit frame_iob_feed | |
358 | ( | |
359 | .pci_frame_out (pci_frame_out), | |
360 | .force_frame_in (force_frame), | |
361 | .slow_frame_in (slow_frame), | |
362 | .pci_stop_in (pci_stop_in) | |
363 | ) ; | |
364 | ||
365 | // frame IOB flip flop's clock enable signal | |
366 | // slow clock enable - calculated from internal - non critical paths | |
367 | wire frame_load_slow = sm_idle || sm_address || mabort1 ; | |
368 | ||
369 | // critical clock enable for frame IOB in separate module - target response signals actually allow frame value change - critical timing | |
370 | pci_frame_load_crit frame_iob_ce | |
371 | ( | |
372 | .pci_frame_load_out (pci_frame_load_out), | |
373 | .sm_data_phases_in (sm_data_phases), | |
374 | .frame_load_slow_in (frame_load_slow), | |
375 | .pci_trdy_in (pci_trdy_in), | |
376 | .pci_stop_in (pci_stop_in) | |
377 | ) ; | |
378 | ||
379 | // IRDY driving | |
380 | // non critical path for IRDY calculation | |
381 | wire irdy_slow = pci_frame_out_in && mabort1 || mabort2 ; | |
382 | ||
383 | // critical path in separate module | |
384 | pci_irdy_out_crit irdy_iob_feed | |
385 | ( | |
386 | .pci_irdy_out (pci_irdy_out), | |
387 | .irdy_slow_in (irdy_slow), | |
388 | .pci_frame_out_in (pci_frame_out_in), | |
389 | .pci_trdy_in (pci_trdy_in), | |
390 | .pci_stop_in (pci_stop_in) | |
391 | ) ; | |
392 | ||
393 | // transfer FF indicator - when first transfer occurs it is set to 1 so backend can distinguish between disconnects and retries. | |
394 | wire sm_transfer = sm_data_phases ; | |
395 | reg transfer ; | |
396 | ||
397 | wire transfer_input = sm_transfer && (~(pci_trdy_in || pci_devsel_in) || transfer) ; | |
398 | ||
399 | always@(posedge clk_in or posedge reset_in) | |
400 | begin | |
401 | if (reset_in) | |
402 | transfer <= #`FF_DELAY 1'b0 ; | |
403 | else | |
404 | transfer <= #`FF_DELAY transfer_input ; | |
405 | end | |
406 | ||
407 | assign first_out = ~transfer ; | |
408 | ||
409 | // fast transfer status output - it's only negated target ready, since wait indicator qualifies valid transfer | |
410 | assign wtransfer_out = ~pci_trdy_in ; | |
411 | ||
412 | // registered transfer status output - calculated from registered target response inputs | |
413 | assign rtransfer_out = ~(pci_trdy_reg_in || pci_devsel_reg_in) ; | |
414 | ||
415 | // registered error status - calculated from registered target response inputs | |
416 | assign rerror_out = (~pci_stop_reg_in && pci_devsel_reg_in) ; | |
417 | ||
418 | // retry is signalled to backend depending on registered target response or when latency timer expires | |
419 | assign retry_out = timeout_termination || (~pci_stop_reg_in && ~pci_devsel_reg_in) ; | |
420 | ||
421 | // AD output flip flops' clock enable | |
422 | // new data is loaded to AD outputs whenever state machine is idle, bus was granted and bus is in idle state or | |
423 | // when address phase is about to be finished | |
424 | wire ad_load_slow = sm_address ; | |
425 | wire ad_load_on_grant = sm_idle && pci_frame_in && pci_irdy_in ; | |
426 | ||
427 | pci_mas_ad_load_crit mas_ad_load_feed | |
428 | ( | |
429 | .ad_load_out (ad_load_out), | |
430 | .ad_load_in (ad_load_slow), | |
431 | .ad_load_on_grant_in (ad_load_on_grant), | |
432 | .pci_gnt_in (pci_gnt_in) | |
433 | ); | |
434 | ||
435 | // next data loading is allowed when state machine is in transfer state and operation is a write | |
436 | assign ad_load_on_transfer_out = sm_data_phases && do_write ; | |
437 | ||
438 | // request for a bus is issued anytime when backend is requesting a transaction and state machine is in idle state | |
439 | assign pci_req_out = ~(req_in && sm_idle) ; | |
440 | ||
441 | // change state signal is actually clock enable for state register | |
442 | // Non critical path for state change enable: | |
443 | // state is always changed when: | |
444 | // - address phase is finishing | |
445 | // - state machine is in turn arround state | |
446 | // - state machine is in transfer state and master abort termination is in progress | |
447 | ||
448 | wire ch_state_slow = sm_address || sm_turn_arround || sm_data_phases && ( pci_frame_out_in && mabort1 || mabort2 ) ; | |
449 | ||
450 | // a bit more critical change state enable is calculated with GNT signal | |
451 | wire ch_state_med = ch_state_slow || sm_idle && u_have_pci_bus && req_in && rdy_in ; | |
452 | ||
453 | // most critical change state enable - calculated from target response signals | |
454 | pci_mas_ch_state_crit state_machine_ce | |
455 | ( | |
456 | .change_state_out (change_state), | |
457 | .ch_state_med_in (ch_state_med), | |
458 | .sm_data_phases_in (sm_data_phases), | |
459 | .pci_trdy_in (pci_trdy_in), | |
460 | .pci_stop_in (pci_stop_in) | |
461 | ) ; | |
462 | ||
463 | // ad enable driving | |
464 | // also divided in several categories - from less critical to most critical in separate module | |
465 | //wire ad_en_slowest = do_write && (sm_address || sm_data_phases && ~pci_frame_out_in) ; | |
466 | //wire ad_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ; | |
467 | //wire ad_en_slow = ad_en_on_grant && ~pci_gnt_in || ad_en_slowest ; | |
468 | //wire ad_en_keep = sm_data_phases && do_write && (pci_frame_out_in && ~mabort1 && ~mabort2) ; | |
469 | ||
470 | wire ad_en_slow = do_write && ( sm_address || ( sm_data_phases && !( ( pci_frame_out_in && mabort1 ) || mabort2 ) ) ) ; | |
471 | wire ad_en_on_grant = ( sm_idle && pci_frame_in && pci_irdy_in ) || sm_turn_arround ; | |
472 | ||
473 | // critical timing ad enable - calculated from grant input | |
474 | pci_mas_ad_en_crit ad_iob_oe_feed | |
475 | ( | |
476 | .pci_ad_en_out (pci_ad_en_out), | |
477 | .ad_en_slow_in (ad_en_slow), | |
478 | .ad_en_on_grant_in (ad_en_on_grant), | |
479 | .pci_gnt_in (pci_gnt_in) | |
480 | ) ; | |
481 | ||
482 | // cbe enable driving | |
483 | wire cbe_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ; | |
484 | wire cbe_en_slow = cbe_en_on_grant && ~pci_gnt_in || sm_address || sm_data_phases && ~pci_frame_out_in ; | |
485 | wire cbe_en_keep = sm_data_phases && pci_frame_out_in && ~mabort1 && ~mabort2 ; | |
486 | ||
487 | // most critical cbe enable in separate module - calculated with most critical target inputs | |
488 | pci_cbe_en_crit cbe_iob_feed | |
489 | ( | |
490 | .pci_cbe_en_out (pci_cbe_en_out), | |
491 | .cbe_en_slow_in (cbe_en_slow), | |
492 | .cbe_en_keep_in (cbe_en_keep), | |
493 | .pci_stop_in (pci_stop_in), | |
494 | .pci_trdy_in (pci_trdy_in) | |
495 | ||
496 | ) ; | |
497 | ||
498 | // IRDY enable is equal to FRAME enable delayed for one clock | |
499 | assign pci_irdy_en_out = pci_frame_en_in ; | |
500 | ||
501 | // frame enable driving - sometimes it's calculated from non critical paths | |
502 | wire frame_en_slow = (sm_idle && u_have_pci_bus && req_in && rdy_in) || sm_address || (sm_data_phases && ~pci_frame_out_in) ; | |
503 | wire frame_en_keep = sm_data_phases && pci_frame_out_in && ~mabort1 && ~mabort2 ; | |
504 | ||
505 | // most critical frame enable - calculated from heavily constrained target inputs in separate module | |
506 | pci_frame_en_crit frame_iob_en_feed | |
507 | ( | |
508 | .pci_frame_en_out (pci_frame_en_out), | |
509 | .frame_en_slow_in (frame_en_slow), | |
510 | .frame_en_keep_in (frame_en_keep), | |
511 | .pci_stop_in (pci_stop_in), | |
512 | .pci_trdy_in (pci_trdy_in) | |
513 | ) ; | |
514 | ||
515 | // state machine next state definitions | |
516 | always@( | |
517 | cur_state or | |
518 | do_write or | |
519 | pci_frame_out_in | |
520 | ) | |
521 | begin | |
522 | // default values for state machine outputs | |
523 | wait_out = 1'b1 ; | |
524 | wdata_selector = SEL_ADDR_BC ; | |
525 | sm_idle = 1'b0 ; | |
526 | sm_address = 1'b0 ; | |
527 | sm_data_phases = 1'b0 ; | |
528 | sm_turn_arround = 1'b0 ; | |
529 | ||
530 | case ( cur_state ) | |
531 | ||
532 | S_IDLE: begin | |
533 | // indicate the state | |
534 | sm_idle = 1'b1 ; | |
535 | // assign next state - only possible is address - if state machine is supposed to stay in idle state | |
536 | // outside signals disable the clock | |
537 | next_state = S_ADDRESS ; | |
538 | wdata_selector = SEL_DATA_BE ; | |
539 | end | |
540 | ||
541 | S_ADDRESS: begin | |
542 | // indicate the state | |
543 | sm_address = 1'b1 ; | |
544 | // select appropriate data/be for outputs | |
545 | wdata_selector = SEL_NEXT_DATA_BE ; | |
546 | // only possible next state is transfer state | |
547 | next_state = S_TRANSFER ; | |
548 | end | |
549 | ||
550 | S_TRANSFER: begin | |
551 | // during transfers wait indicator is inactive - all status signals are now valid | |
552 | wait_out = 1'b0 ; | |
553 | // indicate the state | |
554 | sm_data_phases = 1'b1 ; | |
555 | // select appropriate data/be for outputs | |
556 | wdata_selector = SEL_NEXT_DATA_BE ; | |
557 | if ( pci_frame_out_in ) | |
558 | begin | |
559 | // when frame is inactive next state will be turn arround | |
560 | next_state = S_TA_END ; | |
561 | end | |
562 | else | |
563 | // while frame is active state cannot be anything else then transfer | |
564 | next_state = S_TRANSFER ; | |
565 | end | |
566 | ||
567 | S_TA_END: begin | |
568 | // wait is still inactive because of registered statuses | |
569 | wait_out = 1'b0 ; | |
570 | // indicate the state | |
571 | sm_turn_arround = 1'b1 ; | |
572 | // next state is always idle | |
573 | next_state = S_IDLE ; | |
574 | end | |
575 | default: next_state = S_IDLE ; | |
576 | endcase | |
577 | end | |
578 | ||
579 | // ad and cbe lines multiplexer for write data | |
580 | reg [1:0] rdata_selector ; | |
581 | always@(posedge clk_in or posedge reset_in) | |
582 | begin | |
583 | if ( reset_in ) | |
584 | rdata_selector <= #`FF_DELAY SEL_ADDR_BC ; | |
585 | else | |
586 | if ( change_state ) | |
587 | rdata_selector <= #`FF_DELAY wdata_selector ; | |
588 | end | |
589 | ||
590 | always@(rdata_selector or address_in or bc_in or data_in or be_in or next_data_in or next_be_in) | |
591 | begin | |
592 | case ( rdata_selector ) | |
593 | SEL_ADDR_BC: begin | |
594 | pci_ad_out = address_in ; | |
595 | pci_cbe_out = bc_in ; | |
596 | end | |
597 | ||
598 | SEL_DATA_BE: begin | |
599 | pci_ad_out = data_in ; | |
600 | pci_cbe_out = be_in ; | |
601 | end | |
602 | SEL_NEXT_DATA_BE, | |
603 | 2'b10: begin | |
604 | pci_ad_out = next_data_in ; | |
605 | pci_cbe_out = next_be_in ; | |
606 | end | |
607 | endcase | |
608 | end | |
609 | ||
610 | // data output mux for reads | |
611 | always@(mabort_out or pci_ad_reg_in) | |
612 | begin | |
613 | if ( mabort_out ) | |
614 | data_out = 32'hFFFF_FFFF ; | |
615 | else | |
616 | data_out = pci_ad_reg_in ; | |
617 | end | |
618 | endmodule |