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_EP_MEM_ACCESS.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_EP_MEM_ACCESS.vhd
52
-- Version    : 1.7
53
----
54
---- Description: Endpoint Memory Access Unit. This module provides access functions
55
----              to the Endpoint memory aperture.
56
----
57
----              Read Access: Module returns data for the specifed address and
58
----              byte enables selected. 
59
---- 
60
----              Write Access: Module accepts data and byte enables and updates
61
----              data when write enable is asserted. Modules signals write busy 
62
----              write is in progress.
63
----
64
----------------------------------------------------------------------------------
65
 
66
library ieee;
67
use ieee.std_logic_1164.all;
68
 
69
entity PIO_EP_MEM_ACCESS is port (
70
 
71
  clk          : in std_logic;
72
  rst_n        : in std_logic;
73
 
74
  --  Read Port
75
 
76
  rd_addr_i    : in std_logic_vector(10 downto 0);
77
  rd_be_i      : in std_logic_vector(3 downto 0);
78
  rd_data_o    : out std_logic_vector(31 downto 0);
79
 
80
  --  Write Port
81
 
82
  wr_addr_i    : in std_logic_vector(10 downto 0);
83
  wr_be_i      : in std_logic_vector(7 downto 0);
84
  wr_data_i    : in std_logic_vector(31 downto 0);
85
  wr_en_i      : in std_logic;
86
  wr_busy_o    : out std_logic
87
 
88
);
89
 
90
end PIO_EP_MEM_ACCESS;
91
 
92
architecture rtl of PIO_EP_MEM_ACCESS is
93
 
94
type state_type is (PIO_MEM_ACCESS_WR_RST,
95
                    PIO_MEM_ACCESS_WR_READ,
96
                    PIO_MEM_ACCESS_WR_WRITE
97
                    );
98
 
99
component EP_MEM port (
100
 
101
  clk_i : in std_logic ;
102
 
103
  a_rd_a_i_0 : in std_logic_vector(8 downto 0);
104
  a_rd_d_o_0 : out std_logic_vector(31 downto 0);
105
  a_rd_en_i_0 : in std_logic ;
106
 
107
  b_wr_a_i_0 : in std_logic_vector(8 downto 0);
108
  b_wr_d_i_0 : in std_logic_vector(31 downto 0);
109
  b_wr_en_i_0 : in std_logic ;
110
  b_rd_d_o_0 : out std_logic_vector(31 downto 0);
111
  b_rd_en_i_0 : in std_logic ;
112
 
113
  a_rd_a_i_1 : in std_logic_vector(8 downto 0);
114
  a_rd_d_o_1 : out std_logic_vector(31 downto 0);
115
  a_rd_en_i_1 : in std_logic ;
116
 
117
  b_wr_a_i_1 : in std_logic_vector(8 downto 0);
118
  b_wr_d_i_1 : in std_logic_vector(31 downto 0);
119
  b_wr_en_i_1 : in std_logic ;
120
  b_rd_d_o_1 : out std_logic_vector(31 downto 0);
121
  b_rd_en_i_1 : in std_logic ;
122
 
123
  a_rd_a_i_2 : in std_logic_vector(8 downto 0);
124
  a_rd_d_o_2 : out std_logic_vector(31 downto 0);
125
  a_rd_en_i_2 : in std_logic ;
126
 
127
  b_wr_a_i_2 : in std_logic_vector(8 downto 0);
128
  b_wr_d_i_2 : in std_logic_vector(31 downto 0);
129
  b_wr_en_i_2 : in std_logic ;
130
  b_rd_d_o_2 : out std_logic_vector(31 downto 0);
131
  b_rd_en_i_2 : in std_logic ;
132
 
133
  a_rd_a_i_3 : in std_logic_vector(8 downto 0);
134
  a_rd_d_o_3 : out std_logic_vector(31 downto 0);
135
  a_rd_en_i_3 : in std_logic ;
136
 
137
  b_wr_a_i_3 : in std_logic_vector(8 downto 0);
138
  b_wr_d_i_3 : in std_logic_vector(31 downto 0);
139
  b_wr_en_i_3 : in std_logic ;
140
  b_rd_d_o_3 : out std_logic_vector(31 downto 0);
141
  b_rd_en_i_3 : in std_logic
142
 
143
);
144
 
145
end component;
146
 
147
signal  rd_data0_q        : std_logic_vector(31 downto 0);
148
signal  rd_data1_q        : std_logic_vector(31 downto 0);
149
signal  rd_data2_q        : std_logic_vector(31 downto 0);
150
signal  rd_data3_q        : std_logic_vector(31 downto 0);
151
signal  rd_data0_o        : std_logic_vector(31 downto 0);
152
signal  rd_data1_o        : std_logic_vector(31 downto 0);
153
signal  rd_data2_o        : std_logic_vector(31 downto 0);
154
signal  rd_data3_o        : std_logic_vector(31 downto 0);
155
 
156
signal  write_en          : std_logic;
157
signal  post_wr_data      : std_logic_vector(31 downto 0);
158
signal  w_pre_wr_data     : std_logic_vector(31 downto 0);
159
signal  wr_mem_state      : state_type;
160
signal  pre_wr_data       : std_logic_vector(31 downto 0);
161
 
162
signal  w_pre_wr_data0    : std_logic_vector(31 downto 0);
163
signal  w_pre_wr_data1    : std_logic_vector(31 downto 0);
164
signal  w_pre_wr_data2    : std_logic_vector(31 downto 0);
165
signal  w_pre_wr_data3    : std_logic_vector(31 downto 0);
166
 
167
signal  pre_wr_data0_q, pre_wr_data1_q : std_logic_vector(31 downto 0);
168
signal  pre_wr_data2_q, pre_wr_data3_q : std_logic_vector(31 downto 0);
169
 
170
signal  rd_data_raw_o     : std_logic_vector(31 downto 0);
171
 
172
-- Memory Write Process
173
 
174
--  Extract current data bytes. These need to be swizzled
175
--  BRAM storage format : 
176
--    data[31:0] = { byte[3], byte[2], byte[1], byte[0] (lowest addr) }
177
 
178
signal  w_pre_wr_data_b3 : std_logic_vector(7 downto 0);
179
signal  w_pre_wr_data_b2 : std_logic_vector(7 downto 0);
180
signal  w_pre_wr_data_b1 : std_logic_vector(7 downto 0);
181
signal  w_pre_wr_data_b0 : std_logic_vector(7 downto 0);
182
 
183
--  Extract new data bytes from payload
184
--  TLP Payload format : 
185
--    data[31:0] = { byte[0] (lowest addr), byte[2], byte[1], byte[3] }  
186
 
187
signal  w_wr_data_b3 : std_logic_vector(7 downto 0);
188
signal  w_wr_data_b2 : std_logic_vector(7 downto 0);
189
signal  w_wr_data_b1 : std_logic_vector(7 downto 0);
190
signal  w_wr_data_b0 : std_logic_vector(7 downto 0);
191
 
192
signal w_wr_data0_int : std_logic_vector(7 downto 0);
193
signal w_wr_data1_int : std_logic_vector(7 downto 0);
194
signal w_wr_data2_int : std_logic_vector(7 downto 0);
195
signal w_wr_data3_int : std_logic_vector(7 downto 0);
196
 
197
signal  rd_data0_en : std_logic;
198
signal  rd_data1_en : std_logic;
199
signal  rd_data2_en : std_logic;
200
signal  rd_data3_en : std_logic;
201
 
202
signal interim : std_logic;
203
 
204
signal rd_data_raw_int0 : std_logic_vector(7 downto 0);
205
signal rd_data_raw_int1 : std_logic_vector(7 downto 0);
206
signal rd_data_raw_int2 : std_logic_vector(7 downto 0);
207
signal rd_data_raw_int3 : std_logic_vector(7 downto 0);
208
 
209
signal b_wr_en_0, b_wr_en_0_int : std_logic;
210
signal b_wr_en_1, b_wr_en_1_int : std_logic;
211
signal b_wr_en_2, b_wr_en_2_int : std_logic;
212
signal b_wr_en_3, b_wr_en_3_int : std_logic;
213
 
214
signal wr_addr_0 : std_logic;
215
signal wr_addr_1 : std_logic;
216
signal wr_addr_2 : std_logic;
217
signal wr_addr_3 : std_logic;
218
 
219
begin
220
 
221
  w_wr_data_b3 <= wr_data_i(7 downto 0);
222
  w_wr_data_b2 <= wr_data_i(15 downto 8);
223
  w_wr_data_b1 <= wr_data_i(23 downto 16);
224
  w_wr_data_b0 <= wr_data_i(31 downto 24);
225
 
226
  w_pre_wr_data_b3 <= pre_wr_data(31 downto 24);
227
  w_pre_wr_data_b2 <= pre_wr_data(23 downto 16);
228
  w_pre_wr_data_b1 <= pre_wr_data(15 downto 08);
229
  w_pre_wr_data_b0 <= pre_wr_data(07 downto 00);
230
 
231
  w_wr_data3_int <= w_wr_data_b3 when (wr_be_i(3) = '1') else w_pre_wr_data_b3;
232
  w_wr_data2_int <= w_wr_data_b2 when (wr_be_i(2) = '1') else w_pre_wr_data_b2;
233
  w_wr_data1_int <= w_wr_data_b1 when (wr_be_i(1) = '1') else w_pre_wr_data_b1;
234
  w_wr_data0_int <= w_wr_data_b0 when (wr_be_i(0) = '1') else w_pre_wr_data_b0;
235
 
236
process(clk, rst_n)
237
begin
238
 
239
  if ( rst_n = '0' ) then
240
 
241
    write_en   <= '0';
242
    pre_wr_data <= (others => '0');
243
    post_wr_data <= (others => '0');
244
    pre_wr_data <= (others => '0');
245
    pre_wr_data0_q <= (others => '0');
246
    pre_wr_data1_q <= (others => '0');
247
    pre_wr_data2_q <=  (others => '0');
248
    pre_wr_data3_q <= (others => '0');
249
    wr_mem_state <= PIO_MEM_ACCESS_WR_RST;
250
 
251
  else
252
 
253
    if (clk'event and clk = '1') then
254
 
255
      case ( wr_mem_state ) is
256
 
257
        when PIO_MEM_ACCESS_WR_RST =>
258
 
259
          if (wr_en_i = '1') then -- read state
260
 
261
            -- Pipeline B port data before processing
262
 
263
            pre_wr_data0_q <= w_pre_wr_data0;
264
            pre_wr_data1_q <= w_pre_wr_data1;
265
            pre_wr_data2_q <= w_pre_wr_data2;
266
            pre_wr_data3_q <= w_pre_wr_data3;
267
            write_en <= '0';
268
            wr_mem_state <= PIO_MEM_ACCESS_WR_READ ;
269
 
270
          else
271
 
272
            write_en <= '0';
273
            wr_mem_state <= PIO_MEM_ACCESS_WR_RST;
274
 
275
          end if;
276
 
277
 
278
        when PIO_MEM_ACCESS_WR_READ =>
279
 
280
          -- Now save the selected BRAM B port data out
281
 
282
          pre_wr_data <= w_pre_wr_data;
283
          write_en <= '0';
284
          wr_mem_state <= PIO_MEM_ACCESS_WR_WRITE;
285
 
286
        when PIO_MEM_ACCESS_WR_WRITE =>
287
 
288
          -- Merge new enabled data and write target BlockRAM location
289
 
290
          post_wr_data <= w_wr_data3_int &
291
                          w_wr_data2_int &
292
                          w_wr_data1_int &
293
                          w_wr_data0_int;
294
          write_en     <= '1';
295
          wr_mem_state <= PIO_MEM_ACCESS_WR_RST;
296
 
297
       when others => null;
298
 
299
     end case;
300
 
301
   end if;
302
 
303
end if;
304
 
305
end process;
306
 
307
-- Write controller busy
308
 
309
wr_busy_o <= wr_en_i or interim;
310
 
311
interim <= '1' when (wr_mem_state /= PIO_MEM_ACCESS_WR_RST) else '0';
312
 
313
-- Select BlockRAM output based on higher 2 address bits
314
process(wr_addr_i, pre_wr_data0_q, pre_wr_data1_q, pre_wr_data2_q,
315
        pre_wr_data3_q)
316
 
317
begin
318
 
319
  case (wr_addr_i(10 downto 9)) is
320
 
321
    when "00" => w_pre_wr_data <= pre_wr_data0_q;
322
    when "01" => w_pre_wr_data <= pre_wr_data1_q;
323
    when "10" => w_pre_wr_data <= pre_wr_data2_q;
324
    when "11" => w_pre_wr_data <= pre_wr_data3_q;
325
    when others => null;
326
 
327
  end case;
328
 
329
end process;
330
 
331
 
332
-- Memory Read Controller
333
 
334
rd_data0_en <= '1' when (rd_addr_i(10 downto 9) = "00") else '0';
335
rd_data1_en <= '1' when (rd_addr_i(10 downto 9) = "01") else '0';
336
rd_data2_en <= '1' when (rd_addr_i(10 downto 9) = "10") else '0';
337
rd_data3_en <= '1' when (rd_addr_i(10 downto 9) = "11") else '0';
338
 
339
-- pipeline stage BRAM read data before processing --
340
 
341
process(rst_n, clk)
342
begin
343
 
344
  if ( rst_n = '0' ) then
345
 
346
    rd_data0_q <= (others => '0');
347
    rd_data1_q <= (others => '0');
348
    rd_data2_q <= (others => '0');
349
    rd_data3_q <= (others => '0');
350
 
351
  else
352
 
353
    if (clk'event and clk='1') then
354
 
355
      rd_data0_q <= rd_data0_o(31 downto 0);
356
      rd_data1_q <= rd_data1_o(31 downto 0);
357
      rd_data2_q <= rd_data2_o(31 downto 0);
358
      rd_data3_q <= rd_data3_o(31 downto 0);
359
 
360
    end if;
361
 
362
  end if;
363
 
364
end process;
365
 
366
process(rd_addr_i(10 downto 0), rd_data0_q(31 downto 0), rd_data1_q(31 downto 0),
367
        rd_data2_q(31 downto 0), rd_data3_q(31 downto 0))
368
begin
369
 
370
  case (rd_addr_i(10 downto 9)) is
371
 
372
    when "00" => rd_data_raw_o  <= rd_data0_q(31 downto 0);
373
    when "01" => rd_data_raw_o <= rd_data1_q(31 downto 0);
374
    when "10" => rd_data_raw_o <= rd_data2_q(31 downto 0);
375
    when "11" => rd_data_raw_o <= rd_data3_q(31 downto 0);
376
    when others => null;
377
 
378
  end case;
379
 
380
end process;
381
 
382
-- Handle Read byte enables  --
383
 
384
rd_data_o        <= rd_data_raw_int0 &
385
                    rd_data_raw_int1 &
386
                    rd_data_raw_int2 &
387
                    rd_data_raw_int3 ;
388
 
389
rd_data_raw_int0 <= rd_data_raw_o(7 downto 0) when (rd_be_i(0) = '1') else (others => '0');
390
rd_data_raw_int1 <= rd_data_raw_o(15 downto 8) when (rd_be_i(1) = '1') else (others => '0');
391
rd_data_raw_int2 <= rd_data_raw_o(23 downto 16) when (rd_be_i(2) = '1') else (others => '0');
392
rd_data_raw_int3 <= rd_data_raw_o (31 downto 24) when (rd_be_i(3) = '1') else (others => '0');
393
 
394
b_wr_en_0        <= write_en and b_wr_en_0_int;
395
b_wr_en_0_int    <= '1' when (wr_addr_i(10 downto 9) = "00") else '0';
396
 
397
b_wr_en_1        <= write_en and b_wr_en_1_int;
398
b_wr_en_1_int    <= '1' when (wr_addr_i(10 downto 9) = "01") else '0';
399
 
400
b_wr_en_2        <= write_en and b_wr_en_2_int;
401
b_wr_en_2_int    <= '1' when (wr_addr_i(10 downto 9) = "10") else '0';
402
 
403
b_wr_en_3        <= write_en and b_wr_en_3_int;
404
b_wr_en_3_int    <= '1' when (wr_addr_i(10 downto 9) = "11") else '0';
405
 
406
wr_addr_0        <= '1' when (wr_addr_i(10 downto 9) = "00") else '0';
407
wr_addr_1        <= '1' when (wr_addr_i(10 downto 9) = "01") else '0';
408
wr_addr_2        <= '1' when (wr_addr_i(10 downto 9) = "10") else '0';
409
wr_addr_3        <= '1' when (wr_addr_i(10 downto 9) = "11") else '0';
410
 
411
 
412
EP_MEM_inst : EP_MEM  port map (
413
 
414
  clk_i => clk,
415
 
416
  a_rd_a_i_0 => rd_addr_i(8 downto 0),       -- I [8:0]
417
  a_rd_en_i_0 => rd_data0_en,                -- I [1:0]
418
  a_rd_d_o_0 => rd_data0_o,                  -- O [31:0]
419
 
420
  b_wr_a_i_0 => wr_addr_i(8 downto 0),       -- I [8:0]
421
  b_wr_d_i_0 => post_wr_data,                -- I [31:0]
422
  b_wr_en_i_0 => b_wr_en_0, --{write_en & (wr_addr_i[10:9] == 2'b00)}), -- I
423
  b_rd_d_o_0 => w_pre_wr_data0(31 downto 0),        -- O [31:0]
424
  b_rd_en_i_0 => wr_addr_0, --{wr_addr_i[10:9] == 2'b00}), -- I
425
 
426
  a_rd_a_i_1 => rd_addr_i(8 downto 0),       -- I [8:0]
427
  a_rd_en_i_1 => rd_data1_en,                -- I [1:0]
428
  a_rd_d_o_1 => rd_data1_o,                  -- O [31:0]
429
 
430
  b_wr_a_i_1 => wr_addr_i(8 downto 0),       -- [8:0]
431
  b_wr_d_i_1 => post_wr_data,                -- [31:0]
432
  b_wr_en_i_1 => b_wr_en_1, --{write_en & (wr_addr_i[10:9] == 2'b01)}), -- I
433
  b_rd_d_o_1 => w_pre_wr_data1(31 downto 0),        -- [31:0]
434
  b_rd_en_i_1 => wr_addr_1, --{wr_addr_i[10:9] == 2'b01}), -- I
435
 
436
  a_rd_a_i_2 => rd_addr_i(8 downto 0),       -- I [8:0]
437
  a_rd_en_i_2 => rd_data2_en,                -- I [1:0]
438
  a_rd_d_o_2 => rd_data2_o,                  -- O [31:0]
439
 
440
  b_wr_a_i_2 => wr_addr_i(8 downto 0),       -- I [8:0]
441
  b_wr_d_i_2 => post_wr_data,                -- I [31:0]
442
  b_wr_en_i_2 => b_wr_en_2, --{write_en & (wr_addr_i[10:9] == 2'b10)}), -- I
443
  b_rd_d_o_2 => w_pre_wr_data2(31 downto 0),        -- I [31:0]
444
  b_rd_en_i_2 => wr_addr_2, --{wr_addr_i[10:9] == 2'b10}), -- I
445
 
446
  a_rd_a_i_3 => rd_addr_i(8 downto 0),       -- [8:0]
447
  a_rd_en_i_3 => rd_data3_en,                -- [1:0]
448
  a_rd_d_o_3 => rd_data3_o,                  -- O [31:0]
449
 
450
  b_wr_a_i_3 => wr_addr_i(8 downto 0),       -- I [8:0]
451
  b_wr_d_i_3 => post_wr_data,                -- I [31:0]
452
  b_wr_en_i_3 => b_wr_en_3, --{write_en & (wr_addr_i(10 downto 9) == 2'b11)}), -- I
453
  b_rd_d_o_3 => w_pre_wr_data3(31 downto 0),        -- I [31:0]
454
  b_rd_en_i_3 => wr_addr_3 --{wr_addr_i[10:9] == 2'b11}  -- I
455
 
456
);
457
 
458
end; -- PIO_EP_MEM_ACCESS
459
 

powered by: WebSVN 2.1.0

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