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_bram_s6.vhd 00052 -- Description: BlockRAM module for Spartan-6 PCIe Block 00053 -- The BRAM A port is the write port. 00054 -- The BRAM B port is the read port. 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_s6 is 00066 generic ( 00067 DOB_REG : integer := 0; -- 1 use output register, 0 don't use output register 00068 WIDTH : integer := 0 -- supported WIDTH values are: 4, 9, 18, 36 00069 ); 00070 port ( 00071 user_clk_i : in std_logic; -- user clock 00072 reset_i : in std_logic; -- bram reset 00073 00074 wen_i : in std_logic; -- write enable 00075 waddr_i : in std_logic_vector(11 downto 0); -- write address 00076 wdata_i : in std_logic_vector(WIDTH-1 downto 0); -- write data 00077 00078 ren_i : in std_logic; -- read enable 00079 rce_i : in std_logic; -- output register clock enable 00080 raddr_i : in std_logic_vector(11 downto 0); -- read address 00081 00082 rdata_o : out std_logic_vector(WIDTH-1 downto 0) -- read data 00083 ); 00084 end pcie_bram_s6; 00085 00086 architecture rtl of pcie_bram_s6 is 00087 00088 function CALC_ADDR(constant WIDTH : in integer; 00089 constant addr_in : in std_logic_vector(11 downto 0) 00090 ) return std_logic_vector is 00091 variable ADDR : std_logic_vector(13 downto 0); 00092 begin 00093 if WIDTH = 4 then ADDR := addr_in(11 downto 0) & "00"; 00094 elsif WIDTH = 9 then ADDR := addr_in(10 downto 0) & "000"; 00095 elsif WIDTH = 18 then ADDR := addr_in(9 downto 0) & "0000"; 00096 else ADDR := addr_in(8 downto 0) & "00000"; -- WIDTH=36 00097 end if; 00098 return ADDR; 00099 end function CALC_ADDR; 00100 00101 signal di_int : std_logic_vector(31 downto 0); 00102 signal dip_int : std_logic_vector(3 downto 0); 00103 signal do_int : std_logic_vector(31 downto 0); 00104 signal dop_int : std_logic_vector(3 downto 0); 00105 signal waddr_int : std_logic_vector(13 downto 0); 00106 signal raddr_int : std_logic_vector(13 downto 0); 00107 signal wen_int : std_logic_vector(3 downto 0); 00108 00109 begin 00110 00111 --synthesis translate_off 00112 process 00113 begin 00114 case WIDTH is 00115 when 4 | 9 | 18 | 36 => 00116 null; 00117 when others => 00118 report "ERROR: WIDTH size " & integer'image(WIDTH) & " is not supported." 00119 severity failure; 00120 end case; 00121 wait; 00122 end process; 00123 --synthesis translate_on 00124 00125 -- Wire up BRAM I/Os to module I/Os - map data & parity bits appropriately 00126 width_36 : if (WIDTH = 36) generate 00127 di_int <= wdata_i(31 downto 0); 00128 dip_int <= wdata_i(35 downto 32); 00129 rdata_o(35 downto 32) <= dop_int; 00130 rdata_o(31 downto 0) <= do_int; 00131 end generate width_36; 00132 00133 width_18 : if (WIDTH = 18) generate 00134 di_int(31 downto 16) <= (OTHERS => '0'); 00135 di_int(15 downto 0) <= wdata_i(15 downto 0); 00136 dip_int(3 downto 2) <= (OTHERS => '0'); 00137 dip_int(1 downto 0) <= wdata_i(17 downto 16); 00138 rdata_o(17 downto 16) <= dop_int(1 downto 0); 00139 rdata_o(15 downto 0) <= do_int(15 downto 0); 00140 end generate width_18; 00141 00142 width_9 : if (WIDTH = 9) generate 00143 di_int(31 downto 8) <= (OTHERS => '0'); 00144 di_int(7 downto 0) <= wdata_i(7 downto 0); 00145 dip_int(3 downto 1) <= (OTHERS => '0'); 00146 dip_int(0) <= wdata_i(8); 00147 rdata_o(8) <= dop_int(0); 00148 rdata_o(7 downto 0) <= do_int(7 downto 0); 00149 end generate width_9; 00150 00151 width_4 : if (WIDTH = 4) generate 00152 di_int(31 downto 4) <= (OTHERS => '0'); 00153 di_int(3 downto 0) <= wdata_i(3 downto 0); 00154 dip_int <= (OTHERS => '0'); 00155 rdata_o <= do_int(3 downto 0); 00156 end generate width_4; 00157 00158 waddr_int <= CALC_ADDR(WIDTH, waddr_i); 00159 raddr_int <= CALC_ADDR(WIDTH, raddr_i); 00160 wen_int <= wen_i & wen_i & wen_i & wen_i; 00161 00162 ramb16 : RAMB16BWER 00163 generic map ( 00164 DATA_WIDTH_A => WIDTH, 00165 DATA_WIDTH_B => WIDTH, 00166 DOA_REG => 0, 00167 DOB_REG => DOB_REG, 00168 WRITE_MODE_A => "NO_CHANGE", 00169 WRITE_MODE_B => "NO_CHANGE" 00170 ) 00171 port map ( 00172 CLKA => user_clk_i, 00173 RSTA => reset_i, 00174 DOA => open, 00175 DOPA => open , 00176 ADDRA => waddr_int, 00177 DIA => di_int, 00178 DIPA => dip_int, 00179 ENA => wen_i, 00180 WEA => wen_int, 00181 REGCEA => '0', 00182 00183 CLKB => user_clk_i, 00184 RSTB => reset_i, 00185 WEB => "0000", 00186 DIB => x"00000000", 00187 DIPB => "0000", 00188 ADDRB => raddr_int, 00189 DOB => do_int, 00190 DOPB => dop_int, 00191 ENB => ren_i, 00192 REGCEB => rce_i 00193 ); 00194 00195 end rtl; 00196