DS_DMA
pcie_src/pcie_core64_m1/source_s6/pcie_brams_s6.vhd
00001 -------------------------------------------------------------------------------
00002 --
00003 -- (c) Copyright 2008, 2009 Xilinx, Inc. All rights reserved.
00004 --
00005 -- This file contains confidential and proprietary information
00006 -- of Xilinx, Inc. and is protected under U.S. and
00007 -- international copyright and other intellectual property
00008 -- laws.
00009 --
00010 -- DISCLAIMER
00011 -- This disclaimer is not a license and does not grant any
00012 -- rights to the materials distributed herewith. Except as
00013 -- otherwise provided in a valid license issued to you by
00014 -- Xilinx, and to the maximum extent permitted by applicable
00015 -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
00016 -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
00017 -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
00018 -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
00019 -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
00020 -- (2) Xilinx shall not be liable (whether in contract or tort,
00021 -- including negligence, or under any other theory of
00022 -- liability) for any loss or damage of any kind or nature
00023 -- related to, arising under or in connection with these
00024 -- materials, including for any direct, or any indirect,
00025 -- special, incidental, or consequential loss or damage
00026 -- (including loss of data, profits, goodwill, or any type of
00027 -- loss or damage suffered as a result of any action brought
00028 -- by a third party) even if such damage or loss was
00029 -- reasonably foreseeable or Xilinx had been advised of the
00030 -- possibility of the same.
00031 --
00032 -- CRITICAL APPLICATIONS
00033 -- Xilinx products are not designed or intended to be fail-
00034 -- safe, or for use in any application requiring fail-safe
00035 -- performance, such as life-support or safety devices or
00036 -- systems, Class III medical devices, nuclear facilities,
00037 -- applications related to the deployment of airbags, or any
00038 -- other applications that could lead to death, personal
00039 -- injury, or severe property or environmental damage
00040 -- (individually and collectively, "Critical
00041 -- Applications"). Customer assumes the sole risk and
00042 -- liability of any use of Xilinx products in Critical
00043 -- Applications, subject only to applicable laws and
00044 -- regulations governing limitations on product liability.
00045 --
00046 -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
00047 -- PART OF THIS FILE AT ALL TIMES.
00048 --
00049 -------------------------------------------------------------------------------
00050 -- Project    : Spartan-6 Integrated Block for PCI Express
00051 -- File       : pcie_brams_s6.vhd
00052 -- Description: BlockRAM module for Spartan-6 PCIe Block
00053 --
00054 --              Arranges and connects brams
00055 --              Implements address decoding, datapath muxing and
00056 --              pipeline stages
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_s6 is
00065   generic (
00066     -- the number of BRAMs to use
00067     -- supported values are:
00068     -- 1,2,4,9
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   port (
00098     user_clk_i          : in std_logic;
00099     reset_i             : in std_logic;
00100     wen                 : in std_logic;
00101     waddr               : in std_logic_vector(11 downto 0);
00102     wdata               : in std_logic_vector(35 downto 0);
00103     ren                 : in std_logic;
00104     rce                 : in std_logic;
00105     raddr               : in std_logic_vector(11 downto 0);
00106     rdata               : out std_logic_vector(35 downto 0)
00107   );
00108 end pcie_brams_s6;
00109 
00110 architecture rtl of pcie_brams_s6 is
00111 
00112   constant TCQ : time := 1 ns;  -- Clock-to-out delay to be modeled
00113 
00114   -- Turn on the bram output register
00115   function CALC_DOB_REG(constant RAM_RDATA_LATENCY : in integer) return integer is
00116     variable DOB_REG : integer;
00117   begin
00118     if   (RAM_RDATA_LATENCY > 1) then DOB_REG := 1;
00119     else                              DOB_REG := 0;
00120     end if;
00121     return DOB_REG;
00122   end function CALC_DOB_REG;
00123 
00124   -- Calculate the data width of the individual BRAMs
00125   function CALC_WIDTH(constant NUM_BRAMS : in integer) return integer is
00126     variable WIDTH : integer;
00127   begin
00128     if    (NUM_BRAMS = 1) then WIDTH := 36;
00129     elsif (NUM_BRAMS = 2) then WIDTH := 18;
00130     elsif (NUM_BRAMS = 4) then WIDTH := 9;
00131     else                       WIDTH := 4; -- NUM_BRAMS = 9
00132     end if;
00133     return WIDTH;
00134   end function CALC_WIDTH;
00135 
00136   component pcie_bram_s6 is
00137   generic (
00138     DOB_REG           : integer;
00139     WIDTH             : integer
00140   );
00141   port (
00142     user_clk_i : in std_logic;
00143     reset_i    : in std_logic;
00144 
00145     wen_i      : in std_logic;
00146     waddr_i    : in std_logic_vector(11 downto 0);
00147     wdata_i    : in std_logic_vector(CALC_WIDTH(NUM_BRAMS)-1 downto 0);
00148 
00149     ren_i      : in std_logic;
00150     rce_i      : in std_logic;
00151     raddr_i    : in std_logic_vector(11 downto 0);
00152 
00153     rdata_o    : out std_logic_vector(CALC_WIDTH(NUM_BRAMS)-1 downto 0) --  read data
00154   );
00155   end component;
00156 
00157   -- Model the delays for RAM write latency
00158   signal wen_int   : std_logic;
00159   signal waddr_int : std_logic_vector(11 downto 0);
00160   signal wdata_int : std_logic_vector(35 downto 0);
00161 
00162   signal wen_dly   : std_logic;
00163   signal waddr_dly : std_logic_vector(11 downto 0);
00164   signal wdata_dly : std_logic_vector(35 downto 0);
00165 
00166   -- Model the delays for RAM read latency
00167   signal ren_int   : std_logic;
00168   signal raddr_int : std_logic_vector(11 downto 0);
00169   signal rdata_int : std_logic_vector(35 downto 0);
00170 
00171   signal ren_dly   : std_logic;
00172   signal raddr_dly : std_logic_vector(11 downto 0);
00173   signal rdata_dly : std_logic_vector(35 downto 0);
00174 
00175 begin
00176 
00177   --synthesis translate_off
00178   process begin
00179     case NUM_BRAMS is
00180       when 1 | 2 | 4 | 9 =>
00181         null;
00182       when others =>
00183         report "Error NUM_BRAMS size " & integer'image(NUM_BRAMS) & " is not supported." severity failure;
00184     end case; -- case NUM_BRAMS
00185 
00186     case RAM_RADDR_LATENCY is
00187       when 0 | 1 =>
00188         null;
00189       when others =>
00190         report "Error RAM_RADDR_LATENCY size " & integer'image(RAM_RADDR_LATENCY) & " is not supported." severity failure;
00191     end case; -- case RAM_RADDR_LATENCY
00192 
00193     case RAM_RDATA_LATENCY is
00194       when 1 | 2 | 3 =>
00195         null;
00196       when others =>
00197         report "Error RAM_RDATA_LATENCY size " & integer'image(RAM_RDATA_LATENCY) & " is not supported." severity failure;
00198     end case; -- case RAM_RDATA_LATENCY
00199 
00200     case RAM_WRITE_LATENCY is
00201       when 0 | 1 =>
00202         null;
00203       when others =>
00204         report "Error RAM_WRITE_LATENCY size " & integer'image(RAM_WRITE_LATENCY) & " is not supported." severity failure;
00205     end case; -- case RAM_WRITE_LATENCY
00206 
00207     wait;
00208   end process;
00209   --synthesis translate_on
00210 
00211   -- 1 stage RAM write pipeline
00212   wr_lat_1 : if(RAM_WRITE_LATENCY = 1) generate
00213     process (user_clk_i) begin
00214       if (user_clk_i'event and user_clk_i = '1') then
00215          if (reset_i = '1') then
00216            wen_dly   <= '0' after TCQ;
00217            waddr_dly <= (others => '0') after TCQ;
00218            wdata_dly <= (others => '0') after TCQ;
00219          else
00220            wen_dly   <= wen after TCQ;
00221            waddr_dly <= waddr after TCQ;
00222            wdata_dly <= wdata after TCQ;
00223          end if;
00224       end if;
00225     end process;
00226 
00227     wen_int <= wen_dly;
00228     waddr_int <= waddr_dly;
00229     wdata_int <= wdata_dly;
00230   end generate wr_lat_1;
00231 
00232   -- No RAM write pipeline
00233   wr_lat_0 : if(RAM_WRITE_LATENCY /= 1) generate
00234     wen_int   <= wen;
00235     waddr_int <= waddr;
00236     wdata_int <= wdata;
00237   end generate wr_lat_0;
00238 
00239 
00240   -- 1 stage RAM read addr pipeline
00241   raddr_lat_1 : if(RAM_RADDR_LATENCY = 1) generate
00242     process (user_clk_i) begin
00243       if (user_clk_i'event and user_clk_i = '1') then
00244         if (reset_i = '1') then
00245           ren_dly   <= '0' after TCQ;
00246           raddr_dly <= (others => '0') after TCQ;
00247         else 
00248           ren_dly   <= ren after TCQ;
00249           raddr_dly <= raddr after TCQ;
00250         end if;
00251       end if;
00252     end process;
00253 
00254     ren_int <= ren_dly;
00255     raddr_int <= raddr_dly;
00256 
00257   end generate raddr_lat_1;
00258 
00259   -- No RAM read addr pipeline
00260   raddr_lat_0 : if(RAM_RADDR_LATENCY /= 1) generate
00261     ren_int   <= ren after TCQ;
00262     raddr_int <= raddr after TCQ;
00263   end generate raddr_lat_0;
00264 
00265   -- 3 stages RAM read data pipeline (first is internal to BRAM)
00266   rdata_lat_3 : if(RAM_RDATA_LATENCY = 3) generate
00267     process (user_clk_i) begin
00268       if (user_clk_i'event and user_clk_i = '1') then
00269         if (reset_i = '1') then
00270           rdata_dly <= (others => '0') after TCQ;
00271         else
00272           rdata_dly <= rdata_int after TCQ;
00273         end if;
00274       end if;
00275     end process;
00276 
00277     rdata <= rdata_dly;
00278 
00279   end generate rdata_lat_3;
00280 
00281   -- 1 or 2 stages RAM read data pipeline
00282   rdata_lat_1_2 : if(RAM_RDATA_LATENCY /= 3) generate
00283     rdata <= rdata_int;
00284   end generate rdata_lat_1_2;
00285 
00286   -- Instantiate BRAM(s)
00287   brams : for i in 0 to (NUM_BRAMS - 1) generate
00288   begin
00289     ram : pcie_bram_s6
00290     generic map (
00291       DOB_REG => CALC_DOB_REG(RAM_RDATA_LATENCY),
00292       WIDTH   => CALC_WIDTH (NUM_BRAMS)
00293     )
00294     port map (
00295       user_clk_i => user_clk_i,
00296       reset_i    => reset_i,
00297       wen_i      => wen_int,
00298       waddr_i    => waddr_int,
00299       wdata_i    => wdata_int((((i + 1) * CALC_WIDTH(NUM_BRAMS)) - 1) downto (i * CALC_WIDTH(NUM_BRAMS))),
00300       ren_i      => ren_int,
00301       rce_i      => rce,
00302       raddr_i    => raddr_int,
00303       rdata_o    => rdata_int((((i + 1) * CALC_WIDTH(NUM_BRAMS)) - 1) downto (i * CALC_WIDTH(NUM_BRAMS)))
00304     );
00305   end generate brams;
00306 
00307 end rtl;
00308