Add Tercel PHY reset synchronization
[microwatt.git] / sim_bram.vhdl
1 -- Single port Block RAM with one cycle output buffer
2 --
3 -- Simulated via C helpers
4
5 library ieee;
6 use ieee.std_logic_1164.all;
7 use ieee.numeric_std.all;
8 use std.textio.all;
9
10 library work;
11 use work.utils.all;
12 use work.sim_bram_helpers.all;
13
14 entity main_bram is
15 generic(
16 WIDTH : natural := 64;
17 HEIGHT_BITS : natural := 1024;
18 MEMORY_SIZE : natural := 65536;
19 RAM_INIT_FILE : string
20 );
21 port(
22 clk : in std_logic;
23 addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ;
24 di : in std_logic_vector(WIDTH-1 downto 0);
25 do : out std_logic_vector(WIDTH-1 downto 0);
26 sel : in std_logic_vector((WIDTH/8)-1 downto 0);
27 re : in std_ulogic;
28 we : in std_ulogic
29 );
30 end entity main_bram;
31
32 architecture sim of main_bram is
33
34 constant WIDTH_BYTES : natural := WIDTH / 8;
35 constant pad_zeros : std_ulogic_vector(log2(WIDTH_BYTES)-1 downto 0)
36 := (others => '0');
37
38 signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE,
39 size => MEMORY_SIZE);
40 -- Others
41 signal obuf : std_logic_vector(WIDTH-1 downto 0);
42 begin
43
44 -- Actual RAM template
45 memory_0: process(clk)
46 variable ret_dat_v : std_ulogic_vector(63 downto 0);
47 variable addr64 : std_ulogic_vector(63 downto 0);
48 begin
49 if rising_edge(clk) then
50 addr64 := (others => '0');
51 addr64(HEIGHT_BITS + 2 downto 3) := addr;
52 if we = '1' then
53 report "RAM writing " & to_hstring(di) & " to " &
54 to_hstring(addr & pad_zeros) & " sel:" & to_hstring(sel);
55 behavioural_write(di, addr64, to_integer(unsigned(sel)), identifier);
56 end if;
57 if re = '1' then
58 behavioural_read(ret_dat_v, addr64, to_integer(unsigned(sel)), identifier);
59 report "RAM reading from " & to_hstring(addr & pad_zeros) &
60 " returns " & to_hstring(ret_dat_v);
61 obuf <= ret_dat_v(obuf'left downto 0);
62 end if;
63 do <= obuf;
64 end if;
65 end process;
66
67 end architecture sim;