DS_DMA
|
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