begin working on linux verilator simulation
[microwatt.git] / wishbone_bram_wrapper.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use std.textio.all;
5
6 library work;
7 use work.utils.all;
8 use work.wishbone_types.all;
9
10 --- verilator access TODO
11
12 --! @brief Simple memory module for use in Wishbone-based systems.
13 entity wishbone_bram_wrapper is
14 generic(
15 MEMORY_SIZE : natural := 4096; --! Memory size in bytes.
16 RAM_INIT_FILE : string;
17 SIM_MAIN_BRAM : boolean := false
18 );
19 port(
20 clk : in std_logic;
21 rst : in std_logic;
22
23 -- Wishbone interface:
24 wishbone_in : in wishbone_master_out;
25 wishbone_out : out wishbone_slave_out;
26
27 -- BRAM verilator access
28 bram_we : out std_ulogic;
29 bram_re : out std_ulogic;
30 bram_addr : out std_logic_vector(log2ceil(MEMORY_SIZE) - 3- 1 downto 0);
31 bram_di : out std_logic_vector(63 downto 0);
32 bram_do : in std_logic_vector(63 downto 0);
33 bram_sel : out std_logic_vector(7 downto 0)
34
35 );
36 end entity wishbone_bram_wrapper;
37
38 architecture behaviour of wishbone_bram_wrapper is
39 constant ram_addr_bits : integer := log2ceil(MEMORY_SIZE) - 3;
40
41 -- RAM interface
42 signal ram_addr : std_logic_vector(ram_addr_bits - 1 downto 0);
43 signal ram_we : std_ulogic;
44 signal ram_re : std_ulogic;
45
46 -- Others
47 signal ack, ack_buf : std_ulogic;
48 begin
49
50 -- Actual RAM template
51 sim_ram: if SIM_MAIN_BRAM = true generate
52 ram_0: entity work.main_bram
53 generic map(
54 WIDTH => 64,
55 HEIGHT_BITS => ram_addr_bits,
56 MEMORY_SIZE => MEMORY_SIZE,
57 RAM_INIT_FILE => RAM_INIT_FILE
58 )
59 port map(
60 clk => clk,
61 addr => ram_addr,
62 din => wishbone_in.dat,
63 dout => wishbone_out.dat,
64 sel => wishbone_in.sel,
65 re => ram_re,
66 we => ram_we
67 );
68 end generate;
69
70 -- Verilator access to bram signals
71 bram_sel <= wishbone_in.sel;
72 wishbone_out.dat <= bram_do;
73 bram_di <= wishbone_in.dat;
74 bram_addr <= ram_addr;
75 bram_we <= ram_we;
76 bram_re <= ram_re;
77
78 -- Wishbone interface
79 ram_addr <= wishbone_in.adr(ram_addr_bits - 1 downto 0);
80 -- not that a wishbone compliant version of libre-soc is needed
81 ram_we <= wishbone_in.stb and wishbone_in.cyc and wishbone_in.we;
82 ram_re <= wishbone_in.stb and wishbone_in.cyc and not wishbone_in.we;
83 wishbone_out.stall <= '0';
84 wishbone_out.ack <= ack_buf;
85
86 wb_0: process(clk)
87 begin
88 if rising_edge(clk) then
89 if rst = '1' or wishbone_in.cyc = '0' then
90 ack_buf <= '0';
91 ack <= '0';
92 else
93 -- On loads, we have a delay cycle due to BRAM bufferring
94 -- but not on stores. So try to send an early ack on a
95 -- store if we aren't behind an existing load ack.
96 --
97 if ram_we = '1' and ack = '0' then
98 ack_buf <= '1';
99 else
100 ack <= wishbone_in.stb;
101 ack_buf <= ack;
102 end if;
103 end if;
104 end if;
105 end process;
106
107 end architecture behaviour;