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 154

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

powered by: WebSVN 2.1.0

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