forked from antonblanchard/microwatt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wishbone_bram_wrapper.vhdl
84 lines (74 loc) · 2.04 KB
/
wishbone_bram_wrapper.vhdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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;