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

Subversion Repositories pci

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

powered by: WebSVN 2.1.0

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