DS_DMA
pcie_src/pcie_core64_m1/source_virtex6/pcie_brams_v6.vhd
00001 
00002 -------------------------------------------------------------------------------
00003 --
00004 -- (c) Copyright 2009-2011 Xilinx, Inc. All rights reserved.
00005 --
00006 -- This file contains confidential and proprietary information
00007 -- of Xilinx, Inc. and is protected under U.S. and
00008 -- international copyright and other intellectual property
00009 -- laws.
00010 --
00011 -- DISCLAIMER
00012 -- This disclaimer is not a license and does not grant any
00013 -- rights to the materials distributed herewith. Except as
00014 -- otherwise provided in a valid license issued to you by
00015 -- Xilinx, and to the maximum extent permitted by applicable
00016 -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
00017 -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
00018 -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
00019 -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
00020 -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
00021 -- (2) Xilinx shall not be liable (whether in contract or tort,
00022 -- including negligence, or under any other theory of
00023 -- liability) for any loss or damage of any kind or nature
00024 -- related to, arising under or in connection with these
00025 -- materials, including for any direct, or any indirect,
00026 -- special, incidental, or consequential loss or damage
00027 -- (including loss of data, profits, goodwill, or any type of
00028 -- loss or damage suffered as a result of any action brought
00029 -- by a third party) even if such damage or loss was
00030 -- reasonably foreseeable or Xilinx had been advised of the
00031 -- possibility of the same.
00032 --
00033 -- CRITICAL APPLICATIONS
00034 -- Xilinx products are not designed or intended to be fail-
00035 -- safe, or for use in any application requiring fail-safe
00036 -- performance, such as life-support or safety devices or
00037 -- systems, Class III medical devices, nuclear facilities,
00038 -- applications related to the deployment of airbags, or any
00039 -- other applications that could lead to death, personal
00040 -- injury, or severe property or environmental damage
00041 -- (individually and collectively, "Critical
00042 -- Applications"). Customer assumes the sole risk and
00043 -- liability of any use of Xilinx products in Critical
00044 -- Applications, subject only to applicable laws and
00045 -- regulations governing limitations on product liability.
00046 --
00047 -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
00048 -- PART OF THIS FILE AT ALL TIMES.
00049 --
00050 -------------------------------------------------------------------------------
00051 -- Project    : Virtex-6 Integrated Block for PCI Express
00052 -- File       : pcie_brams_v6.vhd
00053 -- Version    : 2.3
00054 ---- Description: BlockRAM module for Virtex6 PCIe Block
00055 ----
00056 ----
00057 ----
00058 ----------------------------------------------------------------------------------
00059 
00060 library ieee;
00061    use ieee.std_logic_1164.all;
00062    use ieee.std_logic_unsigned.all;
00063 
00064 entity pcie_brams_v6 is
00065    generic (
00066       -- the number of BRAMs to use
00067       -- supported values are:
00068       -- 1,2,4,8,18
00069       NUM_BRAMS                            : integer := 0;
00070       
00071       -- BRAM read address latency
00072       --
00073       -- value     meaning
00074       -- ====================================================
00075       --   0       BRAM read address port sample
00076       --   1       BRAM read address port sample and a pipeline stage on the address port
00077       RAM_RADDR_LATENCY                    : integer := 1;
00078       
00079       -- BRAM read data latency
00080       --
00081       -- value     meaning
00082       -- ====================================================
00083       --   1       no BRAM OREG
00084       --   2       use BRAM OREG
00085       --   3       use BRAM OREG and a pipeline stage on the data port
00086       RAM_RDATA_LATENCY                    : integer := 1;
00087       
00088       -- BRAM write latency
00089       -- The BRAM write port is synchronous
00090       --
00091       -- value     meaning
00092       -- ====================================================
00093       --   0       BRAM write port sample
00094       --   1       BRAM write port sample plus pipeline stage
00095       RAM_WRITE_LATENCY                    : integer := 1
00096       
00097    );
00098    port (
00099       user_clk_i                           : in std_logic;
00100       reset_i                              : in std_logic;
00101       wen                                  : in std_logic;
00102       waddr                                : in std_logic_vector(12 downto 0);
00103       wdata                                : in std_logic_vector(71 downto 0);
00104       ren                                  : in std_logic;
00105       rce                                  : in std_logic;
00106       raddr                                : in std_logic_vector(12 downto 0);
00107       rdata                                : out std_logic_vector(71 downto 0)
00108    );
00109 end pcie_brams_v6;
00110 
00111 architecture v6_pcie of pcie_brams_v6 is
00112    component pcie_bram_v6 is
00113       generic (
00114          DOB_REG                           : integer;
00115          WIDTH                             : integer
00116       );
00117       port (
00118          user_clk_i                        : in std_logic;
00119          reset_i                           : in std_logic;
00120          wen_i                             : in std_logic;
00121          waddr_i                           : in std_logic_vector(12 downto 0);
00122          wdata_i                           : in std_logic_vector(WIDTH - 1 downto 0);
00123          ren_i                             : in std_logic;
00124          rce_i                             : in std_logic;
00125          raddr_i                           : in std_logic_vector(12 downto 0);
00126          rdata_o                           : out std_logic_vector(WIDTH - 1 downto 0)
00127       );
00128    end component;
00129    
00130    FUNCTION to_integer (
00131       in_val      : IN boolean) RETURN integer IS
00132    BEGIN
00133       IF (in_val) THEN
00134          RETURN(1);
00135       ELSE
00136          RETURN(0);
00137       END IF;
00138    END to_integer;
00139 
00140       -- turn on the bram output register
00141    constant DOB_REG                        : integer := to_integer(RAM_RDATA_LATENCY > 1);
00142       
00143       -- calculate the data width of the individual brams
00144   function width (
00145     constant NUM_BRAM   : integer)
00146     return integer is
00147      variable WIDTH_BRAM : integer := 1;
00148   begin  -- width
00149 
00150     if (NUM_BRAM = 1) then
00151       WIDTH_BRAM := 72;
00152     elsif (NUM_BRAM = 2) then
00153       WIDTH_BRAM := 36;
00154     elsif (NUM_BRAM = 4) then
00155       WIDTH_BRAM := 18;
00156     elsif (NUM_BRAM = 8) then
00157       WIDTH_BRAM := 9;
00158     else
00159       WIDTH_BRAM := 4;
00160     end if;
00161     return WIDTH_BRAM;
00162   end width;
00163 
00164    constant BRAM_WIDTH : integer := width(NUM_BRAMS);
00165 
00166    constant TCQ                            : integer := 1;
00167 
00168    
00169    signal wen_int                          : std_logic;
00170    signal waddr_int                        : std_logic_vector(12 downto 0);
00171    signal wdata_int                        : std_logic_vector(71 downto 0);
00172    
00173    signal wen_dly                          : std_logic := '0';
00174    signal waddr_dly                        : std_logic_vector(12 downto 0) := (others => '0');
00175    signal wdata_dly                        : std_logic_vector(71 downto 0) := (others => '0');
00176    
00177    -- if (RAM_WRITE_LATENCY == 1)
00178    
00179    -- model the delays for ram read latency
00180    
00181    signal ren_int                          : std_logic;
00182    signal raddr_int                        : std_logic_vector(12 downto 0);
00183    signal rdata_int                        : std_logic_vector(71 downto 0);
00184 
00185    signal ren_dly                          : std_logic;
00186    signal raddr_dly                        : std_logic_vector(12 downto 0);
00187    signal rdata_dly                        : std_logic_vector(71 downto 0);
00188 
00189 begin
00190    
00191    --synthesis translate_off
00192    process 
00193    begin
00194       -- $display("[%t] %m NUM_BRAMS %0d  DOB_REG %0d WIDTH %0d RAM_WRITE_LATENCY %0d RAM_RADDR_LATENCY %0d RAM_RDATA_LATENCY %0d", now, to_stdlogic(NUM_BRAMS), to_stdlogicvector(DOB_REG, 13), ("00000000000000000000000000000000000000000000000000000000000000000" & WIDTH), to_stdlogic(RAM_WRITE_LATENCY), to_stdlogic(RAM_RADDR_LATENCY), to_stdlogicvector(RAM_RDATA_LATENCY, 13));
00195       case NUM_BRAMS is
00196          when 1 | 2 | 4 | 8 | 18 =>
00197          when others =>
00198             -- $display("[%t] %m Error NUM_BRAMS %0d not supported", now, to_stdlogic(NUM_BRAMS));
00199             -- $finish();
00200       end case;   -- case(NUM_BRAMS)
00201       case RAM_RADDR_LATENCY is
00202          when 0 | 1 =>
00203          when others =>
00204             -- $display("[%t] %m Error RAM_READ_LATENCY %0d not supported", now, to_stdlogic(RAM_RADDR_LATENCY));
00205             -- $finish();
00206       end case;   -- case (RAM_RADDR_LATENCY)
00207       case RAM_RDATA_LATENCY is
00208          when 1 | 2 | 3 =>
00209          when others =>
00210             -- $display("[%t] %m Error RAM_READ_LATENCY %0d not supported", now, to_stdlogic(RAM_RDATA_LATENCY));
00211             -- $finish();
00212       end case;   -- case (RAM_RDATA_LATENCY)
00213       case RAM_WRITE_LATENCY is
00214          when 0 | 1 =>
00215          when others =>
00216             -- $display("[%t] %m Error RAM_WRITE_LATENCY %0d not supported", now, to_stdlogic(RAM_WRITE_LATENCY));
00217             -- $finish();
00218       end case;   -- case(RAM_WRITE_LATENCY)
00219       wait;
00220    end process;
00221    --synthesis translate_on
00222    
00223    -- model the delays for ram write latency
00224    wr_lat_2 : if (RAM_WRITE_LATENCY = 1) generate
00225       process (user_clk_i)
00226       begin
00227          if (user_clk_i'event and user_clk_i = '1') then
00228             if (reset_i = '1') then
00229                wen_dly <= '0' after (TCQ)*1 ps;
00230                waddr_dly <= "0000000000000" after (TCQ)*1 ps;
00231                wdata_dly <= "000000000000000000000000000000000000000000000000000000000000000000000000" after (TCQ)*1 ps;
00232             else
00233                wen_dly <= wen after (TCQ)*1 ps;
00234                waddr_dly <= waddr after (TCQ)*1 ps;
00235                wdata_dly <= wdata after (TCQ)*1 ps;
00236             end if;
00237          end if;
00238       end process;
00239       
00240       wen_int <= wen_dly;
00241       waddr_int <= waddr_dly;
00242       wdata_int <= wdata_dly;
00243    end generate;
00244 
00245    wr_lat_1 : if (RAM_WRITE_LATENCY = 0) generate
00246       wen_int <= wen;
00247       waddr_int <= waddr;
00248       wdata_int <= wdata;
00249    end generate;
00250    
00251    raddr_lat_2 : if (RAM_RADDR_LATENCY = 1) generate
00252       
00253       process (user_clk_i)
00254       begin
00255          if (user_clk_i'event and user_clk_i = '1') then
00256             if (reset_i = '1') then
00257                ren_dly <= '0' after (TCQ)*1 ps;
00258                raddr_dly <= "0000000000000" after (TCQ)*1 ps;
00259             else
00260                ren_dly <= ren after (TCQ)*1 ps;
00261                raddr_dly <= raddr after (TCQ)*1 ps;
00262             end if;             -- else: !if(reset_i)
00263          end if;
00264       end process;
00265 
00266       ren_int <= ren_dly;
00267       raddr_int <= raddr_dly;
00268 
00269    end generate;      -- block: rd_lat_addr_2
00270    
00271    raddr_lat_1 : if (not(RAM_RADDR_LATENCY = 1)) generate
00272       ren_int <= ren;
00273       raddr_int <= raddr;
00274    end generate;
00275    
00276    rdata_lat_3 : if (RAM_RDATA_LATENCY = 3) generate
00277       
00278       process (user_clk_i)
00279       begin
00280          if (user_clk_i'event and user_clk_i = '1') then
00281             if (reset_i = '1') then
00282                rdata_dly <= "000000000000000000000000000000000000000000000000000000000000000000000000" after (TCQ)*1 ps;
00283             else
00284                rdata_dly <= rdata_int after (TCQ)*1 ps;
00285             end if;             -- else: !if(reset_i)
00286          end if;
00287       end process;
00288 
00289       rdata <= rdata_dly;
00290 
00291    end generate;      -- block: rd_lat_data_3
00292 
00293    rdata_lat_1_2 : if (not(RAM_RDATA_LATENCY = 3)) generate
00294       rdata <= rdata_int after (TCQ)*1 ps;
00295    end generate;
00296    
00297    -- instantiate the brams
00298    brams : for i in 0 to  NUM_BRAMS - 1 generate
00299 
00300      ram : pcie_bram_v6
00301          generic map (
00302             DOB_REG  => DOB_REG,
00303             WIDTH    => BRAM_WIDTH
00304          )
00305          port map (
00306             user_clk_i  => user_clk_i,
00307             reset_i     => reset_i,
00308             wen_i       => wen_int,
00309             waddr_i     => waddr_int,
00310             wdata_i      => wdata_int((((i + 1) * BRAM_WIDTH) - 1) downto (i * BRAM_WIDTH)),
00311             ren_i        => ren_int,
00312             raddr_i     => raddr_int,
00313             rdata_o      => rdata_int((((i + 1) * BRAM_WIDTH) - 1) downto (i * BRAM_WIDTH)),
00314             rce_i       => rce
00315          );
00316    end generate;
00317                 -- pcie_brams_v6
00318 end v6_pcie;
00319 
00320