-- Single port Block RAM with one cycle output buffer -- -- Simulated via C helpers library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; library work; use work.utils.all; use work.sim_bram_helpers.all; entity main_bram is generic( WIDTH : natural := 64; HEIGHT_BITS : natural := 1024; MEMORY_SIZE : natural := 65536; RAM_INIT_FILE : string ); port( clk : in std_logic; addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ; din : in std_logic_vector(WIDTH-1 downto 0); dout : out std_logic_vector(WIDTH-1 downto 0); sel : in std_logic_vector((WIDTH/8)-1 downto 0); re : in std_ulogic; we : in std_ulogic ); end entity main_bram; architecture sim of main_bram is constant WIDTH_BYTES : natural := WIDTH / 8; constant pad_zeros : std_ulogic_vector(log2(WIDTH_BYTES)-1 downto 0) := (others => '0'); signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE, size => MEMORY_SIZE); -- Others signal obuf : std_logic_vector(WIDTH-1 downto 0); begin -- Actual RAM template memory_0: process(clk) variable ret_dat_v : std_ulogic_vector(63 downto 0); variable addr64 : std_ulogic_vector(63 downto 0); begin if rising_edge(clk) then addr64 := (others => '0'); addr64(HEIGHT_BITS + 2 downto 3) := addr; if we = '1' then report "RAM writing " & to_hstring(din) & " to " & to_hstring(addr & pad_zeros) & " sel:" & to_hstring(sel); behavioural_write(din, addr64, to_integer(unsigned(sel)), identifier); end if; if re = '1' then behavioural_read(ret_dat_v, addr64, to_integer(unsigned(sel)), identifier); report "RAM reading from " & to_hstring(addr & pad_zeros) & " returns " & to_hstring(ret_dat_v); obuf <= ret_dat_v(obuf'left downto 0); end if; dout <= obuf; end if; end process; end architecture sim;