-- PROJECT: D0 Run IIb Trigger L1 Calorimeter upgrade -- -- MODULE: RS232 to generic bus converter -- -- ELEMENT: RAM -- -- DESCRIPTION: simple RAM to test RS232 to generic bus converter -- -- synchronous RAM with acknowledge and separate data in and out busses -- -- AUTHOR: J.Marquet marquet@efrei.fr -- -- DATE AND HISTORY: -- July 2004: created -- September 2004: revised by D. Calvet -- RAM supports 8, 16 or 32 bit wide data bus -- individual bytes are addressed by DBE_B pattern -- the number of memory locations can be smaller than 2**ADDR_BUS_SIZE. -- For access outside the memory array, the RAM is unaffected and -- acknowlegde is not asserted. -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; library work; use work.utility_pkg.all; use work.constant_package.all; -- -- RAM -- entity RAM is generic ( ADDR_BUS_SIZE : integer := 12; DATA_BUS_SIZE : integer := 8; RAM_SIZE : integer := 4096 ); port ( RESET : in std_logic; -- Asynch. RESET CLK : in std_logic; -- Clock ADDR : in std_logic_vector(ADDR_BUS_SIZE-1 downto 0); -- address bus DBE_B : in std_logic_vector(3 downto 0); -- byte selection WE : in std_logic; -- active high write enable CS_B : in std_logic; -- active low chip select DATA_OUT : out std_logic_vector(DATA_BUS_SIZE-1 downto 0); -- data bus output (read) DATA_IN : in std_logic_vector(DATA_BUS_SIZE-1 downto 0); -- data bus input (write) DTACK_B : out std_logic -- active low transfer acknowledge ); end RAM; Architecture behavioral of RAM is subtype byte is std_logic_vector(7 downto 0); type Mem is array (0 to (RAM_SIZE-1)) of byte; begin Run_RAM : process (RESET,CLK) variable Memory : Mem; variable addr_base : std_logic_vector(ADDR_BUS_SIZE-1 downto 0); variable address_n : natural; variable i, j : integer; begin if RESET = '1' then DTACK_B <= '1'; DATA_OUT <= (others => '0'); for i in 0 to (RAM_SIZE-1) loop Memory(i) := (others => '0'); end loop; elsif (rising_edge(CLK)) then if (CS_B ='0') then addr_base := ADDR(ADDR_BUS_SIZE-1 downto 2) & "00"; address_n := std_logic_vector_to_natural(addr_base); if address_n < RAM_SIZE then j := DATA_BUS_SIZE; for i in 0 to 3 loop if DBE_B(i) = '0' then if WE = '0' then DATA_OUT(j-1 downto j-8) <= Memory(address_n); else Memory(address_n):= DATA_IN(j-1 downto j-8); end if; end if; j := j - 8; if j = 0 then j := DATA_BUS_SIZE; end if; address_n := address_n + 1; DTACK_B <= '0' ; end loop; else DTACK_B <= '1'; end if; else DTACK_B <= '1'; end if; end if; end process; end behavioral;