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_virtex6/] [axi_basic_rx_pipeline.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dsmv
-------------------------------------------------------------------------------
2
--
3
-- (c) Copyright 2009-2011 Xilinx, Inc. All rights reserved.
4
--
5
-- This file contains confidential and proprietary information
6
-- of Xilinx, Inc. and is protected under U.S. and
7
-- international copyright and other intellectual property
8
-- laws.
9
--
10
-- DISCLAIMER
11
-- This disclaimer is not a license and does not grant any
12
-- rights to the materials distributed herewith. Except as
13
-- otherwise provided in a valid license issued to you by
14
-- Xilinx, and to the maximum extent permitted by applicable
15
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
16
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
17
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
18
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
19
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
20
-- (2) Xilinx shall not be liable (whether in contract or tort,
21
-- including negligence, or under any other theory of
22
-- liability) for any loss or damage of any kind or nature
23
-- related to, arising under or in connection with these
24
-- materials, including for any direct, or any indirect,
25
-- special, incidental, or consequential loss or damage
26
-- (including loss of data, profits, goodwill, or any type of
27
-- loss or damage suffered as a result of any action brought
28
-- by a third party) even if such damage or loss was
29
-- reasonably foreseeable or Xilinx had been advised of the
30
-- possibility of the same.
31
--
32
-- CRITICAL APPLICATIONS
33
-- Xilinx products are not designed or intended to be fail-
34
-- safe, or for use in any application requiring fail-safe
35
-- performance, such as life-support or safety devices or
36
-- systems, Class III medical devices, nuclear facilities,
37
-- applications related to the deployment of airbags, or any
38
-- other applications that could lead to death, personal
39
-- injury, or severe property or environmental damage
40
-- (individually and collectively, "Critical
41
-- Applications"). Customer assumes the sole risk and
42
-- liability of any use of Xilinx products in Critical
43
-- Applications, subject only to applicable laws and
44
-- regulations governing limitations on product liability.
45
--
46
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
47
-- PART OF THIS FILE AT ALL TIMES.
48
--
49
-------------------------------------------------------------------------------
50
-- Project    : Virtex-6 Integrated Block for PCI Express
51
-- File       : axi_basic_rx_pipeline.vhd
52
-- Version    : 2.3
53
--
54
-- Description:
55
--  TRN to AXI RX pipeline. Converts received data from TRN protocol to AXI.
56
--
57
--  Notes:
58
--  Optional notes section.
59
--
60
--  Hierarchical:
61
--    axi_basic_top
62
--      axi_basic_rx
63
--        axi_basic_rx_pipeline
64
--
65
-------------------------------------------------------------------------------
66
-- Library Declarations
67
--------------------------------------------------------------------------------
68
 
69
LIBRARY ieee;
70
   USE ieee.std_logic_1164.all;
71
   USE ieee.std_logic_unsigned.all;
72
 
73
 
74
ENTITY axi_basic_rx_pipeline IS
75
   GENERIC (
76
      C_DATA_WIDTH            : INTEGER := 128;           -- RX/TX interface data width
77
      C_FAMILY                : STRING := "X7";           -- Targeted FPGA family
78
      TCQ                     : INTEGER := 1;             -- Clock to Q time
79
 
80
      C_REM_WIDTH             : INTEGER := 1;             -- trem/rrem width
81
      C_STRB_WIDTH            : INTEGER := 4              -- TSTRB width
82
   );
83
   PORT (
84
 
85
      -- AXI RX
86
      -------------
87
      M_AXIS_RX_TDATA         : OUT STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0) ;       -- RX data to user
88
      M_AXIS_RX_TVALID        : OUT STD_LOGIC                                   ;       -- RX data is valid
89
      M_AXIS_RX_TREADY        : IN STD_LOGIC                                    ;       -- RX ready for data
90
      M_AXIS_RX_TSTRB         : OUT STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0) ;       -- RX strobe byte enables
91
      M_AXIS_RX_TLAST         : OUT STD_LOGIC                                   ;       -- RX data is last
92
      M_AXIS_RX_TUSER         : OUT STD_LOGIC_VECTOR(21 DOWNTO 0)               ;       -- RX user signals
93
 
94
       -- TRN RX
95
       -------------
96
      TRN_RD                  : IN STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0)  ;       -- RX data from block
97
      TRN_RSOF                : IN STD_LOGIC                                    ;       -- RX start of packet
98
      TRN_REOF                : IN STD_LOGIC                                    ;       -- RX end of packet
99
      TRN_RSRC_RDY            : IN STD_LOGIC                                    ;       -- RX source ready
100
      TRN_RDST_RDY            : OUT STD_LOGIC                                   ;       -- RX destination ready
101
      TRN_RSRC_DSC            : IN STD_LOGIC                                    ;       -- RX source discontinue
102
      TRN_RREM                : IN STD_LOGIC_VECTOR(C_REM_WIDTH - 1 DOWNTO 0)   ;       -- RX remainder
103
      TRN_RERRFWD             : IN STD_LOGIC                                    ;       -- RX error forward
104
      TRN_RBAR_HIT            : IN STD_LOGIC_VECTOR(6 DOWNTO 0)                 ;       -- RX BAR hit
105
      TRN_RECRC_ERR           : IN STD_LOGIC                                    ;       -- RX ECRC error
106
 
107
      -- Null Inputs
108
      -------------
109
      NULL_RX_TVALID          : IN STD_LOGIC                                    ;       -- NULL generated tvalid
110
      NULL_RX_TLAST           : IN STD_LOGIC                                    ;       -- NULL generated tlast
111
      NULL_RX_TSTRB           : IN STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0)  ;       -- NULL generated tstrb
112
      NULL_RDST_RDY           : IN STD_LOGIC                                    ;       -- NULL generated rdst_rdy
113
      NULL_IS_EOF             : IN STD_LOGIC_VECTOR(4 DOWNTO 0)                 ;       -- NULL generated is_eof
114
 
115
      -- System
116
      -------------
117
      NP_COUNTER              : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)                ;       -- Non-posted counter
118
      USER_CLK                : IN STD_LOGIC                                    ;       -- user clock from block
119
      USER_RST                : IN STD_LOGIC                                            -- user reset from block
120
   );
121
END axi_basic_rx_pipeline;
122
 
123
ARCHITECTURE trans OF axi_basic_rx_pipeline IS
124
 
125
   SIGNAL is_sof                 : STD_LOGIC_VECTOR(4 DOWNTO 0);
126
   SIGNAL is_sof_prev            : STD_LOGIC_VECTOR(4 DOWNTO 0);
127
 
128
   SIGNAL is_eof                 : STD_LOGIC_VECTOR(4 DOWNTO 0);
129
   SIGNAL is_eof_prev            : STD_LOGIC_VECTOR(4 DOWNTO 0);
130
 
131
   SIGNAL reg_tstrb              : STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0);
132
   SIGNAL tstrb                  : STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0);
133
   SIGNAL tstrb_prev             : STD_LOGIC_VECTOR(C_STRB_WIDTH - 1 DOWNTO 0);
134
 
135
   SIGNAL reg_tlast              : STD_LOGIC;
136
   SIGNAL rsrc_rdy_filtered      : STD_LOGIC;
137
 
138
   SIGNAL trn_rd_DW_swapped      : STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0);
139
   SIGNAL trn_rd_prev            : STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0);
140
 
141
   SIGNAL data_hold              : STD_LOGIC;
142
   SIGNAL data_prev              : STD_LOGIC;
143
 
144
   SIGNAL trn_reof_prev          : STD_LOGIC;
145
   SIGNAL trn_rrem_prev          : STD_LOGIC_VECTOR(C_REM_WIDTH - 1 DOWNTO 0);
146
   SIGNAL trn_rsrc_rdy_prev      : STD_LOGIC;
147
   SIGNAL trn_rsrc_dsc_prev      : STD_LOGIC;
148
   SIGNAL trn_rsof_prev          : STD_LOGIC;
149
   SIGNAL trn_rbar_hit_prev      : STD_LOGIC_VECTOR(6 DOWNTO 0);
150
   SIGNAL trn_rerrfwd_prev       : STD_LOGIC;
151
   SIGNAL trn_recrc_err_prev     : STD_LOGIC;
152
 
153
   -- Null packet handling signals
154
   SIGNAL null_mux_sel           : STD_LOGIC;
155
   SIGNAL trn_in_packet          : STD_LOGIC;
156
   SIGNAL dsc_flag               : STD_LOGIC;
157
   SIGNAL dsc_detect             : STD_LOGIC;
158
   SIGNAL reg_dsc_detect         : STD_LOGIC;
159
   SIGNAL trn_rsrc_dsc_d         : STD_LOGIC;
160
 
161
   -- Declare intermediate signals for referenced outputs
162
   SIGNAL m_axis_rx_tdata_xhdl0  : STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0);
163
   SIGNAL m_axis_rx_tvalid_xhdl2 : STD_LOGIC;
164
   SIGNAL m_axis_rx_tuser_xhdl1  : STD_LOGIC_VECTOR(21 DOWNTO 0);
165
   SIGNAL trn_rdst_rdy_xhdl4     : STD_LOGIC;
166
   SIGNAL mrd_lower              : STD_LOGIC;
167
   SIGNAL mrd_lk_lower           : STD_LOGIC;
168
   SIGNAL io_rdwr_lower          : STD_LOGIC;
169
   SIGNAL cfg_rdwr_lower         : STD_LOGIC;
170
   SIGNAL atomic_lower           : STD_LOGIC;
171
   SIGNAL np_pkt_lower           : STD_LOGIC;
172
   SIGNAL mrd_upper              : STD_LOGIC;
173
   SIGNAL mrd_lk_upper           : STD_LOGIC;
174
   SIGNAL io_rdwr_upper          : STD_LOGIC;
175
   SIGNAL cfg_rdwr_upper         : STD_LOGIC;
176
   SIGNAL atomic_upper           : STD_LOGIC;
177
   SIGNAL np_pkt_upper           : STD_LOGIC;
178
   SIGNAL pkt_accepted           : STD_LOGIC;
179
   SIGNAL reg_np_counter         : STD_LOGIC_VECTOR(2 DOWNTO 0);
180
 
181
BEGIN
182
   -- Drive referenced outputs
183
   M_AXIS_RX_TDATA     <= m_axis_rx_tdata_xhdl0;
184
   M_AXIS_RX_TVALID    <= m_axis_rx_tvalid_xhdl2;
185
   M_AXIS_RX_TUSER     <= m_axis_rx_tuser_xhdl1;
186
   TRN_RDST_RDY        <= trn_rdst_rdy_xhdl4;
187
 
188
   -- Create "filtered" version of rsrc_rdy, where discontinued SOFs are removed
189
   rsrc_rdy_filtered <= trn_rsrc_rdy AND (trn_in_packet OR (trn_rsof AND NOT trn_rsrc_dsc));
190
 
191
   --------------------------------------------------------------------------------
192
   -- Previous value buffer                                                      --
193
   -- ---------------------                                                      --
194
   -- We are inserting a pipeline stage in between TRN and AXI, which causes     --
195
   -- some issues with handshaking signals m_axis_rx_tready/trn_rdst_rdy. The    --
196
   -- added cycle of latency in the path causes the user design to fall behind   --
197
   -- the TRN interface whenever it throttles.                                   --
198
   --                                                                            --
199
   -- To avoid loss of data, we must keep the previous value of all trn_r*       --
200
   -- signals in case the user throttles.                                        --
201
   --------------------------------------------------------------------------------
202
   PROCESS (USER_CLK)
203
   BEGIN
204
      IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
205
         IF (USER_RST = '1') THEN
206
            trn_rd_prev        <=  (others => '0')AFTER 1 ps;
207
            trn_rsof_prev      <=  '0'  AFTER (TCQ)*1 ps;
208
            trn_rrem_prev      <=  (others => '0') AFTER (TCQ)*1 ps;
209
            trn_rsrc_rdy_prev  <=  '0' AFTER 1 ps;
210
            trn_rbar_hit_prev  <=  (others => '0') AFTER 1 ps;
211
            trn_rerrfwd_prev   <=  '0' AFTER 1 ps;
212
            trn_recrc_err_prev <=  '0' AFTER 1 ps;
213
            trn_reof_prev      <=  '0' AFTER 1 ps;
214
            trn_rsrc_dsc_prev  <=  '0' AFTER 1 ps;
215
         ELSE
216
                  -- prev buffer works by checking trn_rdst_rdy. When trn_rdst_rdy is
217
                  -- asserted, a new value is present on the interface.
218
 
219
            IF (trn_rdst_rdy_xhdl4 = '1') THEN
220
               trn_rd_prev        <= trn_rd_DW_swapped  AFTER (TCQ)*1 ps;
221
               trn_rsof_prev      <= TRN_RSOF           AFTER (TCQ)*1 ps;
222
               trn_rrem_prev      <= TRN_RREM           AFTER (TCQ)*1 ps;
223
               trn_rbar_hit_prev  <= TRN_RBAR_HIT       AFTER (TCQ)*1 ps;
224
               trn_rerrfwd_prev   <= TRN_RERRFWD        AFTER (TCQ)*1 ps;
225
               trn_recrc_err_prev <= TRN_RECRC_ERR      AFTER (TCQ)*1 ps;
226
               trn_rsrc_rdy_prev  <= rsrc_rdy_filtered  AFTER (TCQ)*1 ps;
227
               trn_reof_prev      <= trn_reof           AFTER (TCQ)*1 ps;
228
               trn_rsrc_dsc_prev  <= TRN_RSRC_DSC OR dsc_flag AFTER (TCQ)*1 ps;
229
            END IF;
230
         END IF;
231
      END IF;
232
   END PROCESS;
233
 
234
  --------------------------------------------------------------------------------
235
  -- Create TDATA
236
  ------------------------------------------------------------------------------
237
  -- Convert TRN data format to AXI data format. AXI is DWORD swapped from TRN
238
  -- 128-bit:                 64-bit:                  32-bit:
239
  -- TRN DW0 maps to AXI DW3  TRN DW0 maps to AXI DW1  TNR DW0 maps to AXI DW0
240
  -- TRN DW1 maps to AXI DW2  TRN DW1 maps to AXI DW0
241
  -- TRN DW2 maps to AXI DW1
242
  -- TRN DW3 maps to AXI DW0
243
 
244
   xhdl7 : IF (C_DATA_WIDTH = 128) GENERATE
245
      trn_rd_DW_swapped <= (TRN_RD(31 DOWNTO 0) & TRN_RD(63 DOWNTO 32) & TRN_RD(95 DOWNTO 64) & TRN_RD(127 DOWNTO 96));
246
   END GENERATE;
247
   --xhdl8 : IF (NOT(C_DATA_WIDTH = 128)) GENERATE
248
   xhdl9 : IF (C_DATA_WIDTH = 64) GENERATE
249
           trn_rd_DW_swapped <= (TRN_RD(31 DOWNTO 0) & TRN_RD(63 DOWNTO 32));
250
   END GENERATE;
251
 
252
   xhdl10 : IF (NOT(C_DATA_WIDTH = 64) AND NOT(C_DATA_WIDTH = 128)) GENERATE
253
           trn_rd_DW_swapped <= TRN_RD;
254
   END GENERATE;
255
   --END GENERATE;
256
 
257
   -- Create special buffer which locks in the proper value of TDATA depending
258
   -- on whether the user is throttling or not. This buffer has three states:
259
   --
260
   --   HOLD state: TDATA maintains its current value
261
   --                   - the user has throttled the PCIe block
262
   --   PREVIOUS state: the buffer provides the previous value on trn_rd
263
   --                   - the user has finished throttling, and is a little behind
264
   --                     the PCIe block
265
   --   CURRENT state: the buffer passes the current value on trn_rd
266
   --                   - the user is caught up and ready to receive the latest
267
   --                     data from the PCIe block
268
 
269
   PROCESS (USER_CLK)
270
   BEGIN
271
           IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
272
                   IF (USER_RST = '1') THEN
273
                           m_axis_rx_tdata_xhdl0 <= (OTHERS=>'0') AFTER (TCQ)*1 ps;
274
                   ELSE
275
                           IF ((NOT(data_hold)) = '1') THEN
276
                                    -- PREVIOUS state
277
                                   IF (data_prev = '1') THEN
278
                                           m_axis_rx_tdata_xhdl0 <= trn_rd_prev  AFTER (TCQ)*1 ps;
279
                                   -- CURRENT state
280
                                   ELSE
281
                                           m_axis_rx_tdata_xhdl0 <= trn_rd_DW_swapped  AFTER (TCQ)*1 ps;
282
                                   END IF;
283
                           END IF;
284
                           -- else HOLD state
285
                   END IF;
286
           END IF;
287
   END PROCESS;
288
 
289
   -- Logic to instruct pipeline to hold its value
290
   data_hold <= (NOT(M_AXIS_RX_TREADY) AND m_axis_rx_tvalid_xhdl2);
291
 
292
   -- Logic to instruct pipeline to use previous bus values. Always use previous value after holding a value.
293
   PROCESS (USER_CLK)
294
   BEGIN
295
      IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
296
         IF (USER_RST = '1') THEN
297
            data_prev <= '0'  AFTER (TCQ)*1 ps;
298
         ELSE
299
            data_prev <= data_hold  AFTER (TCQ)*1 ps;
300
         END IF;
301
      END IF;
302
   END PROCESS;
303
 
304
   ------------------------------------------------------------------------------
305
   -- Create TVALID, TLAST, TSTRB, TUSER
306
   -- -----------------------------------
307
   -- Use the same strategy for these signals as for TDATA, except here we need
308
   -- an extra provision for null packets.
309
   ------------------------------------------------------------------------------
310
   PROCESS (USER_CLK)
311
   BEGIN
312
      IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
313
              IF (USER_RST = '1') THEN
314
                      m_axis_rx_tvalid_xhdl2 <= '0'  AFTER (TCQ)*1 ps;
315
                      reg_tlast <= '0' AFTER (TCQ)*1 ps;
316
                      reg_tstrb <= (others => '1') AFTER (TCQ)*1 ps;
317
                      m_axis_rx_tuser_xhdl1 <= (others => '0')  AFTER (TCQ)*1 ps;
318
              ELSE
319
                 IF (data_hold = '0') THEN
320
                      -- If in a null packet, use null generated value
321
                      IF (null_mux_sel = '1') THEN
322
                              m_axis_rx_tvalid_xhdl2 <= NULL_RX_TVALID  AFTER (TCQ)*1 ps;
323
                              reg_tlast <= NULL_RX_TLAST AFTER (TCQ)*1 ps;
324
                              reg_tstrb <= NULL_RX_TSTRB AFTER (TCQ)*1 ps;
325
                              m_axis_rx_tuser_xhdl1 <= (NULL_IS_EOF & "00000000000000000") AFTER (TCQ)*1 ps;
326
 
327
                      -- PREVIOUS state
328
                      ELSIF (data_prev = '1') THEN
329
                              m_axis_rx_tvalid_xhdl2 <= (trn_rsrc_rdy_prev  OR dsc_flag) AFTER (TCQ)*1 ps;
330
                              reg_tlast <= trn_reof_prev AFTER (TCQ)*1 ps;
331
                              reg_tstrb <= tstrb_prev AFTER (TCQ)*1 ps;
332
                              m_axis_rx_tuser_xhdl1 <= (is_eof_prev & "00" & is_sof_prev & '0' & trn_rbar_hit_prev & trn_rerrfwd_prev & trn_recrc_err_prev) AFTER (TCQ)*1 ps;
333
                                              -- TUSER bits [21:17] & TUSER bits [16:15] & TUSER bits [14:10] & TUSER bits [9] & TUSER bits [8:2] & TUSER bit  [1] & TUSER bit  [0]
334
 
335
                      -- CURRENT state
336
                      ELSE
337
 
338
                              m_axis_rx_tvalid_xhdl2 <= (rsrc_rdy_filtered OR dsc_flag) AFTER (TCQ)*1 ps;
339
                              reg_tlast <= TRN_REOF AFTER (TCQ)*1 ps;
340
                              reg_tstrb <= tstrb AFTER (TCQ)*1 ps;
341
                              m_axis_rx_tuser_xhdl1 <= (is_eof & "00" & is_sof & '0' & trn_rbar_hit & TRN_RERRFWD & TRN_RECRC_ERR) AFTER (TCQ)*1 ps;
342
                                                  -- TUSER bits [21:17] & TUSER bits [16:15] & TUSER bits [14:10] & TUSER bits [9] & TUSER bits [8:2] & TUSER bit  [1] & TUSER bit  [0]
343
                       END IF;
344
                 END IF;
345
                 -- else HOLD state
346
              END IF;
347
      END IF;
348
   END PROCESS;
349
 
350
-- Hook up TLAST and TSTRB depending on interface width
351
   xhdl11 : IF (C_DATA_WIDTH = 128) GENERATE
352
            -- For 128-bit interface, don't pass TLAST and TSTRB to user (is_eof and is_data passed to user instead). reg_tlast is still used internally.
353
           M_AXIS_RX_TLAST <= '0';
354
           M_AXIS_RX_TSTRB <= (others => '1');
355
   END GENERATE;
356
 
357
 
358
 -- For 64/32-bit interface, pass TLAST to user.
359
   xhdl12 : IF (NOT(C_DATA_WIDTH = 128)) GENERATE
360
           M_AXIS_RX_TLAST <= reg_tlast;
361
           M_AXIS_RX_TSTRB <= reg_tstrb;
362
   END GENERATE;
363
 
364
   --------------------------------------------------------------------------------
365
   -- Create TSTRB                                                              ---
366
   -- ------------                                                              ---
367
   -- Convert RREM to STRB. Here, we are converting the encoding method for the ---
368
   -- location of the EOF from TRN flavor (rrem) to AXI (TSTRB).                ---
369
   --                                                                           ---
370
   -- NOTE: for each configuration, we need two values of TSTRB, the current and---
371
   --       previous values. The need for these two values is described below.  ---
372
   --------------------------------------------------------------------------------
373
   xhdl13 : IF (C_DATA_WIDTH = 128) GENERATE
374
           -- TLAST and TSTRB not used in 128-bit interface. is_sof and is_eof used instead.
375
           tstrb <= x"0000";
376
           tstrb_prev <= x"0000";
377
   END GENERATE;
378
 
379
   xhdl14 : IF (C_DATA_WIDTH /= 128) GENERATE
380
           xhdl15 : IF (C_DATA_WIDTH = 64) GENERATE
381
                   -- 64-bit interface: contains 2 DWORDs per cycle, for a total of 8 bytes
382
                   -- TSTRB has only two possible values here, 0xFF or 0x0F
383
                   tstrb      <= x"FF" WHEN (TRN_RREM = "11") ELSE x"0F";
384
                   tstrb_prev <= x"FF" WHEN (trn_rrem_prev = "11" ) ELSE x"0F";
385
           END GENERATE;
386
           xhdl16 : IF (C_DATA_WIDTH /= 64) GENERATE
387
                   -- 32-bit interface: contains 1 DWORD per cycle, for a total of 4 bytes
388
                   -- TSTRB is always 0xF in this case, due to the nature of the PCIe block
389
                   tstrb      <= "1111";
390
                   tstrb_prev <= "1111";
391
           END GENERATE;
392
   END GENERATE;
393
 
394
   ------------------------------------------------------------------------------//
395
   -- Create is_sof                                                              //
396
   -- -------------                                                              //
397
   -- is_sof is a signal to the user indicating the location of SOF in TDATA   . //
398
   -- Due to inherent 64-bit alignment of packets from the block, the only       //
399
   -- possible values are:                                                       //
400
   --                      Value                      Valid data widths          //
401
   --                      5'b11000 (sof @ byte 8)    128                        //
402
   --                      5'b10000 (sof @ byte 0)    128, 64, 32                //
403
   --                      5'b00000 (sof not present) 128, 64, 32                //
404
   ------------------------------------------------------------------------------//
405
   xhdl17 : IF (C_DATA_WIDTH = 128) GENERATE
406
           is_sof <= (((NOT(TRN_RSRC_DSC)) AND TRN_RSOF) & ((NOT(TRN_RREM(1))) AND TRN_RSOF ) & "000");
407
           is_sof_prev <= (((trn_rsof_prev AND (NOT(trn_rsrc_dsc_prev)))) & (trn_rsof_prev AND (NOT(trn_rrem_prev(1)))) & "000");
408
                          -- bit 4:   enable bit 3:   sof @ byte 8? bit 2-0: hardwired 0
409
   END GENERATE;
410
 
411
   xhdl18 : IF (NOT(C_DATA_WIDTH = 128)) GENERATE
412
           is_sof      <= ((TRN_RSOF AND (NOT TRN_RSRC_DSC)) & "0000"); -- bit 4: enable, bits 3-0: hardwired 0
413
           is_sof_prev <= ((trn_rsof_prev AND (NOT trn_rsrc_dsc_prev)) & "0000");
414
   END GENERATE;
415
 
416
   ------------------------------------------------------------------------------//
417
   -- Create is_eof                                                              //
418
   -- -------------                                                              //
419
   -- is_eof is a signal to the user indicating the location of EOF in TDATA   . //
420
   -- Due to DWORD granularity of packets from the block, the only               //
421
   -- possible values are:                                                       //
422
   --                      Value                      Valid data widths          //
423
   --                      5'b11111 (eof @ byte 15)   128                        //
424
   --                      5'b11011 (eof @ byte 11)   128                        //
425
   --                      5'b10111 (eof @ byte 7)    128, 64                    //
426
   --                      5'b10011 (eof @ byte 3)`   128, 64, 32                //
427
   --                      5'b00011 (eof not present) 128, 64, 32                //
428
   ------------------------------------------------------------------------------//
429
   xhdl19 : IF (C_DATA_WIDTH = 128) GENERATE
430
           is_eof       <= (TRN_REOF & TRN_RREM & "11");
431
           is_eof_prev  <= (trn_reof_prev & trn_rrem_prev & "11");
432
           -- bit 4:   enable bit 3-2: encoded eof loc from block  bit 1-0: hardwired 1
433
   END GENERATE;
434
 
435
   xhdl20 : IF (C_DATA_WIDTH = 64) GENERATE
436
           is_eof       <= (TRN_REOF & '0' & TRN_RREM & "11");
437
           is_eof_prev  <= (trn_reof_prev & '0' & trn_rrem_prev & "11");
438
           -- bit 4: enable, bit 3: hardwired 0, bit 2: encoded eof loc from  block, bit 1-0: hardwired 1
439
   END GENERATE;
440
 
441
   --------------------------------------------------------------------------------
442
   xhdl20A : IF (C_DATA_WIDTH = 32) GENERATE
443
           is_eof       <= (TRN_REOF & "0011");
444
           is_eof_prev  <= (trn_reof_prev & "0011");
445
           -- bit 4: enable, bit 3: hardwired 0, bit 2: encoded eof loc from  block, bit 1-0: hardwired 1
446
   END GENERATE;
447
 
448
 
449
   -- Create trn_rdst_rdy                                                        --
450
   --------------------------------------------------------------------------------
451
   PROCESS (USER_CLK)
452
   BEGIN
453
      IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
454
              IF (USER_RST = '1') THEN
455
                      trn_rdst_rdy_xhdl4 <= '0' AFTER (TCQ)*1 ps;
456
              ELSE
457
                      -- If in a null packet, use null generated value
458
                      IF (null_mux_sel = '1' AND M_AXIS_RX_TREADY = '1') THEN
459
                              trn_rdst_rdy_xhdl4 <= NULL_RDST_RDY AFTER (TCQ)*1 ps;
460
                      -- If a discontinue needs to be serviced, throttle the block until we are
461
                      -- ready to pad out the packet
462
                      ELSIF (dsc_flag = '1') THEN
463
                              trn_rdst_rdy_xhdl4 <= '0' AFTER (TCQ)*1 ps;
464
                      -- If in a packet, pass user back-pressure directly to block
465
                      ELSIF (m_axis_rx_tvalid_xhdl2 = '1') THEN
466
                              trn_rdst_rdy_xhdl4 <= M_AXIS_RX_TREADY AFTER (TCQ)*1 ps;
467
                      -- If idle, default to no back-pressure. We need to default to the
468
                      -- "ready to accept data" state to make sure we catch the first
469
                      -- clock of data of a new packet.
470
                      ELSE
471
                              trn_rdst_rdy_xhdl4 <= '1' AFTER (TCQ)*1 ps;
472
                      END IF;
473
              END IF;
474
      END IF;
475
   END PROCESS;
476
 
477
   ------------------------------------------------------------------------------//
478
   -- Create null_mux_sel                                                        //
479
   -- null_mux_sel is the signal used to detect a discontinue situation and      //
480
   -- mux in the null packet generated in rx_null_gen. Only mux in null data     //
481
   -- when not at the beginningof a packet. SOF discontinues do not require      //
482
   -- padding, as the whole packet is simply squashed instead.                   //
483
   ------------------------------------------------------------------------------//
484
   PROCESS (USER_CLK)
485
   BEGIN
486
      IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
487
              IF (USER_RST = '1') THEN
488
                      null_mux_sel <= '0' AFTER (TCQ)*1 ps;
489
              ELSE
490
                      -- NULL packet done
491
                      IF (null_mux_sel = '1' AND NULL_RX_TLAST = '1' AND M_AXIS_RX_TREADY = '1') THEN
492
                              null_mux_sel <= '0' AFTER (TCQ)*1 ps;
493
                      -- Discontinue detected and we're in packet, so switch to NULL packet
494
                      ELSIF (dsc_flag = '1' AND data_hold = '0') THEN
495
                              null_mux_sel <= '1' AFTER (TCQ)*1 ps;
496
                      END IF;
497
              END IF;
498
      END IF;
499
   END PROCESS;
500
 
501
   ------------------------------------------------------------------------------//
502
   -- Create discontinue tracking signals                                        //
503
   ------------------------------------------------------------------------------//
504
   -- Create signal trn_in_packet, which is needed to validate trn_rsrc_dsc. We
505
   -- should ignore trn_rsrc_dsc when it's asserted out-of-packet.
506
   PROCESS (USER_CLK)
507
   BEGIN
508
      IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
509
              IF (USER_RST = '1') THEN
510
                      trn_in_packet <= '0' AFTER (TCQ)*1 ps;
511
              ELSE
512
                      IF ((TRN_RSOF = '1') AND (NOT(TRN_REOF = '1')) AND rsrc_rdy_filtered = '1' AND trn_rdst_rdy_xhdl4 = '1') THEN
513
                              trn_in_packet <= '1' AFTER (TCQ)*1 ps;
514
                      ELSIF (TRN_RSRC_DSC = '1') THEN
515
                              trn_in_packet <= '0' AFTER (TCQ)*1 ps;
516
                      ELSIF (TRN_REOF= '1' AND (NOT(TRN_RSOF= '1')) AND TRN_RSRC_RDY = '1' AND trn_rdst_rdy_xhdl4 = '1') THEN
517
                              trn_in_packet <= '0';
518
                      END IF;
519
              END IF;
520
      END IF;
521
   END PROCESS;
522
 
523
   -- Create dsc_flag, which identifies and stores mid-packet discontinues that
524
   -- require null packet padding. This signal is edge sensitive to trn_rsrc_dsc,
525
   -- to make sure we don't service the same dsc twice in the event that
526
   -- trn_rsrc_dsc stays asserted for longer than it takes to pad out the packet.
527
 
528
   dsc_detect <= TRN_RSRC_DSC and (not(trn_rsrc_dsc_d)) and trn_in_packet and ((not(TRN_RSOF)) or TRN_REOF) and (not(trn_rdst_rdy_xhdl4 and TRN_REOF));
529
 
530
   PROCESS (USER_CLK,USER_RST)
531
   BEGIN
532
           IF (USER_CLk'EVENT AND USER_CLK = '1') THEN
533
                   IF (USER_RST = '1') THEN
534
                           reg_dsc_detect <= '0' AFTER (TCQ)*1 ps;
535
                           trn_rsrc_dsc_d <= '0' AFTER (TCQ)*1 ps;
536
                   ELSE
537
                           IF (dsc_detect = '1') THEN
538
                                   reg_dsc_detect <= '1' AFTER (TCQ)*1 ps;
539
                           ELSIF (null_mux_sel = '1') THEN
540
                                   reg_dsc_detect <= '0' AFTER (TCQ)*1 ps;
541
                           END IF;
542
 
543
                           trn_rsrc_dsc_d <= TRN_RSRC_DSC AFTER (TCQ)*1 ps;
544
                   END IF;
545
           END IF;
546
   END PROCESS;
547
 
548
   dsc_flag <= dsc_detect OR reg_dsc_detect;
549
 
550
   --------------------------------------------------------------------------------
551
   -- Create np_counter (V6 128-bit only). This counter tells the V6 128-bit     --
552
   -- interface core how many NP packets have left the RX pipeline. The V6       --
553
   -- 128-bit interface uses this count to perform rnp_ok modulation.            --
554
   --------------------------------------------------------------------------------
555
 
556
   xhdl21 : IF ((C_FAMILY = "V6") AND (C_DATA_WIDTH = 128)) GENERATE
557
      -- Look for NP packets beginning on lower (i.e. unaligned) start
558
      mrd_lower      <= '1' WHEN (m_axis_rx_tdata_xhdl0(92 DOWNTO 88) = "00000" AND m_axis_rx_tdata_xhdl0(94) = '0') ELSE '0';
559
      mrd_lk_lower   <= '1' WHEN (m_axis_rx_tdata_xhdl0(92 DOWNTO 88) = "00001") ELSE '0';
560
      io_rdwr_lower  <= '1' WHEN (m_axis_rx_tdata_xhdl0(92 DOWNTO 88) = "00010") ELSE '0';
561
      cfg_rdwr_lower <= '1' WHEN (m_axis_rx_tdata_xhdl0(92 DOWNTO 89) = "0010") ELSE '0';
562
      atomic_lower   <= '1' WHEN (m_axis_rx_tdata_xhdl0(91 DOWNTO 90) = "11" AND m_axis_rx_tdata_xhdl0(94) = '1') ELSE '0';
563
 
564
      np_pkt_lower <= '1' WHEN ((mrd_lower = '1'      OR
565
                                 mrd_lk_lower = '1'   OR
566
                                 io_rdwr_lower = '1'  OR
567
                                 cfg_rdwr_lower = '1' OR
568
                                 atomic_lower = '1') AND m_axis_rx_tuser_xhdl1(13) = '1') ELSE '0';
569
 
570
      -- Look for NP packets beginning on upper (i.e. aligned) start
571
      mrd_upper      <= '1' WHEN (m_axis_rx_tdata_xhdl0(28 DOWNTO 24) = "00000" AND m_axis_rx_tdata_xhdl0(30) = '0') ELSE '0';
572
      mrd_lk_upper   <= '1' WHEN (m_axis_rx_tdata_xhdl0(28 DOWNTO 24) = "00001") ELSE '0';
573
      io_rdwr_upper  <= '1' WHEN (m_axis_rx_tdata_xhdl0(28 DOWNTO 24) = "00010") ELSE '0';
574
      cfg_rdwr_upper <= '1' WHEN (m_axis_rx_tdata_xhdl0(28 DOWNTO 25) = "0010") ELSE '0';
575
      atomic_upper   <= '1' WHEN (m_axis_rx_tdata_xhdl0(27 DOWNTO 26) = "11" AND m_axis_rx_tdata_xhdl0(30) = '1') ELSE '0';
576
 
577
      np_pkt_upper <= '1' WHEN ((mrd_upper = '1'      OR
578
                                 mrd_lk_upper = '1'   OR
579
                                 io_rdwr_upper = '1'  OR
580
                                 cfg_rdwr_upper = '1' OR
581
                                 atomic_upper = '1') AND m_axis_rx_tuser_xhdl1(13) = '0') ELSE '0';
582
 
583
      pkt_accepted <= '1' WHEN (m_axis_rx_tuser_xhdl1(14) = '1' AND M_AXIS_RX_TREADY = '1' AND m_axis_rx_tvalid_xhdl2 = '1') ELSE '0';
584
 
585
      -- Increment counter whenever an NP packet leaves the RX pipeline
586
      PROCESS (USER_CLK)
587
      BEGIN
588
              IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
589
                      IF (USER_RST = '1') THEN
590
                              reg_np_counter <= "000" AFTER (TCQ)*1 ps;
591
                      ELSE
592
                              IF ((np_pkt_lower = '1' OR np_pkt_upper = '1') AND pkt_accepted = '1') THEN
593
                                      reg_np_counter <= reg_np_counter + "001" AFTER (TCQ)*1 ps;
594
                              END IF;
595
                      END IF;
596
              END IF;
597
      END PROCESS;
598
 
599
      NP_COUNTER <= reg_np_counter;
600
   END GENERATE;
601
 
602
   xhdl22 : IF (NOT(C_FAMILY = "V6" AND C_DATA_WIDTH = 128)) GENERATE
603
           NP_COUNTER <= "000";
604
   END GENERATE;
605
END trans;
606
 
607
 

powered by: WebSVN 2.1.0

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