Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / niu_tdmc_dmacontext.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_tdmc_dmacontext.v
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35/*********************************************************************
36 *
37 *
38 * Orignal Author(s): Arvind Srinivasan
39 * Modifier(s):
40 * Project(s): Neptune
41 *
42 * Copyright (c) 2004 Sun Microsystems, Inc.
43 *
44 * All Rights Reserved.
45 *
46 * This verilog model is the confidential and proprietary property of
47 * Sun Microsystems, Inc., and the possession or use of this model
48 * requires a written license from Sun Microsystems, Inc.
49 *
50 **********************************************************************/
51
52`include "txc_defines.h"
53`include "niu_dmc_reg_defines.h"
54
55module niu_tdmc_dmacontext ( /*AUTOARG*/
56 // Outputs
57 ShadowRingCurrentPtr_DMA, DMA_Address, DMA_Ring_Wrapped,
58 DMA_RingLength, DMACacheEntryValid, dmc_txc_dma_active,
59 dmc_txc_dma_eoflist, DMA_EmptySpace, tx_rng_head_dma,
60 DMA_AvailableFor_Fetch, DMA_ReqPending, DMA_EntriesValid,
61 DMA_CacheEmpty, DMA_CacheReadPtr, DMA_CacheWritePtrReOrder,
62 dma_reset_scheduled, dma_clear_reset,
63 set_conf_part_error_dma, set_tx_ring_oflow_dma,
64 meta_entries_requested_dma, tx_dma_cfg_dma_stop_state,
65 dma_debug_port,
66 // Inputs
67 inc_DMAHeadShadow, updateCacheWritePtrs, ResetDMARdPtr,
68 meta_resp_address, tx_rng_cfg_dma_staddr,
69 meta_req_address, DMA_UpdateAddress,
70 DMC_TxCache_SMX_Req_Length, tx_rng_cfg_dma_len, tx_rng_tail_dma,
71 tx_dma_cfg_dma_stall, NoOfCacheWritesDispatched, DMANumToReq,
72 dmc_txc_dma_cacheready, meta_resp_dma_num, IncrDMARdPtr,
73 updateCacheContext, NoOfValidEntries, page0_mask_dma,
74 page0_value_dma, page0_reloc_dma, page0_valid_dma, page1_mask_dma,
75 page1_value_dma, page1_reloc_dma, page1_valid_dma,
76 dmc_txc_dma_page_handle, txc_dmc_dma_inc_head,
77 dmc_txc_dma_partial, receivedErrorResp,
78 dma_reset_done_hold, tx_dma_cfg_dma_rst,
79 tx_dma_cfg_dma_stop, SysClk, Reset_L
80 );
81
82
83 output [`PTR_WIDTH -1 :0] ShadowRingCurrentPtr_DMA;
84 output [63:0] DMA_Address;
85 output DMA_Ring_Wrapped;
86 output [`PTR_WIDTH -1 :0] DMA_RingLength;
87 output DMACacheEntryValid;
88 output dmc_txc_dma_active;
89 output dmc_txc_dma_eoflist;
90 output [3:0] DMA_EmptySpace ;
91 output [`PTR_WIDTH :0] tx_rng_head_dma;
92 output DMA_AvailableFor_Fetch;
93 output DMA_ReqPending;
94 output [4:0] DMA_EntriesValid;
95 output DMA_CacheEmpty;
96 output [3:0] DMA_CacheReadPtr;
97 output [3:0] DMA_CacheWritePtrReOrder;
98 output dma_reset_scheduled;
99 output dma_clear_reset;
100 output set_conf_part_error_dma;
101 output set_tx_ring_oflow_dma;
102 output [4:0] meta_entries_requested_dma;
103 input inc_DMAHeadShadow;
104 input updateCacheWritePtrs;
105 input ResetDMARdPtr;
106 input [2:0] meta_resp_address;
107 input [37:0] tx_rng_cfg_dma_staddr;
108 input [7:0] meta_req_address;
109 input [43:0] DMA_UpdateAddress;
110 input [13:0] DMC_TxCache_SMX_Req_Length;
111 input [`RNG_LENGTH_WIDTH - 1 :0] tx_rng_cfg_dma_len;
112 input [`PTR_WIDTH :0] tx_rng_tail_dma;
113 input tx_dma_cfg_dma_stall;
114 input [3:0] NoOfCacheWritesDispatched;
115 input [4:0] DMANumToReq;
116 input dmc_txc_dma_cacheready;
117 input [4:0] meta_resp_dma_num;
118 input IncrDMARdPtr;
119 input updateCacheContext;
120 input [4:0] NoOfValidEntries;
121
122 input [31:0] page0_mask_dma;
123 input [31:0] page0_value_dma;
124 input [31:0] page0_reloc_dma;
125 input page0_valid_dma;
126 input [31:0] page1_mask_dma;
127 input [31:0] page1_value_dma;
128 input [31:0] page1_reloc_dma;
129 input page1_valid_dma;
130 input [19:0] dmc_txc_dma_page_handle;
131 input dmc_txc_dma_partial;
132 input dma_reset_done_hold;
133 input receivedErrorResp;
134 input tx_dma_cfg_dma_rst;
135 input tx_dma_cfg_dma_stop;
136 output tx_dma_cfg_dma_stop_state;
137 input SysClk;
138 input Reset_L;
139 input txc_dmc_dma_inc_head; // Needs to come from txc
140 output [31:0] dma_debug_port;
141
142 reg [`PTR_WIDTH -1 :0] ShadowRingCurrentPtr_DMA;
143 reg [63:0] DMA_Address;
144 wire DMA_Ring_Wrapped;
145 reg [`PTR_WIDTH -1 :0] DMA_RingLength;
146 wire DMACacheEntryValid;
147 wire FetchMoreDMA ;
148 wire dmc_txc_dma_active;
149 wire dmc_txc_dma_eoflist;
150 wire DMAActive;
151 wire [3:0] DMA_EmptySpace ;
152 reg ReceivedDMAKick;
153 reg [`PTR_WIDTH :0] tx_rng_head_dma;
154 wire DMA_AvailableFor_Fetch;
155 reg DMA_ReqPending;
156 reg DMA_ReqPending_d;
157 reg [3:0] DMA_Anchor_Address;
158 wire DMA_CacheEmpty;
159 reg [3:0] DMA_CacheWritePtr;
160 reg [3:0] DMA_CacheShadowWritePtr;
161 reg [3:0] DMA_CacheReadPtr;
162 reg [3:0] DMA_CacheWritePtrReOrder;
163 reg [4:0] DMA_EntriesValid;
164 wire DMA_EntryUpdateCollision;
165 reg ld_TxCacheAddress_dma;
166
167
168 reg [`PTR_WIDTH -1 :0] DMA_RingCurrentPtr;
169 reg tx_dma_cfg_dma_stall_d;
170 reg DMA_EofList;
171 reg [3:0] DMA_CacheReOrderOffset;
172 wire ClearDMAKick;
173
174 reg ShadowRingCurrentPtrWrap_DMA;
175 reg DMA_RingCurrentPtrWrap;
176 wire DMA_RingTailWrap;
177 wire DMA_Cache_SpaceAvailable;
178
179 reg [4:0] meta_entries_requested_dma;
180
181 // Logic for Pagetable translation
182 reg xlate_done;
183 reg [43:0] xlate_start_addr;
184 reg [3:0] page_xlate_state;
185 reg page0_match;
186 reg page1_match;
187 reg [31:0] page0_reloc_addr;
188 reg [31:0] page1_reloc_addr;
189 reg set_conf_part_error_dma;
190 reg page_xlate_error;
191 reg xlate_valid;
192
193 /* signals for reset logic */
194 reg [3:0] DMA_ResetSM;
195 reg dma_reset_scheduled;
196 reg stop_fetch_descriptors;
197 reg dma_clear_reset;
198 reg flush_dma_cache;
199 wire reset_asserted;
200 reg stop_asserted;
201 reg tx_dma_cfg_dma_stop_d;
202 reg restart_asserted;
203 reg set_stop_state;
204 reg dma_stopped;
205 wire pkt_counts_equal;
206 /* registers for status registers and mailbox */
207
208
209 reg set_tx_ring_oflow_dma;
210 reg oflow_error;
211 reg updateCacheContext_d;
212 /* Debug Port*/
213 wire [31:0] dma_debug_port;
214
215
216
217 /*--------------------------------------------------------------*/
218 // Parameters and Defines
219 /*--------------------------------------------------------------*/
220 parameter PAGE_XLATE_IDLE = 4'h0,
221 CHECK_PAGE_STATUS = 4'h1,
222 PAGE_XLATE_ERROR = 4'h2;
223
224 parameter RESET_IDLE = 4'h0,
225 WAIT_FOR_RESP = 4'h1,
226 WAIT_FOR_DONE = 4'h2,
227 FLUSH_STATES = 4'h3,
228 WAIT_FOR_PKT_DONE = 4'h4;
229
230 //VCS coverage off
231 // synopsys translate_off
232 reg [192:1] PAGE_XLATE_STATE;
233
234 always @(page_xlate_state)
235 begin
236 case(page_xlate_state)
237 PAGE_XLATE_IDLE : PAGE_XLATE_STATE = "PAGE_XLATE_IDLE";
238 CHECK_PAGE_STATUS: PAGE_XLATE_STATE = "CHECK_PAGE_STATUS";
239 PAGE_XLATE_ERROR : PAGE_XLATE_STATE = "PAGE_XLATE_ERROR";
240 default : PAGE_XLATE_STATE = "UNKNOWN";
241 endcase
242 end
243
244 reg [192:1] RESET_STATE;
245 always @(DMA_ResetSM)
246 begin
247 case(DMA_ResetSM)
248 RESET_IDLE : RESET_STATE = "RESET_IDLE";
249 WAIT_FOR_RESP: RESET_STATE = "WAIT_FOR_RESP";
250 WAIT_FOR_DONE : RESET_STATE = "WAIT_FOR_DONE";
251 FLUSH_STATES : RESET_STATE = "FLUSH_STATES";
252 WAIT_FOR_PKT_DONE : RESET_STATE = "WAIT_FOR_PKT_DONE";
253 default : RESET_STATE = "UNKNOWN";
254 endcase
255 end
256 // synopsys translate_on
257 //VCS coverage on
258
259
260 function [3:0] IncrTxCachePtr;
261 input [3:0] CurrentPtr;
262 input [3:0] ValueToAdd;
263 reg [3:0] tmp_result;
264 begin
265 tmp_result = {1'b0,CurrentPtr[2:0]} + { ValueToAdd[3:0]};
266 IncrTxCachePtr[3] = CurrentPtr[3] ^ tmp_result[3];
267 IncrTxCachePtr[2:0] = tmp_result[2:0];
268 end
269 endfunction // IncrTxCachePtr
270
271
272 wire [43:0] dma_start_addr = {tx_rng_cfg_dma_staddr,6'h0};
273
274
275 always@(posedge SysClk) begin
276 if (!Reset_L) begin
277 xlate_valid <= 1'b0;
278 end else begin
279 xlate_valid <= xlate_done | ( xlate_valid & ~ dma_clear_reset) ;
280 end
281 end
282 always@(posedge SysClk) begin
283 if (!Reset_L) begin
284 page_xlate_state <= PAGE_XLATE_IDLE;
285 xlate_done <= 1'b0;
286 page0_match <= 1'b0;
287 page1_match <= 1'b0;
288 set_conf_part_error_dma <= 1'b0;
289 page_xlate_error <= 1'b0;
290 xlate_start_addr <= 44'h0;
291 end else begin
292 case(page_xlate_state) // synopsys full_case parallel_case
293 PAGE_XLATE_IDLE: begin
294 xlate_done <= 1'b0;
295 set_conf_part_error_dma <= 1'b0;
296 page_xlate_error <= 1'b0;
297 if(ld_TxCacheAddress_dma ) begin
298 xlate_start_addr <= {tx_rng_cfg_dma_staddr,6'h0};
299 if( ~page0_valid_dma & ~page1_valid_dma ) begin
300 // Set ERROR Flags?
301 set_conf_part_error_dma <= 1'b1;
302 page_xlate_state <= PAGE_XLATE_ERROR;
303 end else begin
304 page_xlate_state <= CHECK_PAGE_STATUS;
305 page0_reloc_addr <= ((dma_start_addr[43:12] & ~page0_mask_dma) |
306 ( page0_reloc_dma & page0_mask_dma)) ;
307 page0_match <= page0_valid_dma &
308 ((page0_mask_dma & dma_start_addr [43:12] ) == page0_value_dma );
309
310 page1_reloc_addr <= ((dma_start_addr[43:12] & ~page1_mask_dma) |
311 ( page1_reloc_dma & page1_mask_dma)) ;
312
313 page1_match <= page1_valid_dma &
314 ((page1_mask_dma & dma_start_addr [43:12] ) == page1_value_dma );
315
316 end // else: !if( ~page0_valid_dma & ~page1_valid_dma )
317 end // if (ld_TxCacheAddress_dma )
318 end // case: PAGE_XLATE_IDLE
319 CHECK_PAGE_STATUS: begin
320 if(page0_match) begin
321 xlate_done <= 1'b1;
322 xlate_start_addr <= {page0_reloc_addr,xlate_start_addr[11:0]};
323 page_xlate_state <= PAGE_XLATE_IDLE;
324 end else if(page1_match) begin
325 xlate_done <= 1'b1;
326 xlate_start_addr <= {page1_reloc_addr,xlate_start_addr[11:0]};
327 page_xlate_state <= PAGE_XLATE_IDLE;
328 end else begin
329 set_conf_part_error_dma <= 1'b1;
330 page_xlate_state <= PAGE_XLATE_ERROR;
331 end
332 end // case: CHECK_PAGE_STATUS
333 PAGE_XLATE_ERROR: begin
334 // Go back to IDLE -- for now
335 set_conf_part_error_dma <= 1'b0;
336 page_xlate_error <= 1'b1;
337 // xlate_done <= 1'b1; // This is to be removed !!!
338 if(reset_asserted) begin
339 page_xlate_state <= PAGE_XLATE_IDLE;
340 end else begin
341 page_xlate_state <= PAGE_XLATE_ERROR;
342 end
343 // synopsys translate_off
344 // $display(" %m: Warning-- Page translation failure Time - %t",$time);
345 // synopsys translate_on
346 end
347 default: begin
348 page_xlate_state <= PAGE_XLATE_IDLE;
349 xlate_done <= 1'b0;
350 page0_match <= 1'b0;
351 page1_match <= 1'b0;
352 set_conf_part_error_dma <= 1'b0;
353 page_xlate_error <= 1'b0;
354 xlate_start_addr <= 44'h0;
355 end
356 endcase // case(page_xlate_state)
357 end // else: !if(!Reset_L)
358 end // always@ (posedge SysClk)
359
360
361
362
363 assign ClearDMAKick = updateCacheContext & ReceivedDMAKick;
364
365 always@(posedge SysClk )
366 if (!Reset_L) begin
367 updateCacheContext_d <= 1'b0;
368 end else begin
369 updateCacheContext_d <= updateCacheContext;
370 end
371 // DMA
372 reg ring_wraped_or_not;
373 always@(posedge SysClk )
374 if (!Reset_L) begin
375 ShadowRingCurrentPtr_DMA <= `PTR_WIDTH'h0;
376 ShadowRingCurrentPtrWrap_DMA <= 1'b0;
377 DMA_Address <= 64'h0;
378 ring_wraped_or_not <= 1'b0;
379 end else begin // if (!Reset_L)
380 if(xlate_done | dma_clear_reset ) begin
381 ShadowRingCurrentPtr_DMA <= `PTR_WIDTH'h0;
382 // DMA_Address <= {20'h0,tx_rng_cfg_dma_staddr,6'h0};
383 DMA_Address <= {dmc_txc_dma_page_handle,xlate_start_addr};
384 ShadowRingCurrentPtrWrap_DMA <= 1'b0;
385 ring_wraped_or_not <= 1'b0;
386 end else begin
387 if(updateCacheContext) begin
388 ring_wraped_or_not <= ( ( ShadowRingCurrentPtr_DMA + {10'h0,DMC_TxCache_SMX_Req_Length[8:3]}) >= (DMA_RingLength ));
389 end else if(updateCacheContext_d ) begin
390 if(ring_wraped_or_not) begin
391 // ShadowRingCurrentPtr_DMA <= {13'h0,DMC_TxCache_SMX_Req_Length[8:3]};
392 ShadowRingCurrentPtr_DMA <= `PTR_WIDTH'h0;
393 ShadowRingCurrentPtrWrap_DMA <= ~ ShadowRingCurrentPtrWrap_DMA;
394 // DMA_Address <= {20'h0,tx_rng_cfg_dma_staddr,6'h0};
395 DMA_Address <= {dmc_txc_dma_page_handle,xlate_start_addr};
396 end else begin
397 ShadowRingCurrentPtr_DMA <= ShadowRingCurrentPtr_DMA + {10'h0,DMC_TxCache_SMX_Req_Length[8:3]};
398 ShadowRingCurrentPtrWrap_DMA <= ShadowRingCurrentPtrWrap_DMA;
399 DMA_Address <= {dmc_txc_dma_page_handle,DMA_UpdateAddress};
400 end // else: !if(( ShadowRingCurrentPtr_DMA + {13'h0,DMC_TxCache_SMX_Req_Length[8:3]}) > (DMA_RingLength ) )
401 end // if (updateCacheContext & (DMANumToReq== DMA_CHANNEL_NUMBER) )
402 end // else: !if(xlate_done)
403 end // else: !if(!Reset_L)
404
405 assign DMA_Ring_Wrapped = ShadowRingCurrentPtrWrap_DMA ^ DMA_RingTailWrap ;
406
407 always@(posedge SysClk )
408 if (!Reset_L) begin
409 meta_entries_requested_dma <= 5'h0;
410 end else if(updateCacheContext) begin
411 meta_entries_requested_dma <= DMC_TxCache_SMX_Req_Length[7:3];
412 end
413
414 always@(posedge SysClk )
415 if (!Reset_L) begin
416 DMA_RingLength <= `PTR_WIDTH'h0;
417 end else if(xlate_done) begin
418 DMA_RingLength <= {tx_rng_cfg_dma_len,3'h0};
419 end // if (xlate_done)
420
421 // Head Pointer for S/W
422
423
424 always@(posedge SysClk )
425 if (!Reset_L) begin
426 tx_rng_head_dma <= `PTR_WIDTH_PLUS1'h0;
427 end else if(xlate_done | dma_clear_reset) begin
428 tx_rng_head_dma <= `PTR_WIDTH_PLUS1'h0;
429 end else if( txc_dmc_dma_inc_head) begin// if (xlate_done)
430 if( tx_rng_head_dma[`PTR_WIDTH -1 :0] == (DMA_RingLength - `PTR_WIDTH'b1) ) begin
431 tx_rng_head_dma[`PTR_WIDTH] <= ~tx_rng_head_dma[`PTR_WIDTH];
432 tx_rng_head_dma[`PTR_WIDTH -1 :0] <= `PTR_WIDTH'h0;
433 end else begin // if ( tx_rng_head_dma[`PTR_WIDTH -1 :0] == (DMA_RingLength - `PTR_WIDTH'b1) )
434 tx_rng_head_dma[`PTR_WIDTH -1 :0] <= tx_rng_head_dma[`PTR_WIDTH -1 :0] + `PTR_WIDTH'h1 ;
435 end // else: !if( tx_rng_head_dma[`PTR_WIDTH -1 :0] == (DMA_RingLength - `PTR_WIDTH'b1) )
436 end // if ( txc_dmc_inc_head)
437
438
439 reg ring_oflow;
440 reg ring_oflow_d;
441 always@(posedge SysClk) begin
442 if(!Reset_L) begin
443 set_tx_ring_oflow_dma <= 1'b0;
444 oflow_error <= 1'b0;
445 ring_oflow <= 1'b0;
446 ring_oflow_d <= 1'b0;
447 end else begin
448 ring_oflow <= xlate_valid & ( (tx_rng_tail_dma[`PTR_WIDTH -1 :0] > DMA_RingLength)
449 | ( ~DMA_Ring_Wrapped & ( ShadowRingCurrentPtr_DMA > tx_rng_tail_dma[`PTR_WIDTH -1 :0]) )
450 | ( DMA_Ring_Wrapped & ( tx_rng_tail_dma[`PTR_WIDTH -1 :0] > ShadowRingCurrentPtr_DMA ) )
451 );
452 ring_oflow_d <= ring_oflow;
453
454 if(dma_clear_reset) begin
455 set_tx_ring_oflow_dma <= 1'b0;
456 oflow_error <= 1'b0;
457 end else if(ring_oflow &~ring_oflow_d) begin
458 set_tx_ring_oflow_dma <= 1'b1;
459 oflow_error <= 1'b1;
460 end else set_tx_ring_oflow_dma <= 1'b0;
461 end // else: !if(!Reset_L)
462 end // always@ (posedge SysClk)
463
464 // This logic can be taken out-- TOADS This is used by TxCif files
465
466 always@(posedge SysClk )
467 if (!Reset_L) begin
468 DMA_RingCurrentPtr <= `PTR_WIDTH'h0;
469 DMA_RingCurrentPtrWrap <= 1'b0;
470 end else if(xlate_done | dma_clear_reset ) begin
471 DMA_RingCurrentPtr <= `PTR_WIDTH'h0;
472 DMA_RingCurrentPtrWrap <= 1'b0;
473 end else if(inc_DMAHeadShadow) begin // if (xlate_done)
474 // Take care of wrap around cases
475 if(DMA_RingCurrentPtr == (DMA_RingLength - `PTR_WIDTH'b1) ) begin
476 DMA_RingCurrentPtr <= `PTR_WIDTH'h0;
477 DMA_RingCurrentPtrWrap <= ~DMA_RingCurrentPtrWrap;
478 end else begin
479 DMA_RingCurrentPtr <= DMA_RingCurrentPtr + `PTR_WIDTH'b1;
480 DMA_RingCurrentPtrWrap <= DMA_RingCurrentPtrWrap;
481 end // else: !if(DMA_RingCurrentPtr == DMA_RingLength )
482 end // if (inc_DMAHeadShadow)
483
484 assign DMA_RingTailWrap = tx_rng_tail_dma[`PTR_WIDTH];
485
486
487 assign DMACacheEntryValid = ( ~ ( ( DMA_RingCurrentPtrWrap == DMA_RingTailWrap ) &
488 ( DMA_RingCurrentPtr == tx_rng_tail_dma[`PTR_WIDTH -1 :0] ) ) ) & DMAActive ; // Check exact width
489
490
491
492 always@(posedge SysClk )
493 if (!Reset_L) begin
494 DMA_CacheShadowWritePtr <=4'h0;
495 end else if(flush_dma_cache) begin
496 DMA_CacheShadowWritePtr <=4'h0;
497 end else if(updateCacheContext ) begin
498 DMA_CacheShadowWritePtr <= IncrTxCachePtr(DMA_CacheShadowWritePtr,NoOfCacheWritesDispatched);
499 end // if (updateCacheContext)
500
501
502 assign FetchMoreDMA = ~ ( ( ShadowRingCurrentPtrWrap_DMA == DMA_RingTailWrap ) &
503 (ShadowRingCurrentPtr_DMA == tx_rng_tail_dma[`PTR_WIDTH -1 :0] ) );
504
505 assign dmc_txc_dma_active = DMAActive ;
506
507 always@(posedge SysClk )
508 if(!Reset_L)begin
509 DMA_EofList <= 1'b1;
510 end else begin
511 DMA_EofList <= ~DMACacheEntryValid;
512 end // else: !if(!Reset_L)
513
514 assign dmc_txc_dma_eoflist =DMA_EofList;
515 assign DMAActive = ~tx_dma_cfg_dma_stall;
516 assign DMA_EmptySpace= (DMA_CacheShadowWritePtr[3]^DMA_CacheReadPtr[3]) ?
517 ( {1'b0,DMA_CacheReadPtr[2:0]} - {1'b0,DMA_CacheShadowWritePtr[2:0]}) :
518 ( 4'h8 - {1'b0,DMA_CacheShadowWritePtr[2:0]} + {1'b0,DMA_CacheReadPtr[2:0]}) ;
519 assign DMA_Cache_SpaceAvailable = ( (DMA_EmptySpace >4'h3) ? 1'b1: 1'b0 ) |
520 ( (dmc_txc_dma_partial & (DMA_EmptySpace >4'h0)) ? 1'b1:1'b0 );
521 always@(posedge SysClk )
522 if(!Reset_L) begin
523 ReceivedDMAKick <= 1'b0;
524 tx_dma_cfg_dma_stall_d <= 1'b0;
525 ld_TxCacheAddress_dma <= 1'b0;
526 DMA_ReqPending_d <= 1'b0;
527 end else begin
528 tx_dma_cfg_dma_stall_d <= tx_dma_cfg_dma_stall;
529 ReceivedDMAKick <= (!tx_dma_cfg_dma_stall & tx_dma_cfg_dma_stall_d) | ( ReceivedDMAKick & ~ClearDMAKick);
530 ld_TxCacheAddress_dma <= ~tx_dma_cfg_dma_stall & tx_dma_cfg_dma_stall_d;
531 DMA_ReqPending_d <= DMA_ReqPending;
532 end // else: !if(!Reset_L)
533
534
535
536 assign DMA_AvailableFor_Fetch = ( ( FetchMoreDMA & ReceivedDMAKick & DMA_Cache_SpaceAvailable ) | ( FetchMoreDMA & DMA_Cache_SpaceAvailable))
537 & DMAActive & ~stop_fetch_descriptors & ~page_xlate_error & ~dma_stopped & xlate_valid & ~DMA_ReqPending_d & ~oflow_error;
538
539 // DMA
540 always@(posedge SysClk )
541 if (!Reset_L) begin
542 DMA_ReqPending <=1'h0;
543 DMA_Anchor_Address <= 4'h0;
544 end else if(updateCacheContext ) begin
545 DMA_ReqPending <= 1'b1;
546 DMA_Anchor_Address <= meta_req_address[7:4];
547 end else if(updateCacheWritePtrs | receivedErrorResp ) begin
548 /* This should be write confirm signal based upon transaction complete */
549 DMA_ReqPending <= 1'b0;
550 end // if (updateCacheWritePtrs & (meta_resp_dma_num ==DMA_CHANNEL_NUMBER) )
551
552 assign DMA_EntryUpdateCollision = inc_DMAHeadShadow & updateCacheWritePtrs;
553
554 always@(posedge SysClk )
555 if (!Reset_L) begin
556 DMA_EntriesValid <= 5'h0;
557 end else begin // if (!Reset_L)
558 if(flush_dma_cache) begin
559 DMA_EntriesValid <= 5'h0;
560 end else if(~DMA_EntryUpdateCollision & updateCacheWritePtrs) begin
561 DMA_EntriesValid <= DMA_EntriesValid + NoOfValidEntries;
562 end // if (~DMA_EntryUpdateCollision & (updateCacheWritePtrs & (meta_resp_dma_num ==DMA_CHANNEL_NUMBER) ) begin...
563 else if( ~DMA_EntryUpdateCollision & inc_DMAHeadShadow ) begin
564 DMA_EntriesValid <= DMA_EntriesValid - 5'h1;
565 end // if ( ~DMA_EntryUpdateCollision & IncrDMARdPtr)
566 else if(DMA_EntryUpdateCollision) begin
567 DMA_EntriesValid <= DMA_EntriesValid + NoOfValidEntries - 5'h1;
568 end else begin
569 DMA_EntriesValid <= DMA_EntriesValid;
570 end // else: !if(DMA_EntryUpdateCollision)
571 end // else: !if(!Reset_L)
572
573
574 // DMA
575 // assign DMA_CacheFull = (DMA_CacheReadPtr[2:0] == DMA_CacheWritePtr[2:0]) & (DMA_CacheReadPtr[3]^DMA_CacheWritePtr[3]) ;
576 assign DMA_CacheEmpty = (DMA_CacheReadPtr[2:0] == DMA_CacheWritePtr[2:0]) &~ (DMA_CacheReadPtr[3]^DMA_CacheWritePtr[3]);
577
578 always@(posedge SysClk )
579 if (!Reset_L) begin
580 DMA_CacheWritePtr <=4'h0;
581 end else begin
582 if(flush_dma_cache) begin
583 DMA_CacheWritePtr <=4'h0;
584 end else if(updateCacheWritePtrs) begin
585 DMA_CacheWritePtr <= DMA_CacheShadowWritePtr;
586 end // if (updateCacheWritePtrs)
587 end // else: !if(!Reset_L)
588
589 always@(posedge SysClk )
590 if (!Reset_L) begin
591 DMA_CacheReadPtr <=4'h0;
592 end else begin // if (!Reset_L)
593 if(IncrDMARdPtr) begin
594 DMA_CacheReadPtr <= IncrTxCachePtr(DMA_CacheReadPtr,4'h1);
595 end else if(flush_dma_cache ) begin // if (IncrDMARdPtr)
596 DMA_CacheReadPtr <=4'h0;
597 end else if(ResetDMARdPtr ) begin // if (IncrDMARdPtr)
598 DMA_CacheReadPtr <= DMA_CacheWritePtr;
599 end // if (ResetDMARdPtr)
600 end // else: !if(!Reset_L)
601
602
603
604
605 // DMA_31 Offset Calculations
606 always@( meta_resp_address or DMA_Anchor_Address or DMA_CacheWritePtr) begin
607 DMA_CacheReOrderOffset = ( meta_resp_address[2:0] >= DMA_Anchor_Address[2:0] ) ?
608 ( {1'b0,meta_resp_address[2:0]} - {1'b0,DMA_Anchor_Address[2:0]} ) :
609 ( 4'h8 + {1'b0,meta_resp_address[2:0]} - {1'b0,DMA_Anchor_Address[2:0]} );
610 DMA_CacheWritePtrReOrder = IncrTxCachePtr(DMA_CacheWritePtr, DMA_CacheReOrderOffset);
611 end
612
613
614 /* DMA Reset logic - */
615
616 //TODO-
617 // PIO Write Collisions
618 // Knowing what is the state of pending scheduling info
619 //
620 assign reset_asserted = tx_dma_cfg_dma_rst;
621 assign tx_dma_cfg_dma_stop_state = dma_stopped;
622 assign pkt_counts_equal = ( {DMA_RingCurrentPtrWrap,DMA_RingCurrentPtr} == tx_rng_head_dma[`PTR_WIDTH:0] );
623
624 always@(posedge SysClk) begin
625 if(!Reset_L) begin
626 dma_stopped <= 1'b0;
627 tx_dma_cfg_dma_stop_d <= 1'b0;
628 restart_asserted <= 1'b0;
629 stop_asserted <= 1'b0;
630 end else begin
631 tx_dma_cfg_dma_stop_d <= tx_dma_cfg_dma_stop;
632 stop_asserted <= (tx_dma_cfg_dma_stop & ~tx_dma_cfg_dma_stop_d) | ( stop_asserted & ~set_stop_state);
633 restart_asserted <= ~tx_dma_cfg_dma_stop & tx_dma_cfg_dma_stop_d;
634 dma_stopped <= set_stop_state | (dma_stopped & ~restart_asserted);
635 end
636 end // always@ (posedge SysClk)
637
638
639
640
641 always@(posedge SysClk) begin
642 if(!Reset_L) begin
643 DMA_ResetSM <= RESET_IDLE;
644 dma_reset_scheduled <= 1'b0;
645 stop_fetch_descriptors <= 1'b0;
646 dma_clear_reset <= 1'b0;
647 flush_dma_cache <= 1'b0;
648 set_stop_state <= 1'b0;
649 end else begin
650 case(DMA_ResetSM)
651 RESET_IDLE: begin
652 dma_reset_scheduled <= 1'b0;
653 flush_dma_cache <= 1'b0;
654 stop_fetch_descriptors <= 1'b0;
655 dma_clear_reset <= 1'b0;
656 set_stop_state <= 1'b0;
657 if(reset_asserted | stop_asserted ) begin
658 if(!DMAActive) begin
659 if(reset_asserted) begin
660 DMA_ResetSM <= WAIT_FOR_PKT_DONE;
661 end else begin
662 DMA_ResetSM <= RESET_IDLE;
663 set_stop_state <= 1'b1;
664 end
665 end else begin
666 DMA_ResetSM <= WAIT_FOR_DONE;
667 dma_reset_scheduled <= 1'b1;
668 end // else: !if(!DMAActive)
669 end // if (reset_asserted | stop_asserted )
670 end // case: RESET_IDLE
671 WAIT_FOR_DONE: begin
672 if(dma_reset_done_hold) begin
673 DMA_ResetSM <= WAIT_FOR_RESP;
674 stop_fetch_descriptors <= 1'b1;
675 end else begin
676 DMA_ResetSM <= WAIT_FOR_DONE;
677 end // else: !if(!dma_reset_done)
678 end // case: WAIT_FOR_DONE
679 WAIT_FOR_RESP: begin
680 if(!DMA_ReqPending) begin
681 DMA_ResetSM <= WAIT_FOR_PKT_DONE;
682 end else begin
683 DMA_ResetSM <= WAIT_FOR_RESP;
684 end
685 end
686 WAIT_FOR_PKT_DONE: begin
687 if(pkt_counts_equal) begin
688 DMA_ResetSM <= FLUSH_STATES;
689 dma_reset_scheduled <= 1'b0;
690 if(reset_asserted) begin
691 flush_dma_cache <= 1'b1;
692 dma_clear_reset <= 1'b1;
693 end // if (reset_asserted)
694 if(stop_asserted)
695 set_stop_state <= 1'b1;
696 end else begin
697 DMA_ResetSM <= WAIT_FOR_PKT_DONE;
698 end // else: !if(pkt_counts_equal)
699 end // case: WAIT_FOR_PKT_DONE
700 FLUSH_STATES: begin
701 // clear caches, clear reset bit etc
702 flush_dma_cache <= 1'b0;
703 dma_clear_reset <= 1'b0;
704 set_stop_state <= 1'b0;
705 dma_reset_scheduled <= 1'b0;
706 DMA_ResetSM <= RESET_IDLE;
707 end
708 endcase // case(DMA_ResetSM)
709 end // else: !if(!Reset_L)
710 end
711
712
713
714assign dma_debug_port = {3'h0,dmc_txc_dma_cacheready,dmc_txc_dma_partial,stop_fetch_descriptors,FetchMoreDMA,DMA_AvailableFor_Fetch,DMA_Cache_SpaceAvailable,
715 DMA_ReqPending,DMACacheEntryValid,DMA_EmptySpace,DMA_EntriesValid,DMA_ResetSM,DMA_CacheReadPtr,DMA_CacheWritePtr};
716// DMA_CacheWritePtr Cache Write Pointer Updated only after transfer_complete is received bit 3 is used for wrap_arounds
717// DMA_CacheReadPtr Cache Read Pointer Updated based upon number of getNextDesc signals from TXC bit3 is used for wrap_arounds
718// DMA_ResetSM DMA Reset/Stop State Machine
719// DMA_EntriesValid Number of descriptors currently within the cache - Max of 16
720// DMA_EmptySpace Indicates how much Space is available withing the cache. Computed based upon ( ShadowWritePtr - ReadPtr)
721// DMACacheEntryValid Compares current local ringptr with software tail pointer
722// DMA_ReqPending Pending Request Flag
723// DMA_Cache_SpaceAvailable Is Space available for new requests?
724// DMA_AvailableFor_Fetch - This triggers a new descriptor fetch, function of new kicks, space availble and any errors
725// FetchMoreDMA ShadowHead Pointer and tail pointer difference indicator.
726// stop_fetch_descriptors - Function of reaset/stop issued by Software. This needs to be cleared for any new fetch requests
727// dmc_txc_dma_partial - Partial signal to TXC
728
729endmodule
730
731/* -- algorithm for page table translation
732 if( ~page0_valid & ~page1_valid ){
733 set_error();
734 }
735
736 if(page0_valid) { // check page0 match
737 mask0 = page0_mask;
738 value0 = page0_value;
739 reloc0 = page0_reloc;
740 if( (mask0 & address[43:12] ) == (value0)) {
741 page0_match = 1;
742 page1_match = 0;
743
744 }
745 }
746 if(page1_valid & ~page0_match) {// check page1 match
747 mask1 = page1_mask;
748 value1 = page1_value;
749 reloc1 = page1_reloc;
750 if( (mask1 & address[43:12] ) == (value1)) {
751 page1_match = 1;
752 page0_match = 0;
753
754 }
755 }
756
757 // Calculate new address
758 if(page0_match) {
759 new_address[43:12] = (address[43:12] & ~mask0) | ( reloc0 & mask0) ;
760 new_address[11:0] = address[11:0];
761 } else if(page1_match) {
762 new_address[43:12] = (address[43:12] & ~mask1) | ( reloc1 & mask1) ;
763 new_address[11:0] = address[11:0];
764 } else {
765 new_address = address; // no change
766 }
767
768 */
769
770
771
772
773
774
775