]> cvs.zerfleddert.de Git - raggedstone/blob - ethernet/source/pci/pci_master32_sm.v
29fdf0890e7147eca2003dc389830315a4b74654
[raggedstone] / ethernet / source / pci / pci_master32_sm.v
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
Impressum, Datenschutz