You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.0 KiB
84 lines
2.0 KiB
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.wishbone_types.all; |
|
|
|
--! @brief Simple memory module for use in Wishbone-based systems. |
|
entity wishbone_bram_wrapper is |
|
generic( |
|
MEMORY_SIZE : natural := 4096; --! Memory size in bytes. |
|
RAM_INIT_FILE : string |
|
); |
|
port( |
|
clk : in std_logic; |
|
rst : in std_logic; |
|
|
|
-- Wishbone interface: |
|
wishbone_in : in wishbone_master_out; |
|
wishbone_out : out wishbone_slave_out |
|
); |
|
end entity wishbone_bram_wrapper; |
|
|
|
architecture behaviour of wishbone_bram_wrapper is |
|
constant ram_addr_bits : integer := log2ceil(MEMORY_SIZE-1) - 3; |
|
|
|
-- RAM interface |
|
signal ram_addr : std_logic_vector(ram_addr_bits - 1 downto 0); |
|
signal ram_we : std_ulogic; |
|
signal ram_re : std_ulogic; |
|
|
|
-- Others |
|
signal ack, ack_buf : std_ulogic; |
|
begin |
|
|
|
-- Actual RAM template |
|
ram_0: entity work.main_bram |
|
generic map( |
|
WIDTH => 64, |
|
HEIGHT_BITS => ram_addr_bits, |
|
MEMORY_SIZE => MEMORY_SIZE, |
|
RAM_INIT_FILE => RAM_INIT_FILE |
|
) |
|
port map( |
|
clk => clk, |
|
addr => ram_addr, |
|
din => wishbone_in.dat, |
|
dout => wishbone_out.dat, |
|
sel => wishbone_in.sel, |
|
re => ram_re, |
|
we => ram_we |
|
); |
|
|
|
-- Wishbone interface |
|
ram_addr <= wishbone_in.adr(ram_addr_bits - 1 downto 0); |
|
ram_we <= wishbone_in.stb and wishbone_in.cyc and wishbone_in.we; |
|
ram_re <= wishbone_in.stb and wishbone_in.cyc and not wishbone_in.we; |
|
wishbone_out.stall <= '0'; |
|
wishbone_out.ack <= ack_buf; |
|
|
|
wb_0: process(clk) |
|
begin |
|
if rising_edge(clk) then |
|
if rst = '1' or wishbone_in.cyc = '0' then |
|
ack_buf <= '0'; |
|
ack <= '0'; |
|
else |
|
-- On loads, we have a delay cycle due to BRAM bufferring |
|
-- but not on stores. So try to send an early ack on a |
|
-- store if we aren't behind an existing load ack. |
|
-- |
|
if ram_we = '1' and ack = '0' then |
|
ack_buf <= '1'; |
|
else |
|
ack <= wishbone_in.stb; |
|
ack_buf <= ack; |
|
end if; |
|
end if; |
|
end if; |
|
end process; |
|
|
|
end architecture behaviour;
|
|
|