1 |
2 |
dsmv |
|
2 |
|
|
//-----------------------------------------------------------------------------
|
3 |
|
|
//
|
4 |
|
|
// (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
|
5 |
|
|
//
|
6 |
|
|
// This file contains confidential and proprietary information
|
7 |
|
|
// of Xilinx, Inc. and is protected under U.S. and
|
8 |
|
|
// international copyright and other intellectual property
|
9 |
|
|
// laws.
|
10 |
|
|
//
|
11 |
|
|
// DISCLAIMER
|
12 |
|
|
// This disclaimer is not a license and does not grant any
|
13 |
|
|
// rights to the materials distributed herewith. Except as
|
14 |
|
|
// otherwise provided in a valid license issued to you by
|
15 |
|
|
// Xilinx, and to the maximum extent permitted by applicable
|
16 |
|
|
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
|
17 |
|
|
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
|
18 |
|
|
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
|
19 |
|
|
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
|
20 |
|
|
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
|
21 |
|
|
// (2) Xilinx shall not be liable (whether in contract or tort,
|
22 |
|
|
// including negligence, or under any other theory of
|
23 |
|
|
// liability) for any loss or damage of any kind or nature
|
24 |
|
|
// related to, arising under or in connection with these
|
25 |
|
|
// materials, including for any direct, or any indirect,
|
26 |
|
|
// special, incidental, or consequential loss or damage
|
27 |
|
|
// (including loss of data, profits, goodwill, or any type of
|
28 |
|
|
// loss or damage suffered as a result of any action brought
|
29 |
|
|
// by a third party) even if such damage or loss was
|
30 |
|
|
// reasonably foreseeable or Xilinx had been advised of the
|
31 |
|
|
// possibility of the same.
|
32 |
|
|
//
|
33 |
|
|
// CRITICAL APPLICATIONS
|
34 |
|
|
// Xilinx products are not designed or intended to be fail-
|
35 |
|
|
// safe, or for use in any application requiring fail-safe
|
36 |
|
|
// performance, such as life-support or safety devices or
|
37 |
|
|
// systems, Class III medical devices, nuclear facilities,
|
38 |
|
|
// applications related to the deployment of airbags, or any
|
39 |
|
|
// other applications that could lead to death, personal
|
40 |
|
|
// injury, or severe property or environmental damage
|
41 |
|
|
// (individually and collectively, "Critical
|
42 |
|
|
// Applications"). Customer assumes the sole risk and
|
43 |
|
|
// liability of any use of Xilinx products in Critical
|
44 |
|
|
// Applications, subject only to applicable laws and
|
45 |
|
|
// regulations governing limitations on product liability.
|
46 |
|
|
//
|
47 |
|
|
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
|
48 |
|
|
// PART OF THIS FILE AT ALL TIMES.
|
49 |
|
|
//
|
50 |
|
|
//-----------------------------------------------------------------------------
|
51 |
|
|
// Project : V5-Block Plus for PCI Express
|
52 |
|
|
// File : tlm_rx_data_snk.v
|
53 |
|
|
//--------------------------------------------------------------------------------
|
54 |
|
|
//--------------------------------------------------------------------------------
|
55 |
|
|
/*****************************************************************************
|
56 |
|
|
* Description : Rx Data Sink
|
57 |
|
|
*
|
58 |
|
|
* Hierarchical : tlm_rx
|
59 |
|
|
* tlm_rx_data_snk *
|
60 |
|
|
* malformed_checks
|
61 |
|
|
* pwr_mgmt
|
62 |
|
|
* bar_hit
|
63 |
|
|
*
|
64 |
|
|
* Functional :
|
65 |
|
|
* Takes incoming packets, examines the packet for correct
|
66 |
|
|
* construction and drops if it malformed.
|
67 |
|
|
* Removes power management packets from the stream and signals
|
68 |
|
|
* sideband to CMM
|
69 |
|
|
* Rips out header control information for easier control downstream
|
70 |
|
|
*
|
71 |
|
|
****************************************************************************/
|
72 |
|
|
|
73 |
|
|
`timescale 1ns/1ps
|
74 |
|
|
`ifndef TCQ
|
75 |
|
|
`define TCQ 1
|
76 |
|
|
`endif
|
77 |
|
|
`ifndef PCIE
|
78 |
|
|
`ifndef AS
|
79 |
|
|
`define PCIE
|
80 |
|
|
`endif
|
81 |
|
|
`endif
|
82 |
|
|
|
83 |
|
|
module tlm_rx_data_snk #(parameter DW = 32,// Data width
|
84 |
|
|
parameter FCW = 6, // Packet credit width
|
85 |
|
|
`ifdef PCIE
|
86 |
|
|
parameter BARW = 7, // BAR-hit width
|
87 |
|
|
parameter DOWNSTREAM_PORT = 0, // Endpoint or switch?
|
88 |
|
|
`else // `ifdef AS
|
89 |
|
|
parameter OVC = 0, // Any ordered VCs?
|
90 |
|
|
parameter MVC = 0, // Any multicast VCs?
|
91 |
|
|
`endif
|
92 |
|
|
parameter MPS = 512,//Core MPS
|
93 |
|
|
parameter TYPE1_UR = 0) // Type1 config bad?
|
94 |
|
|
(
|
95 |
|
|
input clk_i,
|
96 |
|
|
input reset_i,
|
97 |
|
|
|
98 |
|
|
//--------------------------------------------------------
|
99 |
|
|
// Datapath signals
|
100 |
|
|
//--------------------------------------------------------
|
101 |
|
|
|
102 |
|
|
// To FIFO
|
103 |
|
|
output reg [DW-1:0] d_o, // Data
|
104 |
|
|
output reg sof_o, // ll sof
|
105 |
|
|
output reg eof_o, // ll eof
|
106 |
|
|
output reg preeof_o, // ll eof - one cycle early
|
107 |
|
|
output reg src_rdy_o, // ll src_rdy
|
108 |
|
|
output reg rem_o, // ll rem (in words)
|
109 |
|
|
output reg dsc_o, // ll dsc
|
110 |
|
|
|
111 |
|
|
output reg cfg_o, // Config packet, @bar
|
112 |
|
|
`ifdef PCIE
|
113 |
|
|
output reg np_o, // Non-posted packet, @bar
|
114 |
|
|
output reg cpl_o, // Completion packet, @bar
|
115 |
|
|
output reg locked_o, // Locked msg or cpl, @bar
|
116 |
|
|
output reg [BARW-1:0] bar_o, // Bar hit, @bar
|
117 |
|
|
output reg rid_o, // RID hit, @bar
|
118 |
|
|
output reg vend_msg_o, // Vendor-defined MSG
|
119 |
|
|
output reg bar_src_rdy_o, // ll src_rdy
|
120 |
|
|
`endif
|
121 |
|
|
|
122 |
|
|
// To Flow controller
|
123 |
|
|
output reg fc_use_p_o, // posted update.. implies 1 hdr
|
124 |
|
|
output reg fc_use_np_o, // nonposted update.. ''
|
125 |
|
|
`ifdef PCIE
|
126 |
|
|
output reg fc_use_cpl_o, // compl update.. ''
|
127 |
|
|
`endif
|
128 |
|
|
output reg [FCW-1:0] fc_use_data_o, // number of data credits used
|
129 |
|
|
output reg fc_unuse_o, // ll src_rdy.. implies 1 header
|
130 |
|
|
|
131 |
|
|
// From LLM
|
132 |
|
|
input [DW-1:0] d_i, // Data
|
133 |
|
|
input sof_i, // ll sof
|
134 |
|
|
input eof_i, // ll eof
|
135 |
|
|
input rem_i, // ll rem in binary bytes
|
136 |
|
|
input src_rdy_i, // ll src_rdy
|
137 |
|
|
input src_dsc_i, // ll dsc
|
138 |
|
|
|
139 |
|
|
//--------------------------------------------------------
|
140 |
|
|
// Sideband signals
|
141 |
|
|
//--------------------------------------------------------
|
142 |
|
|
|
143 |
|
|
// InitFC communication to LLM
|
144 |
|
|
output reg vc_hit_o, // TLP received on VC0
|
145 |
|
|
|
146 |
|
|
// Power management signals for CMM
|
147 |
|
|
`ifdef PCIE
|
148 |
|
|
output pm_as_nak_l1_o, // Pkt detected, implies src_rdy
|
149 |
|
|
output pm_turn_off_o, // Pkt detected, implies src_rdy
|
150 |
|
|
output pm_set_slot_pwr_o, // Pkt detected, implies src_rdy
|
151 |
|
|
output [9:0] pm_set_slot_pwr_data_o, // value of field
|
152 |
|
|
input pm_suspend_req_i, // Go into pm.. drop packets
|
153 |
|
|
`else // `ifdef AS
|
154 |
|
|
input [1:0] lnk_state_i, // Link state
|
155 |
|
|
input lnk_state_src_rdy_i, // New link state valid
|
156 |
|
|
`endif
|
157 |
|
|
|
158 |
|
|
`ifdef PCIE
|
159 |
|
|
// Completion event information for CMM
|
160 |
|
|
output reg [47:0] err_tlp_cpl_header_o, // Header fields
|
161 |
|
|
output reg err_tlp_p_o, // Pkt is posted
|
162 |
|
|
output reg err_tlp_ur_o, // Unsupported req, implies src_rdy
|
163 |
|
|
output reg err_tlp_ur_lock_o, // Unsupported req due to Lock, implies src_rdy
|
164 |
|
|
output reg err_tlp_uc_o, // Unsupported cpl, implies src_rdy
|
165 |
|
|
output reg err_tlp_malformed_o, // Pkt is badly constructed,
|
166 |
|
|
// implies src_rdy
|
167 |
|
|
// status register in the CMM
|
168 |
|
|
output reg stat_tlp_cpl_ep_o, // cpl inc pkt poison
|
169 |
|
|
output reg stat_tlp_cpl_abort_o, // cpl stat is abort
|
170 |
|
|
output reg stat_tlp_cpl_ur_o, // cpl stat is ur
|
171 |
|
|
output reg stat_tlp_ep_o, // incoming pkt poison
|
172 |
|
|
|
173 |
|
|
// Outgoing information to check CMM for bar hit
|
174 |
|
|
output [63:0] check_raddr_o, // is address mapped?
|
175 |
|
|
output check_mem32_o,
|
176 |
|
|
output check_mem64_o,
|
177 |
|
|
output check_rio_o, // implies src_rdy
|
178 |
|
|
output check_rdev_o, // implies src_rdy
|
179 |
|
|
output check_rbus_o, // implies src_rdy
|
180 |
|
|
output check_rfun_o, // implies src_rdy
|
181 |
|
|
// Incoming information from CMM on bar hit status
|
182 |
|
|
input check_rhit_i, // match found
|
183 |
|
|
input [BARW-1:0] check_rhit_bar_i, // address of match
|
184 |
|
|
`else // `ifdef AS
|
185 |
|
|
// PI-5 event information for CMM.
|
186 |
|
|
output reg err_tlp_bad_header_crc_o, // Bad HCRC
|
187 |
|
|
output reg err_tlp_bad_pi_chain_o, // Bad PI chain
|
188 |
|
|
output reg err_tlp_bad_credit_length_o, // CR < length
|
189 |
|
|
output reg err_tlp_invalid_credit_length_o, // CR > MPS
|
190 |
|
|
output reg err_tlp_non_zero_turn_pointer_o, // Endpoints only
|
191 |
|
|
output reg err_tlp_unsup_mvc_o, // MVC
|
192 |
|
|
output reg err_tlp_unsup_ovc_o, // OVC
|
193 |
|
|
output reg [159:0] err_tlp_type_b_header_o, // PI-5 rtn. info
|
194 |
|
|
input err_tlp_type_b_ack_i, // PI-5 ack'd
|
195 |
|
|
`endif
|
196 |
|
|
// Static control from CMM
|
197 |
|
|
`ifdef PCIE
|
198 |
|
|
input [2:0] max_payload_i, // Enc val for max paysize allowed
|
199 |
|
|
input rhit_bar_lat3_i, // BAR-hit latency 3 clocks?
|
200 |
|
|
input legacy_mode_i, // For interp of the spec
|
201 |
|
|
input legacy_cfg_access_i,//User implements legacy config?
|
202 |
|
|
input ext_cfg_access_i, // User implements ext. config?
|
203 |
|
|
input hotplug_msg_enable_i,//Pass obsolete hot-plug to user?
|
204 |
|
|
`else // `ifdef AS
|
205 |
|
|
input [3:0] max_payload_i, // Enc val for max paysize allowed
|
206 |
|
|
input switch_mode_i, // Is core a Switch?
|
207 |
|
|
input fabric_manager_mode_i, // Is core a Fabric Manager?
|
208 |
|
|
input [31:0] cfg_ap0_space_end_i, // End of Aperture 0 range
|
209 |
|
|
input [31:0] cfg_ap1_space_start_i, // Start of Aperture 1 range
|
210 |
|
|
input [31:0] cfg_ap1_space_end_i, // End of Aperture 1 range
|
211 |
|
|
`endif
|
212 |
|
|
input td_ecrc_trim_i // Strip digest for user?
|
213 |
|
|
);
|
214 |
|
|
|
215 |
|
|
//--------------------------------------------------------------------------
|
216 |
|
|
// Locally derived constants
|
217 |
|
|
|
218 |
|
|
`ifdef PCIE
|
219 |
|
|
//--------------------------------------------------------------------------
|
220 |
|
|
// Symbolic constants
|
221 |
|
|
|
222 |
|
|
// Full type
|
223 |
|
|
localparam MRD32 = 7'b00_00000;
|
224 |
|
|
localparam MRD64 = 7'b01_00000;
|
225 |
|
|
localparam MRD32LK = 7'b00_00001;
|
226 |
|
|
localparam MRD64LK = 7'b01_00001;
|
227 |
|
|
localparam MWR32 = 7'b10_00000;
|
228 |
|
|
localparam MWR64 = 7'b11_00000;
|
229 |
|
|
localparam IORD = 7'b00_00010;
|
230 |
|
|
localparam IOWR = 7'b10_00010;
|
231 |
|
|
localparam CFGRD0 = 7'b00_00100;
|
232 |
|
|
localparam CFGWR0 = 7'b10_00100;
|
233 |
|
|
localparam CFGRD1 = 7'b00_00101;
|
234 |
|
|
localparam CFGWR1 = 7'b10_00101;
|
235 |
|
|
localparam MSG = 7'b01_10xxx;
|
236 |
|
|
localparam MSGD = 7'b11_10xxx;
|
237 |
|
|
localparam MSGAS = 7'b01_11xxx;
|
238 |
|
|
localparam MSGASD = 7'b11_11xxx;
|
239 |
|
|
localparam CPL = 7'b00_01010;
|
240 |
|
|
localparam CPLD = 7'b10_01010;
|
241 |
|
|
localparam CPLLK = 7'b00_01011;
|
242 |
|
|
localparam CPLDLK = 7'b10_01011;
|
243 |
|
|
// Encoded Full type into "one hots"
|
244 |
|
|
localparam MEM_BIT = 8;
|
245 |
|
|
localparam ADR_BIT = 7;
|
246 |
|
|
localparam MRD_BIT = 6;
|
247 |
|
|
localparam MWR_BIT = 5;
|
248 |
|
|
localparam MLK_BIT = 4;
|
249 |
|
|
localparam IO_BIT = 3;
|
250 |
|
|
localparam CFG_BIT = 2;
|
251 |
|
|
localparam MSG_BIT = 1;
|
252 |
|
|
localparam CPL_BIT = 0;
|
253 |
|
|
|
254 |
|
|
// Memory and address-routed types are given an extra bits to improve
|
255 |
|
|
// timing for BAR checks
|
256 |
|
|
localparam [8:0] OTHERTYPE = 9'b0;
|
257 |
|
|
localparam [8:0] MEMANY = 9'b1 << MEM_BIT;
|
258 |
|
|
localparam [8:0] ADRANY = 9'b1 << ADR_BIT;
|
259 |
|
|
localparam [8:0] MRDANY = (9'b1 << MRD_BIT) | ADRANY | MEMANY;
|
260 |
|
|
localparam [8:0] MWRANY = (9'b1 << MWR_BIT) | ADRANY | MEMANY;
|
261 |
|
|
localparam [8:0] MLKANY = (9'b1 << MLK_BIT) | ADRANY | MEMANY;
|
262 |
|
|
localparam [8:0] IOANY = (9'b1 << IO_BIT) | ADRANY;
|
263 |
|
|
localparam [8:0] CFGANY = 9'b1 << CFG_BIT;
|
264 |
|
|
localparam [8:0] MSGANY = 9'b1 << MSG_BIT;
|
265 |
|
|
localparam [8:0] CPLANY = 9'b1 << CPL_BIT;
|
266 |
|
|
// Message code
|
267 |
|
|
localparam UNLOCK = 8'b0000_0000;
|
268 |
|
|
localparam PM_ACTIVE_STATE_NAK = 8'b0001_0100;
|
269 |
|
|
localparam PM_PME = 8'b0001_1000;
|
270 |
|
|
localparam PME_TURN_OFF = 8'b0001_1001;
|
271 |
|
|
localparam PME_TO_ACK = 8'b0001_1011;
|
272 |
|
|
localparam ATTENTION_INDICATOR_OFF = 8'b0100_0000;
|
273 |
|
|
localparam ATTENTION_INDICATOR_ON = 8'b0100_0001;
|
274 |
|
|
localparam ATTENTION_INDICATOR_BLINK = 8'b0100_0011;
|
275 |
|
|
localparam POWER_INDICATOR_ON = 8'b0100_0101;
|
276 |
|
|
localparam POWER_INDICATOR_BLINK = 8'b0100_0111;
|
277 |
|
|
localparam POWER_INDICATOR_OFF = 8'b0100_0100;
|
278 |
|
|
localparam ATTENTION_BUTTON_PRESSED = 8'b0100_1000;
|
279 |
|
|
localparam SET_SLOT_POWER_LIMIT = 8'b0101_0000;
|
280 |
|
|
localparam VENDOR_DEFINED_TYPE_0 = 8'b0111_1110;
|
281 |
|
|
localparam VENDOR_DEFINED_TYPE_1 = 8'b0111_1111;
|
282 |
|
|
// Route
|
283 |
|
|
localparam ROUTE_BY_ID = 3'b010;
|
284 |
|
|
// Format
|
285 |
|
|
localparam FMT_3DW_NODATA = 2'b00;
|
286 |
|
|
localparam FMT_4DW_NODATA = 2'b01;
|
287 |
|
|
localparam FMT_3DW_WDATA = 2'b10;
|
288 |
|
|
localparam FMT_4DW_WDATA = 2'b11;
|
289 |
|
|
// Completion status
|
290 |
|
|
localparam CPL_STAT_SC = 3'b000;
|
291 |
|
|
localparam CPL_STAT_UR = 3'b001;
|
292 |
|
|
localparam CPL_STAT_CRS = 3'b010;
|
293 |
|
|
localparam CPL_STAT_CA = 3'b100;
|
294 |
|
|
`endif // `ifdef PCIE
|
295 |
|
|
|
296 |
|
|
//------------------------------------------------------------------
|
297 |
|
|
// Bit indices for aliasing
|
298 |
|
|
|
299 |
|
|
`ifdef PCIE
|
300 |
|
|
// First Dword
|
301 |
|
|
localparam FULLTYPE_HI_IND = DW-2;
|
302 |
|
|
localparam FULLTYPE_LO_IND = DW-8;
|
303 |
|
|
localparam TC_HI_IND = DW-10;
|
304 |
|
|
localparam TC_LO_IND = DW-12;
|
305 |
|
|
localparam TD_IND = DW-17;
|
306 |
|
|
localparam EP_IND = DW-18;
|
307 |
|
|
localparam ATTR_HI_IND = DW-19;
|
308 |
|
|
localparam ATTR_LO_IND = DW-20;
|
309 |
|
|
localparam LENGTH_HI_IND = DW-23;
|
310 |
|
|
localparam LENGTH_LO_IND = DW-32;
|
311 |
|
|
// Second Dword
|
312 |
|
|
localparam REQ_ID_HI_IND = 31;
|
313 |
|
|
localparam REQ_ID_LO_IND = 16;
|
314 |
|
|
localparam TAG_HI_IND = 15;
|
315 |
|
|
localparam TAG_LO_IND = 8;
|
316 |
|
|
localparam CPL_STAT_HI_IND = 15;
|
317 |
|
|
localparam CPL_STAT_LO_IND = 13;
|
318 |
|
|
// Third Dword
|
319 |
|
|
localparam REQ_ID_CPL_HI_IND = DW-1;
|
320 |
|
|
localparam REQ_ID_CPL_LO_IND = DW-16;
|
321 |
|
|
localparam LOWER_ADDR32_HI_IND = DW-26;
|
322 |
|
|
localparam LOWER_ADDR32_LO_IND = DW-30;
|
323 |
|
|
localparam APERTURE_HI_IND = DW-21;
|
324 |
|
|
localparam APERTURE_LO_IND = DW-24;
|
325 |
|
|
localparam OFFSET_HI_IND = DW-25;
|
326 |
|
|
localparam OFFSET_LO_IND = DW-30;
|
327 |
|
|
// Fourth Dword
|
328 |
|
|
localparam LOWER_ADDR64_HI_IND = 6;
|
329 |
|
|
localparam LOWER_ADDR64_LO_IND = 2;
|
330 |
|
|
// Data
|
331 |
|
|
localparam SET_SLOT_PWRVAL_HI_IND = DW-1;
|
332 |
|
|
localparam SET_SLOT_PWRVAL_LO_IND = DW-8;
|
333 |
|
|
localparam SET_SLOT_PWRSCL_HI_IND = DW-15;
|
334 |
|
|
localparam SET_SLOT_PWRSCL_LO_IND = DW-16;
|
335 |
|
|
`else // `ifdef AS
|
336 |
|
|
// First Dword
|
337 |
|
|
localparam PI_1ST_HI_IND = DW-26;
|
338 |
|
|
localparam PI_1ST_LO_IND = DW-32;
|
339 |
|
|
localparam TC_HI_IND = DW-21;
|
340 |
|
|
localparam TC_LO_IND = DW-23;
|
341 |
|
|
localparam TD_IND = DW-24;
|
342 |
|
|
localparam OO_IND = DW-20;
|
343 |
|
|
localparam TS_IND = DW-19;
|
344 |
|
|
localparam LENGTH_HI_IND = DW-14;
|
345 |
|
|
localparam LENGTH_LO_IND = DW-18;
|
346 |
|
|
localparam TURN_PTR_HI_IND = DW-8;
|
347 |
|
|
localparam TURN_PTR_LO_IND = DW-12;
|
348 |
|
|
localparam HCRC_HI_IND = DW-1;
|
349 |
|
|
localparam HCRC_LO_IND = DW-7;
|
350 |
|
|
// Second Dword
|
351 |
|
|
localparam TURN_POOL_HI_IND= 30;
|
352 |
|
|
localparam TURN_POOL_LO_IND= 0;
|
353 |
|
|
localparam DIR_IND = 31;
|
354 |
|
|
// Third Dword
|
355 |
|
|
localparam PI_2ND_HI_IND = DW-26;
|
356 |
|
|
localparam PI_2ND_LO_IND = DW-32;
|
357 |
|
|
localparam APERTURE_HI_IND = DW-29;
|
358 |
|
|
localparam APERTURE_LO_IND = DW-32;
|
359 |
|
|
// Fourth Dword
|
360 |
|
|
localparam PI_3RD_HI_IND = 6;
|
361 |
|
|
localparam PI_3RD_LO_IND = 0;
|
362 |
|
|
localparam OFFSET_HI_IND = 31;
|
363 |
|
|
localparam OFFSET_LO_IND = 2;
|
364 |
|
|
// Fifth Dword
|
365 |
|
|
localparam PI_4TH_HI_IND = DW-26;
|
366 |
|
|
localparam PI_4TH_LO_IND = DW-32;
|
367 |
|
|
`endif
|
368 |
|
|
|
369 |
|
|
// Delayed versions of input signals
|
370 |
|
|
//--------------------------------------------------------
|
371 |
|
|
reg [6:1] sof_q;
|
372 |
|
|
reg [6:1] eof_q;
|
373 |
|
|
reg [6:1] eof_nd_q;
|
374 |
|
|
reg [6:1] src_rdy_q;
|
375 |
|
|
reg [6:1] dsc_q;
|
376 |
|
|
reg [6:1] rem_q;
|
377 |
|
|
reg cur_rem; // before TD change
|
378 |
|
|
reg packet_ip;
|
379 |
|
|
wire [DW-1:0] d_mux;
|
380 |
|
|
reg [DW-1:0] d_q1, d_q2, d_q3, d_q4, d_q5, d_q6;
|
381 |
|
|
// 2D makes NC unhappy
|
382 |
|
|
|
383 |
|
|
//====================================================================
|
384 |
|
|
// Because certain operations take more time than might be available
|
385 |
|
|
// in a packet, we need the information for the packet that's arriving
|
386 |
|
|
// as well as the information from the packet that is exiting. Since
|
387 |
|
|
// we're immediately registering the values when they come in we can
|
388 |
|
|
// alias the D-input of the flops right to the data coming in.
|
389 |
|
|
//====================================================================
|
390 |
|
|
|
391 |
|
|
//----------------------------------------------------------
|
392 |
|
|
// Latch enable signals
|
393 |
|
|
//----------------------------------------------------------
|
394 |
|
|
// 64 bit 32 bit
|
395 |
|
|
// ------------- ------
|
396 |
|
|
// sof_i | DW 1 | DW 2 | | DW 1 |
|
397 |
|
|
// sof_q1 | DW 3 | DW 4 | | DW 2 |
|
398 |
|
|
// sof_q2 ------------- | DW 3 |
|
399 |
|
|
// sof_q3 | DW 4 |
|
400 |
|
|
// ------
|
401 |
|
|
|
402 |
|
|
wire latch_1st_dword = sof_i && src_rdy_i;
|
403 |
|
|
reg latch_1st_dword_q1, latch_1st_dword_q2,
|
404 |
|
|
latch_1st_dword_q3, latch_1st_dword_q4;
|
405 |
|
|
wire latch_2nd_dword = (DW == 32) ? sof_q[1]:
|
406 |
|
|
sof_i && src_rdy_i;
|
407 |
|
|
reg latch_2nd_dword_q1, latch_2nd_dword_q2;
|
408 |
|
|
wire latch_3rd_dword = (DW == 32) ? sof_q[2] : sof_q[1];
|
409 |
|
|
reg latch_3rd_dword_q1;
|
410 |
|
|
wire latch_4th_dword = (DW == 32) ? sof_q[3] : sof_q[1];
|
411 |
|
|
reg latch_4th_dword_q1;
|
412 |
|
|
`ifdef AS
|
413 |
|
|
wire latch_5th_dword = (DW == 32) ? sof_q[4] : sof_q[2];
|
414 |
|
|
`endif
|
415 |
|
|
|
416 |
|
|
//-----------------------------------------------------------
|
417 |
|
|
// First Dword
|
418 |
|
|
//-----------------------------------------------------------
|
419 |
|
|
`ifdef PCIE
|
420 |
|
|
// Fulltype is used in packet type determination, and header type
|
421 |
|
|
wire [6:0] fulltype_in = d_i[FULLTYPE_HI_IND:FULLTYPE_LO_IND];
|
422 |
|
|
reg [6:0] cur_fulltype;
|
423 |
|
|
reg cur_fulltype_64, cur_fulltype_mem;
|
424 |
|
|
wire cur_has_data = cur_fulltype[6];
|
425 |
|
|
wire [2:0] cur_routing = cur_fulltype[2:0];
|
426 |
|
|
reg [8:0] cur_fulltype_oh;
|
427 |
|
|
reg cur_locked, cur_locked_q;
|
428 |
|
|
reg cur_cpl;
|
429 |
|
|
|
430 |
|
|
// Traffic class needs to be 0 for certain packets, also to CMM cpl
|
431 |
|
|
wire [2:0] tc_in = d_i[TC_HI_IND:TC_LO_IND];
|
432 |
|
|
reg [2:0] cur_tc;
|
433 |
|
|
reg cur_tc0;
|
434 |
|
|
|
435 |
|
|
// The error poisoned bit gets forwarded with the packet
|
436 |
|
|
wire ep_in = d_i[EP_IND];
|
437 |
|
|
reg cur_ep, cur_ep_q;
|
438 |
|
|
|
439 |
|
|
// Attributes needs to be know for the CMM to construct a completion
|
440 |
|
|
wire [1:0] attr_in = d_i[ATTR_HI_IND:ATTR_LO_IND];
|
441 |
|
|
reg [1:0] cur_attr;
|
442 |
|
|
`else // `ifdef AS
|
443 |
|
|
// Primary PI
|
444 |
|
|
wire [6:0] pi_1st = d_i[PI_1ST_HI_IND:PI_1ST_LO_IND];
|
445 |
|
|
|
446 |
|
|
// Header CRC
|
447 |
|
|
reg [6:0] cur_hcrc;
|
448 |
|
|
|
449 |
|
|
// Turn Pointer
|
450 |
|
|
reg [4:0] cur_turn_pointer;
|
451 |
|
|
|
452 |
|
|
// Ordered-Only and Type-Specific
|
453 |
|
|
reg cur_oo, cur_ts;
|
454 |
|
|
`endif
|
455 |
|
|
|
456 |
|
|
// TLP Digest/PCRC
|
457 |
|
|
wire td_in = d_i[TD_IND];
|
458 |
|
|
reg cur_td, cur_td_q;
|
459 |
|
|
|
460 |
|
|
// Length/Credits Required is used in correct length determination
|
461 |
|
|
localparam LENW = LENGTH_HI_IND - LENGTH_LO_IND + 1;
|
462 |
|
|
|
463 |
|
|
wire [9:0] length_in = d_i[LENGTH_HI_IND:LENGTH_LO_IND];
|
464 |
|
|
reg [9:0] cur_length;
|
465 |
|
|
`ifdef PCIE
|
466 |
|
|
reg cur_length1;
|
467 |
|
|
`else // `ifdef AS
|
468 |
|
|
reg np_o; // Local in AS, needed for credit tracking
|
469 |
|
|
`endif
|
470 |
|
|
|
471 |
|
|
reg cur_np;
|
472 |
|
|
wire cur_cfg;
|
473 |
|
|
|
474 |
|
|
//----------------------------------------------------------
|
475 |
|
|
// Second Dword
|
476 |
|
|
//----------------------------------------------------------
|
477 |
|
|
`ifdef PCIE
|
478 |
|
|
wire [15:0] req_id_in = d_i[REQ_ID_HI_IND:REQ_ID_LO_IND];
|
479 |
|
|
reg [15:0] cur_req_id;
|
480 |
|
|
|
481 |
|
|
// Used in CMM cpl to mark pkts
|
482 |
|
|
wire [7:0] tag_in = d_i[TAG_HI_IND:TAG_LO_IND];
|
483 |
|
|
reg [7:0] cur_tag;
|
484 |
|
|
|
485 |
|
|
// Byte enables on boundaries
|
486 |
|
|
wire [3:0] last_be_in = d_i[7:4];
|
487 |
|
|
reg [1:0] last_be_missing;
|
488 |
|
|
wire [3:0] first_be_in = d_i[3:0];
|
489 |
|
|
reg [1:0] cur_first_be_adj;
|
490 |
|
|
reg [1:0] first_be_missing;
|
491 |
|
|
reg [2:0] cur_bytes_missing;
|
492 |
|
|
reg [2:0] cur_byte_ct_1dw;
|
493 |
|
|
reg [2:0] byte_ct_1dw;
|
494 |
|
|
|
495 |
|
|
// Message types
|
496 |
|
|
wire [7:0] msgcode_in = d_i[7:0];
|
497 |
|
|
reg [7:0] cur_msgcode;
|
498 |
|
|
reg cur_vend_msg;
|
499 |
|
|
`else // `ifdef AS
|
500 |
|
|
// Turn Pool and Routing Direction
|
501 |
|
|
reg [30:0] cur_turn_pool;
|
502 |
|
|
reg cur_dir;
|
503 |
|
|
|
504 |
|
|
// Route header (for Header CRC check, actually covers 2 DW)
|
505 |
|
|
reg [50:0] cur_route_header;
|
506 |
|
|
`endif
|
507 |
|
|
|
508 |
|
|
//----------------------------------------------------------
|
509 |
|
|
// Third Dword
|
510 |
|
|
//----------------------------------------------------------
|
511 |
|
|
`ifdef PCIE
|
512 |
|
|
wire [15:0] req_id_cpl_in = d_i[REQ_ID_CPL_HI_IND:
|
513 |
|
|
REQ_ID_CPL_LO_IND];
|
514 |
|
|
wire [31:0] addr_hi_in = d_i[DW-1:DW-32];
|
515 |
|
|
reg [31:0] cur_addr_hi;
|
516 |
|
|
wire [6:2] lower_addr32_in = d_i[LOWER_ADDR32_HI_IND:
|
517 |
|
|
LOWER_ADDR32_LO_IND];
|
518 |
|
|
wire [6:2] lower_addr64_in = d_i[LOWER_ADDR64_HI_IND:
|
519 |
|
|
LOWER_ADDR64_LO_IND];
|
520 |
|
|
reg [6:2] lower_addr32_in_q, lower_addr64_in_q;
|
521 |
|
|
wire [2:0] cpl_stat_in = d_i[CPL_STAT_HI_IND:
|
522 |
|
|
CPL_STAT_LO_IND];
|
523 |
|
|
reg [2:0] cur_cpl_stat;
|
524 |
|
|
`else // `ifdef AS
|
525 |
|
|
// Secondary PI
|
526 |
|
|
wire [6:0] pi_2nd = d_i[PI_2ND_HI_IND:PI_2ND_LO_IND];
|
527 |
|
|
`endif
|
528 |
|
|
|
529 |
|
|
// PCIe config extended reg. number or AS PI-4 config address aperture
|
530 |
|
|
wire [3:0] aperture = d_i[APERTURE_HI_IND:APERTURE_LO_IND];
|
531 |
|
|
|
532 |
|
|
//----------------------------------------------------------
|
533 |
|
|
// Third/Fourth Dword
|
534 |
|
|
//----------------------------------------------------------
|
535 |
|
|
|
536 |
|
|
// Config TLP (3rd DW) or PI-4 config (4th DW) address offset
|
537 |
|
|
wire [OFFSET_HI_IND-OFFSET_LO_IND+2:0] offset;
|
538 |
|
|
|
539 |
|
|
assign offset = {d_i[OFFSET_HI_IND:OFFSET_LO_IND],2'b00};
|
540 |
|
|
|
541 |
|
|
//----------------------------------------------------------
|
542 |
|
|
// Fourth Dword
|
543 |
|
|
//----------------------------------------------------------
|
544 |
|
|
`ifdef PCIE
|
545 |
|
|
wire [31:0] addr_lo_i = d_i[31:0];
|
546 |
|
|
`else // `ifdef AS
|
547 |
|
|
// Tertiary PI
|
548 |
|
|
wire [6:0] pi_3rd = d_i[PI_3RD_HI_IND:PI_3RD_LO_IND];
|
549 |
|
|
`endif
|
550 |
|
|
|
551 |
|
|
`ifdef AS
|
552 |
|
|
//----------------------------------------------------------
|
553 |
|
|
// Fifth Dword
|
554 |
|
|
//----------------------------------------------------------
|
555 |
|
|
// Quaternary PI
|
556 |
|
|
wire [6:0] pi_4th = d_i[PI_4TH_HI_IND:PI_4TH_LO_IND];
|
557 |
|
|
`endif
|
558 |
|
|
|
559 |
|
|
`ifdef PCIE
|
560 |
|
|
//----------------------------------------------------------
|
561 |
|
|
// Data
|
562 |
|
|
//----------------------------------------------------------
|
563 |
|
|
wire [9:0] pwr_data_i = {d_i[SET_SLOT_PWRSCL_HI_IND:
|
564 |
|
|
SET_SLOT_PWRSCL_LO_IND],
|
565 |
|
|
d_i[SET_SLOT_PWRVAL_HI_IND:
|
566 |
|
|
SET_SLOT_PWRVAL_LO_IND]};
|
567 |
|
|
`endif
|
568 |
|
|
|
569 |
|
|
//----------------------------------------------------------
|
570 |
|
|
// Derived signals
|
571 |
|
|
//----------------------------------------------------------
|
572 |
|
|
// Data credits
|
573 |
|
|
wire [FCW-1:0] cur_data_credits;
|
574 |
|
|
wire cur_data_credits_vld;
|
575 |
|
|
reg [FCW-1:0] fc_use_data_d;
|
576 |
|
|
// Digest removal
|
577 |
|
|
reg remove_lastword;
|
578 |
|
|
// Bad or dropped packets
|
579 |
|
|
`ifdef PCIE
|
580 |
|
|
wire malformed;
|
581 |
|
|
wire tlp_ur;
|
582 |
|
|
wire tlp_ur_lock;
|
583 |
|
|
wire tlp_uc;
|
584 |
|
|
wire tlp_filt;
|
585 |
|
|
reg [6:0] cur_lower_addr; // used to assemble cpl's
|
586 |
|
|
reg [11:0] cur_byte_ct; // ''
|
587 |
|
|
`else // `ifdef AS
|
588 |
|
|
wire bad_header_crc;
|
589 |
|
|
wire bad_pi_chain;
|
590 |
|
|
wire bad_credit_length;
|
591 |
|
|
wire invalid_credit_length;
|
592 |
|
|
wire non_zero_turn_pointer;
|
593 |
|
|
wire unsup_mvc;
|
594 |
|
|
wire unsup_ovc;
|
595 |
|
|
wire filter_drop;
|
596 |
|
|
`endif
|
597 |
|
|
reg cur_drop, next_cur_drop;
|
598 |
|
|
`ifdef PCIE
|
599 |
|
|
// Power management
|
600 |
|
|
reg pwr_mgmt_mode_on;
|
601 |
|
|
wire cur_pm_msg_detect;
|
602 |
|
|
// packet types
|
603 |
|
|
reg np_d, cpl_d, cfg_d, locked_d, vend_msg_d;
|
604 |
|
|
// bar checks
|
605 |
|
|
wire [BARW-1:0] rhit_bar_d;
|
606 |
|
|
wire rhit_src_rdy;
|
607 |
|
|
wire rhit_ack;
|
608 |
|
|
wire rhit_lock;
|
609 |
|
|
// cmm status
|
610 |
|
|
reg cur_cpl_ep, cur_cpl_abort, cur_cpl_ur;
|
611 |
|
|
reg [28:0] cur_cpl_header_fmt;
|
612 |
|
|
reg [47:0] err_tlp_cpl_header_d;
|
613 |
|
|
// obsolete packet types (hot-plug)
|
614 |
|
|
wire cur_hp_msg_detect;
|
615 |
|
|
`else // `ifdef AS
|
616 |
|
|
// Storage of Type B header
|
617 |
|
|
reg [5:0] load_type_b;
|
618 |
|
|
reg type_b_pending;
|
619 |
|
|
wire wr_hdr;
|
620 |
|
|
wire rd_hdr;
|
621 |
|
|
wire sof_hdr;
|
622 |
|
|
wire [DW-1:0] hdr;
|
623 |
|
|
`endif
|
624 |
|
|
// data-path sync
|
625 |
|
|
wire [2:0] out_d1;
|
626 |
|
|
wire [2:0] out_d2;
|
627 |
|
|
wire [2:0] out_d3;
|
628 |
|
|
|
629 |
|
|
|
630 |
|
|
//================================================================
|
631 |
|
|
// EOF/Discontinue
|
632 |
|
|
//================================================================
|
633 |
|
|
// Synchronize EOF events, including error reporting
|
634 |
|
|
//----------------------------------------------------------------
|
635 |
|
|
|
636 |
|
|
`ifdef PCIE
|
637 |
|
|
assign out_d1 = rhit_bar_lat3_i ? 6 : 5;
|
638 |
|
|
`else // `ifdef AS
|
639 |
|
|
assign out_d1 = 4;
|
640 |
|
|
`endif
|
641 |
|
|
assign out_d2 = out_d1 - 1;
|
642 |
|
|
assign out_d3 = out_d1 - 2;
|
643 |
|
|
|
644 |
|
|
|
645 |
|
|
//====================================================
|
646 |
|
|
// Credit transmissions
|
647 |
|
|
//====================================================
|
648 |
|
|
// Output registers that drive the flow controller
|
649 |
|
|
//----------------------------------------------------
|
650 |
|
|
always @(posedge clk_i) begin
|
651 |
|
|
if (reset_i) begin
|
652 |
|
|
fc_use_p_o <= #`TCQ 0;
|
653 |
|
|
fc_use_np_o <= #`TCQ 0;
|
654 |
|
|
`ifdef PCIE
|
655 |
|
|
fc_use_cpl_o <= #`TCQ 0;
|
656 |
|
|
`endif
|
657 |
|
|
fc_unuse_o <= #`TCQ 0;
|
658 |
|
|
|
659 |
|
|
// At this point we know if the packet is correctly
|
660 |
|
|
// formed..
|
661 |
|
|
// np and cpl we can directly use the same control
|
662 |
|
|
// going to the FIFO
|
663 |
|
|
end else if (eof_q[out_d2] && !dsc_q[out_d2]) begin
|
664 |
|
|
fc_use_np_o <= #`TCQ np_o;
|
665 |
|
|
`ifdef PCIE
|
666 |
|
|
fc_use_p_o <= #`TCQ !np_o && !cpl_o;
|
667 |
|
|
fc_use_cpl_o <= #`TCQ cpl_o;
|
668 |
|
|
`else // `ifdef AS
|
669 |
|
|
fc_use_p_o <= #`TCQ !np_o;
|
670 |
|
|
`endif
|
671 |
|
|
// Packets that we dropped because we signal them
|
672 |
|
|
// sideband or they are invalid, we 'fake' out
|
673 |
|
|
// the flow controller by freeing those packets
|
674 |
|
|
// immediately
|
675 |
|
|
// Dsc in from the LLM is the only case we don't
|
676 |
|
|
// do this-- which has priority over invalid
|
677 |
|
|
// packets
|
678 |
|
|
fc_unuse_o <= #`TCQ next_cur_drop;
|
679 |
|
|
|
680 |
|
|
// all signals imply src ready, return back to zero
|
681 |
|
|
end else begin
|
682 |
|
|
fc_use_p_o <= #`TCQ 0;
|
683 |
|
|
fc_use_np_o <= #`TCQ 0;
|
684 |
|
|
`ifdef PCIE
|
685 |
|
|
fc_use_cpl_o <= #`TCQ 0;
|
686 |
|
|
`endif
|
687 |
|
|
fc_unuse_o <= #`TCQ 0;
|
688 |
|
|
end
|
689 |
|
|
end
|
690 |
|
|
|
691 |
|
|
// cur_data_credits may only be valid until eof_q3.. but
|
692 |
|
|
// since this signal only has a quantity, latch it earlier
|
693 |
|
|
always @(posedge clk_i) begin
|
694 |
|
|
`ifdef PCIE
|
695 |
|
|
if (!rhit_bar_lat3_i || (DW == 32))
|
696 |
|
|
`endif
|
697 |
|
|
begin
|
698 |
|
|
if (cur_data_credits_vld) begin
|
699 |
|
|
fc_use_data_o <= #`TCQ cur_data_credits;
|
700 |
|
|
end
|
701 |
|
|
fc_use_data_d <= #`TCQ 0;
|
702 |
|
|
`ifdef PCIE
|
703 |
|
|
end else begin
|
704 |
|
|
if (cur_data_credits_vld) begin
|
705 |
|
|
fc_use_data_d <= #`TCQ cur_data_credits;
|
706 |
|
|
end
|
707 |
|
|
fc_use_data_o <= #`TCQ fc_use_data_d;
|
708 |
|
|
`endif
|
709 |
|
|
end
|
710 |
|
|
end
|
711 |
|
|
|
712 |
|
|
`ifdef PCIE
|
713 |
|
|
//====================================================
|
714 |
|
|
// Status register updates for the CMM's registers
|
715 |
|
|
//====================================================
|
716 |
|
|
// Output registers
|
717 |
|
|
//-------------------------------------------------
|
718 |
|
|
always @(posedge clk_i) begin
|
719 |
|
|
if (reset_i) begin
|
720 |
|
|
stat_tlp_ep_o <= #`TCQ 0;
|
721 |
|
|
stat_tlp_cpl_ep_o <= #`TCQ 0;
|
722 |
|
|
stat_tlp_cpl_abort_o <= #`TCQ 0;
|
723 |
|
|
stat_tlp_cpl_ur_o <= #`TCQ 0;
|
724 |
|
|
|
725 |
|
|
// at this point we know if the packet is valid so we
|
726 |
|
|
// can safely communicate these status fields to the
|
727 |
|
|
// cmm.. we can wait until eof5, because we might lose
|
728 |
|
|
// the ep bit when multiple packets are in the pipe for
|
729 |
|
|
// 64 bit
|
730 |
|
|
end else if (eof_q[out_d2] && !dsc_q[out_d2] && !next_cur_drop) begin
|
731 |
|
|
stat_tlp_ep_o <= #`TCQ cur_ep_q;
|
732 |
|
|
stat_tlp_cpl_ep_o <= #`TCQ cur_cpl_ep;
|
733 |
|
|
stat_tlp_cpl_abort_o <= #`TCQ cur_cpl_abort;
|
734 |
|
|
stat_tlp_cpl_ur_o <= #`TCQ cur_cpl_ur;
|
735 |
|
|
|
736 |
|
|
// all signals imply source ready, return to zero
|
737 |
|
|
end else begin
|
738 |
|
|
stat_tlp_ep_o <= #`TCQ 0;
|
739 |
|
|
stat_tlp_cpl_ep_o <= #`TCQ 0;
|
740 |
|
|
stat_tlp_cpl_abort_o <= #`TCQ 0;
|
741 |
|
|
stat_tlp_cpl_ur_o <= #`TCQ 0;
|
742 |
|
|
end
|
743 |
|
|
end
|
744 |
|
|
always @(posedge clk_i) begin
|
745 |
|
|
if (reset_i) begin
|
746 |
|
|
cur_cpl_ep <= #`TCQ 0;
|
747 |
|
|
cur_cpl_abort <= #`TCQ 0;
|
748 |
|
|
cur_cpl_ur <= #`TCQ 0;
|
749 |
|
|
end else if (latch_2nd_dword_q2) begin
|
750 |
|
|
// We need to know if completions are poisoned, or if have
|
751 |
|
|
// their status fields set to abort or ur.
|
752 |
|
|
// We're stealing one cycle to keep these calcs valid for
|
753 |
|
|
// the output drivers
|
754 |
|
|
if (cur_fulltype_oh[CPL_BIT]) begin
|
755 |
|
|
cur_cpl_ep <= #`TCQ cur_ep;
|
756 |
|
|
cur_cpl_abort <= #`TCQ cur_cpl_stat == CPL_STAT_CA;
|
757 |
|
|
cur_cpl_ur <= #`TCQ cur_cpl_stat == CPL_STAT_UR;
|
758 |
|
|
end else begin
|
759 |
|
|
cur_cpl_ep <= #`TCQ 0;
|
760 |
|
|
cur_cpl_abort <= #`TCQ 0;
|
761 |
|
|
cur_cpl_ur <= #`TCQ 0;
|
762 |
|
|
end
|
763 |
|
|
end
|
764 |
|
|
end
|
765 |
|
|
|
766 |
|
|
//================================================================
|
767 |
|
|
// In the case of malformed packets, communicate data to the CMM
|
768 |
|
|
// such that it can construct the completion header
|
769 |
|
|
//================================================================
|
770 |
|
|
always @(posedge clk_i) begin
|
771 |
|
|
if (reset_i) begin
|
772 |
|
|
err_tlp_malformed_o <= #`TCQ 0;
|
773 |
|
|
err_tlp_ur_o <= #`TCQ 0;
|
774 |
|
|
err_tlp_ur_lock_o <= #`TCQ 0;
|
775 |
|
|
err_tlp_uc_o <= #`TCQ 0;
|
776 |
|
|
err_tlp_p_o <= #`TCQ 0;
|
777 |
|
|
// If the LNK signaled dsc, then the packet never happened
|
778 |
|
|
// if not, we can signal malformed
|
779 |
|
|
// if not malformed, we can signal ur or uc
|
780 |
|
|
// wait until eof4/5 -> the earliest time bar misses are known
|
781 |
|
|
// as well as if the packet has invalid length
|
782 |
|
|
// We don't need a return to 0 because eof is in the logic signal
|
783 |
|
|
end else begin
|
784 |
|
|
err_tlp_malformed_o <= #`TCQ eof_nd_q[out_d2] && malformed;
|
785 |
|
|
err_tlp_ur_o <= #`TCQ (eof_nd_q[out_d2] && !malformed) && tlp_ur;
|
786 |
|
|
err_tlp_ur_lock_o <= #`TCQ (eof_nd_q[out_d2] && !malformed) && tlp_ur_lock;
|
787 |
|
|
err_tlp_uc_o <= #`TCQ (eof_nd_q[out_d2] && !malformed) && tlp_uc;
|
788 |
|
|
// posted continuously valid -> no eof
|
789 |
|
|
err_tlp_p_o <= #`TCQ !np_o;
|
790 |
|
|
end
|
791 |
|
|
end
|
792 |
|
|
|
793 |
|
|
// The header is only looked at if there was a problem, always latch
|
794 |
|
|
always @(posedge clk_i) begin
|
795 |
|
|
// In order to save 48 flops, steal some time by delaying capture of
|
796 |
|
|
// err_tlp_cpl_header as long as possible.
|
797 |
|
|
// In 64-bit, worst case is eof_q2 of next == eof_q4 of current.
|
798 |
|
|
// Current errors are latched on eof_q4, so we need to wait until
|
799 |
|
|
// AFTER eof_q2 of next to make sure the next err_tlp_cpl_header is
|
800 |
|
|
// not associated with any current TLP error.
|
801 |
|
|
if (!rhit_bar_lat3_i || (DW == 32)) begin
|
802 |
|
|
if (eof_q[3]) begin
|
803 |
|
|
err_tlp_cpl_header_o <= #`TCQ {cur_lower_addr, cur_byte_ct,
|
804 |
|
|
cur_cpl_header_fmt};
|
805 |
|
|
end
|
806 |
|
|
|
807 |
|
|
// Unfortunately, we cannot do this in case of a three-clock BAR
|
808 |
|
|
// latency with a 64-bit data path as the minimum TLP size is only
|
809 |
|
|
// two clocks.
|
810 |
|
|
end else begin
|
811 |
|
|
if (eof_q[3]) begin
|
812 |
|
|
err_tlp_cpl_header_d <= #`TCQ {cur_lower_addr, cur_byte_ct,
|
813 |
|
|
cur_cpl_header_fmt};
|
814 |
|
|
end
|
815 |
|
|
err_tlp_cpl_header_o <= #`TCQ err_tlp_cpl_header_d;
|
816 |
|
|
end
|
817 |
|
|
end
|
818 |
|
|
|
819 |
|
|
always @(posedge clk_i) begin
|
820 |
|
|
// For 64b, the most we can wait is 2 cycles for either 1st or
|
821 |
|
|
// 2nd word. For 32b, we can wait 3 cycles on the 1st word
|
822 |
|
|
// because we are guaranteed a gap
|
823 |
|
|
if (latch_2nd_dword_q2) begin
|
824 |
|
|
cur_cpl_header_fmt <= #`TCQ {cur_tc, cur_attr, cur_req_id, cur_tag};
|
825 |
|
|
end
|
826 |
|
|
end
|
827 |
|
|
`endif
|
828 |
|
|
|
829 |
|
|
// Packets are dropped when they're malformed, unexpected/unsupported,
|
830 |
|
|
// filtered or signaled sideband to the LLM such as power management.
|
831 |
|
|
// This does not contain dsc, which has different credit rules. We
|
832 |
|
|
// use the "next" signal in another place, which is why the flop is
|
833 |
|
|
// split out from the logic cloud.
|
834 |
|
|
//--------------------------------------------------------------------
|
835 |
|
|
always @* begin
|
836 |
|
|
if (eof_q[out_d2]) begin
|
837 |
|
|
`ifdef PCIE
|
838 |
|
|
next_cur_drop = malformed || tlp_ur || tlp_uc || cur_pm_msg_detect ||
|
839 |
|
|
tlp_filt || (!hotplug_msg_enable_i && cur_hp_msg_detect);
|
840 |
|
|
`else // `ifdef AS
|
841 |
|
|
next_cur_drop = bad_header_crc || bad_pi_chain || bad_credit_length ||
|
842 |
|
|
invalid_credit_length || non_zero_turn_pointer ||
|
843 |
|
|
unsup_ovc || unsup_mvc || filter_drop;
|
844 |
|
|
`endif
|
845 |
|
|
end else begin
|
846 |
|
|
next_cur_drop = 0;
|
847 |
|
|
end
|
848 |
|
|
end
|
849 |
|
|
|
850 |
|
|
always @(posedge clk_i) begin
|
851 |
|
|
if (reset_i) begin
|
852 |
|
|
cur_drop <= #`TCQ 0;
|
853 |
|
|
end else begin
|
854 |
|
|
cur_drop <= #`TCQ next_cur_drop;
|
855 |
|
|
end
|
856 |
|
|
end
|
857 |
|
|
|
858 |
|
|
//====================================================================
|
859 |
|
|
// Instantiation of malformed checks/drops
|
860 |
|
|
// power management checks/drops
|
861 |
|
|
// bar hits/drops
|
862 |
|
|
// These are scheduled when we know that the fields are able to be
|
863 |
|
|
// latched. All power managment sidebands are not allowed to actually
|
864 |
|
|
// activate until we know that the packet is sound.
|
865 |
|
|
//====================================================================
|
866 |
|
|
|
867 |
|
|
tlm_rx_data_snk_mal #(
|
868 |
|
|
.DW (DW),
|
869 |
|
|
.FCW (FCW),
|
870 |
|
|
`ifdef PCIE
|
871 |
|
|
.DOWNSTREAM_PORT (DOWNSTREAM_PORT),
|
872 |
|
|
`else // `ifdef AS
|
873 |
|
|
.OVC (OVC),
|
874 |
|
|
.MVC (MVC),
|
875 |
|
|
`endif
|
876 |
|
|
.MPS (MPS),
|
877 |
|
|
.TYPE1_UR (TYPE1_UR))
|
878 |
|
|
malformed_checks
|
879 |
|
|
(.clk_i (clk_i),
|
880 |
|
|
.reset_i (reset_i),
|
881 |
|
|
.sof_i (sof_i && src_rdy_i && !packet_ip),
|
882 |
|
|
.eof_i (eof_i && src_rdy_i && packet_ip),
|
883 |
|
|
`ifdef PCIE
|
884 |
|
|
.rem_i (rem_i),
|
885 |
|
|
`endif
|
886 |
|
|
|
887 |
|
|
.eval_formats_i (latch_2nd_dword_q1),
|
888 |
|
|
.length_i (cur_length),
|
889 |
|
|
`ifdef PCIE
|
890 |
|
|
.length_1dw_i (cur_length1),
|
891 |
|
|
`endif
|
892 |
|
|
.aperture_i (aperture),
|
893 |
|
|
.load_aperture_i (latch_3rd_dword),
|
894 |
|
|
.offset_i (offset),
|
895 |
|
|
|
896 |
|
|
`ifdef PCIE
|
897 |
|
|
.eval_fulltype_i (latch_1st_dword),
|
898 |
|
|
.fulltype_i (fulltype_in),
|
899 |
|
|
.eval_msgcode_i (latch_2nd_dword),
|
900 |
|
|
.msgcode_i (msgcode_in),
|
901 |
|
|
|
902 |
|
|
.tc0_i (cur_tc0),
|
903 |
|
|
.td_i (cur_td),
|
904 |
|
|
.hit_src_rdy_i (rhit_src_rdy),
|
905 |
|
|
.hit_ack_i (rhit_ack),
|
906 |
|
|
.hit_lock_i (rhit_lock),
|
907 |
|
|
.hit_i (rhit_d),
|
908 |
|
|
`else // `ifdef AS
|
909 |
|
|
.oo_i (cur_oo),
|
910 |
|
|
.ts_i (cur_ts),
|
911 |
|
|
|
912 |
|
|
.pi_1st_i (pi_1st),
|
913 |
|
|
.pi_2nd_i (pi_2nd),
|
914 |
|
|
.pi_3rd_i (pi_3rd),
|
915 |
|
|
.pi_4th_i (pi_4th),
|
916 |
|
|
.load_pi_1st_i (latch_1st_dword),
|
917 |
|
|
.load_pi_2nd_i (latch_3rd_dword),
|
918 |
|
|
.load_pi_3rd_i (latch_4th_dword),
|
919 |
|
|
.load_pi_4th_i (latch_5th_dword),
|
920 |
|
|
|
921 |
|
|
.load_offset_i (latch_4th_dword),
|
922 |
|
|
|
923 |
|
|
.hcrc_i (cur_hcrc),
|
924 |
|
|
.route_header_i (cur_route_header),
|
925 |
|
|
.turn_pointer_i (cur_turn_pointer),
|
926 |
|
|
.dir_i (cur_dir),
|
927 |
|
|
`endif
|
928 |
|
|
|
929 |
|
|
.data_credits_o (cur_data_credits),
|
930 |
|
|
.data_credits_vld_o (cur_data_credits_vld),
|
931 |
|
|
.cfg_o (cur_cfg),
|
932 |
|
|
.hp_msg_detect_o (cur_hp_msg_detect),
|
933 |
|
|
`ifdef PCIE
|
934 |
|
|
.malformed_o (malformed),
|
935 |
|
|
.tlp_ur_o (tlp_ur),
|
936 |
|
|
.tlp_ur_lock_o (tlp_ur_lock),
|
937 |
|
|
.tlp_uc_o (tlp_uc),
|
938 |
|
|
.tlp_filt_o (tlp_filt),
|
939 |
|
|
`else // `ifdef AS
|
940 |
|
|
.bad_header_crc_o (bad_header_crc),
|
941 |
|
|
.bad_pi_chain_o (bad_pi_chain),
|
942 |
|
|
.bad_credit_length_o (bad_credit_length),
|
943 |
|
|
.invalid_credit_length_o (invalid_credit_length),
|
944 |
|
|
.non_zero_turn_pointer_o (non_zero_turn_pointer),
|
945 |
|
|
.unsup_mvc_o (unsup_mvc),
|
946 |
|
|
.unsup_ovc_o (unsup_ovc),
|
947 |
|
|
.filter_drop_o (filter_drop),
|
948 |
|
|
`endif
|
949 |
|
|
|
950 |
|
|
.max_payload_i (max_payload_i),
|
951 |
|
|
`ifdef PCIE
|
952 |
|
|
.legacy_mode_i (legacy_mode_i),
|
953 |
|
|
.legacy_cfg_access_i (legacy_cfg_access_i),
|
954 |
|
|
.ext_cfg_access_i (ext_cfg_access_i),
|
955 |
|
|
.hit_lat3_i (rhit_bar_lat3_i),
|
956 |
|
|
.pwr_mgmt_on_i (pwr_mgmt_mode_on)
|
957 |
|
|
`else // `ifdef AS
|
958 |
|
|
.switch_mode_i (switch_mode_i),
|
959 |
|
|
.fabric_manager_mode_i (fabric_manager_mode_i),
|
960 |
|
|
.cmm_ap0_space_end_i (cfg_ap0_space_end_i),
|
961 |
|
|
.cmm_ap1_space_start_i (cfg_ap1_space_start_i),
|
962 |
|
|
.cmm_ap1_space_end_i (cfg_ap1_space_end_i),
|
963 |
|
|
.lnk_state_i (lnk_state_i),
|
964 |
|
|
.lnk_state_src_rdy_i (lnk_state_src_rdy_i)
|
965 |
|
|
`endif
|
966 |
|
|
);
|
967 |
|
|
|
968 |
|
|
`ifdef PCIE
|
969 |
|
|
tlm_rx_data_snk_pwr_mgmt
|
970 |
|
|
pwr_mgmt
|
971 |
|
|
(.clk_i (clk_i),
|
972 |
|
|
.reset_i (reset_i),
|
973 |
|
|
.pm_as_nak_l1_o (pm_as_nak_l1_o),
|
974 |
|
|
.pm_turn_off_o (pm_turn_off_o),
|
975 |
|
|
.pm_set_slot_pwr_o (pm_set_slot_pwr_o),
|
976 |
|
|
.pm_set_slot_pwr_data_o (pm_set_slot_pwr_data_o),
|
977 |
|
|
.pm_msg_detect_o (cur_pm_msg_detect),
|
978 |
|
|
// AS messages will get thrown out elsewhere as UR's
|
979 |
|
|
.ismsg_i (cur_fulltype_oh[MSG_BIT]),
|
980 |
|
|
.msgcode_i (cur_msgcode),
|
981 |
|
|
.pwr_data_i (pwr_data_i),
|
982 |
|
|
.eval_pwr_mgmt_i (latch_2nd_dword_q2),
|
983 |
|
|
// The set slot power field is not known at the same
|
984 |
|
|
// time as the message types
|
985 |
|
|
.eval_pwr_mgmt_data_i (latch_4th_dword_q1),
|
986 |
|
|
// This is the first time we know the packet it correct
|
987 |
|
|
// -we only check bar hits for ROUTE_BY_ID, which is not
|
988 |
|
|
// allowed for any of the pwr mgmt message types
|
989 |
|
|
// Messages are never completion types
|
990 |
|
|
.act_pwr_mgmt_i (eof_q[out_d3] && !(malformed || tlp_ur))
|
991 |
|
|
);
|
992 |
|
|
|
993 |
|
|
tlm_rx_data_snk_bar #(
|
994 |
|
|
.BARW (BARW))
|
995 |
|
|
bar_hit
|
996 |
|
|
(.clk_i (clk_i),
|
997 |
|
|
.reset_i (reset_i),
|
998 |
|
|
.check_raddr_o (check_raddr_o),
|
999 |
|
|
.check_rmem64_o (check_mem64_o),
|
1000 |
|
|
.check_rmem32_o (check_mem32_o),
|
1001 |
|
|
.check_rio_o (check_rio_o),
|
1002 |
|
|
.check_rdev_id_o (check_rdev_o),
|
1003 |
|
|
.check_rbus_id_o (check_rbus_o),
|
1004 |
|
|
.check_rfun_id_o (check_rfun_o),
|
1005 |
|
|
.check_rhit_bar_i (check_rhit_bar_i),
|
1006 |
|
|
.check_rhit_i (check_rhit_i),
|
1007 |
|
|
.check_rhit_bar_o (rhit_bar_d),
|
1008 |
|
|
.check_rhit_o (rhit_d),
|
1009 |
|
|
.check_rhit_src_rdy_o (rhit_src_rdy),
|
1010 |
|
|
.check_rhit_ack_o (rhit_ack),
|
1011 |
|
|
.check_rhit_lock_o (rhit_lock),
|
1012 |
|
|
.addr_lo_i (addr_lo_i),
|
1013 |
|
|
.addr_hi_i (((DW == 32) && cur_fulltype_64) ?
|
1014 |
|
|
cur_addr_hi : addr_hi_in),
|
1015 |
|
|
.fulltype_oh_i (cur_fulltype_oh),
|
1016 |
|
|
.mem64_i (cur_fulltype_64),
|
1017 |
|
|
.routing_i (cur_routing),
|
1018 |
|
|
.req_id_i (cur_req_id),
|
1019 |
|
|
.req_id_cpl_i (req_id_cpl_in), // in 3rd dw, latch on 3rd
|
1020 |
|
|
.eval_check_i (cur_fulltype_64 ? latch_4th_dword:
|
1021 |
|
|
latch_3rd_dword),
|
1022 |
|
|
.rhit_lat3_i (rhit_bar_lat3_i),
|
1023 |
|
|
.legacy_mode_i (legacy_mode_i)
|
1024 |
|
|
);
|
1025 |
|
|
`endif
|
1026 |
|
|
|
1027 |
|
|
`ifdef PCIE
|
1028 |
|
|
//===================================================================
|
1029 |
|
|
// Generate Byte Count and Lower Address fields for non-Successful
|
1030 |
|
|
// Completion Header using the byte enables as offsets, and the
|
1031 |
|
|
// byte counts as totals
|
1032 |
|
|
// Byte Count from table 2-21, page 90 PCI 1.1 spec
|
1033 |
|
|
// Lower address from table 2-22, page 91 PCI 1.1 spec
|
1034 |
|
|
//===================================================================
|
1035 |
|
|
// convert the byte enable signals into actual bytes removed from
|
1036 |
|
|
// the length field
|
1037 |
|
|
//--------------------------------------------------------------------------
|
1038 |
|
|
always @* begin
|
1039 |
|
|
casex (last_be_in)
|
1040 |
|
|
4'b1xxx: last_be_missing = 0; // 1111 - all enabled, no offset
|
1041 |
|
|
4'b01xx: last_be_missing = 1;
|
1042 |
|
|
4'b001x: last_be_missing = 2;
|
1043 |
|
|
4'b0001: last_be_missing = 3; // 0001 - 1 enabled, 3 offset
|
1044 |
|
|
default: last_be_missing = 0;
|
1045 |
|
|
endcase
|
1046 |
|
|
casex (first_be_in)
|
1047 |
|
|
4'bxxx1: first_be_missing = 0; // 1111 - all enabled, no offset
|
1048 |
|
|
4'bxx10: first_be_missing = 1; // 1110 - 1st 3 enabled, 1 offset
|
1049 |
|
|
4'bx100: first_be_missing = 2; // 1100 - 1st 2 enables, 2 offset
|
1050 |
|
|
4'b1000: first_be_missing = 3; // 1000 - 1st enabled, 3 offset
|
1051 |
|
|
default: first_be_missing = 0; // 0000 - no offset, 1 DW flush below
|
1052 |
|
|
endcase
|
1053 |
|
|
casex (first_be_in) // last_be_in must == 0000
|
1054 |
|
|
4'b1xx1: byte_ct_1dw = 4;
|
1055 |
|
|
4'b01x1: byte_ct_1dw = 3;
|
1056 |
|
|
4'b1x10: byte_ct_1dw = 3;
|
1057 |
|
|
4'b0011: byte_ct_1dw = 2;
|
1058 |
|
|
4'b0110: byte_ct_1dw = 2;
|
1059 |
|
|
4'b1100: byte_ct_1dw = 2;
|
1060 |
|
|
4'b0001: byte_ct_1dw = 1;
|
1061 |
|
|
4'b0010: byte_ct_1dw = 1;
|
1062 |
|
|
4'b0100: byte_ct_1dw = 1;
|
1063 |
|
|
4'bx000: byte_ct_1dw = 1;
|
1064 |
|
|
endcase
|
1065 |
|
|
end
|
1066 |
|
|
|
1067 |
|
|
// Subtract from the total byte count (length x 4) based on the First
|
1068 |
|
|
// and Last DW BE fields.
|
1069 |
|
|
//--------------------------------------------------------------------------
|
1070 |
|
|
always @(posedge clk_i) begin
|
1071 |
|
|
if (latch_2nd_dword) begin
|
1072 |
|
|
cur_bytes_missing <= #`TCQ first_be_missing + last_be_missing;
|
1073 |
|
|
end
|
1074 |
|
|
end
|
1075 |
|
|
|
1076 |
|
|
always @(posedge clk_i) begin
|
1077 |
|
|
if (reset_i) begin
|
1078 |
|
|
cur_byte_ct_1dw <= #`TCQ 0;
|
1079 |
|
|
end else if (latch_2nd_dword) begin
|
1080 |
|
|
cur_byte_ct_1dw <= #`TCQ byte_ct_1dw;
|
1081 |
|
|
end
|
1082 |
|
|
end
|
1083 |
|
|
|
1084 |
|
|
// We need to move the address forward to handle any empty bytes
|
1085 |
|
|
// in the payload.. this will be the start of the first actual
|
1086 |
|
|
// byte of payload
|
1087 |
|
|
always @(posedge clk_i) begin
|
1088 |
|
|
if (reset_i) begin
|
1089 |
|
|
cur_first_be_adj <= #`TCQ 0;
|
1090 |
|
|
end else if (latch_2nd_dword) begin
|
1091 |
|
|
cur_first_be_adj <= #`TCQ first_be_missing;
|
1092 |
|
|
end
|
1093 |
|
|
end
|
1094 |
|
|
|
1095 |
|
|
//--------------------------------------------------------------------------
|
1096 |
|
|
// Determine the Byte Count for the CMM to create a completion
|
1097 |
|
|
//--------------------------------------------------------------------------
|
1098 |
|
|
always @(posedge clk_i) begin
|
1099 |
|
|
if (latch_2nd_dword_q2) begin
|
1100 |
|
|
casex (cur_fulltype)
|
1101 |
|
|
MRD32, MRD64, MRD32LK, MRD64LK:
|
1102 |
|
|
// for a 1 dword length, the last be is not involved, so
|
1103 |
|
|
// be sure not to use it
|
1104 |
|
|
if (cur_length1) begin
|
1105 |
|
|
cur_byte_ct <= #`TCQ cur_byte_ct_1dw;
|
1106 |
|
|
end else begin
|
1107 |
|
|
// length is in words- total length is length*4
|
1108 |
|
|
// ..subtracting the bytes that don't particpate
|
1109 |
|
|
cur_byte_ct <= #`TCQ {cur_length,2'b00} - cur_bytes_missing;
|
1110 |
|
|
end
|
1111 |
|
|
// The Byte Count is set to 4 for Completions other than Memory Read
|
1112 |
|
|
default:
|
1113 |
|
|
cur_byte_ct <= #`TCQ 4;
|
1114 |
|
|
endcase
|
1115 |
|
|
end
|
1116 |
|
|
end
|
1117 |
|
|
|
1118 |
|
|
//--------------------------------------------------------------------------
|
1119 |
|
|
// Lower Address is calculated from the Address field for Memory Reads,
|
1120 |
|
|
// and is set to zero for all other transaction types. The lower address is
|
1121 |
|
|
// taken from the third dword in MR32 and from the fourth dword in MR64.
|
1122 |
|
|
//--------------------------------------------------------------------------
|
1123 |
|
|
|
1124 |
|
|
always @(posedge clk_i) begin
|
1125 |
|
|
if (cur_fulltype_64) begin
|
1126 |
|
|
if (latch_4th_dword_q1) begin
|
1127 |
|
|
if (cur_fulltype_mem) begin
|
1128 |
|
|
cur_lower_addr[6:2] <= #`TCQ lower_addr64_in_q;
|
1129 |
|
|
end else begin
|
1130 |
|
|
cur_lower_addr[6:2] <= #`TCQ 0;
|
1131 |
|
|
end
|
1132 |
|
|
end
|
1133 |
|
|
end else begin
|
1134 |
|
|
if (latch_3rd_dword_q1) begin
|
1135 |
|
|
if (cur_fulltype_mem) begin
|
1136 |
|
|
cur_lower_addr[6:2] <= #`TCQ lower_addr32_in_q;
|
1137 |
|
|
end else begin
|
1138 |
|
|
cur_lower_addr[6:2] <= #`TCQ 0;
|
1139 |
|
|
end
|
1140 |
|
|
end
|
1141 |
|
|
end
|
1142 |
|
|
end
|
1143 |
|
|
|
1144 |
|
|
// The lower two bits are based on the First DW Byte Enables.
|
1145 |
|
|
always @(posedge clk_i) begin
|
1146 |
|
|
if (latch_3rd_dword_q1) begin
|
1147 |
|
|
if (cur_fulltype_mem) begin
|
1148 |
|
|
cur_lower_addr[1:0] <= #`TCQ cur_first_be_adj;
|
1149 |
|
|
end else begin
|
1150 |
|
|
cur_lower_addr[1:0] <= #`TCQ 0;
|
1151 |
|
|
end
|
1152 |
|
|
end
|
1153 |
|
|
end
|
1154 |
|
|
|
1155 |
|
|
always @(posedge clk_i) begin
|
1156 |
|
|
lower_addr32_in_q <= #`TCQ lower_addr32_in;
|
1157 |
|
|
lower_addr64_in_q <= #`TCQ lower_addr64_in;
|
1158 |
|
|
end
|
1159 |
|
|
|
1160 |
|
|
//=======================================================================
|
1161 |
|
|
// If directed to go to into management, let the current packet
|
1162 |
|
|
// complete, then reject following packets - used in malformed checks
|
1163 |
|
|
//=======================================================================
|
1164 |
|
|
always @(posedge clk_i) begin
|
1165 |
|
|
if (reset_i) begin
|
1166 |
|
|
pwr_mgmt_mode_on <= #`TCQ 0;
|
1167 |
|
|
end else if (sof_i) begin
|
1168 |
|
|
pwr_mgmt_mode_on <= #`TCQ pm_suspend_req_i;
|
1169 |
|
|
end
|
1170 |
|
|
end
|
1171 |
|
|
`endif // `ifdef PCIE
|
1172 |
|
|
|
1173 |
|
|
//=====================================================================
|
1174 |
|
|
// Datapath pipe and associated control logic
|
1175 |
|
|
// there are only resets where absolutely required as we want
|
1176 |
|
|
// to infer SRLs wherever possible
|
1177 |
|
|
//=====================================================================
|
1178 |
|
|
|
1179 |
|
|
// used to create clean local link packets... concatenating two packets
|
1180 |
|
|
// together because one had bad signalling will results in a malformed
|
1181 |
|
|
// packet, so we are covered
|
1182 |
|
|
//---------------------------------------------------------------------
|
1183 |
|
|
always @(posedge clk_i) begin
|
1184 |
|
|
if (reset_i) begin
|
1185 |
|
|
packet_ip <= #`TCQ 0;
|
1186 |
|
|
end else if (src_rdy_i) begin
|
1187 |
|
|
packet_ip <= #`TCQ (sof_i || packet_ip) && !eof_i;
|
1188 |
|
|
end
|
1189 |
|
|
end
|
1190 |
|
|
//--------------------------------------------------------------------------
|
1191 |
|
|
// The last qword of the frame is removed if it doesn't contain any header
|
1192 |
|
|
// or data information (contain only an unaligned TD dword)
|
1193 |
|
|
// If the TD is in the lower dword of the last qword, it is disabled by
|
1194 |
|
|
// inverting rem for 64b
|
1195 |
|
|
//--------------------------------------------------------------------------
|
1196 |
|
|
always @(posedge clk_i) begin
|
1197 |
|
|
if (reset_i) begin
|
1198 |
|
|
remove_lastword <= #`TCQ 0;
|
1199 |
|
|
end else begin
|
1200 |
|
|
// defer calc until needed due to packet overlap
|
1201 |
|
|
if (eof_q[3]) begin
|
1202 |
|
|
if (DW == 64) begin
|
1203 |
|
|
remove_lastword <= #`TCQ !cur_rem && (cur_td_q && td_ecrc_trim_i);
|
1204 |
|
|
end else begin
|
1205 |
|
|
remove_lastword <= #`TCQ cur_td_q && td_ecrc_trim_i;
|
1206 |
|
|
end
|
1207 |
|
|
end else if (eof_o) begin
|
1208 |
|
|
remove_lastword <= #`TCQ 0;
|
1209 |
|
|
end
|
1210 |
|
|
end
|
1211 |
|
|
end
|
1212 |
|
|
|
1213 |
|
|
|
1214 |
|
|
// Control pipe
|
1215 |
|
|
//-------------------------------------------------------------
|
1216 |
|
|
always @(posedge clk_i) begin
|
1217 |
|
|
if (reset_i) begin
|
1218 |
|
|
sof_q[1] <= #`TCQ 0;
|
1219 |
|
|
eof_q[1] <= #`TCQ 0;
|
1220 |
|
|
src_rdy_q[1] <= #`TCQ 0;
|
1221 |
|
|
rem_q[1] <= #`TCQ 1;
|
1222 |
|
|
dsc_q[1] <= #`TCQ 0;
|
1223 |
|
|
eof_nd_q[1] <= #`TCQ 0;
|
1224 |
|
|
|
1225 |
|
|
sof_o <= #`TCQ 0;
|
1226 |
|
|
end else begin
|
1227 |
|
|
// gate the input signals with src_rdy, and ensure valid
|
1228 |
|
|
// local link signalling
|
1229 |
|
|
sof_q[1] <= #`TCQ sof_i && src_rdy_i && !packet_ip;
|
1230 |
|
|
eof_q[1] <= #`TCQ eof_i && src_rdy_i && packet_ip;
|
1231 |
|
|
src_rdy_q[1] <= #`TCQ src_rdy_i && (packet_ip || sof_i);
|
1232 |
|
|
dsc_q[1] <= #`TCQ eof_i && src_rdy_i && packet_ip
|
1233 |
|
|
&& src_dsc_i;
|
1234 |
|
|
eof_nd_q[1] <= #`TCQ eof_i && src_rdy_i && packet_ip
|
1235 |
|
|
&& !src_dsc_i;
|
1236 |
|
|
// if we have rem, only modify it if we are actually removing the digest
|
1237 |
|
|
if (DW == 64) begin
|
1238 |
|
|
if (eof_i) begin
|
1239 |
|
|
rem_q[1] <= #`TCQ rem_i ^ (cur_td && td_ecrc_trim_i);
|
1240 |
|
|
cur_rem <= #`TCQ rem_i;
|
1241 |
|
|
end else begin
|
1242 |
|
|
rem_q[1] <= #`TCQ 1;
|
1243 |
|
|
end
|
1244 |
|
|
end else begin
|
1245 |
|
|
rem_q[1] <= #`TCQ 1;
|
1246 |
|
|
cur_rem <= #`TCQ 1;
|
1247 |
|
|
end
|
1248 |
|
|
|
1249 |
|
|
sof_o <= #`TCQ sof_q[out_d1];
|
1250 |
|
|
end
|
1251 |
|
|
end
|
1252 |
|
|
// Mux for last word when digest removal requires a forward. Turn off
|
1253 |
|
|
// src_rdy_o for one cycle if the last (unadjusted) data beat is
|
1254 |
|
|
// unaligned in 64-bit. In 32-bit, this cycle is always invalidated.
|
1255 |
|
|
always @(posedge clk_i) begin
|
1256 |
|
|
if (reset_i) begin
|
1257 |
|
|
src_rdy_o <= #`TCQ 0;
|
1258 |
|
|
dsc_o <= #`TCQ 0;
|
1259 |
|
|
rem_o <= #`TCQ 1;
|
1260 |
|
|
eof_o <= #`TCQ 0;
|
1261 |
|
|
preeof_o <= #`TCQ 0;
|
1262 |
|
|
end else if (remove_lastword) begin
|
1263 |
|
|
if (!eof_o) begin
|
1264 |
|
|
src_rdy_o <= #`TCQ src_rdy_q[out_d2];
|
1265 |
|
|
|
1266 |
|
|
// Note that rem_q has already been adjusted for ECRC trim by this
|
1267 |
|
|
// point so that, in a 64-bit system, an UNaligned indicator means
|
1268 |
|
|
// that the trimming has NOT blanked out the original EOF quadword
|
1269 |
|
|
// completely. Thus the original src_rdy is still valid.
|
1270 |
|
|
end else if ((DW == 64) && !rem_q[out_d2]) begin
|
1271 |
|
|
src_rdy_o <= #`TCQ src_rdy_q[out_d2];
|
1272 |
|
|
end else begin
|
1273 |
|
|
src_rdy_o <= #`TCQ 1'b0;
|
1274 |
|
|
end
|
1275 |
|
|
dsc_o <= #`TCQ dsc_q[out_d2] ||
|
1276 |
|
|
(eof_q[out_d2] && next_cur_drop);
|
1277 |
|
|
rem_o <= #`TCQ (DW == 64) ? rem_q[out_d2] : 1'b1;
|
1278 |
|
|
eof_o <= #`TCQ eof_q[out_d2];
|
1279 |
|
|
preeof_o <= #`TCQ eof_q[out_d3];
|
1280 |
|
|
end else begin
|
1281 |
|
|
// Special case to filter src_rdy_o
|
1282 |
|
|
// when eof is moved forward across
|
1283 |
|
|
// DWORD boundaries due to ECRC trimming
|
1284 |
|
|
src_rdy_o <= #`TCQ src_rdy_q[out_d1] &&
|
1285 |
|
|
!(eof_o && !sof_q[out_d1]);
|
1286 |
|
|
dsc_o <= #`TCQ dsc_q[out_d1] || (eof_q[out_d1] && cur_drop);
|
1287 |
|
|
rem_o <= #`TCQ (DW == 64) ? rem_q[out_d1] : 1'b1;
|
1288 |
|
|
eof_o <= #`TCQ eof_q[out_d1];
|
1289 |
|
|
preeof_o <= #`TCQ eof_q[out_d2];
|
1290 |
|
|
end
|
1291 |
|
|
end
|
1292 |
|
|
// we want SRLs for the internal stages
|
1293 |
|
|
// we've got resets on the input/output -> the middles will resolve
|
1294 |
|
|
always @(posedge clk_i) begin
|
1295 |
|
|
sof_q[6:2] <= #`TCQ sof_q[5:1];
|
1296 |
|
|
eof_q[6:2] <= #`TCQ eof_q[5:1];
|
1297 |
|
|
src_rdy_q[6:2] <= #`TCQ src_rdy_q[5:1];
|
1298 |
|
|
dsc_q[6:2] <= #`TCQ dsc_q[5:1];
|
1299 |
|
|
rem_q[6:2] <= #`TCQ (DW == 64) ? rem_q[5:1] : 5'h1f;
|
1300 |
|
|
eof_nd_q[6:2] <= #`TCQ eof_nd_q[5:1];
|
1301 |
|
|
end
|
1302 |
|
|
|
1303 |
|
|
`ifdef PCIE
|
1304 |
|
|
// In PCIe, if we are dropping the digest, we don't want to tell the
|
1305 |
|
|
// downstream logic that we have one. It's a bit ugly, but it creates
|
1306 |
|
|
// only one extra flop instead of a whole word.
|
1307 |
|
|
assign d_mux = (sof_i && td_ecrc_trim_i) ?
|
1308 |
|
|
{d_i[DW-1:TD_IND+1], 1'b0, d_i[TD_IND-1:0]} : d_i;
|
1309 |
|
|
`else // `ifdef AS
|
1310 |
|
|
// In AS, even if we trim the packet CRC, we still want to tell the
|
1311 |
|
|
// Read Monitor that PCRC existed, so it can be counted toward credit
|
1312 |
|
|
// reallocation. The FIFO will turn off the PCRC bit later so that the
|
1313 |
|
|
// packet looks clean to the user.
|
1314 |
|
|
assign d_mux = d_i;
|
1315 |
|
|
`endif
|
1316 |
|
|
|
1317 |
|
|
// Data pipe
|
1318 |
|
|
always @(posedge clk_i) begin
|
1319 |
|
|
d_q1 <= #`TCQ d_mux;
|
1320 |
|
|
d_q2 <= #`TCQ d_q1;
|
1321 |
|
|
d_q3 <= #`TCQ d_q2;
|
1322 |
|
|
d_q4 <= #`TCQ d_q3;
|
1323 |
|
|
d_q5 <= #`TCQ d_q4;
|
1324 |
|
|
d_q6 <= #`TCQ d_q5;
|
1325 |
|
|
case (out_d1)
|
1326 |
|
|
5: d_o <= #`TCQ d_q5;
|
1327 |
|
|
6: d_o <= #`TCQ d_q6;
|
1328 |
|
|
default: d_o <= #`TCQ d_q4;
|
1329 |
|
|
endcase
|
1330 |
|
|
end
|
1331 |
|
|
|
1332 |
|
|
// Tell the LLM that a TLP has been received, so that it can exit
|
1333 |
|
|
// FC_INIT2 if necessary. This signal stays asserted for the life of
|
1334 |
|
|
// device operation, until the next system reset.
|
1335 |
|
|
|
1336 |
|
|
always @(posedge clk_i) begin
|
1337 |
|
|
if (reset_i) begin
|
1338 |
|
|
vc_hit_o <= #`TCQ 1'b0;
|
1339 |
|
|
end else if (src_rdy_o && eof_o && !dsc_o) begin
|
1340 |
|
|
vc_hit_o <= #`TCQ 1'b1;
|
1341 |
|
|
end
|
1342 |
|
|
end
|
1343 |
|
|
|
1344 |
|
|
|
1345 |
|
|
// Latch the side bands signals that the FIFO needs which are valid at eof
|
1346 |
|
|
// We never have to worry about mal/ur/uc checks here.. but we do need
|
1347 |
|
|
// to worry about back-to-back packets.
|
1348 |
|
|
// We can have up to three packets in the pipeline on any given time
|
1349 |
|
|
// we need three copies of the registers
|
1350 |
|
|
//-----------------------------------------------------------------------
|
1351 |
|
|
always @(posedge clk_i) begin
|
1352 |
|
|
`ifdef PCIE
|
1353 |
|
|
if (!rhit_bar_lat3_i || (DW == 32))
|
1354 |
|
|
`endif
|
1355 |
|
|
begin
|
1356 |
|
|
if (latch_1st_dword_q4) begin
|
1357 |
|
|
`ifdef PCIE
|
1358 |
|
|
cpl_o <= #`TCQ cur_cpl;
|
1359 |
|
|
locked_o <= #`TCQ cur_locked_q;
|
1360 |
|
|
vend_msg_o <= #`TCQ cur_vend_msg;
|
1361 |
|
|
`endif
|
1362 |
|
|
np_o <= #`TCQ cur_np;
|
1363 |
|
|
cfg_o <= #`TCQ cur_cfg;
|
1364 |
|
|
end
|
1365 |
|
|
end
|
1366 |
|
|
`ifdef PCIE
|
1367 |
|
|
else begin
|
1368 |
|
|
if (latch_1st_dword_q4) begin
|
1369 |
|
|
np_d <= #`TCQ cur_np;
|
1370 |
|
|
cpl_d <= #`TCQ cur_cpl;
|
1371 |
|
|
locked_d <= #`TCQ cur_locked_q;
|
1372 |
|
|
cfg_d <= #`TCQ cur_cfg;
|
1373 |
|
|
vend_msg_d <= #`TCQ vend_msg_d;
|
1374 |
|
|
end
|
1375 |
|
|
|
1376 |
|
|
np_o <= #`TCQ np_d;
|
1377 |
|
|
cpl_o <= #`TCQ cpl_d;
|
1378 |
|
|
locked_o <= #`TCQ locked_d;
|
1379 |
|
|
cfg_o <= #`TCQ cfg_d;
|
1380 |
|
|
vend_msg_o <= #`TCQ vend_msg_d;
|
1381 |
|
|
end
|
1382 |
|
|
`endif
|
1383 |
|
|
end
|
1384 |
|
|
|
1385 |
|
|
always @(posedge clk_i) begin
|
1386 |
|
|
if (latch_1st_dword_q2) begin
|
1387 |
|
|
`ifdef PCIE
|
1388 |
|
|
cur_ep_q <= #`TCQ cur_ep;
|
1389 |
|
|
cur_cpl <= #`TCQ cur_fulltype_oh[CPL_BIT];
|
1390 |
|
|
cur_locked_q <= #`TCQ cur_locked;
|
1391 |
|
|
// These are the POSTED types
|
1392 |
|
|
cur_np <= #`TCQ !cur_fulltype_oh[MWR_BIT] &&
|
1393 |
|
|
!cur_fulltype_oh[MSG_BIT] &&
|
1394 |
|
|
!cur_fulltype_oh[CPL_BIT];
|
1395 |
|
|
`else // `ifdef AS
|
1396 |
|
|
cur_np <= #`TCQ !cur_oo && cur_ts;
|
1397 |
|
|
`endif
|
1398 |
|
|
cur_td_q <= #`TCQ cur_td;
|
1399 |
|
|
end
|
1400 |
|
|
end
|
1401 |
|
|
|
1402 |
|
|
`ifdef PCIE
|
1403 |
|
|
always @(posedge clk_i) begin
|
1404 |
|
|
if (latch_2nd_dword_q2) begin
|
1405 |
|
|
cur_vend_msg <= #`TCQ ((cur_msgcode == VENDOR_DEFINED_TYPE_0) ||
|
1406 |
|
|
(cur_msgcode == VENDOR_DEFINED_TYPE_1)) &&
|
1407 |
|
|
cur_fulltype_oh[MSG_BIT];
|
1408 |
|
|
end
|
1409 |
|
|
end
|
1410 |
|
|
`endif
|
1411 |
|
|
|
1412 |
|
|
`ifdef PCIE
|
1413 |
|
|
// Bar has come back from the CMM when src_rdy is true.
|
1414 |
|
|
// If the packet type needs bar set to 0, the bar block
|
1415 |
|
|
// has already done this for us
|
1416 |
|
|
// Assert rid_o if the requester ID matches (used for completions)
|
1417 |
|
|
//------------------------------------------------------
|
1418 |
|
|
always @(posedge clk_i) begin
|
1419 |
|
|
if (rhit_src_rdy) begin
|
1420 |
|
|
bar_o <= #`TCQ rhit_bar_d;
|
1421 |
|
|
rid_o <= #`TCQ rhit_d;
|
1422 |
|
|
end
|
1423 |
|
|
end
|
1424 |
|
|
|
1425 |
|
|
always @(posedge clk_i) begin
|
1426 |
|
|
if (reset_i) begin
|
1427 |
|
|
bar_src_rdy_o <= #`TCQ 0;
|
1428 |
|
|
end else if (rhit_src_rdy) begin
|
1429 |
|
|
bar_src_rdy_o <= #`TCQ 1;
|
1430 |
|
|
end else begin
|
1431 |
|
|
bar_src_rdy_o <= #`TCQ 0;
|
1432 |
|
|
end
|
1433 |
|
|
end
|
1434 |
|
|
`else // `ifdef AS
|
1435 |
|
|
// Latch the OO and TS bits for Bypassable determination.
|
1436 |
|
|
|
1437 |
|
|
always @(posedge clk_i) begin
|
1438 |
|
|
if (latch_1st_dword) begin
|
1439 |
|
|
cur_oo <= #`TCQ d_i[OO_IND];
|
1440 |
|
|
cur_ts <= #`TCQ d_i[TS_IND];
|
1441 |
|
|
end
|
1442 |
|
|
end
|
1443 |
|
|
`endif
|
1444 |
|
|
|
1445 |
|
|
//=======================================================================
|
1446 |
|
|
// Latch the data fields as the packet arrives into the core
|
1447 |
|
|
//=======================================================================
|
1448 |
|
|
// Delayed versions of control signals
|
1449 |
|
|
//-----------------------------------------------------------------------
|
1450 |
|
|
always @(posedge clk_i) begin
|
1451 |
|
|
if (reset_i) begin
|
1452 |
|
|
latch_1st_dword_q1 <= #`TCQ 0;
|
1453 |
|
|
latch_1st_dword_q2 <= #`TCQ 0;
|
1454 |
|
|
latch_1st_dword_q3 <= #`TCQ 0;
|
1455 |
|
|
latch_1st_dword_q4 <= #`TCQ 0;
|
1456 |
|
|
latch_2nd_dword_q1 <= #`TCQ 0;
|
1457 |
|
|
latch_2nd_dword_q2 <= #`TCQ 0;
|
1458 |
|
|
latch_3rd_dword_q1 <= #`TCQ 0;
|
1459 |
|
|
latch_4th_dword_q1 <= #`TCQ 0;
|
1460 |
|
|
end else begin
|
1461 |
|
|
latch_1st_dword_q1 <= #`TCQ latch_1st_dword;
|
1462 |
|
|
latch_1st_dword_q2 <= #`TCQ latch_1st_dword_q1;
|
1463 |
|
|
latch_1st_dword_q3 <= #`TCQ latch_1st_dword_q2;
|
1464 |
|
|
latch_1st_dword_q4 <= #`TCQ latch_1st_dword_q3;
|
1465 |
|
|
latch_2nd_dword_q1 <= #`TCQ latch_2nd_dword;
|
1466 |
|
|
latch_2nd_dword_q2 <= #`TCQ latch_2nd_dword_q1;
|
1467 |
|
|
latch_3rd_dword_q1 <= #`TCQ latch_3rd_dword;
|
1468 |
|
|
latch_4th_dword_q1 <= #`TCQ latch_4th_dword;
|
1469 |
|
|
end
|
1470 |
|
|
end
|
1471 |
|
|
|
1472 |
|
|
// fields valid on this packet
|
1473 |
|
|
//-----------------------------------------------------------------------
|
1474 |
|
|
// NOTE: The following attributes were added for XST synthesis of the
|
1475 |
|
|
// PCIe Block Plus project. They are needed to make 250 MHz in a V-5,
|
1476 |
|
|
// but it is very likely that they will have to be removed/disabled for
|
1477 |
|
|
// V-4 and V-IIPro.
|
1478 |
|
|
// synthesis attribute use_clock_enable of cur_td is no;
|
1479 |
|
|
// synthesis attribute use_clock_enable of cur_length is no;
|
1480 |
|
|
// synthesis attribute use_clock_enable of cur_tc is no;
|
1481 |
|
|
// synthesis attribute use_clock_enable of cur_tc0 is no;
|
1482 |
|
|
// synthesis attribute use_clock_enable of cur_ep is no;
|
1483 |
|
|
// synthesis attribute use_clock_enable of cur_attr is no;
|
1484 |
|
|
// synthesis attribute use_clock_enable of cur_length1 is no;
|
1485 |
|
|
// synthesis attribute use_clock_enable of cur_fulltype is no;
|
1486 |
|
|
|
1487 |
|
|
always @(posedge clk_i) begin
|
1488 |
|
|
if (latch_1st_dword) begin
|
1489 |
|
|
cur_td <= #`TCQ td_in;
|
1490 |
|
|
cur_length <= #`TCQ length_in;
|
1491 |
|
|
`ifdef PCIE
|
1492 |
|
|
cur_tc <= #`TCQ tc_in;
|
1493 |
|
|
cur_tc0 <= #`TCQ tc_in == 0;
|
1494 |
|
|
cur_ep <= #`TCQ ep_in;
|
1495 |
|
|
cur_attr <= #`TCQ attr_in;
|
1496 |
|
|
cur_length1 <= #`TCQ length_in == 1;
|
1497 |
|
|
cur_fulltype <= #`TCQ fulltype_in;
|
1498 |
|
|
casex (fulltype_in)
|
1499 |
|
|
MRD32, MRD32LK, MWR32, MRD64, MRD64LK, MWR64:
|
1500 |
|
|
cur_fulltype_mem <= #`TCQ 1;
|
1501 |
|
|
default:
|
1502 |
|
|
cur_fulltype_mem <= #`TCQ 0;
|
1503 |
|
|
endcase
|
1504 |
|
|
casex (fulltype_in)
|
1505 |
|
|
MRD64, MRD64LK, MWR64:
|
1506 |
|
|
cur_fulltype_64 <= #`TCQ 1;
|
1507 |
|
|
default:
|
1508 |
|
|
cur_fulltype_64 <= #`TCQ 0;
|
1509 |
|
|
endcase
|
1510 |
|
|
casex (fulltype_in)
|
1511 |
|
|
MRD32, MRD64:
|
1512 |
|
|
cur_fulltype_oh <= #`TCQ MRDANY;
|
1513 |
|
|
MWR32, MWR64:
|
1514 |
|
|
cur_fulltype_oh <= #`TCQ MWRANY;
|
1515 |
|
|
MRD32LK, MRD64LK:
|
1516 |
|
|
cur_fulltype_oh <= #`TCQ MLKANY;
|
1517 |
|
|
IORD, IOWR:
|
1518 |
|
|
cur_fulltype_oh <= #`TCQ IOANY;
|
1519 |
|
|
CFGRD0, CFGWR0, CFGRD1, CFGWR1:
|
1520 |
|
|
cur_fulltype_oh <= #`TCQ CFGANY;
|
1521 |
|
|
MSG, MSGD:
|
1522 |
|
|
cur_fulltype_oh <= #`TCQ MSGANY;
|
1523 |
|
|
CPL, CPLD, CPLLK, CPLDLK:
|
1524 |
|
|
cur_fulltype_oh <= #`TCQ CPLANY;
|
1525 |
|
|
default: // don't want MSGAS to alias other types
|
1526 |
|
|
cur_fulltype_oh <= #`TCQ OTHERTYPE;
|
1527 |
|
|
endcase
|
1528 |
|
|
casex (fulltype_in)
|
1529 |
|
|
MRD32LK, MRD64LK, CPLLK, CPLDLK:
|
1530 |
|
|
cur_locked <= #`TCQ 1;
|
1531 |
|
|
default:
|
1532 |
|
|
cur_locked <= #`TCQ 0;
|
1533 |
|
|
endcase
|
1534 |
|
|
`else // `ifdef AS
|
1535 |
|
|
cur_hcrc <= #`TCQ d_i[HCRC_HI_IND:HCRC_LO_IND];
|
1536 |
|
|
cur_turn_pointer <= #`TCQ d_i[TURN_PTR_HI_IND:TURN_PTR_LO_IND];
|
1537 |
|
|
`endif
|
1538 |
|
|
end
|
1539 |
|
|
end
|
1540 |
|
|
|
1541 |
|
|
`ifdef PCIE
|
1542 |
|
|
always @(posedge clk_i) begin
|
1543 |
|
|
if (latch_2nd_dword) begin
|
1544 |
|
|
cur_req_id <= #`TCQ req_id_in;
|
1545 |
|
|
cur_tag <= #`TCQ tag_in;
|
1546 |
|
|
cur_msgcode <= #`TCQ msgcode_in;
|
1547 |
|
|
cur_cpl_stat <= #`TCQ cpl_stat_in;
|
1548 |
|
|
end
|
1549 |
|
|
end
|
1550 |
|
|
|
1551 |
|
|
// Store the High Address field for a 64-bit memory address (only
|
1552 |
|
|
// needed with the 32-bit datapath)
|
1553 |
|
|
//--------------------------------------------------------------------
|
1554 |
|
|
always @(posedge clk_i) begin
|
1555 |
|
|
if (latch_3rd_dword) begin
|
1556 |
|
|
cur_addr_hi <= #`TCQ addr_hi_in;
|
1557 |
|
|
end
|
1558 |
|
|
end
|
1559 |
|
|
`else // `ifdef AS
|
1560 |
|
|
|
1561 |
|
|
// Store the Direction bit for Turn Pointer check
|
1562 |
|
|
//--------------------------------------------------------------------
|
1563 |
|
|
always @(posedge clk_i) begin
|
1564 |
|
|
if (latch_2nd_dword) begin
|
1565 |
|
|
cur_dir <= #`TCQ d_i[DIR_IND];
|
1566 |
|
|
end
|
1567 |
|
|
end
|
1568 |
|
|
|
1569 |
|
|
// Store the Route Header for HCRC check
|
1570 |
|
|
//--------------------------------------------------------------------
|
1571 |
|
|
always @(posedge clk_i) begin
|
1572 |
|
|
if (latch_1st_dword) begin
|
1573 |
|
|
cur_route_header[50:32] <= #`TCQ d_i[DW-14:DW-32];
|
1574 |
|
|
end
|
1575 |
|
|
if (latch_2nd_dword) begin
|
1576 |
|
|
cur_route_header[31:0] <= #`TCQ d_i[31:0];
|
1577 |
|
|
end
|
1578 |
|
|
end
|
1579 |
|
|
`endif
|
1580 |
|
|
|
1581 |
|
|
`ifdef AS
|
1582 |
|
|
//====================================================================
|
1583 |
|
|
// Error Reporting
|
1584 |
|
|
//====================================================================
|
1585 |
|
|
// All errors detected by AS data_snk are Type B events. A Type B
|
1586 |
|
|
// event must be reported with the first 5 DW of the offending packet.
|
1587 |
|
|
// Because the CMM must process the event and send out a PI-5 event
|
1588 |
|
|
// before it can digest the next one, we must wait for acknowledgment
|
1589 |
|
|
// of a Type B event before we can report a new one. This means that
|
1590 |
|
|
// we may need to forgo report of any Type B events while we are
|
1591 |
|
|
// waiting for the CMM's reply.
|
1592 |
|
|
//--------------------------------------------------------------------
|
1593 |
|
|
|
1594 |
|
|
// Capture the header information in case of a Type B event. Read it
|
1595 |
|
|
// out and forward it to the CMM if a previous event is not pending.
|
1596 |
|
|
//--------------------------------------------------------------------
|
1597 |
|
|
|
1598 |
|
|
tlm_srl_fifo
|
1599 |
|
|
#(.DW (DW),
|
1600 |
|
|
.DMW (DW+1), // Mark each header's SOF
|
1601 |
|
|
.DEPTH (7),
|
1602 |
|
|
.CT_OUT (0))
|
1603 |
|
|
buf_fifo
|
1604 |
|
|
(.clk_i (clk_i),
|
1605 |
|
|
.reset_i (reset_i),
|
1606 |
|
|
.wen_i (wr_hdr),
|
1607 |
|
|
.d_i ({sof_i,d_i}),
|
1608 |
|
|
.ren_i (rd_hdr),
|
1609 |
|
|
.d_o ({hdr_sof,hdr}),
|
1610 |
|
|
.vld_o (),
|
1611 |
|
|
.nxt_vld_o(),
|
1612 |
|
|
.ct_o (),
|
1613 |
|
|
.chkpt_i (1'b1),
|
1614 |
|
|
.bkp_i (1'b0)
|
1615 |
|
|
);
|
1616 |
|
|
|
1617 |
|
|
// Write any of the first 5 DWORDs to the queue.
|
1618 |
|
|
|
1619 |
|
|
assign wr_hdr = (latch_1st_dword && !packet_ip) ||
|
1620 |
|
|
latch_2nd_dword || latch_3rd_dword ||
|
1621 |
|
|
latch_4th_dword || latch_5th_dword;
|
1622 |
|
|
|
1623 |
|
|
// Read out of the queue when we're about to see the result of the
|
1624 |
|
|
// error checks. Don't append the start of the next packet.
|
1625 |
|
|
|
1626 |
|
|
generate
|
1627 |
|
|
if (DW == 64) begin : rd_hdr_64
|
1628 |
|
|
assign rd_hdr = eof_q[1] || (|eof_q[3:2] || !sof_hdr);
|
1629 |
|
|
end else begin : rd_hdr_32
|
1630 |
|
|
assign rd_hdr = eof_o || (|eof_q[4:1] || !sof_hdr);
|
1631 |
|
|
end
|
1632 |
|
|
endgenerate
|
1633 |
|
|
|
1634 |
|
|
// Read into the header output register if a Type B is not already
|
1635 |
|
|
// pending. Since the queue must synchronize with the data stream, any
|
1636 |
|
|
// headers received while waiting for a Type B acknowledgment will be
|
1637 |
|
|
// read from the queue and silently dropped.
|
1638 |
|
|
|
1639 |
|
|
always @* load_type_b[0] = !type_b_pending &&
|
1640 |
|
|
((DW == 64) ? eof_q[1] :
|
1641 |
|
|
(eof_i && src_rdy_i && packet_ip));
|
1642 |
|
|
|
1643 |
|
|
always @(posedge clk_i) begin
|
1644 |
|
|
load_type_b[5:1] <= #`TCQ load_type_b[4:0];
|
1645 |
|
|
end
|
1646 |
|
|
|
1647 |
|
|
wire latch_1st_hdr_dword = load_type_b[0];
|
1648 |
|
|
wire latch_2nd_hdr_dword = (DW == 64) ? load_type_b[0] : load_type_b[1];
|
1649 |
|
|
wire latch_3rd_hdr_dword = (DW == 64) ? load_type_b[1] : load_type_b[2];
|
1650 |
|
|
wire latch_4th_hdr_dword = (DW == 64) ? load_type_b[1] :
|
1651 |
|
|
(load_type_b[3] && !sof_hdr);
|
1652 |
|
|
wire latch_5th_hdr_dword = (DW == 64) ?(load_type_b[2] && !sof_hdr) :
|
1653 |
|
|
(load_type_b[4] && !sof_hdr);
|
1654 |
|
|
localparam UPPER_HI_IND = DW-1;
|
1655 |
|
|
localparam UPPER_LO_IND = DW-32;
|
1656 |
|
|
localparam LOWER_HI_IND = 31;
|
1657 |
|
|
localparam LOWER_LO_IND = 0;
|
1658 |
|
|
|
1659 |
|
|
always @(posedge clk_i) begin
|
1660 |
|
|
if (latch_1st_hdr_dword) begin
|
1661 |
|
|
err_tlp_type_b_header_o[159:128]<= #`TCQ hdr[UPPER_HI_IND:UPPER_LO_IND];
|
1662 |
|
|
end
|
1663 |
|
|
|
1664 |
|
|
if (latch_2nd_hdr_dword) begin
|
1665 |
|
|
err_tlp_type_b_header_o[127:96] <= #`TCQ hdr[LOWER_HI_IND:LOWER_LO_IND];
|
1666 |
|
|
end else if (latch_1st_hdr_dword) begin
|
1667 |
|
|
err_tlp_type_b_header_o[127:96] <= #`TCQ 0;
|
1668 |
|
|
end
|
1669 |
|
|
|
1670 |
|
|
if (latch_3rd_hdr_dword) begin
|
1671 |
|
|
err_tlp_type_b_header_o[95:64] <= #`TCQ hdr[UPPER_HI_IND:UPPER_LO_IND];
|
1672 |
|
|
end else if (latch_1st_hdr_dword) begin
|
1673 |
|
|
err_tlp_type_b_header_o[95:64] <= #`TCQ 0;
|
1674 |
|
|
end
|
1675 |
|
|
|
1676 |
|
|
if (latch_4th_hdr_dword) begin
|
1677 |
|
|
err_tlp_type_b_header_o[63:32] <= #`TCQ hdr[LOWER_HI_IND:LOWER_LO_IND];
|
1678 |
|
|
end else if (latch_1st_hdr_dword) begin
|
1679 |
|
|
err_tlp_type_b_header_o[63:32] <= #`TCQ 0;
|
1680 |
|
|
end
|
1681 |
|
|
|
1682 |
|
|
if (latch_5th_hdr_dword) begin
|
1683 |
|
|
err_tlp_type_b_header_o[31:0] <= #`TCQ hdr[UPPER_HI_IND:UPPER_LO_IND];
|
1684 |
|
|
end else if (latch_1st_hdr_dword) begin
|
1685 |
|
|
err_tlp_type_b_header_o[31:0] <= #`TCQ 0;
|
1686 |
|
|
end
|
1687 |
|
|
end
|
1688 |
|
|
|
1689 |
|
|
// Synchronize the data_snk_mal error flags to the Type B header.
|
1690 |
|
|
|
1691 |
|
|
// In 64-bit, the header is available following the 3rd quadword.
|
1692 |
|
|
// In 32-bit, the header is available following the 5th doubleword.
|
1693 |
|
|
|
1694 |
|
|
localparam Q2HDR = (DW == 64) ? 3 : 5;
|
1695 |
|
|
|
1696 |
|
|
// In 64-bit, the header is available following EOF + 3.
|
1697 |
|
|
// In 32-bit, the header is available following EOF + 4.
|
1698 |
|
|
|
1699 |
|
|
localparam EOF2HDR = (DW == 64) ? 3 : 4;
|
1700 |
|
|
|
1701 |
|
|
always @(posedge clk_i) begin
|
1702 |
|
|
if (reset_i) begin
|
1703 |
|
|
err_tlp_bad_header_crc_o <= #`TCQ 0;
|
1704 |
|
|
err_tlp_bad_pi_chain_o <= #`TCQ 0;
|
1705 |
|
|
err_tlp_invalid_credit_length_o <= #`TCQ 0;
|
1706 |
|
|
err_tlp_bad_credit_length_o <= #`TCQ 0;
|
1707 |
|
|
err_tlp_non_zero_turn_pointer_o <= #`TCQ 0;
|
1708 |
|
|
err_tlp_unsup_ovc_o <= #`TCQ 0;
|
1709 |
|
|
err_tlp_unsup_mvc_o <= #`TCQ 0;
|
1710 |
|
|
|
1711 |
|
|
// load_type_b makes sure we stored the current header (i.e., a
|
1712 |
|
|
// previous Type B was not pending). eof_nd_q makes sure the packet
|
1713 |
|
|
// wasn't discontinued.
|
1714 |
|
|
end else if (load_type_b[Q2HDR] && eof_nd_q[EOF2HDR]) begin
|
1715 |
|
|
err_tlp_bad_header_crc_o <= #`TCQ bad_header_crc;
|
1716 |
|
|
err_tlp_bad_pi_chain_o <= #`TCQ bad_pi_chain &&
|
1717 |
|
|
!bad_header_crc;
|
1718 |
|
|
err_tlp_invalid_credit_length_o <= #`TCQ invalid_credit_length &&
|
1719 |
|
|
!bad_pi_chain &&
|
1720 |
|
|
!bad_header_crc;
|
1721 |
|
|
err_tlp_bad_credit_length_o <= #`TCQ bad_credit_length &&
|
1722 |
|
|
!invalid_credit_length &&
|
1723 |
|
|
!bad_pi_chain &&
|
1724 |
|
|
!bad_header_crc;
|
1725 |
|
|
err_tlp_non_zero_turn_pointer_o <= #`TCQ non_zero_turn_pointer &&
|
1726 |
|
|
!bad_credit_length &&
|
1727 |
|
|
!invalid_credit_length &&
|
1728 |
|
|
!bad_pi_chain &&
|
1729 |
|
|
!bad_header_crc;
|
1730 |
|
|
err_tlp_unsup_mvc_o <= #`TCQ unsup_mvc &&
|
1731 |
|
|
!non_zero_turn_pointer &&
|
1732 |
|
|
!bad_credit_length &&
|
1733 |
|
|
!invalid_credit_length &&
|
1734 |
|
|
!bad_pi_chain &&
|
1735 |
|
|
!bad_header_crc;
|
1736 |
|
|
err_tlp_unsup_ovc_o <= #`TCQ unsup_ovc &&
|
1737 |
|
|
!unsup_mvc &&
|
1738 |
|
|
!non_zero_turn_pointer &&
|
1739 |
|
|
!bad_credit_length &&
|
1740 |
|
|
!invalid_credit_length &&
|
1741 |
|
|
!bad_pi_chain &&
|
1742 |
|
|
!bad_header_crc;
|
1743 |
|
|
end else begin
|
1744 |
|
|
err_tlp_bad_header_crc_o <= #`TCQ 0;
|
1745 |
|
|
err_tlp_bad_pi_chain_o <= #`TCQ 0;
|
1746 |
|
|
err_tlp_invalid_credit_length_o <= #`TCQ 0;
|
1747 |
|
|
err_tlp_bad_credit_length_o <= #`TCQ 0;
|
1748 |
|
|
err_tlp_non_zero_turn_pointer_o <= #`TCQ 0;
|
1749 |
|
|
err_tlp_unsup_mvc_o <= #`TCQ 0;
|
1750 |
|
|
err_tlp_unsup_ovc_o <= #`TCQ 0;
|
1751 |
|
|
end
|
1752 |
|
|
end
|
1753 |
|
|
|
1754 |
|
|
always @(posedge clk_i) begin
|
1755 |
|
|
if (reset_i) begin
|
1756 |
|
|
type_b_pending <= #`TCQ 0;
|
1757 |
|
|
end else if (eof_nd_q[EOF2HDR] && load_type_b[Q2HDR]) begin
|
1758 |
|
|
type_b_pending <= #`TCQ bad_header_crc || bad_pi_chain ||
|
1759 |
|
|
invalid_credit_length || bad_credit_length ||
|
1760 |
|
|
non_zero_turn_pointer || unsup_mvc || unsup_ovc;
|
1761 |
|
|
end else if (err_tlp_type_b_ack_i) begin
|
1762 |
|
|
type_b_pending <= #`TCQ 0;
|
1763 |
|
|
end
|
1764 |
|
|
end
|
1765 |
|
|
`endif
|
1766 |
|
|
|
1767 |
|
|
// synthesis translate_off
|
1768 |
|
|
`ifdef PCIE
|
1769 |
|
|
reg [10*8:0] cur_type_str;
|
1770 |
|
|
always @* begin
|
1771 |
|
|
casex (cur_fulltype)
|
1772 |
|
|
MRD32 : begin cur_type_str = "MRD32"; end
|
1773 |
|
|
MRD64 : begin cur_type_str = "MRD64"; end
|
1774 |
|
|
MRD32LK : begin cur_type_str = "MRD32LK";end
|
1775 |
|
|
MRD64LK : begin cur_type_str = "MRD64LK";end
|
1776 |
|
|
MWR32 : begin cur_type_str = "MWR32"; end
|
1777 |
|
|
MWR64 : begin cur_type_str = "MWR64"; end
|
1778 |
|
|
IORD : begin cur_type_str = "IORD"; end
|
1779 |
|
|
IOWR : begin cur_type_str = "IOWR"; end
|
1780 |
|
|
CFGRD0 : begin cur_type_str = "CFGRD0"; end
|
1781 |
|
|
CFGWR0 : begin cur_type_str = "CFGWR0"; end
|
1782 |
|
|
CFGRD1 : begin cur_type_str = "CFGRD1"; end
|
1783 |
|
|
CFGWR1 : begin cur_type_str = "CFGWR1"; end
|
1784 |
|
|
MSG : begin cur_type_str = "MSG"; end
|
1785 |
|
|
MSGD : begin cur_type_str = "MSGD"; end
|
1786 |
|
|
MSGAS : begin cur_type_str = "MSGAS"; end
|
1787 |
|
|
MSGASD : begin cur_type_str = "MSGASD"; end
|
1788 |
|
|
CPL : begin cur_type_str = "CPL"; end
|
1789 |
|
|
CPLD : begin cur_type_str = "CPLD"; end
|
1790 |
|
|
CPLLK : begin cur_type_str = "CPLLK"; end
|
1791 |
|
|
CPLDLK : begin cur_type_str = "CPLDLK"; end
|
1792 |
|
|
default : begin cur_type_str = "undef"; end
|
1793 |
|
|
endcase
|
1794 |
|
|
end
|
1795 |
|
|
reg [30*8:0] cur_msgstr;
|
1796 |
|
|
always @* begin
|
1797 |
|
|
case (cur_msgcode)
|
1798 |
|
|
UNLOCK : cur_msgstr = "UNLOCK";
|
1799 |
|
|
PM_ACTIVE_STATE_NAK : cur_msgstr = "PM_ACTIVE_STATE_NAK";
|
1800 |
|
|
PM_PME : cur_msgstr = "PM_PME";
|
1801 |
|
|
PME_TURN_OFF : cur_msgstr = "PME_TURN_OFF";
|
1802 |
|
|
PME_TO_ACK : cur_msgstr = "PME_TO_ACK";
|
1803 |
|
|
ATTENTION_INDICATOR_OFF : cur_msgstr = "ATTENTION_INDICATOR_OFF";
|
1804 |
|
|
ATTENTION_INDICATOR_ON : cur_msgstr = "ATTENTION_INDICATOR_ON";
|
1805 |
|
|
ATTENTION_INDICATOR_BLINK : cur_msgstr = "ATTENTION_INDICATOR_BLINK";
|
1806 |
|
|
POWER_INDICATOR_ON : cur_msgstr = "POWER_INDICATOR_ON";
|
1807 |
|
|
POWER_INDICATOR_BLINK : cur_msgstr = "POWER_INDICATOR_BLINK";
|
1808 |
|
|
POWER_INDICATOR_OFF : cur_msgstr = "POWER_INDICATOR_OFF";
|
1809 |
|
|
ATTENTION_BUTTON_PRESSED : cur_msgstr = "ATTENTION_BUTTON_PRESSED";
|
1810 |
|
|
SET_SLOT_POWER_LIMIT : cur_msgstr = "SET_SLOT_POWER_LIMIT";
|
1811 |
|
|
VENDOR_DEFINED_TYPE_0 : cur_msgstr = "VENDOR_DEFINED_TYPE_0";
|
1812 |
|
|
VENDOR_DEFINED_TYPE_1 : cur_msgstr = "VENDOR_DEFINED_TYPE_1";
|
1813 |
|
|
default : cur_msgstr = "undef";
|
1814 |
|
|
endcase
|
1815 |
|
|
end
|
1816 |
|
|
`endif
|
1817 |
|
|
// synthesis translate_on
|
1818 |
|
|
|
1819 |
|
|
endmodule
|