OpenCores
URL https://opencores.org/ocsvn/pci/pci/trunk

Subversion Repositories pci

[/] [pci/] [tags/] [rel_6/] [rtl/] [verilog/] [pci_master32_sm.v] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.