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

Subversion Repositories pcie_ds_dma

[/] [pcie_ds_dma/] [trunk/] [core/] [ds_dma64/] [pcie_src/] [pcie_core64_m1/] [source/] [tlm_rx_data_snk_mal.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
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_mal.v
53
//--------------------------------------------------------------------------------
54
//--------------------------------------------------------------------------------
55
/****************************************************************************
56
 *  Description : Rx Data Sink malformed packet detection
57
 *
58
 *     Hierarchical :
59
 *
60
 *     Functional :
61
 *      Takes incoming packets, examines the packet for correct
62
 *        construction and drops if it malformed.
63
 *
64
 ***************************************************************************/
65
`timescale 1ns/1ps
66
`ifndef TCQ
67
 `define TCQ 1
68
`endif
69
`ifndef PCIE
70
 `ifndef AS
71
  `define PCIE
72
 `endif
73
`endif
74
 
75
module tlm_rx_data_snk_mal #(parameter DW = 32,
76
                             parameter FCW = 6,
77
                             parameter LENW = 10,
78
                             `ifdef PCIE
79
                             parameter DOWNSTREAM_PORT = 0,
80
                             `else // `ifdef AS
81
                             parameter OVC = 0,
82
                             parameter MVC = 0,
83
                             `endif
84
                             parameter MPS = 512,
85
                             parameter TYPE1_UR = 0)
86
  (
87
   input                 clk_i,
88
   input                 reset_i,
89
 
90
   // credit output
91
   output reg [FCW-1:0]  data_credits_o,    // data credits for the packet
92
   output                data_credits_vld_o,// data credits valid
93
 
94
   // packet steering
95
   output reg            cfg_o,             // Packet is config
96
   `ifdef AS
97
   input                 oo_i,              // Packet is OVC-bound
98
   input                 ts_i,              // Packet is Bypassable in BVC
99
   `endif
100
 
101
   // errors
102
   `ifdef PCIE
103
   output reg            malformed_o,       // packet is badly constructed
104
   output reg            tlp_ur_o,          // unsupported request
105
   output reg            tlp_ur_lock_o,     // unsupported request due to MemRdLk
106
   output reg            tlp_uc_o,          // unexpected completion
107
   output reg            tlp_filt_o,        // filter this packet - not an
108
                                            //  error, but handled @same time
109
   `else // `ifdef AS
110
   output reg            bad_header_crc_o,
111
   output reg            bad_pi_chain_o,
112
   output reg            bad_credit_length_o,
113
   output reg            invalid_credit_length_o,
114
   output reg            non_zero_turn_pointer_o,
115
   output reg            unsup_mvc_o,
116
   output reg            unsup_ovc_o,
117
   `endif
118
 
119
   // For user/config steering
120
   input [3:0]           aperture_i,        // Config address ext. reg. number
121
   input                 load_aperture_i,
122
 
123
   `ifdef PCIE
124
   // for format calculations
125
   input                 eval_fulltype_i,   // Latch fulltype_i
126
   input [6:0]           fulltype_i,        // Type valid on eval_fulltype_i
127
   input                 eval_msgcode_i,    // Latch msgcode_i
128
   input [7:0]           msgcode_i,         // Msg code valid on eval_msgcode_i
129
   input                 tc0_i,             // Are we traffic class 0?
130
 
131
   // for UC/UR determination
132
   input                 hit_src_rdy_i,     // are the results ready
133
   input                 hit_ack_i,         // did we request a check?
134
   input                 hit_lock_i,        // was it for a locked Memrd?
135
   input                 hit_i,             // is this our address?
136
   input                 hit_lat3_i,        // is the hit latency 3 clocks?
137
   input                 pwr_mgmt_on_i,     // are we in power mgmt mode?
138
   input                 legacy_mode_i,     // core is in legacy mode
139
 
140
   // For user/config steering
141
   input                 legacy_cfg_access_i,//user implements legacy config
142
   input                 ext_cfg_access_i,  // user implements extended config
143
   input [7:0]           offset_i,          // Config address offset
144
 
145
   // for (potential) packet drop
146
   output reg            hp_msg_detect_o,   // obsolete hot-plug msg detected
147
   `else // `ifdef AS
148
   // for PI calculations
149
   input [6:0]           pi_1st_i,
150
   input [6:0]           pi_2nd_i,
151
   input [6:0]           pi_3rd_i,
152
   input [6:0]           pi_4th_i,
153
 
154
   input                 load_pi_1st_i,
155
   input                 load_pi_2nd_i,
156
   input                 load_pi_3rd_i,
157
   input                 load_pi_4th_i,
158
 
159
   // for format calculations
160
   input [6:0]           hcrc_i,            // Header CRC
161
   input [50:0]          route_header_i,    // Route header covered by HCRC
162
   input [4:0]           turn_pointer_i,    // Pointer into the Turn Pool
163
   input                 dir_i,             // Direction (1 = back-route)
164
   input                 switch_mode_i,     // Are we in a Switch?
165
 
166
   // For user/config steering
167
   input [31:0]          offset_i,          // Config address offset
168
   input                 load_offset_i,
169
 
170
   input                 fabric_manager_mode_i, // Is core a Fabric Manager?
171
   input [31:0]          cmm_ap0_space_end_i,   // End of Aperture 0 range
172
   input [31:0]          cmm_ap1_space_start_i, // Start of Aperture 1 range
173
   input [31:0]          cmm_ap1_space_end_i,   // End of Aperture 1 range
174
 
175
   // for packet drop
176
   input [1:0]           lnk_state_i,      // link state
177
   input                 lnk_state_src_rdy_i,   // link state write enable
178
   output                filter_drop_o,
179
   `endif
180
 
181
   // for length calculations
182
   input                 eval_formats_i,    // latch the formatting check
183
   input [9:0]           length_i,          // supposed length of the packet
184
   `ifdef PCIE
185
   input                 length_1dw_i,      // true if length_i == 1
186
   `endif
187
   input                 sof_i,             // beginning of header
188
   input                 eof_i,             // end of packet
189
   `ifdef PCIE
190
   input                 rem_i,             // rem at eof
191
   input                 td_i,              // packet has digest
192
   input [2:0]           max_payload_i      // as cfg'd by the cmm
193
   `else // `ifdef AS
194
   input [3:0]           max_payload_i      // as cfg'd by the cmm
195
   `endif
196
   );
197
 
198
  `ifdef PCIE
199
  //---------------------------------------------------------------------------
200
  // PCI Express constants
201
  //---------------------------------------------------------------------------
202
  // Full Type
203
  localparam             MRD32   = 7'b00_00000;
204
  localparam             MRD64   = 7'b01_00000;
205
  localparam             MRD32LK = 7'b00_00001;
206
  localparam             MRD64LK = 7'b01_00001;
207
  localparam             MWR32   = 7'b10_00000;
208
  localparam             MWR64   = 7'b11_00000;
209
  localparam             IORD    = 7'b00_00010;
210
  localparam             IOWR    = 7'b10_00010;
211
  localparam             CFGRD0  = 7'b00_00100;
212
  localparam             CFGWR0  = 7'b10_00100;
213
  localparam             CFGRD1  = 7'b00_00101;
214
  localparam             CFGWR1  = 7'b10_00101;
215
  localparam             CFGANY  = 7'bx0_0010x;
216
  localparam             CFGANY0 = 7'bx0_00100;
217
  localparam             CFGANY1 = 7'bx0_00101;
218
  localparam             MSG     = 7'b01_10xxx;
219
  localparam             MSGD    = 7'b11_10xxx;
220
  localparam             CPL     = 7'b00_01010;
221
  localparam             CPLD    = 7'b10_01010;
222
  localparam             CPLLK   = 7'b00_01011;
223
  localparam             CPLDLK  = 7'b10_01011;
224
 
225
  // Message code
226
  localparam             UNLOCK                    = 8'b0000_0000;
227
  localparam             PM_ACTIVE_STATE_NAK       = 8'b0001_0100;
228
  localparam             PM_PME                    = 8'b0001_1000;
229
  localparam             PME_TURN_OFF              = 8'b0001_1001;
230
  localparam             PME_TO_ACK                = 8'b0001_1011;
231
  localparam             ATTENTION_INDICATOR_OFF   = 8'b0100_0000;
232
  localparam             ATTENTION_INDICATOR_ON    = 8'b0100_0001;
233
  localparam             ATTENTION_INDICATOR_BLINK = 8'b0100_0011;
234
  localparam             POWER_INDICATOR_ON        = 8'b0100_0101;
235
  localparam             POWER_INDICATOR_BLINK     = 8'b0100_0111;
236
  localparam             POWER_INDICATOR_OFF       = 8'b0100_0100;
237
  localparam             ATTENTION_BUTTON_PRESSED  = 8'b0100_1000;
238
  localparam             SET_SLOT_POWER_LIMIT      = 8'b0101_0000;
239
  localparam             ASSERT_INTA               = 8'b0010_0000;
240
  localparam             ASSERT_INTB               = 8'b0010_0001;
241
  localparam             ASSERT_INTC               = 8'b0010_0010;
242
  localparam             ASSERT_INTD               = 8'b0010_0011;
243
  localparam             DEASSERT_INTA             = 8'b0010_0100;
244
  localparam             DEASSERT_INTB             = 8'b0010_0101;
245
  localparam             DEASSERT_INTC             = 8'b0010_0110;
246
  localparam             DEASSERT_INTD             = 8'b0010_0111;
247
  localparam             ERR_COR                   = 8'b0011_0000;
248
  localparam             ERR_NONFATAL              = 8'b0011_0001;
249
  localparam             ERR_FATAL                 = 8'b0011_0011;
250
  localparam             VENDOR_DEFINED_TYPE_0     = 8'b0111_1110;
251
  localparam             VENDOR_DEFINED_TYPE_1     = 8'b0111_1111;
252
 
253
  // Route
254
  localparam             ROUTE_TO_RC = 3'b000;
255
  localparam             ROUTE_BY_AD = 3'b001;
256
  localparam             ROUTE_BY_ID = 3'b010;
257
  localparam             ROUTE_BROAD = 3'b011;
258
  localparam             ROUTE_LOCAL = 3'b100;
259
  localparam             ROUTE_GATHR = 3'b101;
260
  localparam             ROUTE_RSRV0 = 3'b110;
261
  localparam             ROUTE_RSRV1 = 3'b111;
262
  `endif // `ifdef PCIE
263
 
264
  //---------------------------------------------------------------------------
265
  // Other constants
266
  //---------------------------------------------------------------------------
267
  // Bus widths
268
  `ifdef PCIE
269
  localparam             DCW = FCW + ((DW == 64) ? 1 : 2);  // Data-count width
270
  localparam             PLW = (FCW == 9) ? 10 : (FCW + 2);
271
                         // Pertinent portion of the Length field
272
  `else // `ifdef AS
273
  localparam             DCW = FCW + ((DW == 64) ? 3 : 4);  // Data-count width
274
  localparam             PLW = (FCW == 6) ? 5 : FCW;
275
                         // Pertinent portion of the Credits Required field
276
  `endif
277
 
278
  // Port direction
279
  localparam UPSTREAM_PORT = !DOWNSTREAM_PORT;
280
 
281
  //---------------------------------------------------------------------------
282
  // Internal signals
283
  //---------------------------------------------------------------------------
284
  // delayed versions of signals
285
  reg                    eof_q1;
286
  `ifdef PCIE
287
  reg                    sof_q1, sof_q2, sof_q3, sof_q4;
288
  reg                    eof_q2, eof_q3;
289
  reg                    eval_formats_q, eval_formats_q2;
290
  wire                   eof_sync, bar_sync;
291
  reg                    load_aperture_q;
292
  `else // `ifdef AS
293
  reg                    load_offset_q;
294
  `endif
295
 
296
  // Length check
297
  reg [DCW-1:0]          word_ct;
298
  reg [DCW-1:0]          word_ct_d;
299
  reg                    malformed_maxsize;
300
  reg                    malformed_over;
301
  `ifdef AS
302
  reg                    malformed_byp_not_1;
303
  reg                    malformed_pi4_or_5_not_1;
304
  `endif
305
  reg [LENW-1:0]         max_length;
306
 
307
  `ifdef PCIE
308
  reg [6:0]              fulltype_in;
309
  reg [7:0]              msgcode_in;
310
 
311
  wire                   has_data   = fulltype_in[6];
312
  wire                   header_4dw = fulltype_in[5];
313
  wire                   length_odd = length_i[0] && has_data;
314
  reg                    type_1dw;
315
 
316
  reg                    malformed_eof;
317
  reg                    malformed_rem;
318
  reg                    malformed_len;
319
  reg                    malformed_min;
320
  wire                   malformed_1dw;
321
 
322
  wire                   word_ct_zero;
323
  wire                   word_ct_neg1;
324
  wire                   expected_rem;
325
 
326
  reg                    delay_ct;
327
  reg                    delay_ct_d;
328
  `endif
329
 
330
  `ifdef PCIE
331
  // URs and UCs
332
  reg                    malformed_fulltype;
333
  reg                    malformed_tc;
334
  reg                    malformed_message;
335
  reg                    malformed_fmt;
336
 
337
  reg                    ismsg, ismsgd, ismsgany;
338
  reg                    fulltype_tc0;
339
  wire                   msgcode_tc0;
340
  reg                    msgcode_legacy;
341
  reg                    msgcode_hotplug;
342
  reg                    msgcode_sigdef;
343
  reg                    msgcode_vendef;
344
  reg                    msgcode_dmatch;
345
  reg [2:0]              msgcode_routing;
346
 
347
  wire [2:0]             routing    = fulltype_i[2:0];
348
  wire [2:0]             routing_in = fulltype_in[2:0];
349
  reg                    routing_vendef;
350
  reg                    cpl_ip;
351
  reg                    filter_msgcode;
352
  reg                    filter_msgcode_q;
353
  reg                    ur_pwr_mgmt, uc_pwr_mgmt;
354
  reg                    ur_type1_cfg = 0;
355
  reg                    ur_mem_lk, uc_cpl_lk;
356
  reg                    ur_format, uc_format;
357
  reg                    ur_format_lock;
358
 
359
  // Packet steering
360
  reg                    cfg0_ip, cfg1_ip;
361
  reg                    is_usr_leg_ap, is_usr_ext_ap;
362
  `else // `ifdef AS
363
  // PI chain
364
  reg  [7:0]             pi_1st;
365
  reg  [7:0]             pi_2nd;
366
  reg  [7:0]             pi_3rd;
367
  reg  [7:0]             pi_4th;
368
 
369
  wire                   load_pi_1st;
370
  wire                   load_pi_2nd;
371
  wire                   load_pi_3rd;
372
  wire                   load_pi_4th;
373
 
374
  reg                    pi_1st_vld;
375
  reg                    pi_2nd_vld;
376
  reg                    pi_3rd_vld;
377
  reg                    pi_4th_vld;
378
 
379
  reg                    pi_2nd_seq_vld;
380
  reg                    pi_3rd_seq_vld;
381
  reg                    pi_4th_seq_vld;
382
 
383
  reg                    primary_pi0;
384
  reg                    primary_pi4;
385
  reg                    primary_pi5;
386
 
387
  // Config-packet detection
388
  reg                    pi4_ap0;
389
  reg                    pi4_ap1;
390
  reg                    in_ap0_range;
391
  reg                    in_ap1_range;
392
  reg                    secondary_pi0;
393
 
394
  // Link state and packet drop
395
  reg  [1:0]             lnk_state_d;
396
  reg  [1:0]             lnk_state;
397
  reg                    packet_ip;
398
  reg                    packet_keep;
399
 
400
  // Header CRC
401
  wire [6:0]             header_crc_d;
402
  wire [6:0]             header_crc_pb_d;
403
  reg  [6:0]             header_crc;
404
  reg  [6:0]             header_crc_pb;
405
  reg                    path_build;
406
  `endif
407
 
408
  `ifdef PCIE
409
  // Synchronize checks with BAR-hit latency
410
 
411
  assign eof_sync = hit_lat3_i ? eof_q3 : eof_q2;
412
  assign bar_sync = hit_lat3_i ? eval_formats_q2 : eval_formats_q;
413
  `endif
414
 
415
  `ifdef PCIE
416
  // Calculate data credits from Length field
417
  //====================================================================
418
  // If the Length field is not correct, we'll signal Malformed for the
419
  // packet later, while freeing that same amount with unuse.
420
  //-------------------------------------------------------------------
421
 
422
  // Data credits are calculated on SOF q2 and provided to the top level
423
  // at SOF q4 for pipelining purposes.
424
 
425
  // 1 data credit = 4 dwords, round up partials
426
  always @(posedge clk_i) begin
427
    if (sof_q2) begin
428
      data_credits_o[PLW-3:0] <= #`TCQ has_data ?
429
                                       (length_i[PLW-1:2] + |length_i[1:0]): 0;
430
    end
431
  end
432
 
433
  generate
434
    if (FCW == 9) begin : max_data_credits
435
      always @(posedge clk_i) begin
436
        if (sof_q2) begin
437
          data_credits_o[FCW-1] <= #`TCQ ~|length_i && has_data;
438
        end
439
      end
440
    end
441
  endgenerate
442
 
443
  assign data_credits_vld_o = sof_q4;
444
  `else // `ifdef AS
445
  // Calculate data credits from actual length count
446
  //====================================================================
447
 
448
  localparam WPC  = 512/DW;      // Words/credit (64 bytes = 512 bits/credit)
449
  localparam WPCW = (DW == 64) ? 3 : 4;  // log2(WPC)
450
 
451
  // We pull off the upper portion of the word count to get the number
452
  // of credits. An illustration is how this works is given further
453
  // along.
454
 
455
  always @* data_credits_o     = word_ct[DCW-1:WPCW];
456
  assign    data_credits_vld_o = eof_q1;
457
  `endif
458
 
459
  // Malformed length checks
460
  //====================================================================
461
 
462
  //------------------------------------------------------------------------
463
  // Convert the incoming CMM max-payload signal to a max length.
464
  //------------------------------------------------------------------------
465
 
466
  // Optimize out any unsupported MPS settings. Note: 2176/4096 checked
467
  // differently.
468
 
469
  `ifdef PCIE
470
  localparam MAX_128  =                 32;             // 128B
471
  localparam MAX_256  = (MPS >= 256)  ? 64  : MAX_128;  // 256B
472
  localparam MAX_512  = (MPS >= 512)  ? 128 : MAX_256;  // 512B
473
  localparam MAX_1024 = (MPS >= 1024) ? 256 : MAX_512;  // 1024B
474
  localparam MAX_2048 = (MPS >= 2048) ? 512 : MAX_1024; // 2048B
475
  localparam MAX_4096 = (MPS >= 4096) ? 0   : MAX_2048; // 4096B*
476
 
477
  always @(posedge clk_i) begin
478
    if (reset_i) begin
479
      max_length            <= #`TCQ MAX_128;
480
    end else begin
481
      case (max_payload_i)
482
        3'b000:  max_length <= #`TCQ MAX_128;
483
        3'b001:  max_length <= #`TCQ MAX_256;
484
        3'b010:  max_length <= #`TCQ MAX_512;
485
        3'b011:  max_length <= #`TCQ MAX_1024;
486
        3'b100:  max_length <= #`TCQ MAX_2048;
487
        default: max_length <= #`TCQ MAX_4096;
488
      endcase
489
    end
490
  end
491
  `else // `ifdef AS
492
  localparam BVC = !OVC && !MVC;
493
 
494
  localparam MAX_64   =  !BVC                  ? 1 : 3;
495
  localparam MAX_96   = (!BVC && (MPS >= 96))  ? 2 : 3;
496
  localparam MAX_128  = (!BVC && (MPS >= 128)) ? 2 : 3;
497
  localparam MAX_192  =          (MPS >= 192)  ? 3 : MAX_128;
498
  localparam MAX_320  =          (MPS >= 320)  ? 5 : MAX_192;
499
  localparam MAX_576  =          (MPS >= 576)  ? 9 : MAX_320;
500
  localparam MAX_1088 =          (MPS >= 1088) ? 17: MAX_576;
501
  localparam MAX_2176 =          (MPS >= 2176) ? 0 : MAX_1088;
502
 
503
  // Max length is MPS, except for PI-0:0, PI-4, PI-5 and Bypassable
504
  // packets, whose max length is 1.
505
 
506
  always @(posedge clk_i) begin
507
    if (reset_i) begin
508
      max_length            <= #`TCQ MAX_192;
509
    end else begin
510
      casex (max_payload_i)
511
        4'b000x: max_length <= #`TCQ MAX_64;
512
        4'b0010: max_length <= #`TCQ MAX_96;
513
        4'b0011: max_length <= #`TCQ MAX_128;
514
        4'b0100: max_length <= #`TCQ MAX_192;
515
        4'b0101: max_length <= #`TCQ MAX_320;
516
        4'b0110: max_length <= #`TCQ MAX_576;
517
        4'b0111: max_length <= #`TCQ MAX_1088;
518
        default: max_length <= #`TCQ MAX_2176;
519
      endcase
520
    end
521
  end
522
  `endif
523
 
524
  //--------------------------------------------------------------------
525
  // This checks if the Length field is set too large for programmed
526
  // MPS. In PCIe, this only applies to packets with data; packets
527
  // without data can have length fields that exceed MPS (other length
528
  // requirements notwithstanding) since they don't have payloads.
529
  //--------------------------------------------------------------------
530
  always @(posedge clk_i) begin
531
    if (reset_i) begin
532
      malformed_maxsize <= #`TCQ 0;
533
    end else if (eval_formats_i) begin
534
      `ifdef PCIE
535
      // If programmed MPS is not 4096, Length must be non-zero
536
      if ((max_payload_i < 3'b101) || (MPS < 4096)) begin
537
        malformed_maxsize <= #`TCQ ((length_i > max_length) || ~|length_i) &&
538
                                    has_data;
539
      // If programmed MPS is 4096, any Length setting is legal
540
      end else begin
541
        malformed_maxsize <= #`TCQ 0;
542
      end
543
      `else // `ifdef AS
544
      // The Credits Required field must be 1 for Bypassable, PI-0:0,
545
      // PI-4 and PI-5.
546
      if ((!oo_i && ts_i) || (primary_pi0 && (pi_2nd_i == 0)) ||
547
          primary_pi4 || primary_pi5) begin
548
        malformed_maxsize <= #`TCQ (length_i != 1);
549
      // If programmed MPS is not 2176, Credits Required must be non-zero
550
      end else if ((max_payload_i < 4'b1000) || (MPS < 2176)) begin
551
        malformed_maxsize <= #`TCQ (length_i > max_length) || ~|length_i;
552
      // If programmed MPS is 2176, any Credits Required setting is legal
553
      end else begin
554
        malformed_maxsize <= #`TCQ 0;
555
      end
556
      `endif
557
    end
558
  end
559
 
560
  //--------------------------------------------------------------------
561
  // Payload count: DW count in 32-bit, QW count in 64-bit
562
  //--------------------------------------------------------------------
563
 
564
  `ifdef PCIE
565
  //--------------------------------------------------------------------
566
  // In PCIe, word_ct is loaded with the number of data beats following
567
  // assertion of eval_formats_q (on the 4th DW or 3rd QW), rem
568
  // notwithstanding. After eval_formats_i, word_ct decrements. This
569
  // causes word_ct to equal zero on the same clock cycle EOF is
570
  // expected.
571
  //--------------------------------------------------------------------
572
 
573
  // The load value of word_ct is one of the following:
574
  // * Outside of eval_formats_i: current value of word_ct. We want to
575
  //   decrement word_ct by 1; this will be done separately.
576
  // * If eval_formats_i is asserted, same as Length in 32-bit, or
577
  //   Length right-shifted by 1 in 64-bit. The count is later delayed
578
  //   based on header and TD.
579
 
580
  generate
581
    if (DW == 64) begin : word_ct_load_64
582
      always @* begin
583
        if (!eval_formats_i) begin
584
          word_ct_d[PLW-2:0] = word_ct[PLW-2:0];
585
        end else if (has_data) begin
586
          word_ct_d[PLW-2:0] = length_i[PLW-1:1];
587
        end else begin
588
          word_ct_d[PLW-2:0] = 0;
589
        end
590
      end
591
    end else begin : word_ct_load_32
592
      always @* begin
593
        if (!eval_formats_i) begin
594
          word_ct_d[PLW-1:0] = word_ct[PLW-1:0];
595
        end else if (has_data) begin
596
          word_ct_d[PLW-1:0] = length_i[PLW-1:0];
597
        end else begin
598
          word_ct_d[PLW-1:0] = 0;
599
        end
600
      end
601
    end
602
  endgenerate
603
 
604
  // If the data-count width supports 4096 bytes, we need to take care
605
  // of the all-zero case.
606
 
607
  generate
608
    if (FCW == 9) begin : word_ct_max_load
609
      always @* begin
610
        if (!eval_formats_i) begin
611
          word_ct_d[DCW-1] = word_ct[DCW-1];
612
        end else begin
613
          word_ct_d[DCW-1] = ~|length_i && has_data;
614
        end
615
      end
616
    end
617
  endgenerate
618
 
619
  // Load or increment word_ct, using a mux-before-add strategy. This
620
  // saves us a level of logic over add-before-mux.
621
 
622
  always @(posedge clk_i) begin
623
    if (reset_i) begin
624
      word_ct   <= #`TCQ 0;
625
    end else if (!delay_ct && !delay_ct_d) begin
626
      word_ct   <= #`TCQ word_ct_d - 1;
627
    end
628
  end
629
  `else // `ifdef AS
630
  //--------------------------------------------------------------------
631
  // In AS, word_ct is loaded upon sof_i with the number of data beats
632
  // per credit (16 in 32-bit, 8 in 64-bit). Unlike PCIe, word_ct counts
633
  // upward because the upper bits double as the data-credit quantity.
634
  // As such, the count is valid on the clock cycle after eof_i, as can
635
  // be seen in these 64-bit examples:
636
  //
637
  // 64 bytes => 8 words = 1 credit
638
  //   clock 1:  sof_i          => load counter
639
  //   clock 2:                 => length = 8
640
  //   clock 3:                 => length = 9
641
  //   clock 4:                 => length = 10
642
  //   clock 5:                 => length = 11
643
  //   clock 6:                 => length = 12
644
  //   clock 7:                 => length = 13
645
  //   clock 8:  eof_i          => length = 14
646
  //   clock 9:  eof_q1         => length = 15 -> 01111b -> [01]111b -> 1 cred.
647
  // 72 bytes => 9 words = 2 credits
648
  //   clock 1:  sof_i          => load counter
649
  //   clock 2:                 => length = 8
650
  //   clock 3:                 => length = 9
651
  //   clock 4:                 => length = 10
652
  //   clock 5:                 => length = 11
653
  //   clock 6:                 => length = 12
654
  //   clock 7:                 => length = 13
655
  //   clock 8:                 => length = 14
656
  //   clock 9:  eof_i          => length = 15
657
  //   clock 10: eof_q1         => length = 16 -> 10000b -> [10]000b -> 2 cred.
658
  //
659
  // Note in the second case that if the
660
  //
661
  // To account for built-in incrementer in word_ct, we load
662
  // with the desired value minus one.
663
  //-----------------------------------------------------------
664
 
665
  always @* begin
666
    if (sof_i) begin
667
      word_ct_d = WPC - 1;
668
    end else begin
669
      word_ct_d = word_ct;
670
    end
671
  end
672
 
673
  // Load or increment word_ct, using a mux-before-add strategy. This
674
  // saves us a level of logic over add-before-mux.
675
 
676
  always @(posedge clk_i) begin
677
    if (reset_i) begin
678
      word_ct   <= #`TCQ 0;
679
    end else begin
680
      word_ct   <= #`TCQ word_ct_d + 1;
681
    end
682
  end
683
  `endif
684
 
685
  `ifdef PCIE
686
  // Delay the start of the word count based on header, TD and length
687
  // (in 64-bit, even or odd). Delaying the start of the counter rather
688
  // than adjusting the start value saves muxing logic into the word_ct
689
  // arithmetic.
690
 
691
  always @(posedge clk_i) begin
692
    if (reset_i) begin
693
      delay_ct   <= #`TCQ 0;
694
      delay_ct_d <= #`TCQ 0;
695
    end else if (!eval_formats_i) begin
696
      delay_ct   <= #`TCQ delay_ct_d;
697
      delay_ct_d <= #`TCQ 0;
698
    end else if (DW == 64) begin
699
      // In the 64-bit world, we want to count the number of data beats
700
      // following the 3rd QW. It's easiest to enumerate the possible
701
      // scenarios:
702
      //
703
      // 1. 3 DW header, no digest, even Length: The end of the packet
704
      //    would be aligned if not for the 3 DW header. Thus the EOF
705
      //    ends up at the same place as with a 4 DW, no-digest packet.
706
      //    Beats after 3rd QW: Length/2 + 2 - 3 = Length/2 - 1.
707
      // 2. 3 DW header, no digest, odd Length: The odd DW at the end
708
      //    fills out the last beat in case #1: floor(Length/2) - 1.
709
      // 3. 3 DW header, digest, even Length: Fills out the unaligned
710
      //    end of case #1: Length/2 - 1.
711
      // 4. 3 DW header, digest, odd Length: Adds an unaligned beat to
712
      //    case #2: floor(Length/2).
713
      // 5. 4 DW header, no digest, even Length: Additional header DW
714
      //    fills out the unaligned end of case #1: Length/2 - 1.
715
      // 6. 4 DW header, no digest, odd Length: Adds an unaligned beat
716
      //    to case #2: floor(Length/2).
717
      // 7. 4 DW header, digest, even Length: Adds an unaligned beat to
718
      //    case #3: Length/2.
719
      // 8. 4 DW header, digest, odd Length: Fills out the unaligned end
720
      //    of case #4: floor(Length/2).
721
      //
722
      // The decrementer in word_ct causes the load value to be
723
      // word_ct_d - 1 = (length_i >> 1) - 1 = floor(Length/2) - 1. We
724
      // distill these out to get the delay needed from the start of
725
      // the count:
726
      //
727
      // Case #1: (Length/2 - 1) - (floor(Length/2) - 1)  = 0 delay
728
      // ...
729
      // Case #4: floor(Length/2) - (floor(Length/2) - 1) = 1 delay
730
      // ...
731
 
732
      case ({header_4dw,td_i,length_odd})
733
        3'b000:  delay_ct <= #`TCQ 0;
734
        3'b001:  delay_ct <= #`TCQ 0;
735
        3'b010:  delay_ct <= #`TCQ 0;
736
        3'b011:  delay_ct <= #`TCQ 1;
737
        3'b100:  delay_ct <= #`TCQ 0;
738
        3'b101:  delay_ct <= #`TCQ 1;
739
        3'b110:  delay_ct <= #`TCQ 1;
740
        default: delay_ct <= #`TCQ 1;
741
      endcase
742
 
743
      delay_ct_d <= #`TCQ 0;    // Only used in 32-bit, where two cycles
744
                                // of delay may be necessary
745
    end else begin
746
      // In the 32-bit world, the number of data beats following the 4th
747
      // DW is equal to Length + Hdr_DW + TD - 4. The adjustment from
748
      // word_ct_d is thus Hdr_DW + TD - 4. Note that (Hdr_DW - 3) is
749
      // the same as header_4dw, so the delay is simply the sum of
750
      // header_4dw + td_i - 1, PLUS ONE to account for the built-in
751
      // word_ct decrementer.
752
 
753
      case ({header_4dw,td_i})
754
        2'b11:   {delay_ct_d,delay_ct} <= #`TCQ 2'b10;  // Two-cycle delay
755
        2'b00:   {delay_ct_d,delay_ct} <= #`TCQ 2'b00;  // Zero-cycle delay
756
        default: {delay_ct_d,delay_ct} <= #`TCQ 2'b01;  // One-cycle delay
757
      endcase
758
    end
759
  end
760
 
761
  // Flag a word count of zero. There are two ways to represent zero
762
  // word count:
763
  //
764
  // 1. If word_ct = 0 with no count delay (delay_ct = 0).
765
  // 2. If word_ct = -1 with count delay (delay_ct = 1). Count delay
766
  //    represents a +1 adjustment to word_ct, so these two conditions
767
  //    indicate that the true word count is zero. (See the delay_ct
768
  //    comments below for more information.) This scenario occurs in
769
  //    64-bit when we have a packet of 1 DW payload that ends on the
770
  //    3rd QW: 3 DW header + TD, or 4 DW header w/o TD. (This case is
771
  //    not covered by malformed_min, which only covers EOF on the 1st
772
  //    or 2nd QW.)
773
  //
774
  // This logic also takes care of the case in 32-bit when Length = 1
775
  // (causing word_ct = 0) but delay_ct/d is asserted due to a 4 DW
776
  // header or a TLP Digest. In this case, true word count is non-zero
777
  // even though word_ct = 0, because of the count delay.
778
  //
779
  // The lowest possible start value for word_ct is -1 (derived from a
780
  // payload length of 0 [or 1 in 64-bit]). This means that the true
781
  // word count will never be zero if delay_ct_d is asserted, because
782
  // this represents a two-cycle delay.
783
 
784
  assign word_ct_zero = (delay_ct ? &word_ct : ~|word_ct) && !delay_ct_d;
785
 
786
  // Flag a word count of -1. This occurs when word_ct = -1 with no
787
  // count delay. Needed to detect rollover.
788
 
789
  assign word_ct_neg1 = &word_ct && !delay_ct && !delay_ct_d;
790
reg [4:0] test_temp;
791
  //------------------------------------------------------------------------
792
  // Check length of short packets (1-4 DW in 32-bit, 1-2 DW in 64-bit).
793
  // Longer packets are checked against word_ct.
794
  //------------------------------------------------------------------------
795
  always @(posedge clk_i) begin
796
    if (reset_i) begin
797
      malformed_min     <= #`TCQ 0;
798
    end else begin
799
      if (DW == 64) begin
800
        // 2 words or less
801
        if (sof_i && eof_i) begin
802
          malformed_min <= #`TCQ 1;
803
 
804
        // Header fields too small check (3 or 4 words)
805
        // header words + digest <= 3 + rem
806
        end else if (sof_q1 && eof_i) begin
807
          casex ({header_4dw, rem_i, td_i, has_data, length_1dw_i})
808
            // No-data checks
809
            // 3 DW header, 3 DW packet.. but digest is set!
810
            5'b0010x:  malformed_min  <= #`TCQ 1;
811
            // 4 DW header, 3 DW packet (w/wo digest)
812
            5'b10x0x:  malformed_min  <= #`TCQ 1;
813
            // 4 DW header, 4 DW packet.. but digest is set!
814
            5'b1110x:  malformed_min  <= #`TCQ 1;
815
            // Has-data checks
816
            // 3 DW header, supposed to have data but doesn't
817
            5'b00x1x:  malformed_min  <= #`TCQ 1;
818
            // 3 DW header, only 1 DW of data, but should have more
819
            5'b0xx10:  malformed_min  <= #`TCQ 1;
820
            // 3 DW header w/TD, supposed to have data but doesn't
821
            5'b0x11x:  malformed_min  <= #`TCQ 1;
822
            // 4 DW header, supposed to have data but doesn't
823
            5'b1xx1x:  malformed_min  <= #`TCQ 1;
824
            // header-only (or header + 1DW data) packet is
825
            // correctly constructed
826
            default: malformed_min  <= #`TCQ 0;
827
          endcase
828
 
829
        // There was data.. we'll catch these cases with the
830
        // word counter
831
        end else begin
832
          malformed_min <= #`TCQ 0;
833
        end
834
 
835
      // 32 bit checks
836
      end else begin
837
        // 1 or 2 dwords
838
        if ((sof_i || sof_q1) && eof_i) begin
839
          malformed_min <= #`TCQ 1;
840
        // 3 dword pkt, but w/ digest or data or 4 dw header
841
        end else if (sof_q2 && eof_i && (td_i || header_4dw || has_data)) begin
842
          malformed_min <= #`TCQ 1;
843
        // 4 word pkt && header, but with digest
844
        end else if (sof_q3 && eof_i && td_i && header_4dw) begin
845
          malformed_min <= #`TCQ 1;
846
        // we must be long enough
847
        end else begin
848
          malformed_min <= #`TCQ 0;
849
        end
850
      end
851
    end
852
  end
853
 
854
  //=====================================================================
855
  // Malformed TLP: incorrect length (valid at eof_o)
856
  // * length field != 0 while the TLP has no data
857
  // * length field doesn't match number of data dwords
858
  // * length field is not hardwired correctly (1 DW only for I/O & Cfg)
859
  //=====================================================================
860
 
861
  //--------------------------------------------------------------------
862
  // This checks Config and I/O packets to make sure the Length field is
863
  // set to 1.
864
  //--------------------------------------------------------------------
865
 
866
  always @(posedge clk_i) begin
867
    if (reset_i) begin
868
      type_1dw      <= #`TCQ 0;
869
    end else if (eval_formats_i) begin
870
      casex (fulltype_in)
871
        CFGRD0, CFGWR0, CFGRD1, CFGWR1, IORD, IOWR:
872
          type_1dw  <= #`TCQ 1;
873
        default:
874
          type_1dw  <= #`TCQ 0;
875
      endcase
876
    end
877
  end
878
 
879
  assign malformed_1dw = type_1dw && !length_1dw_i;
880
 
881
  // Determine if the length of the packet is correct. Interpreted on
882
  // every clock, but only latched on eof_q1.
883
  //----------------------------------------------------------
884
 
885
  always @(posedge clk_i) begin
886
    if (reset_i) begin
887
      malformed_eof <= #`TCQ 0;
888
    end else begin
889
      malformed_eof <= #`TCQ !eval_formats_i && !word_ct_zero;
890
    end
891
  end
892
  `endif
893
 
894
  `ifdef PCIE
895
  // Flag when the counter rolls over. This covers the case in 32-bit
896
  // where a start value of -1 is loaded into word_ct on the 4th DW.
897
  // A -1 on the 4th DW means EOF should've been asserted on the 3rd DW;
898
  // but because word_ct cannot be valid on the 3rd DW, we can't flag a
899
  // zero count on that data beat. So we must flag when the count has
900
  // been allowed to load with a rollover value on or before EOF, so
901
  // that eof_q1 will detect the overflow condition.
902
  //
903
  // The rollover flag also ensures that the TLM doesn't mark as legal a
904
  // packet that overshoots Length by exactly MPS*2 (which would cause
905
  // the word counter to go down to zero a SECOND time).
906
 
907
  always @(posedge clk_i) begin
908
    if (reset_i) begin
909
      malformed_over   <= #`TCQ 0;
910
    end else begin
911
      malformed_over   <= #`TCQ (word_ct_neg1 || malformed_over) &&
912
                                !eval_formats_i;
913
    end
914
  end
915
 
916
  // Determine if REM is set incorrectly. Only matters on EOF.
917
  //----------------------------------------------------------
918
 
919
  // The expected REM is determined by payload length (even vs. odd),
920
  // header size and and presence of the digest. The formula is:
921
  //
922
  //    exp_rem = (!header_4dw + length_i[0] + td_i) % 2 == 0 -OR-
923
  //    exp_rem =  (header_4dw + length_i[0] + td_i) % 2 == 1
924
  //
925
  // a.k.a. XOR. Length is qualified by has_data (embodied by the
926
  // length_odd signal) as it depends on the presence of the payload.
927
 
928
  assign expected_rem = header_4dw ^ length_odd ^ td_i;
929
 
930
  // The check for malformed REM is performed on each clock cycle but
931
  // only latched on the cycle after EOF.
932
 
933
  always @(posedge clk_i) begin
934
    if (reset_i) begin
935
      malformed_rem <= #`TCQ 0;
936
    end else if (DW == 32) begin
937
      malformed_rem <= #`TCQ 0;
938
    end else begin
939
      malformed_rem <= #`TCQ rem_i ^ expected_rem;
940
    end
941
  end
942
 
943
  // All our counting is complete on eof_i- latch on q1
944
  // Our length is bad if the payload was bad, or if a header-only
945
  //    packet was too short
946
  //-------------------------------------------------------------
947
  always @(posedge clk_i) begin
948
    if (reset_i) begin
949
      malformed_len <= #`TCQ 0;
950
    end else if (eof_q1) begin
951
      malformed_len <= #`TCQ malformed_eof || malformed_over ||
952
                             malformed_rem || malformed_min;
953
    end
954
  end
955
 
956
  always @(posedge clk_i) begin
957
    if (reset_i) begin
958
      malformed_o <= #`TCQ 0;
959
    end else if (eof_sync) begin
960
      malformed_o <= #`TCQ malformed_len || malformed_fmt;
961
    end
962
  end
963
  `else // `ifdef AS
964
  // Flag when the counter exceeds Credits Required. We trigger when
965
  // word_ct equals the maximum allowed for Credits Required. An
966
  // adjustment must be made for MPS = 96, since this represents an
967
  // overflow on a half-credit. Note that this is the only case where
968
  // we check the RUNNING word count against MPS. The malformed_maxsize
969
  // logic covers all other cases where the actual Credits Required
970
  // field exceeds MPS.
971
  //
972
  // We must adjust the incoming CR upwards for the all-zeroes case.
973
 
974
  reg  [WPCW-1:0] word_ct_lo_limit;
975
  reg  [FCW-1:0]  word_ct_hi_limit;
976
  wire [DCW-1:0]  word_ct_limit;
977
  reg  [FCW-1:0]  true_length;
978
 
979
  always @(posedge clk_i) begin
980
    if (reset_i) begin
981
      word_ct_lo_limit <= #`TCQ 0;
982
    end else if ((max_payload_i == 4'b0010) && !BVC && (MPS >= 96) &&
983
                 (length_i == 2)) begin
984
      word_ct_lo_limit <= #`TCQ WPC/2;
985
    end else begin
986
      word_ct_lo_limit <= #`TCQ 0;
987
    end
988
  end
989
 
990
  generate
991
    if (FCW == 6) begin : word_ct_limit_2176
992
      always @* begin
993
        if (~|length_i) begin   // All zeroes
994
          true_length = 34;
995
        end else begin
996
          true_length = {1'b0,length_i};
997
        end
998
      end
999
    end else begin : word_ct_limit_below_2176
1000
      always @* true_length = length_i[FCW-1:0];
1001
    end
1002
  endgenerate
1003
 
1004
  always @(posedge clk_i) begin
1005
    if (reset_i) begin
1006
      word_ct_hi_limit <= #`TCQ 1;
1007
    end else begin
1008
      word_ct_hi_limit <= #`TCQ true_length + 1;
1009
    end
1010
  end
1011
 
1012
  assign word_ct_limit = {word_ct_hi_limit,word_ct_lo_limit};
1013
 
1014
  always @(posedge clk_i) begin
1015
    if (reset_i) begin
1016
      malformed_over <= #`TCQ 0;
1017
    end else if (eval_formats_i) begin
1018
      malformed_over <= #`TCQ 0;
1019
    end else begin
1020
      malformed_over <= #`TCQ (word_ct == word_ct_limit) || malformed_over;
1021
    end
1022
  end
1023
 
1024
  // Flag if Credits Required is not 1 for a bypassable, PI-4 or PI-5
1025
  // packet.
1026
 
1027
  always @(posedge clk_i) begin
1028
    if (reset_i) begin
1029
      malformed_byp_not_1 <= #`TCQ 0;
1030
    end else if (eval_formats_i) begin
1031
      malformed_byp_not_1 <= #`TCQ BVC && !oo_i && ts_i && (length_i != 1);
1032
    end
1033
  end
1034
 
1035
  always @(posedge clk_i) begin
1036
    if (reset_i) begin
1037
      malformed_pi4_or_5_not_1 <= #`TCQ 0;
1038
    end else if (eval_formats_i) begin
1039
      malformed_pi4_or_5_not_1 <= #`TCQ (primary_pi4 || primary_pi5) &&
1040
                                        (length_i != 1);
1041
    end
1042
  end
1043
 
1044
  // All our counting is complete on eof_i; latch on eof_q1.
1045
  //-------------------------------------------------------------
1046
  always @(posedge clk_i) begin
1047
    if (reset_i) begin
1048
      bad_credit_length_o <= #`TCQ 0;
1049
    end else if (eof_q1) begin
1050
      bad_credit_length_o <= #`TCQ malformed_over;
1051
    end
1052
  end
1053
 
1054
  always @(posedge clk_i) begin
1055
    if (reset_i) begin
1056
      invalid_credit_length_o <= #`TCQ 0;
1057
    end else if (eof_q1) begin
1058
      invalid_credit_length_o <= #`TCQ malformed_maxsize ||
1059
                                       malformed_byp_not_1 ||
1060
                                       malformed_pi4_or_5_not_1;
1061
    end
1062
  end
1063
  `endif
1064
 
1065
  `ifdef PCIE
1066
  //====================================================================
1067
  // Malformed format checks
1068
  //====================================================================
1069
 
1070
  // delay this one cycle more than is strictly necessary- otherwise
1071
  //   we might collide with another bad back-to-back packet
1072
  always @(posedge clk_i) begin
1073
    if (reset_i) begin
1074
      malformed_fmt <= #`TCQ 0;
1075
 
1076
    // All type checks get triggered after we have latched
1077
    //    the inputs. OR together the checks afterwards.
1078
    // ismsg* needs to be added into malformed_message even
1079
    //    though it is also included in some field checks
1080
    //    because completely specifying it in the case statement
1081
    //    absolutely kills timing
1082
    end else if (bar_sync) begin
1083
      malformed_fmt <= #`TCQ malformed_tc ||
1084
                             malformed_fulltype ||
1085
                            (malformed_message && ismsgany) ||
1086
                             malformed_maxsize ||
1087
                             malformed_1dw;
1088
    end
1089
  end
1090
 
1091
  //--------------------------------------------------------------------
1092
  // Traffic class determinations
1093
  //--------------------------------------------------------------------
1094
  // Bad TC received if doesn't map to any enabled VC, meaning either:
1095
  // * TC not mapped to any VC
1096
  // * TC mapped to a VC not enabled ** FOR THIS VERSION ONLY 0 VALID!! **
1097
  // * TC other than TC0 on received:
1098
  //   * io and cfg
1099
  //   * CplDLk and I guess CplLk (MRdLk is UR and Unlock is dropped)
1100
  //   . Msg: power management (INT and errors are UR because routed to Root)
1101
  //
1102
  // Spec references on TC0 traffic restriction:
1103
  // * "MRdLk, CplDLk and Unlock semantics are allowed only for (...) TC0"
1104
  // * "all Assert_INTx and Deassert_INTx interrupts Requests must use TC0"
1105
  // * "for legacy I/O, TC0 is used"
1106
  // * "all power management system messages must use (...) TC0"
1107
  // * "all Error Messages must use (...) TC0"
1108
  // * "the Unlock Message must use (...) TC0"
1109
  // * "MSIs are not restricted to TC0"
1110
  // * cfg and io header shows a TC hardwired to 0
1111
  //--------------------------------------------------------------------
1112
 
1113
  // Latch Type and Message code, should be removed as equivalent to
1114
  // cur_fulltype and cur_msgcode on the upper level
1115
 
1116
  always @(posedge clk_i) begin
1117
    if (eval_fulltype_i) begin
1118
      fulltype_in       <= #`TCQ fulltype_i;
1119
    end
1120
  end
1121
 
1122
  always @(posedge clk_i) begin
1123
    if (eval_msgcode_i) begin
1124
      msgcode_in        <= #`TCQ msgcode_i;
1125
    end
1126
  end
1127
 
1128
  // Pre-calculate whether the Type is Msg or MsgD; ismsgany will be
1129
  // removed during synthesis as equivalent to cur_fulltype_oh[MSG_BIT]
1130
  // on the upper level.
1131
 
1132
  always @(posedge clk_i) begin
1133
    if (eval_fulltype_i) begin
1134
      casex (fulltype_i)
1135
        MSG: begin
1136
          ismsg         <= #`TCQ 1;
1137
          ismsgd        <= #`TCQ 0;
1138
          ismsgany      <= #`TCQ 1;
1139
        end
1140
        MSGD: begin
1141
          ismsg         <= #`TCQ 0;
1142
          ismsgd        <= #`TCQ 1;
1143
          ismsgany      <= #`TCQ 1;
1144
        end
1145
        default: begin
1146
          ismsg         <= #`TCQ 0;
1147
          ismsgd        <= #`TCQ 0;
1148
          ismsgany      <= #`TCQ 0;
1149
        end
1150
      endcase
1151
    end
1152
  end
1153
 
1154
  // Pre-calculate whether the full type requires TC0
1155
 
1156
  always @(posedge clk_i) begin
1157
    if (eval_fulltype_i) begin
1158
      casex (fulltype_i)
1159
        // These Types require TC == 0
1160
        CFGANY, IORD, IOWR, CPLLK, CPLDLK,
1161
        MRD32LK, MRD64LK: begin
1162
          fulltype_tc0  <= #`TCQ 1;
1163
        end
1164
        default: begin
1165
          fulltype_tc0  <= #`TCQ 0;
1166
        end
1167
      endcase
1168
    end
1169
  end
1170
 
1171
  // Pre-calculate whether the Message code requires TC0. All messages
1172
  // other than Vendor_Defined_0/1 require TC0.
1173
 
1174
  assign msgcode_tc0 = msgcode_sigdef;
1175
 
1176
  // Check for Malformed TC
1177
 
1178
  always @(posedge clk_i) begin
1179
    if (reset_i) begin
1180
      malformed_tc      <= #`TCQ 0;
1181
    end else if (eval_formats_i) begin
1182
      if (!tc0_i) begin
1183
        malformed_tc    <= #`TCQ fulltype_tc0 || (ismsgany && msgcode_tc0);
1184
      end else begin
1185
        // tc was 0, we must be good!
1186
        malformed_tc    <= #`TCQ 0;
1187
      end
1188
    end
1189
  end
1190
 
1191
  // Check if type is valid based on allowable full types
1192
  //    (of spec, not what we actually support in our core)
1193
  // Valid but unsupported types get turned into a UR/UC
1194
  //-------------------------------------------------------
1195
  always @(posedge clk_i) begin
1196
    if (reset_i) begin
1197
      malformed_fulltype        <= #`TCQ 0;
1198
    end else if (eval_formats_i) begin
1199
      casex (fulltype_in)
1200
        MWR32, MWR64, MRD32, MRD64, MRD32LK, MRD64LK,
1201
        CFGRD0, CFGWR0, CFGRD1, CFGWR1,
1202
        CPL, CPLD, CPLLK, CPLDLK,
1203
        MSG, MSGD, IORD, IOWR:
1204
          malformed_fulltype    <= #`TCQ 0;
1205
        default:
1206
          malformed_fulltype    <= #`TCQ 1;
1207
      endcase
1208
    end
1209
  end
1210
 
1211
  //====================================================================
1212
  // UR/UC checks
1213
  //====================================================================
1214
 
1215
  // Completions lead to Unexpected Completion, others lead to
1216
  //    Unsupported Request
1217
  //--------------------------------------------------------------
1218
  always @(posedge clk_i) begin
1219
    if (reset_i) begin
1220
      cpl_ip            <= #`TCQ 0;
1221
    end else if (eval_formats_i) begin
1222
      casex (fulltype_in)
1223
        CPL, CPLD, CPLLK, CPLDLK: begin
1224
          cpl_ip        <= #`TCQ 1;
1225
        end
1226
        default: begin
1227
          cpl_ip        <= #`TCQ 0;
1228
        end
1229
      endcase
1230
    end
1231
  end
1232
 
1233
  // Grab some fields that are special cases in our UC/UR
1234
  //   determination
1235
  // * We don't drop vendor messages on bar misses
1236
  // * A locked mem access when not in legacy mode is unsupported
1237
  // * A locked completion when not in legacy mode is unexpected
1238
  // * We reject most types while in power management mode
1239
  //-------------------------------------------------------------
1240
 
1241
  // We can receive the legacy UNLOCK message code if the user design is
1242
  // a legacy device, or if this is a downstream port.
1243
 
1244
  wire allow_legacy = legacy_mode_i || DOWNSTREAM_PORT;
1245
 
1246
  always @(posedge clk_i) begin
1247
    if (reset_i) begin
1248
      ur_mem_lk           <= #`TCQ 0;
1249
      uc_cpl_lk           <= #`TCQ 0;
1250
      ur_pwr_mgmt         <= #`TCQ 0;
1251
      uc_pwr_mgmt         <= #`TCQ 0;
1252
      ur_type1_cfg        <= #`TCQ 0;
1253
    end else if (eval_formats_i) begin
1254
      if (!allow_legacy) begin
1255
        ur_mem_lk         <= #`TCQ (fulltype_in == MRD32LK) ||
1256
                                   (fulltype_in == MRD64LK);
1257
        uc_cpl_lk         <= #`TCQ (fulltype_in == CPLLK) ||
1258
                                   (fulltype_in == CPLDLK);
1259
      end else begin
1260
        ur_mem_lk         <= #`TCQ 0;
1261
        uc_cpl_lk         <= #`TCQ 0;
1262
      end
1263
 
1264
      if (TYPE1_UR && (fulltype_in == CFGWR1 || fulltype_in == CFGRD1 ||
1265
                       fulltype_in == CFGWR1)) begin
1266
        // If TYPE1_UR is left as its default (0) all the ur_type1_cfg
1267
        // logic should be optimized out
1268
        ur_type1_cfg    <= #`TCQ 1'b1;
1269
      end else begin
1270
        ur_type1_cfg    <= #`TCQ 1'b0;
1271
      end
1272
 
1273
      casex (fulltype_in)
1274
        CPL, CPLD, CPLLK, CPLDLK: begin
1275
          uc_pwr_mgmt     <= #`TCQ pwr_mgmt_on_i;
1276
          ur_pwr_mgmt     <= #`TCQ 0;
1277
        end
1278
        MRD32, MRD64, MRD32LK, MRD64LK, MWR32, MWR64, IORD, IOWR: begin
1279
          uc_pwr_mgmt     <= #`TCQ 0;
1280
          ur_pwr_mgmt     <= #`TCQ pwr_mgmt_on_i;
1281
        end
1282
        CFGWR1, CFGRD1, CFGANY1: begin
1283
          uc_pwr_mgmt     <= #`TCQ 0;
1284
          ur_pwr_mgmt     <= #`TCQ 0;
1285
        end
1286
        default: begin
1287
          uc_pwr_mgmt     <= #`TCQ 0;
1288
          ur_pwr_mgmt     <= #`TCQ 0;
1289
        end
1290
     endcase
1291
   end
1292
  end
1293
 
1294
  // There are three components to a UR/UC...
1295
  // 1. We're in power management mode, and this type is
1296
  //    not supported during power management
1297
  // 2. There is a bad field determination.. we grab this
1298
  //    when the formats are ready, and if they are good, we
1299
  //    reset the register back to zero
1300
  // 3. Our bar hit/miss information is available at hit_src_rdy..
1301
  //    if we were a miss set the field
1302
  // Otherwise, use the previous value
1303
  //-------------------------------------------------------------
1304
  always @(posedge clk_i) begin
1305
    if (reset_i) begin
1306
      ur_format        <= #`TCQ 0;
1307
      ur_format_lock   <= #`TCQ 0;
1308
      uc_format        <= #`TCQ 0;
1309
      filter_msgcode_q <= #`TCQ 0;
1310
    end else if (bar_sync) begin
1311
      // 1. In power management -OR-
1312
      // 2. Our packet has a message or type we don't support -OR-
1313
      // 3. Our packet is a type-1 config access and it's not allowed
1314
 
1315
      // Unsupported Request
1316
      ur_format        <= #`TCQ ur_pwr_mgmt || ur_mem_lk || ur_type1_cfg;
1317
      ur_format_lock   <= #`TCQ ur_mem_lk; //needed by errman to generate CplLk
1318
 
1319
      // Unexpected completion
1320
      uc_format        <= #`TCQ uc_pwr_mgmt || uc_cpl_lk;
1321
 
1322
      // Unpassed message (silently filtered in non-legacy mode)
1323
      filter_msgcode_q <= #`TCQ filter_msgcode;
1324
    end
1325
  end
1326
 
1327
  // hits are ready, or & grab the format information
1328
  always @(posedge clk_i) begin
1329
    if (reset_i) begin
1330
      tlp_ur_o            <= #`TCQ 0;
1331
      tlp_ur_lock_o       <= #`TCQ 0;
1332
      tlp_uc_o            <= #`TCQ 0;
1333
      tlp_filt_o          <= #`TCQ 0;
1334
    end else if (hit_src_rdy_i) begin
1335
      if (ur_format) begin
1336
        tlp_ur_o          <= #`TCQ 1;
1337
        tlp_ur_lock_o     <= #`TCQ ur_format_lock;
1338
      end else if (!cpl_ip && hit_ack_i && !hit_i && UPSTREAM_PORT) begin
1339
        tlp_ur_o          <= #`TCQ 1;
1340
        tlp_ur_lock_o     <= #`TCQ hit_lock_i;
1341
      end else begin
1342
        tlp_ur_o          <= #`TCQ 0;
1343
        tlp_ur_lock_o     <= #`TCQ 0;
1344
      end
1345
      if (uc_format) begin
1346
        tlp_uc_o          <= #`TCQ 1;
1347
      end else if (cpl_ip && hit_ack_i && !hit_i && UPSTREAM_PORT) begin
1348
        tlp_uc_o          <= #`TCQ 1;
1349
      end else begin
1350
        tlp_uc_o          <= #`TCQ 0;
1351
      end
1352
      if (filter_msgcode_q) begin
1353
        tlp_filt_o        <= #`TCQ 1;
1354
      end else begin
1355
        tlp_filt_o        <= #`TCQ 0;
1356
      end
1357
    end
1358
  end
1359
 
1360
  //---------------------------------------------------------------------
1361
  // Check if the message is constructed properly according to the spec
1362
  // * routing must be correct by spec
1363
  // * routing must match our ability to route (endpoint/trunk)
1364
  // * Msg/MsgD type must match message value
1365
  //----------------------------------------------------------------------
1366
 
1367
  // Check for valid message code, other than Vendor_Defined. The message
1368
  // code is valid if it is both:
1369
  // * Defined in the spec
1370
  // * Legal for the port direction
1371
 
1372
  always @(posedge clk_i) begin
1373
    if (eval_msgcode_i) begin
1374
      casex (msgcode_i)
1375
        UNLOCK, PME_TURN_OFF, PM_ACTIVE_STATE_NAK,
1376
        SET_SLOT_POWER_LIMIT, ATTENTION_BUTTON_PRESSED,
1377
        ATTENTION_INDICATOR_ON, ATTENTION_INDICATOR_OFF,
1378
        ATTENTION_INDICATOR_BLINK, POWER_INDICATOR_ON,
1379
        POWER_INDICATOR_OFF, POWER_INDICATOR_BLINK:
1380
          msgcode_sigdef <= #`TCQ UPSTREAM_PORT;
1381
 
1382
        ASSERT_INTA, DEASSERT_INTA, ASSERT_INTB, DEASSERT_INTB,
1383
        ASSERT_INTC, DEASSERT_INTC, ASSERT_INTD, DEASSERT_INTD,
1384
        ERR_COR, ERR_NONFATAL, ERR_FATAL, PME_TO_ACK:
1385
          msgcode_sigdef <= #`TCQ DOWNSTREAM_PORT;
1386
 
1387
        default:
1388
          msgcode_sigdef <= #`TCQ 0;
1389
      endcase
1390
    end
1391
  end
1392
 
1393
  // Check for Msg vs. MsgD. In 64-bit, fulltype_i and msgcode_i are
1394
  // available on the same clock cycle. In 32-bit, ismsg and ismsgd are
1395
  // calculated before msgcode_i is available.
1396
 
1397
  generate
1398
    if (DW == 32) begin : msgd_check_32
1399
 
1400
      always @(posedge clk_i) begin
1401
        if (eval_msgcode_i) begin
1402
          casex (msgcode_i)
1403
            SET_SLOT_POWER_LIMIT:
1404
              msgcode_dmatch <= #`TCQ ismsgd;
1405
            default:
1406
              msgcode_dmatch <= #`TCQ ismsg;
1407
          endcase
1408
        end
1409
      end
1410
 
1411
    end else begin : msgd_check_64
1412
 
1413
      always @(posedge clk_i) begin
1414
        if (eval_msgcode_i) begin
1415
          casex (fulltype_i)
1416
            MSG:
1417
              msgcode_dmatch <= #`TCQ (msgcode_i != SET_SLOT_POWER_LIMIT);
1418
            default:
1419
              msgcode_dmatch <= #`TCQ (msgcode_i == SET_SLOT_POWER_LIMIT);
1420
          endcase
1421
        end
1422
      end
1423
 
1424
    end
1425
  endgenerate
1426
 
1427
  // Check the type of routing required by the Message code. Most codes
1428
  // only take one routing type, but Vendor_Defined can take three types
1429
  // (four if received on a downstream port) so it needs a special
1430
  // register.
1431
 
1432
  always @(posedge clk_i) begin
1433
    if (eval_fulltype_i) begin
1434
      routing_vendef <= #`TCQ (routing == ROUTE_LOCAL) ||
1435
                              (routing == ROUTE_BROAD) ||
1436
                              (routing == ROUTE_BY_ID);
1437
    end
1438
  end
1439
 
1440
  // Create different casex blocks depending on whether
1441
  // in downstream port mode or not. This is done so that when not in
1442
  // downstream port mode, the interrupt-message checks will not be included.
1443
  // Interrupts should not be received when in upstream mode so we
1444
  // don't want to risk having their checks impact timing.
1445
 
1446
  generate
1447
    if (DOWNSTREAM_PORT == 0) begin : dont_check_int
1448
      always @(posedge clk_i) begin
1449
        if (eval_msgcode_i) begin
1450
          casex (msgcode_i)
1451
            UNLOCK, PME_TURN_OFF:
1452
              msgcode_routing <= #`TCQ ROUTE_BROAD;
1453
 
1454
            PME_TO_ACK:
1455
              msgcode_routing <= #`TCQ ROUTE_GATHR;
1456
 
1457
            PM_ACTIVE_STATE_NAK, ATTENTION_BUTTON_PRESSED,
1458
            ATTENTION_INDICATOR_ON, ATTENTION_INDICATOR_OFF,
1459
            ATTENTION_INDICATOR_BLINK, POWER_INDICATOR_ON,
1460
            POWER_INDICATOR_OFF, POWER_INDICATOR_BLINK,
1461
            SET_SLOT_POWER_LIMIT:
1462
              msgcode_routing <= #`TCQ ROUTE_LOCAL;
1463
 
1464
            // Vendor_Defined can take other values besides Route to RC;
1465
            // these are covered by routing_vendef.
1466
            default:
1467
              msgcode_routing <= #`TCQ ROUTE_TO_RC;
1468
          endcase
1469
        end
1470
      end
1471
    end else begin : check_int
1472
      always @(posedge clk_i) begin
1473
        if (eval_msgcode_i) begin
1474
          casex (msgcode_i)
1475
            UNLOCK, PME_TURN_OFF:
1476
              msgcode_routing <= #`TCQ ROUTE_BROAD;
1477
 
1478
            PME_TO_ACK:
1479
              msgcode_routing <= #`TCQ ROUTE_GATHR;
1480
 
1481
            PM_ACTIVE_STATE_NAK, ATTENTION_BUTTON_PRESSED,
1482
            ATTENTION_INDICATOR_ON, ATTENTION_INDICATOR_OFF,
1483
            ATTENTION_INDICATOR_BLINK, POWER_INDICATOR_ON,
1484
            POWER_INDICATOR_OFF, POWER_INDICATOR_BLINK,
1485
            ASSERT_INTA, ASSERT_INTB, ASSERT_INTC, ASSERT_INTD,
1486
            DEASSERT_INTA, DEASSERT_INTB, DEASSERT_INTC, DEASSERT_INTD,
1487
            SET_SLOT_POWER_LIMIT:
1488
              msgcode_routing <= #`TCQ ROUTE_LOCAL;
1489
 
1490
            // Vendor_Defined can take other values besides Route to RC;
1491
            // these are covered by routing_vendef.
1492
            default:
1493
              msgcode_routing <= #`TCQ ROUTE_TO_RC;
1494
          endcase
1495
        end
1496
      end
1497
    end
1498
  endgenerate
1499
 
1500
  // Make sure the Message parameters agree with each other:
1501
  //
1502
  // 1. Message code must be valid per spec
1503
  // 2. Type (Msg or MsgD) must agree with the Message code
1504
  // 3. If not Vendor_Defined, the Routing type must agree with the one
1505
  //    allowed by the Message code
1506
  // 4. If Vendor_Defined, the Routing type must be:
1507
  //    a. Broadcast, Local or Route By ID (routing_vendef), or
1508
  //    b. Route to Root Complex if a downstream port
1509
  // NOTE: Vendor_Defined does not care about Msg vs. MsgD.
1510
 
1511
  always @(posedge clk_i) begin
1512
    if (reset_i) begin
1513
      malformed_message   <= #`TCQ 0;
1514
    end else if (eval_formats_i) begin
1515
      if (!msgcode_vendef) begin
1516
        malformed_message <= #`TCQ !msgcode_sigdef ||                     // #1
1517
                                   !msgcode_dmatch ||                     // #2
1518
                                   (routing_in != msgcode_routing);       // #3
1519
      end else begin
1520
        malformed_message <= #`TCQ !routing_vendef &&                     // #4
1521
                                   !(DOWNSTREAM_PORT &&
1522
                                     (routing_in == ROUTE_TO_RC));
1523
      end
1524
    end
1525
  end
1526
 
1527
  //---------------------------------------------------------------------
1528
  // Check if the message is supported by our core
1529
  // * routing must match our ability to route (endpoint/trunk)
1530
  //----------------------------------------------------------------------
1531
 
1532
  always @(posedge clk_i) begin
1533
    if (eval_msgcode_i) begin
1534
      casex (msgcode_i)
1535
        UNLOCK:
1536
          msgcode_legacy        <= #`TCQ 1;
1537
        default:
1538
          msgcode_legacy        <= #`TCQ 0;
1539
      endcase
1540
    end
1541
  end
1542
 
1543
  always @(posedge clk_i) begin
1544
    if (eval_msgcode_i) begin
1545
      casex (msgcode_i)
1546
        POWER_INDICATOR_ON, POWER_INDICATOR_OFF,
1547
        POWER_INDICATOR_BLINK, ATTENTION_INDICATOR_ON,
1548
        ATTENTION_INDICATOR_OFF, ATTENTION_INDICATOR_BLINK,
1549
        ATTENTION_BUTTON_PRESSED:
1550
          msgcode_hotplug       <= #`TCQ 1;
1551
        default:
1552
          msgcode_hotplug       <= #`TCQ 0;
1553
      endcase
1554
    end
1555
  end
1556
 
1557
  always @(posedge clk_i) begin
1558
    if (eval_msgcode_i) begin
1559
      casex (msgcode_i)
1560
        VENDOR_DEFINED_TYPE_0, VENDOR_DEFINED_TYPE_1:
1561
          msgcode_vendef        <= #`TCQ 1;
1562
        default:
1563
          msgcode_vendef        <= #`TCQ 0;
1564
      endcase
1565
    end
1566
  end
1567
 
1568
  always @(posedge clk_i) begin
1569
    if (reset_i) begin
1570
      filter_msgcode            <= #`TCQ 0;
1571
    end else if (eval_formats_i) begin
1572
      if (ismsgany) begin
1573
        filter_msgcode          <= #`TCQ !allow_legacy && msgcode_legacy;
1574
      end else begin    // not a Message
1575
        filter_msgcode          <= #`TCQ 0;
1576
      end
1577
    end
1578
  end
1579
 
1580
  //====================================================================
1581
  // Steer packets to the CMM.
1582
 
1583
  always @(posedge clk_i) begin
1584
    if (reset_i) begin
1585
      cfg0_ip <= #`TCQ 0;
1586
      cfg1_ip <= #`TCQ 0;
1587
    end else if (eval_formats_i) begin
1588
      casex (fulltype_in)
1589
        CFGANY0: cfg0_ip <= #`TCQ 1;
1590
        default: cfg0_ip <= #`TCQ 0;
1591
      endcase
1592
      casex (fulltype_in)
1593
        CFGANY1: cfg1_ip <= #`TCQ 1;
1594
        default: cfg1_ip <= #`TCQ 0;
1595
      endcase
1596
    end
1597
  end
1598
 
1599
  // The user gets a Type 0 packet if:
1600
  //
1601
  // 1. The packet's address range is between 192 and 255 inclusive, and
1602
  //    the user implements legacy config space, or
1603
  // 2. The packet's address range is at or above 1024 (4*256) and the
1604
  //    user implements extended config space.
1605
 
1606
  always @(posedge clk_i) begin
1607
    if (reset_i) begin
1608
      is_usr_leg_ap <= #`TCQ 0;
1609
    end else if (load_aperture_i) begin
1610
      is_usr_leg_ap <= #`TCQ (aperture_i == 0) && (offset_i[7:6] == 3) &&
1611
                             legacy_cfg_access_i;
1612
    end
1613
  end
1614
 
1615
  always @(posedge clk_i) begin
1616
    if (reset_i) begin
1617
      is_usr_ext_ap <= #`TCQ 0;
1618
    end else if (load_aperture_i) begin
1619
      is_usr_ext_ap <= #`TCQ |aperture_i[3:2] && ext_cfg_access_i;
1620
    end
1621
  end
1622
 
1623
  always @(posedge clk_i) begin
1624
    if (reset_i) begin
1625
      load_aperture_q <= #`TCQ 0;
1626
    end else begin
1627
      load_aperture_q <= #`TCQ load_aperture_i;
1628
    end
1629
  end
1630
 
1631
  // The packet goes to the CMM if:
1632
  // 1. It is Config Type 1, OR
1633
  // 2. It is Config Type 0 and the packet doesn't fall into either of
1634
  //    the user categories above.
1635
 
1636
  always @(posedge clk_i) begin
1637
    if (reset_i) begin
1638
      cfg_o <= #`TCQ 0;
1639
    end else if (load_aperture_q) begin
1640
      cfg_o <= #`TCQ cfg1_ip || (cfg0_ip && !is_usr_leg_ap && !is_usr_ext_ap);
1641
    end
1642
  end
1643
 
1644
  // Signal receipt of a hot-plug Message. These have been obsoleted
1645
  // starting with PCIe 1.1, so the user is given the option of dropping
1646
  // them.
1647
 
1648
  always @(posedge clk_i) begin
1649
    if (reset_i) begin
1650
      hp_msg_detect_o <= #`TCQ 0;
1651
    end else if (eval_formats_q) begin
1652
      hp_msg_detect_o <= #`TCQ ismsgany && msgcode_hotplug;
1653
    end
1654
  end
1655
  `else // `ifdef AS
1656
  //====================================================================
1657
  // Check for valid PI and PI chain.
1658
  //====================================================================
1659
 
1660
  // Make sure that PIs are not latched past the end of the chain. Valid
1661
  // chains are:
1662
  // * 0 -> 0
1663
  // * 0 -> 1 -> PDU (8-126)
1664
  // * 0 -> 1 -> 2 -> PDU
1665
  // * 0 -> 2 -> PDU
1666
  // * 1 -> PDU
1667
  // * 1 -> 2 -> PDU
1668
  // * 2 -> PDU
1669
  // * 4
1670
  // * 5
1671
  // * PDU
1672
 
1673
  // The secondary and tertiary PIs appear on the same clock cycle in
1674
  // 64-bit, which is why the equation for load_pi_3rd is more complex
1675
  // than the other ones.
1676
 
1677
  assign load_pi_1st = load_pi_1st_i;
1678
 
1679
  assign load_pi_2nd = load_pi_2nd_i && (pi_1st <= 2);
1680
 
1681
  // In 64-bit, the secondary and tertiary PIs come on the same cycle,
1682
  // so checks on the 3rd PI involve the live version of the 2nd PI.
1683
  assign load_pi_3rd = load_pi_3rd_i && ((DW == 64) ?
1684
                                         ((pi_2nd_i == 1) || (pi_2nd_i == 2)) :
1685
                                         ((pi_2nd   == 1) || (pi_2nd   == 2)));
1686
 
1687
  assign load_pi_4th = load_pi_4th_i && (pi_3rd_i <= 2);
1688
 
1689
  // PIs 128-130 are "placeholders": If their corresponding registers
1690
  // are not written into, they will still be greater than higher-order
1691
  // PIs for the purposes of chain validation.
1692
 
1693
  always @(posedge clk_i) begin
1694
    if (sof_i) begin
1695
      pi_1st <= #`TCQ load_pi_1st ? pi_1st_i : 0;
1696
      pi_2nd <= #`TCQ 128;
1697
      pi_3rd <= #`TCQ 129;
1698
      pi_4th <= #`TCQ 130;
1699
    end else begin
1700
      if (load_pi_2nd) begin
1701
        pi_2nd[7]   <= #`TCQ 0;
1702
        pi_2nd[6:0] <= #`TCQ pi_2nd_i;
1703
      end
1704
      if (load_pi_3rd) begin
1705
        pi_3rd[7]   <= #`TCQ 0;
1706
        pi_3rd[6:0] <= #`TCQ pi_3rd_i;
1707
      end
1708
      if (load_pi_4th) begin
1709
        pi_4th[7]   <= #`TCQ 0;
1710
        pi_4th[6:0] <= #`TCQ pi_4th_i;
1711
      end
1712
    end
1713
  end
1714
 
1715
  // Distill certain PIs into one-hot signals
1716
 
1717
  always @(posedge clk_i) begin
1718
    if (reset_i) begin
1719
      primary_pi0   <= #`TCQ 0;
1720
      primary_pi4   <= #`TCQ 0;
1721
      primary_pi5   <= #`TCQ 0;
1722
    end else if (load_pi_1st) begin
1723
      primary_pi0   <= #`TCQ (pi_1st_i == 0);
1724
      primary_pi4   <= #`TCQ (pi_1st_i == 4);
1725
      primary_pi5   <= #`TCQ (pi_1st_i == 5);
1726
    end
1727
  end
1728
 
1729
  always @(posedge clk_i) begin
1730
    if (reset_i) begin
1731
      secondary_pi0 <= #`TCQ 0;
1732
    end else if (load_pi_2nd) begin
1733
      secondary_pi0 <= #`TCQ (pi_2nd_i == 0);
1734
    end
1735
  end
1736
 
1737
  // Check for invalid PIs. Note that placeholder PIs (128+) which
1738
  // represent "blanks" are always valid.
1739
  //--------------------------------------------------------------------
1740
 
1741
  always @(posedge clk_i) begin
1742
    if (reset_i) begin
1743
      pi_1st_vld <= #`TCQ 1;
1744
      pi_2nd_vld <= #`TCQ 1;
1745
      pi_3rd_vld <= #`TCQ 1;
1746
      pi_4th_vld <= #`TCQ 1;
1747
    end else begin
1748
      // Primary PI: Legal values are 0-2, 4, 5, 8-126
1749
      pi_1st_vld <= #`TCQ (pi_1st != 3) && (pi_1st != 6) && (pi_1st != 7) &&
1750
                          (pi_1st != 127);
1751
 
1752
      // Secondary PI: Legal values are 0-2, 8-126
1753
      pi_2nd_vld <= #`TCQ ((pi_2nd <= 2) || (pi_2nd >= 8)) && (pi_2nd != 127);
1754
 
1755
      // Tertiary PI: Legal values are 2, 8-126
1756
      pi_3rd_vld <= #`TCQ ((pi_2nd == 2) || (pi_2nd >= 8)) && (pi_3rd != 127);
1757
 
1758
      // Quaternary PI: Legal values are 8-126
1759
      pi_4th_vld <= #`TCQ (pi_4th >= 8) && (pi_4th != 127);
1760
    end
1761
  end
1762
 
1763
  // Check for invalid PI sequences. Note that the placeholder PIs will
1764
  // always represent valid chains since they are greater than any legal
1765
  // PI and are loaded in an increasing progression. In addition,
1766
  //--------------------------------------------------------------------
1767
 
1768
  always @(posedge clk_i) begin
1769
    if (reset_i) begin
1770
      pi_2nd_seq_vld <= #`TCQ 1;
1771
      pi_3rd_seq_vld <= #`TCQ 1;
1772
      pi_4th_seq_vld <= #`TCQ 1;
1773
    end else begin
1774
      // Secondary PI is sequence-valid if 1st PI = 0 or 2nd PI > 1st PI
1775
      pi_2nd_seq_vld <= #`TCQ !((pi_1st < 4) && pi_2nd[7]) &&
1776
                                (pi_2nd > pi_1st);
1777
 
1778
      // Tertiary PI is sequence-valid if 3rd PI > 2nd PI
1779
      pi_3rd_seq_vld <= #`TCQ !(((pi_2nd > 0) || (pi_2nd < 4)) && pi_3rd[7]) &&
1780
                                 (pi_3rd > pi_2nd);
1781
 
1782
      // Quaternary PI is sequence-valid if 4th PI > 3rd PI
1783
      pi_4th_seq_vld <= #`TCQ !(((pi_3rd > 0) || (pi_3rd < 4)) && pi_4th[7]) &&
1784
                                 (pi_4th > pi_3rd);
1785
    end
1786
  end
1787
 
1788
  // Latch any PI error condition.
1789
  //--------------------------------------------------------------------
1790
 
1791
  always @(posedge clk_i) begin
1792
    if (reset_i) begin
1793
      bad_pi_chain_o <= #`TCQ 1;
1794
    end else if (eof_q1) begin
1795
      bad_pi_chain_o <= #`TCQ !pi_1st_vld || !pi_2nd_vld ||
1796
                              !pi_3rd_vld || !pi_4th_vld ||
1797
                              !pi_2nd_seq_vld || !pi_3rd_seq_vld ||
1798
                              !pi_4th_seq_vld;
1799
    end
1800
  end
1801
 
1802
  //====================================================================
1803
  // Check the Turn Pointer. Must be zero for any forward-routed packet
1804
  // received by an Endpoint that is not PI-0.
1805
 
1806
  always @(posedge clk_i) begin
1807
    if (reset_i) begin
1808
      non_zero_turn_pointer_o <= #`TCQ 0;
1809
    end else if (eval_formats_i) begin
1810
      non_zero_turn_pointer_o <= #`TCQ !dir_i && !switch_mode_i &&
1811
                                       (pi_1st != 0) && (turn_pointer_i != 0);
1812
    end
1813
  end
1814
 
1815
  //====================================================================
1816
  // Check the Header CRC. Path-building and multicast packets (PI-0)
1817
  // have a mutable Turn Pool which must be masked out when performing
1818
  // the CRC calculation. For timing purposes, both the path-build and
1819
  // non-path-build CRCs are calculated and the correct one is later
1820
  // chosen for comparison.
1821
 
1822
  tlm_hcrc hcrc
1823
   (.d_i        (route_header_i[50:0]),
1824
    .hcrc_o     (header_crc_d));
1825
 
1826
  tlm_hcrc hcrc_pb
1827
   (.d_i        ({route_header_i[50:32],32'b0}),
1828
    .hcrc_o     (header_crc_pb_d));
1829
 
1830
  always @(posedge clk_i) begin
1831
    if (reset_i) begin
1832
      path_build    <= #`TCQ 0;
1833
    end else if (eval_formats_i) begin
1834
      path_build    <= #`TCQ (pi_1st == 0);
1835
    end
1836
  end
1837
 
1838
  always @(posedge clk_i) begin
1839
    if (reset_i) begin
1840
      header_crc    <= #`TCQ 0;
1841
      header_crc_pb <= #`TCQ 0;
1842
    end else if (eval_formats_i) begin
1843
      header_crc    <= #`TCQ header_crc_d;
1844
      header_crc_pb <= #`TCQ header_crc_pb_d;
1845
    end
1846
  end
1847
 
1848
  always @(posedge clk_i) begin
1849
    if (reset_i) begin
1850
      bad_header_crc_o <= #`TCQ 0;
1851
    end else if (eof_q1) begin
1852
      bad_header_crc_o <= #`TCQ (hcrc_i !=
1853
                                 (path_build ? header_crc_pb : header_crc));
1854
    end
1855
  end
1856
 
1857
  //====================================================================
1858
  // Check whether we've received an packet intended for an unsupported
1859
  // OVC or MVC.
1860
 
1861
  always @(posedge clk_i) begin
1862
    if (reset_i) begin
1863
      unsup_ovc_o <= #`TCQ 0;
1864
    end else if (eval_formats_i) begin
1865
      unsup_ovc_o <= #`TCQ oo_i && BVC;
1866
    end
1867
  end
1868
 
1869
  always @(posedge clk_i) begin
1870
    if (reset_i) begin
1871
      unsup_mvc_o <= #`TCQ 0;
1872
    end else if (eof_q1) begin
1873
      unsup_mvc_o <= #`TCQ primary_pi0 && (pi_2nd != 0) && !MVC;
1874
    end
1875
  end
1876
 
1877
  //====================================================================
1878
  // Drop packets depending on link state. In DL_Inactive or DL_init,
1879
  // only PI-0:0 packets are allowed through. In DL_Protected, only
1880
  // PI-0:0, PI-4 and PI-5 packets are allowed.
1881
 
1882
  localparam [1:0] DL_INACTIVE  = 2'b00;
1883
  localparam [1:0] DL_INIT      = 2'b01;
1884
  localparam [1:0] DL_PROTECTED = 2'b10;
1885
  localparam [1:0] DL_ACTIVE    = 2'b11;
1886
 
1887
  // Only change link state in between packets.
1888
 
1889
  always @(posedge clk_i) begin
1890
    if (reset_i) begin
1891
      packet_ip <= #`TCQ 0;
1892
    end else if (sof_i) begin
1893
      packet_ip <= #`TCQ 1;
1894
    end else if (eof_i) begin
1895
      packet_ip <= #`TCQ 0;
1896
    end
1897
  end
1898
 
1899
  always @(posedge clk_i) begin
1900
    if (reset_i) begin
1901
      lnk_state_d <= #`TCQ DL_INACTIVE;
1902
    end else if (lnk_state_src_rdy_i) begin
1903
      lnk_state_d <= #`TCQ lnk_state_i;
1904
    end
1905
  end
1906
 
1907
  always @(posedge clk_i) begin
1908
    if (reset_i) begin
1909
      lnk_state <= #`TCQ DL_INACTIVE;
1910
    end else if (!packet_ip) begin
1911
      lnk_state <= #`TCQ lnk_state_d;
1912
    end
1913
  end
1914
 
1915
  // Signal packet drop
1916
 
1917
  always @(posedge clk_i) begin
1918
    if (reset_i) begin
1919
      packet_keep <= #`TCQ 1'b1;
1920
    end else if (eof_q1) begin
1921
      case (lnk_state)
1922
        DL_INACTIVE:  packet_keep <= #`TCQ  (pi_1st == 0) && (pi_2nd == 0);
1923
        DL_INIT:      packet_keep <= #`TCQ  (pi_1st == 0) && (pi_2nd == 0);
1924
        DL_PROTECTED: packet_keep <= #`TCQ ((pi_1st == 0) && (pi_2nd == 0)) ||
1925
                                            (pi_1st == 4) || (pi_1st == 5);
1926
        DL_ACTIVE:    packet_keep <= #`TCQ  1'b1;
1927
      endcase
1928
    end
1929
  end
1930
 
1931
  assign filter_drop_o = !packet_keep;
1932
 
1933
  //====================================================================
1934
  // Flag PI-0:0 and PI-4 packets as config. For PI-4, make sure the
1935
  // config address is in the CMM's range.
1936
 
1937
  always @(posedge clk_i) begin
1938
    if (reset_i) begin
1939
      pi4_ap0   <= #`TCQ 1'b0;
1940
      pi4_ap1   <= #`TCQ 1'b0;
1941
    end else if (load_aperture_i) begin
1942
      pi4_ap0   <= #`TCQ primary_pi4 && (aperture_i == 0);
1943
      pi4_ap1   <= #`TCQ primary_pi4 && (aperture_i == 1);
1944
    end
1945
  end
1946
 
1947
  always @(posedge clk_i) begin
1948
    if (reset_i) begin
1949
      in_ap0_range  <= #`TCQ 0;
1950
      in_ap1_range  <= #`TCQ 0;
1951
    end else if (load_offset_i) begin
1952
      in_ap0_range  <= #`TCQ (offset_i <  cmm_ap0_space_end_i);
1953
      in_ap1_range  <= #`TCQ (offset_i >= cmm_ap1_space_start_i) &&
1954
                             (offset_i <  cmm_ap1_space_end_i);
1955
    end
1956
  end
1957
 
1958
  always @(posedge clk_i) begin
1959
    if (reset_i) begin
1960
      load_offset_q <= #`TCQ 0;
1961
    end else begin
1962
      load_offset_q <= #`TCQ load_offset_i;
1963
    end
1964
  end
1965
 
1966
  // The packet goes to the CMM if:
1967
  // 1. It is PI-0:0 and we are not a Fabric Manager, OR
1968
  // 2. It is PI-4 Aperture 0, and in the Aperture 0 address range, OR
1969
  // 3. It is PI-4 Aperture 1, and in the Aperture 1 address range.
1970
 
1971
  always @(posedge clk_i) begin
1972
    if (reset_i) begin
1973
      cfg_o <= #`TCQ 0;
1974
    end else if (load_offset_q) begin
1975
      cfg_o <= #`TCQ (primary_pi0 && secondary_pi0 &&
1976
                      !fabric_manager_mode_i) ||
1977
                     (pi4_ap0 && in_ap0_range) ||
1978
                     (pi4_ap1 && in_ap1_range);
1979
    end
1980
  end
1981
  `endif
1982
 
1983
  //====================================================================
1984
  // delay of control signals
1985
 
1986
  always @(posedge clk_i) begin
1987
    if (reset_i) begin
1988
      `ifdef PCIE
1989
      sof_q1          <= #`TCQ 0;
1990
      sof_q2          <= #`TCQ 0;
1991
      sof_q3          <= #`TCQ 0;
1992
      sof_q4          <= #`TCQ 0;
1993
      eof_q2          <= #`TCQ 0;
1994
      eof_q3          <= #`TCQ 0;
1995
      eval_formats_q  <= #`TCQ 0;
1996
      eval_formats_q2 <= #`TCQ 0;
1997
      `endif
1998
      eof_q1          <= #`TCQ 0;
1999
    end else begin
2000
      `ifdef PCIE
2001
      sof_q1          <= #`TCQ sof_i;
2002
      sof_q2          <= #`TCQ sof_q1;
2003
      sof_q3          <= #`TCQ sof_q2;
2004
      sof_q4          <= #`TCQ sof_q3;
2005
      eof_q2          <= #`TCQ eof_q1;
2006
      eof_q3          <= #`TCQ eof_q2;
2007
      eval_formats_q  <= #`TCQ eval_formats_i;
2008
      eval_formats_q2 <= #`TCQ eval_formats_q;
2009
      `endif
2010
      eof_q1          <= #`TCQ eof_i;
2011
    end
2012
  end
2013
endmodule

powered by: WebSVN 2.1.0

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