1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-04-24 19:50:22 +00:00
Files
antonblanchard.microwatt/wishbone_bram_wrapper.vhdl
Paul Mackerras ca4eb46aea Make wishbone addresses be in units of doublewords or words
This makes the 64-bit wishbone buses have the address expressed in
units of doublewords (64 bits), and similarly for the 32-bit buses the
address is in units of words (32 bits).  This is to comply with the
wishbone spec.  Previously the addresses on the wishbone buses were in
units of bytes regardless of the bus data width, which is not correct
and caused problems with interfacing with externally-generated logic.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
2021-09-15 18:18:09 +10:00

85 lines
2.0 KiB
VHDL

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) - 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;