DS_DMA
|
00001 ------------------------------------------------------------------------------- 00002 -- 00003 -- (c) Copyright 2009-2011 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 : Virtex-6 Integrated Block for PCI Express 00051 -- File : pcie_bram_v6.vhd 00052 -- Version : 2.3 00053 -- 00054 -- Description: BlockRAM module for Virtex6 PCIe Block 00055 -- 00056 -------------------------------------------------------------------------------- 00057 00058 library ieee; 00059 use ieee.std_logic_1164.all; 00060 use ieee.std_logic_unsigned.all; 00061 00062 library unisim; 00063 use unisim.vcomponents.all; 00064 00065 entity pcie_bram_v6 is 00066 generic ( 00067 DOB_REG : integer := 0; -- 1 use the output register 0 don't use the output register 00068 WIDTH : integer := 0 -- supported WIDTH's are: 4, 9, 18, 36 (uses RAMB36) and 72 (uses RAMB36SDP) 00069 ); 00070 port ( 00071 00072 user_clk_i : in std_logic; -- user clock 00073 reset_i : in std_logic; -- bram reset 00074 wen_i : in std_logic; -- write enable 00075 waddr_i : in std_logic_vector(12 downto 0); -- write address 00076 wdata_i : in std_logic_vector(WIDTH - 1 downto 0); -- write data 00077 ren_i : in std_logic; -- read enable 00078 rce_i : in std_logic; -- output register clock enable 00079 raddr_i : in std_logic_vector(12 downto 0); -- read address 00080 rdata_o : out std_logic_vector(WIDTH - 1 downto 0) -- read data 00081 ); 00082 end pcie_bram_v6; 00083 00084 architecture v6_pcie of pcie_bram_v6 is 00085 00086 -- map the address bits 00087 function msb_addr ( 00088 constant wdt : integer) 00089 return integer is 00090 variable addr_msb : integer := 8; 00091 begin -- msb_addr 00092 00093 if (wdt = 4) then 00094 addr_msb := 12; 00095 elsif (wdt = 9) then 00096 addr_msb := 11; 00097 elsif (wdt = 18) then 00098 addr_msb := 10; 00099 elsif (wdt = 36) then 00100 addr_msb := 9; 00101 else 00102 addr_msb := 8; 00103 end if; 00104 return addr_msb; 00105 end msb_addr; 00106 00107 constant ADDR_MSB : integer := msb_addr(WIDTH); 00108 00109 -- set the width of the tied off low address bits 00110 function alb ( 00111 constant wdt : integer) 00112 return integer is 00113 variable addr_lo_bit : integer := 8; 00114 begin -- alb 00115 00116 if (wdt = 4) then 00117 addr_lo_bit := 2; 00118 elsif (wdt = 9) then 00119 addr_lo_bit := 3; 00120 elsif (wdt = 18) then 00121 addr_lo_bit := 4; 00122 elsif (wdt = 36) then 00123 addr_lo_bit := 5; 00124 else 00125 addr_lo_bit := 0; -- for WIDTH 72 use RAMB36SDP 00126 end if; 00127 return addr_lo_bit; 00128 end alb; 00129 00130 constant ADDR_LO_BITS : integer := alb(WIDTH); 00131 00132 -- map the data bits 00133 function msb_d ( 00134 constant wdt : integer) 00135 return integer is 00136 variable dmsb : integer := 8; 00137 begin -- msb_d 00138 00139 if (wdt = 4) then 00140 dmsb := 3; 00141 elsif (wdt = 9) then 00142 dmsb := 7; 00143 elsif (wdt = 18) then 00144 dmsb := 15; 00145 elsif (wdt = 36) then 00146 dmsb := 31; 00147 else 00148 dmsb := 63; 00149 end if; 00150 return dmsb; 00151 end msb_d; 00152 00153 constant D_MSB : integer := msb_d(WIDTH); 00154 00155 -- map the data parity bits 00156 constant DP_LSB : integer := D_MSB + 1; 00157 00158 function msb_dp ( 00159 constant wdt : integer) 00160 return integer is 00161 variable dpmsb : integer := 8; 00162 begin -- msb_dp 00163 00164 if (wdt = 4) then 00165 dpmsb := 4; 00166 elsif (wdt = 9) then 00167 dpmsb := 8; 00168 elsif (wdt = 18) then 00169 dpmsb := 17; 00170 elsif (wdt = 36) then 00171 dpmsb := 35; 00172 else 00173 dpmsb := 71; 00174 end if; 00175 return dpmsb; 00176 end msb_dp; 00177 00178 function pad_val ( 00179 in_vec : std_logic_vector; 00180 range_hi : integer; 00181 range_lo : integer; 00182 pad : std_logic; 00183 op_len : integer) 00184 return std_logic_vector is 00185 variable ret : std_logic_vector(op_len-1 downto 0) := (others => '0'); 00186 begin -- pad_val 00187 for i in 0 to op_len-1 loop 00188 if ((i >= range_lo) and (i <= range_hi)) then 00189 ret(i) := in_vec(i - range_lo); 00190 else 00191 ret(i) := pad; 00192 end if; 00193 end loop; -- i 00194 return ret; 00195 end pad_val; 00196 00197 constant DP_MSB : integer := msb_dp(WIDTH); 00198 00199 constant DPW : integer := DP_MSB - DP_LSB + 1; 00200 00201 constant WRITE_MODE : string := "NO_CHANGE"; 00202 00203 -- ground and tied_to_vcc_i signals 00204 signal tied_to_ground_i : std_logic; 00205 signal tied_to_ground_vec_i : std_logic_vector(31 downto 0); 00206 signal tied_to_vcc_i : std_logic; 00207 00208 00209 -- X-HDL generated signals 00210 00211 signal v6pcie2 : std_logic_vector(7 downto 0) := (others => '0'); 00212 signal v6pcie5 : std_logic_vector(15 downto 0) := (others => '0'); 00213 signal v6pcie7 : std_logic_vector(15 downto 0) := (others => '0'); 00214 signal v6pcie11 : std_logic_vector(31 downto 0) := (others => '0'); 00215 signal v6pcie12 : std_logic_vector(3 downto 0) := (others => '0'); 00216 signal v6pcie15 : std_logic_vector(63 downto 0) := (others => '0'); 00217 signal v6pcie16 : std_logic_vector(7 downto 0) := (others => '0'); 00218 signal v6pcie13 : std_logic_vector((DP_MSB - DP_LSB) downto 0) := (others => '0'); 00219 00220 -- dob_unused and dopb_unused only needed when WIDTH < 36. how to declare 00221 -- these accordingly. 00222 signal dob_unused : std_logic_vector(31 - D_MSB - 1 downto 0); 00223 signal dopb_unused : std_logic_vector(4 - DPW - 1 downto 0); 00224 00225 00226 -- Declare intermediate signals for referenced outputs 00227 signal rdata_o_v6pcie0 : std_logic_vector(WIDTH - 1 downto 0); 00228 00229 begin 00230 00231 --------------------------- Static signal Assignments --------------------- 00232 00233 tied_to_ground_i <= '0'; 00234 tied_to_ground_vec_i(31 downto 0) <= (others => '0'); 00235 tied_to_vcc_i <= '1'; 00236 00237 -- Drive referenced outputs 00238 rdata_o <= rdata_o_v6pcie0; 00239 00240 --synthesis translate_off 00241 process 00242 begin 00243 --$display("[%t] %m DOB_REG %0d WIDTH %0d ADDR_MSB %0d ADDR_LO_BITS %0d DP_MSB %0d DP_LSB %0d D_MSB %0d", 00244 -- $time, DOB_REG, WIDTH, ADDR_MSB, ADDR_LO_BITS, DP_MSB, DP_LSB, D_MSB); 00245 00246 case WIDTH is 00247 when 4 | 9 | 18 | 36 | 72 => 00248 when others => -- case (WIDTH) 00249 -- $display("[%t] %m Error WIDTH %0d not supported", now, to_stdlogic(WIDTH)); 00250 -- $finish(); 00251 end case; 00252 wait; 00253 end process; 00254 00255 --synthesis translate_on 00256 00257 use_ramb36sdp : if (WIDTH = 72) generate 00258 00259 v6pcie2 <= (others => wen_i); 00260 rdata_o_v6pcie0 <= v6pcie16((DP_MSB - DP_LSB) downto 0) & v6pcie15(D_MSB downto 0); 00261 00262 -- use RAMB36SDP if the width is 72 00263 ramb36sdp_i : RAMB36SDP 00264 generic map ( 00265 DO_REG => DOB_REG 00266 ) 00267 port map ( 00268 DBITERR => open, 00269 ECCPARITY => open, 00270 SBITERR => open, 00271 WRCLK => user_clk_i , 00272 SSR => '0', 00273 WRADDR => waddr_i(ADDR_MSB downto 0), 00274 DI => wdata_i(D_MSB downto 0), 00275 DIP => wdata_i(DP_MSB downto DP_LSB), 00276 WREN => wen_i, 00277 WE => v6pcie2, 00278 00279 RDCLK => user_clk_i, 00280 RDADDR => raddr_i(ADDR_MSB downto 0), 00281 DO => v6pcie15, 00282 DOP => v6pcie16, 00283 RDEN => ren_i, 00284 REGCE => rce_i 00285 ); 00286 00287 -- use RAMB36's if the width is 4, 9, 18, or 36 00288 end generate; 00289 use_ramb36_1 : if (WIDTH = 36) generate 00290 00291 v6pcie2 <= (others => wen_i); 00292 v6pcie5 <= pad_val(waddr_i(ADDR_MSB downto 0), ADDR_MSB + ADDR_LO_BITS, ADDR_LO_BITS, '1', 16); 00293 v6pcie7 <= pad_val(raddr_i(ADDR_MSB downto 0), ADDR_MSB + ADDR_LO_BITS, ADDR_LO_BITS, '1', 16); 00294 rdata_o_v6pcie0 <= v6pcie16((DP_MSB - DP_LSB) downto 0) & v6pcie15(D_MSB downto 0); 00295 00296 ramb36_i : RAMB36 00297 generic map ( 00298 DOA_REG => 0, 00299 DOB_REG => DOB_REG, 00300 READ_WIDTH_A => 0, 00301 READ_WIDTH_B => WIDTH, 00302 WRITE_WIDTH_A => WIDTH, 00303 WRITE_WIDTH_B => 0, 00304 WRITE_MODE_A => WRITE_MODE 00305 ) 00306 port map ( 00307 CLKA => user_clk_i, 00308 SSRA => '0', 00309 REGCEA => '0', 00310 CASCADEINLATA => '0', 00311 CASCADEINREGA => '0', 00312 CASCADEOUTLATA => open, 00313 CASCADEOUTREGA => open, 00314 DOA => open, 00315 DOPA => open, 00316 ADDRA => v6pcie5, 00317 DIA => wdata_i(D_MSB downto 0), 00318 DIPA => wdata_i(DP_MSB downto DP_LSB), 00319 ENA => wen_i, 00320 WEA => v6pcie2(3 downto 0), 00321 CLKB => user_clk_i, 00322 SSRB => '0', 00323 WEB => "0000", 00324 CASCADEINLATB => '0', 00325 CASCADEINREGB => '0', 00326 CASCADEOUTLATB => open, 00327 CASCADEOUTREGB => open, 00328 DIB => "00000000000000000000000000000000", 00329 DIPB => "0000", 00330 ADDRB => v6pcie7, 00331 DOB => v6pcie15(31 downto 0), 00332 DOPB => v6pcie16(3 downto 0), 00333 ENB => ren_i, 00334 REGCEB => rce_i 00335 ); 00336 00337 end generate; 00338 use_ramb36_2 : if (WIDTH < 36 and WIDTH > 4) generate 00339 00340 v6pcie2 <= (others => wen_i); 00341 v6pcie5 <= pad_val(waddr_i(ADDR_MSB downto 0), ADDR_MSB + ADDR_LO_BITS, ADDR_LO_BITS, '1', 16); 00342 v6pcie7 <= pad_val(raddr_i(ADDR_MSB downto 0), ADDR_MSB + ADDR_LO_BITS, ADDR_LO_BITS, '1', 16); 00343 v6pcie11 <= pad_val(wdata_i(D_MSB downto 0), D_MSB, 0, '0', 32); 00344 v6pcie13 <= wdata_i(DP_MSB downto DP_LSB); 00345 v6pcie12 <= pad_val(v6pcie13((DP_MSB - DP_LSB) downto 0), DP_MSB - DP_LSB, 0, '0', 4); 00346 rdata_o_v6pcie0 <= v6pcie16((DP_MSB - DP_LSB) downto 0) & v6pcie15(D_MSB downto 0); 00347 00348 ramb36_i : RAMB36 00349 generic map ( 00350 DOA_REG => 0, 00351 DOB_REG => DOB_REG, 00352 READ_WIDTH_A => 0, 00353 READ_WIDTH_B => WIDTH, 00354 WRITE_WIDTH_A => WIDTH, 00355 WRITE_WIDTH_B => 0, 00356 WRITE_MODE_A => WRITE_MODE 00357 ) 00358 port map ( 00359 CLKA => user_clk_i, 00360 SSRA => '0', 00361 REGCEA => '0', 00362 CASCADEINLATA => '0', 00363 CASCADEINREGA => '0', 00364 CASCADEOUTLATA => open, 00365 CASCADEOUTREGA => open, 00366 DOA => open, 00367 DOPA => open, 00368 ADDRA => v6pcie5, 00369 DIA => v6pcie11, 00370 DIPA => v6pcie12, 00371 ENA => wen_i, 00372 WEA => v6pcie2(3 downto 0), 00373 CLKB => user_clk_i, 00374 SSRB => '0', 00375 WEB => "0000", 00376 CASCADEINLATB => '0', 00377 CASCADEINREGB => '0', 00378 CASCADEOUTLATB => open, 00379 CASCADEOUTREGB => open, 00380 DIB => "00000000000000000000000000000000", 00381 DIPB => "0000", 00382 ADDRB => v6pcie7, 00383 DOB => v6pcie15(31 downto 0), 00384 DOPB => v6pcie16(3 downto 0), 00385 ENB => ren_i, 00386 REGCEB => rce_i 00387 ); 00388 00389 end generate; 00390 use_ramb36_3 : if (WIDTH = 4) generate 00391 00392 v6pcie2 <= (others => wen_i); 00393 v6pcie5 <= pad_val(waddr_i(ADDR_MSB downto 0), ADDR_MSB + ADDR_LO_BITS, ADDR_LO_BITS, '1', 16); 00394 v6pcie7 <= pad_val(raddr_i(ADDR_MSB downto 0), ADDR_MSB + ADDR_LO_BITS, ADDR_LO_BITS, '1', 16); 00395 v6pcie11 <= pad_val(wdata_i(D_MSB downto 0), D_MSB, 0, '0', 32); 00396 rdata_o_v6pcie0 <= v6pcie15(D_MSB downto 0); 00397 00398 ramb36_i : RAMB36 00399 generic map ( 00400 dob_reg => DOB_REG, 00401 read_width_a => 0, 00402 read_width_b => WIDTH, 00403 write_width_a => WIDTH, 00404 write_width_b => 0, 00405 write_mode_a => WRITE_MODE 00406 ) 00407 port map ( 00408 CLKA => user_clk_i, 00409 SSRA => '0', 00410 REGCEA => '0', 00411 CASCADEINLATA => '0', 00412 CASCADEINREGA => '0', 00413 CASCADEOUTLATA => open, 00414 CASCADEOUTREGA => open, 00415 DOA => open, 00416 DOPA => open, 00417 ADDRA => v6pcie5, 00418 DIA => v6pcie11, 00419 DIPA => tied_to_ground_vec_i(3 downto 0), 00420 ENA => wen_i, 00421 WEA => v6pcie2(3 downto 0), 00422 CLKB => user_clk_i, 00423 SSRB => '0', 00424 WEB => "0000", 00425 CASCADEINLATB => '0', 00426 CASCADEINREGB => '0', 00427 CASCADEOUTLATB => open, 00428 CASCADEOUTREGB => open, 00429 ADDRB => v6pcie7, 00430 DIB => tied_to_ground_vec_i, 00431 DIPB => tied_to_ground_vec_i(3 downto 0), 00432 DOB => v6pcie15(31 downto 0), 00433 DOPB => open, 00434 ENB => ren_i, 00435 REGCEB => rce_i 00436 ); 00437 00438 00439 -- block: use_ramb36 00440 end generate; 00441 00442 -- pcie_bram_v6 00443 end v6_pcie; 00444 00445