mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-04-24 19:50:22 +00:00
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>
85 lines
2.0 KiB
VHDL
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;
|