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

Subversion Repositories pcie_sg_dma

[/] [pcie_sg_dma/] [branches/] [Virtex6/] [ML605_ISE13.3/] [ipcore_dir_ISE13.3/] [v6_pcie_v1_6/] [example_design/] [PIO_RX_ENGINE.vhd] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 barabba
-------------------------------------------------------------------------------
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       : PIO_RX_ENGINE.vhd
52
-- Version    : 1.7
53
----
54
---- Description: 64 bit Local-Link Receive Unit.
55
----
56
----------------------------------------------------------------------------------
57
 
58
library ieee;
59
use ieee.std_logic_1164.all;
60
use ieee.std_logic_arith.all;
61
use ieee.std_logic_unsigned.all;
62
 
63
entity PIO_RX_ENGINE is port (
64
 
65
  clk               : in std_logic;
66
  rst_n             : in std_logic;
67
 
68
--
69
-- Receive local link interface from PCIe core
70
--
71
 
72
  trn_rd            : in std_logic_vector(63 downto 0);
73
  trn_rrem_n        : in std_logic_vector(7 downto 0);
74
  trn_rsof_n        : in std_logic;
75
  trn_reof_n        : in std_logic;
76
  trn_rsrc_rdy_n    : in std_logic;
77
  trn_rsrc_dsc_n    : in std_logic;
78
  trn_rbar_hit_n    : in std_logic_vector(6 downto 0);
79
  trn_rdst_rdy_n    : out std_logic;
80
 
81
  req_compl_o       : out std_logic;
82
  compl_done_i      : in std_logic;
83
 
84
--
85
-- Memory Read data handshake with Completion
86
-- transmit unit. Transmit unit reponds to
87
-- req_compl assertion and responds with compl_done
88
-- assertion when a Completion w/ data is transmitted.
89
--
90
 
91
  req_tc_o          : out std_logic_vector(2 downto 0); -- Memory Read TC
92
  req_td_o          : out std_logic; -- Memory Read TD
93
  req_ep_o          : out std_logic; -- Memory Read EP
94
  req_attr_o        : out std_logic_vector(1 downto 0); -- Memory Read Attribute
95
  req_len_o         : out std_logic_vector(9 downto 0); -- Memory Read Length (1DW)
96
  req_rid_o         : out std_logic_vector(15 downto 0); -- Memory Read Requestor ID
97
  req_tag_o         : out std_logic_vector(7 downto 0); -- Memory Read Tag
98
  req_be_o          : out std_logic_vector(7 downto 0); -- Memory Read Byte Enables
99
  req_addr_o        : out std_logic_vector(12 downto 0); -- Memory Read Address
100
 
101
-- 
102
-- Memory interface used to save 1 DW data received
103
-- on Memory Write 32 TLP. Data extracted from
104
-- inbound TLP is presented to the Endpoint memory
105
-- unit. Endpoint memory unit reacts to wr_en_o
106
-- assertion and asserts wr_busy_i when it is
107
-- processing written information.
108
--
109
 
110
  wr_addr_o         : out std_logic_vector(10 downto 0); -- Memory Write Address
111
  wr_be_o           : out std_logic_vector(7 downto 0); -- Memory Write Byte Enable
112
  wr_data_o         : out std_logic_vector(31 downto 0); -- Memory Write Data
113
  wr_en_o           : out std_logic; -- Memory Write Enable
114
  wr_busy_i         : in std_logic -- Memory Write Busy
115
);
116
 
117
end PIO_RX_ENGINE;
118
 
119
architecture rtl of PIO_RX_ENGINE is
120
 
121
constant RX_MEM_RD32_FMT_TYPE    : std_logic_vector(6 downto 0) := "0000000";
122
constant RX_MEM_WR32_FMT_TYPE    : std_logic_vector(6 downto 0) := "1000000";
123
constant RX_MEM_RD64_FMT_TYPE    : std_logic_vector(6 downto 0) := "0100000";
124
constant RX_MEM_WR64_FMT_TYPE    : std_logic_vector(6 downto 0) := "1100000";
125
constant RX_IO_RD32_FMT_TYPE     : std_logic_vector(6 downto 0) := "0000010";
126
constant RX_IO_WR32_FMT_TYPE     : std_logic_vector(6 downto 0) := "1000010";
127
 
128
type state_type is (RX_RST_STATE,
129
                    RX_MEM_RD32_DW1DW2,
130
                    RX_MEM_WR32_DW1DW2,
131
                    RX_IO_WR_DW1DW2,
132
                    RX_MEM_RD64_DW1DW2,
133
                    RX_MEM_WR64_DW1DW2,
134
                    RX_MEM_WR64_DW3,
135
                    RX_IO_MEM_WR_WAIT_STATE,
136
                    RX_WAIT_STATE);
137
 
138
signal state              : state_type;
139
signal tlp_type           : std_logic_vector(6 downto 0);
140
signal trn_rdst_rdy_n_int : std_logic;
141
signal io_bar_hit_n       : std_logic;
142
signal mem32_bar_hit_n    : std_logic;
143
signal mem64_bar_hit_n    : std_logic;
144
signal erom_bar_hit_n     : std_logic;
145
signal bar_hit_select     : std_logic_vector(3 downto 0);
146
signal region_select      : std_logic_vector(1 downto 0);
147
 
148
begin
149
 
150
trn_rdst_rdy_n <= trn_rdst_rdy_n_int;
151
 
152
mem64_bar_hit_n <= '1';
153
io_bar_hit_n <= '1';
154
mem32_bar_hit_n <= trn_rbar_hit_n(0);
155
erom_bar_hit_n  <= trn_rbar_hit_n(6);
156
 
157
 
158
process (clk, rst_n)
159
begin
160
  if (rst_n = '0' ) then
161
    trn_rdst_rdy_n_int <= '0';
162
    req_compl_o    <= '0';
163
 
164
    req_tc_o       <= (others => '0');
165
    req_td_o       <= '0';
166
    req_ep_o       <= '0';
167
    req_attr_o     <= (others => '0');
168
    req_len_o      <= (others => '0');
169
    req_rid_o      <= (others => '0');
170
    req_tag_o      <= (others => '0');
171
    req_be_o       <= (others => '0');
172
    req_addr_o     <= (others => '0');
173
    wr_be_o        <= (others => '0');
174
    wr_addr_o      <= (others => '0');
175
    wr_data_o      <= (others => '0');
176
    wr_en_o        <= '0';
177
    state          <= RX_RST_STATE;
178
    tlp_type       <= (others => '0');
179
  else
180
    if (clk'event and clk = '1') then
181
 
182
      wr_en_o        <= '0';
183
      req_compl_o    <= '0';
184
 
185
 
186
      case (state) is
187
 
188
        -- Wait in reset state until Memory or IO TLP with 1 DW payload is received
189
        when RX_RST_STATE =>
190
 
191
          trn_rdst_rdy_n_int <= '0';
192
 
193
          -- if start of rx trn transaction
194
          if ((trn_rsof_n = '0') and (trn_rsrc_rdy_n = '0')
195
             and (trn_rdst_rdy_n_int = '0')) then
196
 
197
            -- check tlp fmt and type fields
198
            case (trn_rd(62 downto 56)) is
199
 
200
              -- tlp is mem32 read request
201
              when RX_MEM_RD32_FMT_TYPE =>
202
 
203
                tlp_type           <= trn_rd(62 downto 56);
204
                req_len_o          <= trn_rd(41 downto 32);
205
                trn_rdst_rdy_n_int <= '1';
206
 
207
                -- if tlp payload length is 1 DW, then process
208
                if (trn_rd(41 downto 32) = "0000000001") then
209
 
210
                  req_tc_o     <= trn_rd(54 downto 52);
211
                  req_td_o     <= trn_rd(47);
212
                  req_ep_o     <= trn_rd(46);
213
                  req_attr_o   <= trn_rd(45 downto 44);
214
                  req_len_o    <= trn_rd(41 downto 32);
215
                  req_rid_o     <= trn_rd(31 downto 16);
216
                  req_tag_o    <= trn_rd(15 downto 8);
217
                  req_be_o     <= trn_rd(7 downto 0);
218
                  state        <= RX_MEM_RD32_DW1DW2;
219
 
220
                else
221
 
222
                  state        <= RX_RST_STATE;
223
 
224
                end if;
225
 
226
              -- tlp is mem32 write request 
227
              when RX_MEM_WR32_FMT_TYPE =>
228
 
229
                tlp_type     <= trn_rd(62 downto 56);
230
                req_len_o    <= trn_rd(41 downto 32);
231
                trn_rdst_rdy_n_int <= '1';
232
 
233
                -- if tlp payload length is 1 DW, then process
234
                if (trn_rd(41 downto 32) = "0000000001") then
235
 
236
                  wr_be_o      <= trn_rd(7 downto 0);
237
                  state        <= RX_MEM_WR32_DW1DW2;
238
 
239
                else
240
 
241
                  state        <= RX_RST_STATE;
242
 
243
                end if;
244
 
245
              -- tlp is mem64 read request
246
              when RX_MEM_RD64_FMT_TYPE =>
247
 
248
                tlp_type     <= trn_rd(62 downto 56);
249
                req_len_o    <= trn_rd(41 downto 32);
250
                trn_rdst_rdy_n_int <= '1';
251
 
252
                -- if tlp payload length is 1 DW, then process
253
                if (trn_rd(41 downto 32) = "0000000001") then
254
 
255
                  req_tc_o     <= trn_rd(54 downto 52);
256
                  req_td_o     <= trn_rd(47);
257
                  req_ep_o     <= trn_rd(46);
258
                  req_attr_o   <= trn_rd(45 downto 44);
259
                  req_len_o    <= trn_rd(41 downto 32);
260
                  req_rid_o    <= trn_rd(31 downto 16);
261
                  req_tag_o    <= trn_rd(15 downto 08);
262
                  req_be_o     <= trn_rd(07 downto 00);
263
                  state        <= RX_MEM_RD64_DW1DW2;
264
 
265
                else
266
 
267
                  state        <= RX_RST_STATE;
268
 
269
                end if;
270
 
271
              -- tlp is mem64 write request
272
              when RX_MEM_WR64_FMT_TYPE =>
273
 
274
                tlp_type     <= trn_rd(62 downto 56);
275
                req_len_o    <= trn_rd(41 downto 32);
276
 
277
                -- if tlp payload length is 1 DW, then process
278
                if (trn_rd(41 downto 32) = "0000000001") then
279
 
280
                  wr_be_o      <= trn_rd(7 downto 0);
281
                  state        <= RX_MEM_WR64_DW1DW2;
282
 
283
                else
284
 
285
                  state        <= RX_RST_STATE;
286
 
287
                end if;
288
 
289
              -- tlp is io read request
290
              when RX_IO_RD32_FMT_TYPE =>
291
 
292
                tlp_type     <= trn_rd(62 downto 56);
293
                req_len_o    <= trn_rd(41 downto 32);
294
                trn_rdst_rdy_n_int <= '1';
295
 
296
                -- if tlp payload length is 1 DW then process
297
                if (trn_rd(41 downto 32) = "0000000001") then
298
 
299
                  req_tc_o     <= trn_rd(54 downto 52);
300
                  req_td_o     <= trn_rd(47);
301
                  req_ep_o     <= trn_rd(46);
302
                  req_attr_o   <= trn_rd(45 downto 44);
303
                  req_len_o    <= trn_rd(41 downto 32);
304
                  req_rid_o     <= trn_rd(31 downto 16);
305
                  req_tag_o    <= trn_rd(15 downto 8);
306
                  req_be_o     <= trn_rd(7 downto 0);
307
                  state        <= RX_MEM_RD32_DW1DW2;
308
 
309
                else
310
 
311
                  state        <= RX_RST_STATE;
312
 
313
                end if;
314
 
315
              -- tlp is io write request
316
              when RX_IO_WR32_FMT_TYPE =>
317
 
318
                tlp_type     <= trn_rd(62 downto 56);
319
                req_len_o    <= trn_rd(41 downto 32);
320
                trn_rdst_rdy_n_int <= '1';
321
 
322
                -- if tlp payload length is 1 DW then process 
323
                if (trn_rd(41 downto 32) = "0000000001") then
324
 
325
                  req_tc_o     <= trn_rd(54 downto 52);
326
                  req_td_o     <= trn_rd(47);
327
                  req_ep_o     <= trn_rd(46);
328
                  req_attr_o   <= trn_rd(45 downto 44);
329
                  req_len_o    <= trn_rd(41 downto 32);
330
                  req_rid_o     <= trn_rd(31 downto 16);
331
                  req_tag_o    <= trn_rd(15 downto 8);
332
                  req_be_o     <= trn_rd(7 downto 0);
333
                  wr_be_o      <= trn_rd(7 downto 0);
334
                  state        <= RX_IO_WR_DW1DW2;
335
 
336
                else
337
 
338
                  state        <= RX_RST_STATE;
339
 
340
                end if;
341
 
342
 
343
              when others => -- other TLPs not supported
344
 
345
                state <= RX_RST_STATE;
346
 
347
            end case;
348
 
349
          else
350
 
351
            state <= RX_RST_STATE;
352
 
353
          end if;
354
 
355
        -- first and second dwords of mem32 read tlp
356
        when RX_MEM_RD32_DW1DW2 =>
357
 
358
          if (trn_rsrc_rdy_n = '0') then
359
 
360
            trn_rdst_rdy_n_int <= '1';
361
            req_addr_o   <= region_select(1 downto 0) & trn_rd(42 downto 34) & "00";
362
            req_compl_o  <= '1';
363
 
364
            state        <= RX_WAIT_STATE;
365
 
366
          else
367
 
368
            state        <= RX_MEM_RD32_DW1DW2;
369
 
370
          end if;
371
 
372
        -- first and second dwords of mem32 write tlp
373
        when RX_MEM_WR32_DW1DW2 =>
374
 
375
          if (trn_rsrc_rdy_n = '0') then
376
 
377
            wr_data_o  <= trn_rd(31 downto 0);
378
            trn_rdst_rdy_n_int <= '1';
379
            wr_addr_o  <= region_select(1 downto 0) & trn_rd(42 downto 34);
380
            state        <= RX_IO_MEM_WR_WAIT_STATE;
381
 
382
          else
383
 
384
            state        <= RX_MEM_WR32_DW1DW2;
385
 
386
          end if;
387
 
388
 
389
        --
390
        when RX_IO_MEM_WR_WAIT_STATE =>
391
 
392
            wr_en_o    <= '1';
393
            state        <= RX_WAIT_STATE;
394
 
395
 
396
        -- first and second dwords of io write tlp
397
        when RX_IO_WR_DW1DW2 =>
398
 
399
          if (trn_rsrc_rdy_n = '0') then
400
 
401
            wr_data_o  <= trn_rd(31 downto 0);
402
            trn_rdst_rdy_n_int <= '1';
403
            wr_addr_o  <= region_select(1 downto 0) & trn_rd(42 downto 34);
404
 
405
            req_compl_o  <= '1';
406
 
407
 
408
            state        <= RX_IO_MEM_WR_WAIT_STATE;
409
 
410
          else
411
 
412
            state        <= RX_IO_WR_DW1DW2;
413
 
414
          end if;
415
 
416
        -- first and second dwords of mem64 read tlp
417
        when RX_MEM_RD64_DW1DW2 =>
418
 
419
          if (trn_rsrc_rdy_n = '0') then
420
 
421
            req_addr_o   <= region_select(1 downto 0)  & trn_rd(10 downto 2) & "00";
422
            req_compl_o  <= '1';
423
 
424
            trn_rdst_rdy_n_int <= '1';
425
            state        <= RX_WAIT_STATE;
426
 
427
          else
428
 
429
            state        <= RX_MEM_RD64_DW1DW2;
430
 
431
          end if;
432
 
433
        -- first and second dwords of mem64 write tlp
434
        when RX_MEM_WR64_DW1DW2 =>
435
 
436
          if (trn_rsrc_rdy_n = '0') then
437
 
438
            trn_rdst_rdy_n_int <= '1';
439
            wr_addr_o  <= region_select(1 downto 0) & trn_rd(10 downto 2);
440
            trn_rdst_rdy_n_int <= '1';
441
            -- tlp write data is not available until next clock
442
            state        <= RX_MEM_WR64_DW3;
443
 
444
          else
445
 
446
            state        <= RX_MEM_WR64_DW1DW2;
447
 
448
          end if;
449
 
450
        -- third dword of mem64 write tlp contains 1 DW write data
451
        when RX_MEM_WR64_DW3 =>
452
 
453
          if (trn_rsrc_rdy_n = '0') then
454
 
455
            wr_data_o  <= trn_rd(63 downto 32);
456
            wr_en_o    <= '1';
457
            trn_rdst_rdy_n_int <= '1';
458
            state        <= RX_WAIT_STATE;
459
 
460
          else
461
 
462
            state        <= RX_MEM_WR64_DW3;
463
 
464
          end if;
465
 
466
        -- Stay in wait state for
467
        --  1. Target writes until the write has been completed and
468
        --     written into BRAM.
469
        --  2. Target reads until the completion has been generated
470
        --     and has been successfully transmitted via the PIO's
471
        --     TX interface.
472
        -- 3. IO Write and Extended CFG write until the completion 
473
        --     has been generated and has been successfully transmitted
474
        --     via the PIOs TX interface
475
 
476
        when RX_WAIT_STATE =>
477
 
478
          wr_en_o      <= '0';
479
          req_compl_o  <= '0';
480
          if ((tlp_type = RX_MEM_WR32_FMT_TYPE) and
481
             (wr_busy_i = '0')) then
482
 
483
            trn_rdst_rdy_n_int <= '0';
484
            state        <= RX_RST_STATE;
485
 
486
          elsif ((tlp_type = RX_IO_WR32_FMT_TYPE) and
487
                (wr_busy_i = '0'))  then
488
 
489
            trn_rdst_rdy_n_int <= '0';
490
            state        <= RX_RST_STATE;
491
 
492
          elsif ((tlp_type = RX_MEM_WR64_FMT_TYPE) and
493
                (wr_busy_i = '0')) then
494
 
495
            trn_rdst_rdy_n_int <= '0';
496
            state        <= RX_RST_STATE;
497
 
498
          elsif ((tlp_type = RX_MEM_RD32_FMT_TYPE) and
499
                (compl_done_i = '1')) then
500
 
501
            trn_rdst_rdy_n_int <= '0';
502
            state        <= RX_RST_STATE;
503
 
504
          elsif ((tlp_type = RX_IO_RD32_FMT_TYPE) and
505
                (compl_done_i = '1')) then
506
 
507
            trn_rdst_rdy_n_int <= '0';
508
            state        <= RX_RST_STATE;
509
 
510
          elsif ((tlp_type = RX_MEM_RD64_FMT_TYPE) and
511
                (compl_done_i = '1')) then
512
 
513
            trn_rdst_rdy_n_int <= '0';
514
            state        <= RX_RST_STATE;
515
 
516
          else
517
 
518
            state        <= RX_WAIT_STATE;
519
 
520
          end if;
521
 
522
        when others =>
523
 
524
          state <= RX_WAIT_STATE;
525
 
526
      end  case;
527
 
528
    end if;
529
 
530
  end if;
531
 
532
end process;
533
 
534
-- bar_hit_select is used to map the four dedicated bar hit signals to the
535
-- correct BlockRAM address. This ensures that TLPs destined to BARs that
536
-- are configured for IO, Mem32, Mem64, and EROM transactions will be
537
-- written to the PIO's BlockRAM memories that have been dedicated for IO, 
538
-- Mem32, Mem64,and Erom TLP storage, respectively.
539
 
540
bar_hit_select <= io_bar_hit_n & mem32_bar_hit_n & mem64_bar_hit_n & erom_bar_hit_n;
541
 
542
 
543
process (bar_hit_select)
544
begin
545
 
546
  case (bar_hit_select) is
547
 
548
    when "0111" =>
549
 
550
      -- Enable BlockRAM reserved for IO TLPs for read or write
551
      region_select <= "00";
552
 
553
    when "1011" =>
554
 
555
      -- Enable BlockRAM reserved for Mem32 TLPs for read or write
556
      region_select <= "01";
557
 
558
    when "1101" =>
559
 
560
      -- Enable BlockRAM reserved for Mem64 TLPs for read or write
561
      region_select <= "10";
562
 
563
    when "1110" =>
564
 
565
      -- Enable BlockRAM reserved for Mem32 EROM TLPs for read or write
566
      region_select <= "11";
567
 
568
    when others =>
569
 
570
      region_select <= "00";
571
 
572
  end  case;
573
 
574
end process;
575
 
576
 
577
end; -- PIO_RX_ENGINE
578
 

powered by: WebSVN 2.1.0

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