DS_DMA
pcie_src/pcie_core64_m1/source_s6/pcie_bram_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_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