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

Subversion Repositories pci

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

powered by: WebSVN 2.1.0

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