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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_6/] [rtl/] [verilog/] [pci_master32_sm_if.v] - Blame information for rev 77

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_if.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 77 mihad
// Revision 1.3  2002/02/01 15:25:12  mihad
46
// Repaired a few bugs, updated specification, added test bench files and design document
47
//
48 21 mihad
// Revision 1.2  2001/10/05 08:14:29  mihad
49
// Updated all files with inclusion of timescale file for simulation purposes.
50
//
51 6 mihad
// Revision 1.1.1.1  2001/10/02 15:33:46  mihad
52
// New project directory structure
53 2 mihad
//
54 6 mihad
//
55 2 mihad
 
56 21 mihad
`include "pci_constants.v"
57 2 mihad
`include "bus_commands.v"
58 21 mihad
 
59
// synopsys translate_off
60 6 mihad
`include "timescale.v"
61 21 mihad
// synopsys translate_on
62 2 mihad
 
63
/*====================================================================
64
Module provides interface between PCI bridge internals and PCI master
65
state machine
66
====================================================================*/
67 77 mihad
module pci_master32_sm_if
68 2 mihad
(
69
    clk_in,
70
    reset_in,
71 21 mihad
 
72 2 mihad
    // interconnect to pci master state machine
73
    address_out,
74
    bc_out,
75
    data_out,
76
    data_in,
77
    be_out,
78
    req_out,
79
    rdy_out,
80
    last_out,
81 21 mihad
 
82 2 mihad
    next_data_out,
83
    next_be_out,
84
    next_last_out,
85
 
86
    // status inputs from master SM
87
    wait_in,
88
    wtransfer_in,
89
    rtransfer_in,
90
    retry_in,
91
    rerror_in,
92
    first_in ,
93
    mabort_in,
94
 
95
 
96
    // WISHBONE WRITE fifo inputs and outputs
97
    wbw_renable_out,
98
    wbw_fifo_addr_data_in,
99
    wbw_fifo_cbe_in,
100
    wbw_fifo_control_in,
101
    wbw_fifo_empty_in,
102
    wbw_fifo_transaction_ready_in,
103 21 mihad
 
104 2 mihad
    // WISHBONE READ fifo inputs and outputs
105
    wbr_fifo_wenable_out,
106
    wbr_fifo_data_out,
107
    wbr_fifo_be_out,
108
    wbr_fifo_control_out,
109
 
110
    // delayed transaction control logic inputs and outputs
111
    del_wdata_in,
112
    del_complete_out,
113
    del_req_in,
114
    del_addr_in,
115
    del_bc_in,
116
    del_be_in,
117
    del_burst_in,
118
    del_error_out,
119
    del_rty_exp_out,
120
    del_we_in,
121
 
122
    // configuration space interconnect
123
    // error reporting
124
    err_addr_out,
125
    err_bc_out,
126
    err_signal_out,
127
    err_source_out,
128
    err_rty_exp_out,
129
 
130
    cache_line_size_in,
131 21 mihad
 
132
    // two signals for pci control and status
133 2 mihad
    mabort_received_out,
134 21 mihad
    tabort_received_out,
135
 
136
    posted_write_not_present_out
137 2 mihad
);
138
 
139
// system inputs
140
input clk_in ;
141
input reset_in ;
142
 
143
// PCI master state machine interconnect
144
output  [31:0]  address_out ;   // address output
145
 
146
output  [3:0]   bc_out ;        // bus command output
147 21 mihad
reg     [3:0]   bc_out ;
148 2 mihad
 
149
output  [31:0]  data_out ;      // data output for writes
150
reg     [31:0]  data_out ;
151
 
152
input   [31:0]  data_in ;       // data input for reads
153
output  [3:0]   be_out  ;       // byte enable output
154 21 mihad
reg     [3:0]   be_out  ;
155 2 mihad
 
156
output          req_out ;       // request output
157
 
158
output          rdy_out ;       // ready output
159
reg             rdy_out ;
160
 
161
output          last_out ;      // last data indicator output
162
 
163
output  [31:0]  next_data_out ; // next data output
164
output  [3:0]   next_be_out ;   // next byte enable output
165
output          next_last_out ; // next transfer last indicator
166
 
167
input           wait_in,
168
                wtransfer_in,
169
                rtransfer_in,
170
                retry_in,
171
                rerror_in,
172
                first_in ,
173
                mabort_in ;
174
 
175
// WISHBONE write fifo interconnect
176
output          wbw_renable_out ;          // WBW_FIFO read enable signal
177
 
178
input   [31:0]  wbw_fifo_addr_data_in ;         // WBW_FIFO address/data bus
179
input   [3:0]   wbw_fifo_cbe_in ;               // WBW_FIFO command/byte enable bus
180
input   [3:0]   wbw_fifo_control_in ;           // WBW_FIFO control bus
181
input           wbw_fifo_empty_in ;             // WBW_FIFO's empty status indicator
182
input           wbw_fifo_transaction_ready_in ; // WBW_FIFO transaction ready indicator
183
 
184
// WISHBONE read FIFO interconnect
185
output          wbr_fifo_wenable_out ;          // write enable for WBR_FIFO
186
 
187
output  [31:0]  wbr_fifo_data_out ;             // data output to WBR_FIFO
188
 
189
output  [3:0]   wbr_fifo_be_out ;               // byte enable output for WBR_FIFO
190
 
191
output  [3:0]   wbr_fifo_control_out ;          // WBR_FIFO control output
192
 
193
// delayed transaction control logic inputs and outputs
194
input   [31:0]  del_wdata_in ;                  // delayed write data input
195
output          del_complete_out ;              // delayed transaction completed output
196
 
197
input           del_req_in ;                    // delayed transaction request
198
input   [31:0]  del_addr_in ;                   // delayed transaction address
199
input   [3:0]   del_bc_in ;                     // delayed transaction bus command input
200
input   [3:0]   del_be_in ;                     // delayed transaction byte enables input
201
input           del_burst_in ;                  // delayed transaction burst req. indicator
202
output          del_error_out ;                 // delayed transation error termination signal
203
 
204
output          del_rty_exp_out ;               // retry expired output for delayed transactions
205
 
206
input           del_we_in ;                     // delayed write request indicator
207
 
208
output  [31:0]  err_addr_out ;                  // erroneous address output
209
output  [3:0]   err_bc_out ;                    // erroneous bus command output
210
 
211
output          err_signal_out ;                // error signalization
212
 
213
output          err_source_out ;                // error source indicator
214
 
215
input   [7:0]   cache_line_size_in ;            // cache line size value input
216
 
217
output          err_rty_exp_out ;               // retry expired error output
218
 
219
output          mabort_received_out ;           // master abort signaled to status register
220
output          tabort_received_out ;           // target abort signaled to status register
221
 
222 21 mihad
output          posted_write_not_present_out ;  // used in target state machine - must deny read completions when this signal is 0
223 2 mihad
 
224 21 mihad
 
225 2 mihad
assign err_bc_out   = bc_out ;
226
 
227
// assign read outputs
228
/*==================================================================================================================
229
WISHBONE read FIFO data outputs - just link them to SM data outputs and delayed BE input
230
==================================================================================================================*/
231
assign wbr_fifo_data_out = data_in ;
232
assign wbr_fifo_be_out   = del_be_in ;
233
 
234
// decode if current bus command is configuration command
235
wire conf_cyc_bc = ( bc_out[3:1] == `BC_CONF_RW ) ;
236
 
237
// register for indicating that current data is also last in transfer
238
reg current_last ;
239
 
240
// register indicating that last data was transfered OK
241
reg last_transfered ;
242
always@(posedge reset_in or posedge clk_in)
243
begin
244
    if (reset_in)
245
        last_transfered <= #`FF_DELAY 1'b0 ;
246
    else
247
        last_transfered <= #`FF_DELAY ~wait_in && last_out && wtransfer_in ;
248
end
249
 
250
// status signals output assignement
251
assign mabort_received_out = mabort_in ;
252
 
253
wire tabort_ff_in = ~wait_in && rerror_in ;
254
 
255
reg    tabort_received_out ;
256
always@(posedge reset_in or posedge clk_in)
257
begin
258
    if ( reset_in )
259
        tabort_received_out <= #`FF_DELAY 1'b0 ;
260
    else
261
        tabort_received_out <= #`FF_DELAY tabort_ff_in ;
262
end
263
 
264
// error recovery indicator
265
reg err_recovery ;
266
 
267
// operation is locked until error recovery is in progress or error bit is not cleared in configuration space
268 21 mihad
wire err_lock = err_recovery ;
269 2 mihad
 
270
// three requests are possible - posted write, delayed write and delayed read
271
reg del_write_req ;
272
reg posted_write_req ;
273
reg del_read_req ;
274
 
275
// assign request output
276
assign req_out = del_write_req || posted_write_req || del_read_req ;
277
 
278 21 mihad
// posted write is not present, when WB Write Fifo is empty and posted write transaction is not beeing requested at present time
279
assign posted_write_not_present_out = !posted_write_req && wbw_fifo_empty_in ;
280
 
281 2 mihad
// write requests are staged, so data is read from source into current data register and next data register
282
reg write_req_int ;
283
always@(posedge reset_in or posedge clk_in)
284
begin
285
    if ( reset_in )
286
        write_req_int <= #`FF_DELAY 1'b0 ;
287
    else
288
        write_req_int <= #`FF_DELAY posted_write_req || del_write_req ;
289
 
290
end
291
 
292
// ready output is generated one clock after request for reads and two after for writes
293
always@(posedge reset_in or posedge clk_in)
294
begin
295
    if (reset_in)
296
        rdy_out <= #`FF_DELAY 1'b0 ;
297
    else
298
        rdy_out <= #`FF_DELAY del_read_req || ( (posted_write_req || del_write_req) && write_req_int) ;
299
end
300
 
301
// wires with logic used as inputs to request FFs
302
wire do_posted_write = ( wbw_fifo_transaction_ready_in && ~wbw_fifo_empty_in && ~err_lock ) ;
303
wire do_del          = ( del_req_in && ~err_lock && wbw_fifo_empty_in ) ;
304
wire do_del_write    = do_del &&  del_we_in ;
305
wire do_del_read     = do_del && ~del_we_in ;
306
 
307
// register for indicating current operation's data source
308
parameter DELAYED_WRITE = 1'b1 ;
309
parameter POSTED_WRITE  = 1'b0 ;
310
 
311
// new data source - depending on which transaction will be processed next - delayed read is here because source of byte enables must
312
// be specified for delayed reads also - data source is not relevant for delayed reads, so value is don't care anyway
313
wire new_data_source = (do_del_write || do_del_read) ? DELAYED_WRITE : POSTED_WRITE ; // input to data source register
314
wire data_source_change = ~req_out ;    // change (enable) for data source register - when no requests are in progress
315
 
316
reg data_source ;           // data source value
317
always@(posedge reset_in or posedge clk_in)
318
begin
319
    if (reset_in)
320
        // default value is posted write source - wbw_fifo
321
        data_source <= #`FF_DELAY POSTED_WRITE ;
322
    else
323
    if (data_source_change)
324
        // change data source on rising clock edge
325
        data_source <= #`FF_DELAY new_data_source ;
326
end
327
 
328
// multiplexer for data output to PCI MASTER state machine
329
reg [31:0] source_data ;
330
reg [3:0]  source_be ;
331 21 mihad
always@(data_source or wbw_fifo_addr_data_in or wbw_fifo_cbe_in or del_wdata_in or del_be_in or del_burst_in)
332 2 mihad
begin
333
    case (data_source)
334
        POSTED_WRITE:   begin
335
                            source_data = wbw_fifo_addr_data_in ;
336
                            source_be   = wbw_fifo_cbe_in ;
337
                        end
338
        DELAYED_WRITE:  begin
339
                            source_data = del_wdata_in ;
340 21 mihad
                            // read all bytes during delayed burst read!
341
                            source_be   = ~( del_be_in | {4{del_burst_in}} ) ;
342 2 mihad
                        end
343
    endcase
344
end
345
 
346
wire            waddr =  wbw_fifo_control_in[`ADDR_CTRL_BIT] ;
347
 
348
// address change indicator - address is allowed to be loaded only when no transaction is in progress!
349
wire            address_change = ~req_out ; // address change - whenever there is no request in progress
350
 
351
// new address - input to register storing address of current request - if posted write request will be next,
352
// load address and bus command from wbw_fifo, else load data from delayed transaction logic
353
wire     [31:0] new_address = ( ~req_out && do_posted_write ) ? wbw_fifo_addr_data_in[31:0] : del_addr_in[31:0] ;
354
wire     [3:0]  new_bc      = ( ~req_out && do_posted_write ) ? wbw_fifo_cbe_in : del_bc_in ;
355
 
356
// address counter enable - only for posted writes when data is actually transfered
357 21 mihad
wire addr_count_en = ~wait_in && posted_write_req && rtransfer_in ;
358 2 mihad
 
359
always@(posedge reset_in or posedge clk_in)
360
begin
361
    if (reset_in)
362
        bc_out <= #`FF_DELAY `BC_RESERVED0 ;
363
    else
364
    if (address_change)
365
        bc_out <= #`FF_DELAY new_bc ;
366 21 mihad
end
367 2 mihad
 
368 21 mihad
reg [29:0] current_dword_address ;
369 2 mihad
 
370
// DWORD address counter with load
371
always@(posedge reset_in or posedge clk_in)
372
begin
373
    if (reset_in)
374
        current_dword_address <= #`FF_DELAY 30'h0000_0000 ;
375
    else
376
    if (address_change)
377
        current_dword_address <= #`FF_DELAY new_address[31:2] ;
378
    else
379
    if (addr_count_en)
380
        current_dword_address <= #`FF_DELAY current_dword_address + 1'b1 ;
381 21 mihad
end
382 2 mihad
 
383
reg [1:0] current_byte_address ;
384
always@(posedge reset_in or posedge clk_in)
385
begin
386
    if (reset_in)
387
        current_byte_address <= #`FF_DELAY 2'b00 ;
388
    else
389
    if (address_change)
390
        current_byte_address <= #`FF_DELAY new_address[1:0] ;
391 21 mihad
end
392 2 mihad
 
393
// address output to PCI master state machine assignement
394
assign address_out  = { current_dword_address, current_byte_address } ;
395
 
396
// the same for erroneous address assignement
397
assign err_addr_out = { current_dword_address, current_byte_address } ;
398
 
399
// cacheline size counter - for read transaction length control
400
// cache line count is enabled during burst reads when data is actually transfered
401
wire read_count_enable = ~wait_in && del_read_req && del_burst_in && wtransfer_in  ;
402
 
403
// cache line counter is loaded when del read request is not in progress
404 21 mihad
wire read_count_load   = ~del_read_req ;
405 2 mihad
 
406 21 mihad
reg [(`WBR_ADDR_LENGTH - 1):0] max_read_count ;
407 2 mihad
always@(cache_line_size_in or del_bc_in)
408
begin
409
    if ( (cache_line_size_in >= `WBR_DEPTH) || (~del_bc_in[1] && ~del_bc_in[0]) )
410
        max_read_count = `WBR_DEPTH - 1'b1;
411
    else
412
        max_read_count = cache_line_size_in ;
413
end
414
 
415 21 mihad
reg [(`WBR_ADDR_LENGTH - 1):0] read_count ;
416 2 mihad
 
417
// cache line bound indicator - it signals when data for one complete cacheline was read
418 21 mihad
wire read_bound_comb = ~|(read_count[(`WBR_ADDR_LENGTH - 1):2]) ;
419 2 mihad
reg  read_bound ;
420 21 mihad
always@(posedge clk_in or posedge reset_in)
421 2 mihad
begin
422 21 mihad
    if ( reset_in )
423 2 mihad
        read_bound <= #`FF_DELAY 1'b0 ;
424 21 mihad
    else if (read_count_load)
425
        read_bound <= #`FF_DELAY 1'b0 ;
426 2 mihad
    else if ( read_count_enable )
427
        read_bound <= #`FF_DELAY read_bound_comb ;
428
end
429
 
430
// down counter with load
431
always@(posedge reset_in or posedge clk_in)
432
begin
433
    if (reset_in)
434 21 mihad
        read_count <= #`FF_DELAY 0 ;
435 2 mihad
    else
436
    if (read_count_load)
437
        read_count <= #`FF_DELAY max_read_count ;
438
    else
439
    if (read_count_enable)
440
        read_count <= #`FF_DELAY read_count - 1'b1 ;
441 21 mihad
 
442 2 mihad
end
443
 
444
// flip flop indicating error recovery is in progress
445
reg err_recovery_in ;
446
always@(posedge reset_in or posedge clk_in)
447
begin
448
    if (reset_in)
449
        err_recovery <= #`FF_DELAY 1'b0 ;
450
    else
451
        err_recovery <= #`FF_DELAY err_recovery_in ;
452
end
453
 
454
/*// retry counter implementation
455
reg [7:0] retry_count ;
456
 
457
wire retry_expired = ~|(retry_count[7:1]) ;
458
 
459
// loading of retry counter - whenever no request is present or other termination than retry or wait is signalled
460
wire retry_load = ~req_out || (~wait_in && rtransfer_in) ;
461
 
462
// retry DOWN counter with load
463
always@(posedge reset_in or posedge clk_in)
464
begin
465
    if (reset_in)
466
        retry_count <= #`FF_DELAY 8'hFF ;
467
    else
468
    if ( retry_load )
469
        retry_count <= #`FF_DELAY `PCI_RTY_CNT_MAX ;
470
    else
471
    if (retry_in)
472
        retry_count <= #`FF_DELAY retry_count - 1'b1 ;
473
end*/
474
 
475
/*==================================================================================================================
476
Delayed write requests are always single transfers!
477
Delayed write request starts, when no request is currently beeing processed and it is signaled from other side
478
of the bridge.
479
==================================================================================================================*/
480
// delayed write request FF input control
481
reg del_write_req_input ;
482
 
483
always@(
484 21 mihad
    do_del_write or
485
    del_write_req or
486
    posted_write_req or
487
    del_read_req or
488
    wait_in or
489
    //retry_in or
490 2 mihad
    //retry_expired or
491
    rtransfer_in or
492
    rerror_in or
493
    mabort_in
494
)
495
begin
496
    if (~del_write_req)
497 21 mihad
    begin
498 2 mihad
        // delayed write is not in progress and is requested
499
        // delayed write can be requested when no other request is in progress
500
        del_write_req_input = ~posted_write_req && ~del_read_req && do_del_write ;
501
    end
502
    else
503
    begin
504
        // delayed write request is in progress - assign input
505 21 mihad
        del_write_req_input = wait_in ||
506 2 mihad
                              ( /*~( retry_in && retry_expired) &&*/
507
                                ~rtransfer_in && ~rerror_in && ~mabort_in
508 21 mihad
                              );
509 2 mihad
    end
510
end
511
 
512
// delayed write request FLIP-FLOP
513
always@(posedge reset_in or posedge clk_in)
514
begin
515
    if (reset_in)
516
        del_write_req <= #`FF_DELAY 1'b0 ;
517
    else
518
        del_write_req <= #`FF_DELAY del_write_req_input ;
519
end
520
 
521
/*================================================================================================
522
Posted write request indicator.
523
Posted write starts whenever no request is in progress and one whole posted write is
524 21 mihad
stored in WBW_FIFO. It ends on error terminations ( master, target abort, retry expired) or
525 2 mihad
data transfer terminations if last data is on top of FIFO.
526
Continues on wait, retry, and disconnect without data.
527
================================================================================================*/
528
// posted write request FF input control
529
reg posted_write_req_input ;
530
always@(
531 21 mihad
    do_posted_write or
532
    del_write_req or
533
    posted_write_req or
534
    del_read_req or
535
    wait_in or
536
    //retry_in or
537 2 mihad
    rerror_in or
538
    mabort_in or
539 21 mihad
    //retry_expired or
540
    rtransfer_in or
541 2 mihad
    last_transfered
542
)
543
begin
544
    if (~posted_write_req)
545
    begin
546
        // posted write is not in progress
547
        posted_write_req_input = ~del_write_req && ~del_read_req && do_posted_write ;
548
    end
549
    else
550
    begin
551
        posted_write_req_input = wait_in ||
552
                                 (/*~(retry_in && retry_expired && ~rtransfer_in) &&*/
553
                                  ~rerror_in && ~mabort_in &&
554
                                  ~(last_transfered)
555
                                 ) ;
556 21 mihad
 
557 2 mihad
    end
558
end
559
 
560
// posted write request flip flop
561
always@(posedge reset_in or posedge clk_in)
562
begin
563
    if (reset_in)
564
        posted_write_req <= #`FF_DELAY 1'b0 ;
565
    else
566
        posted_write_req <= #`FF_DELAY posted_write_req_input ;
567 21 mihad
 
568 2 mihad
end
569
 
570
/*================================================================================================
571
Delayed read request indicator.
572
Delayed read starts whenever no request is in progress and delayed read request is signaled from
573 21 mihad
other side of bridge. It ends on error terminations ( master, target abort, retry expired) or
574 2 mihad
data transfer terminations if it is not burst transfer or on cache line bounds on burst transfer.
575
It also ends on disconnects.
576
Continues on wait and retry.
577
================================================================================================*/
578
// delayed read FF input control
579
reg del_read_req_input ;
580
always@(
581 21 mihad
    do_del_read or
582
    del_write_req or
583
    posted_write_req or
584
    del_read_req or
585
    last_transfered or
586
    wait_in or
587
    retry_in or
588
    //retry_expired or
589 2 mihad
    mabort_in or
590 21 mihad
    rtransfer_in or
591 2 mihad
    rerror_in or
592
    first_in or
593
    del_complete_out
594
)
595
begin
596
    if (~del_read_req)
597
    begin
598
        del_read_req_input = ~del_write_req && ~posted_write_req && ~del_complete_out && do_del_read ;
599
    end
600
    else
601
    begin
602
        del_read_req_input = wait_in ||
603
                             ( ~(retry_in && (~first_in /*|| retry_expired */)) &&
604
                               ~mabort_in && ~rerror_in &&
605
                               ~(last_transfered)
606
                             ) ;
607
    end
608
end
609
 
610
// delayed read request FF
611
always@(posedge reset_in or posedge clk_in)
612
begin
613
    if (reset_in)
614
        del_read_req <= #`FF_DELAY 1'b0 ;
615
    else
616
        del_read_req <= #`FF_DELAY del_read_req_input ;
617
end
618
 
619
// wire indicating last entry of transaction on top of fifo
620
wire wlast = wbw_fifo_control_in[`LAST_CTRL_BIT] ;
621
 
622
wire last_int = posted_write_req && wlast || del_write_req ;
623
 
624
// intermidiate data, byte enable and last registers
625
reg [31:0] intermediate_data ;
626
reg  [3:0] intermediate_be ;
627
reg        intermediate_last ;
628
 
629
wire intermediate_enable = ( posted_write_req || del_write_req ) && ( ~write_req_int || (( ~rdy_out || ~wait_in && rtransfer_in ) && ~intermediate_last)) ;
630
 
631
always@(posedge reset_in or posedge clk_in)
632
begin
633
    if ( reset_in )
634
    begin
635
        intermediate_data <= #`FF_DELAY 32'h0000_0000 ;
636 21 mihad
        intermediate_be   <= #`FF_DELAY 4'h0 ;
637 2 mihad
        intermediate_last <= #`FF_DELAY 1'b0 ;
638 21 mihad
    end
639 2 mihad
    else
640
    if ( intermediate_enable )
641
    begin
642
        intermediate_data <= #`FF_DELAY source_data ;
643 21 mihad
        intermediate_be   <= #`FF_DELAY source_be ;
644 2 mihad
        intermediate_last <= #`FF_DELAY last_int ;
645
    end
646
end
647
 
648
// multiplexer for next data
649
reg [31:0] next_data_out ;
650
reg [3:0] next_be_out   ;
651
reg write_next_last ;
652
reg [3:0] write_next_be ;
653
 
654
always@(rtransfer_in or intermediate_data or intermediate_be or intermediate_last or wbw_fifo_addr_data_in or wbw_fifo_cbe_in or wlast)
655
begin
656
    if( rtransfer_in )
657
    begin
658
        next_data_out   = wbw_fifo_addr_data_in ;
659
        write_next_last = wlast ;
660
        write_next_be   = wbw_fifo_cbe_in ;
661
    end
662
    else
663
    begin
664
        next_data_out   = intermediate_data ;
665
        write_next_last = intermediate_last ;
666
        write_next_be   = intermediate_be ;
667
    end
668
end
669
 
670
always@(del_read_req or source_be or write_next_be)
671
begin
672
    if (del_read_req)
673
        next_be_out = source_be ;
674
    else
675
        next_be_out = write_next_be ;
676
end
677
/*================================================================================================
678
WBW_FIFO read enable - read from WBW_FIFO is performed on posted writes, when data transfer
679
termination is received - transfer or disconnect with data. Reads are enabled during error
680
recovery also, since erroneous transaction must be pulled out of FIFO!
681
================================================================================================*/
682
// wbw_fifo read enable input control
683
 
684
assign wbw_renable_out = ~req_out && (do_posted_write || err_recovery) ||
685
                              posted_write_req && ( ~write_req_int || (~rdy_out && ~intermediate_last) || (~wait_in && rtransfer_in && ~intermediate_last)) ;
686
 
687
/*================================================================================================
688 21 mihad
WBR_FIFO write enable control -
689 2 mihad
writes to FIFO are possible only when delayed read request is in progress and data transfer
690
or error termination is signalled. It is not enabled on retry or disconnect without data.
691
================================================================================================*/
692
// wbr_fifo write enable control - enabled when transfer is in progress and data is transfered or error is signalled
693
assign wbr_fifo_wenable_out = del_read_req && ~wait_in && ( rtransfer_in || mabort_in || rerror_in ) ;
694
 
695
/*================================================================================================
696
WBR_FIFO control output for identifying data entries.
697
This is necesary because of prefetched reads, which partially succeed. On error, error entry
698
gets in to signal it on WISHBONE bus if WISHBONE master reads up to this entry.
699
================================================================================================*/
700
assign wbr_fifo_control_out[`ADDR_CTRL_BIT]       = 1'b0 ;
701
assign wbr_fifo_control_out[`LAST_CTRL_BIT]       = last_transfered ;
702
assign wbr_fifo_control_out[`DATA_ERROR_CTRL_BIT] = rerror_in || (mabort_in && ~conf_cyc_bc) ;
703
assign wbr_fifo_control_out[`UNUSED_CTRL_BIT]     = 1'b0 ;
704
 
705
// retry expired error for posted writes control
706
//assign err_rty_exp_out = posted_write_req && ~wait_in && retry_in && retry_expired && ~rtransfer_in;
707
assign err_rty_exp_out = 1'b0 ;
708
 
709
// error source and error signal output control logic - only for posted writes
710
assign err_source_out = mabort_in /*|| err_rty_exp_out*/ ;
711
 
712
assign err_signal_out = /*err_rty_exp_out || */ posted_write_req && ~wait_in && (mabort_in || rerror_in) ;
713
 
714
//assign del_rty_exp_out = (~wait_in && (del_read_req || del_write_req)) && (retry_in && retry_expired && ~rtransfer_in) ;
715
assign del_rty_exp_out = 1'b0 ;
716
 
717
assign del_error_out   = ~wait_in && (del_write_req || del_read_req) && ( (mabort_in && ~conf_cyc_bc) || rerror_in ) ;
718
 
719
wire   del_write_complete = del_write_req && ( rtransfer_in || rerror_in || mabort_in ) ;
720
wire   del_read_complete  = del_read_req  && ( rerror_in || mabort_in || ( last_transfered ) || ( retry_in && ~first_in ) ) ;
721
 
722
assign del_complete_out = ~wait_in && ( del_write_complete || del_read_complete ) ;
723
 
724
// next last output generation
725
assign next_last_out = del_write_req || del_read_req && ( ~del_burst_in || read_bound ) || posted_write_req && ( write_next_last ) ;
726
/*==================================================================================================================
727
Error recovery FF gets a value of one, when during posted write error occurs. It is cleared when all the data provided
728
for erroneous transaction is pulled out of WBW_FIFO
729
==================================================================================================================*/
730
 
731
// error recovery flip flop input - used when posted write is terminated with an error
732
always@(
733
    err_recovery or
734
    last_out or
735
    wlast or
736
    err_signal_out or
737
    intermediate_last
738
)
739
begin
740
    // when error recovery is not set - drive its input so it gets set
741
    if ( ~err_recovery )
742
        err_recovery_in = ~last_out && ~intermediate_last && err_signal_out ;
743
    else
744
        // when error recovery is set, wbw_fifo is enabled - clear err_recovery when last data entry of erroneous transaction is pulled out of fifo
745
        err_recovery_in = ~wlast ;
746
end
747
 
748 21 mihad
wire data_out_load = (posted_write_req || del_write_req) && ( !rdy_out || ( !wait_in && rtransfer_in ) ) ;
749
 
750
wire be_out_load  = (req_out && !rdy_out) || ( posted_write_req && !wait_in && rtransfer_in ) ;
751
 
752 2 mihad
wire last_load  = req_out && ( ~rdy_out || ~wait_in && wtransfer_in ) ;
753
 
754
always@(posedge reset_in or posedge clk_in)
755
begin
756
    if (reset_in)
757
        data_out <= #`FF_DELAY 32'h0000_0000 ;
758 21 mihad
    else
759
    if ( data_out_load )
760
        data_out <= #`FF_DELAY intermediate_data ;
761 2 mihad
end
762
 
763 21 mihad
always@(posedge clk_in or posedge reset_in)
764
begin
765
    if ( reset_in )
766
        be_out <= #`FF_DELAY 4'hF ;
767
    else
768
    if ( be_out_load )
769
        be_out <= #`FF_DELAY posted_write_req ? intermediate_be : source_be ;
770
end
771
 
772 2 mihad
always@(posedge reset_in or posedge clk_in)
773
begin
774
    if (reset_in)
775
        current_last <= #`FF_DELAY 1'b0 ;
776 21 mihad
    else
777 2 mihad
    if ( last_load )
778
        current_last <= #`FF_DELAY next_last_out ;
779
end
780
 
781
assign last_out = current_last ;
782 21 mihad
endmodule

powered by: WebSVN 2.1.0

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