Add Tercel PHY reset synchronization
[microwatt.git] / fpga / main_bram.vhdl
1 -- Single port Block RAM with one cycle output buffer
2
3 library ieee;
4 use ieee.std_logic_1164.all;
5 use ieee.numeric_std.all;
6 use std.textio.all;
7
8 library work;
9
10 entity main_bram is
11 generic(
12 WIDTH : natural := 64;
13 HEIGHT_BITS : natural := 1024;
14 MEMORY_SIZE : natural := 65536;
15 RAM_INIT_FILE : string
16 );
17 port(
18 clk : in std_logic;
19 addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ;
20 di : in std_logic_vector(WIDTH-1 downto 0);
21 do : out std_logic_vector(WIDTH-1 downto 0);
22 sel : in std_logic_vector((WIDTH/8)-1 downto 0);
23 re : in std_ulogic;
24 we : in std_ulogic
25 );
26 end entity main_bram;
27
28 architecture behaviour of main_bram is
29
30 constant WIDTH_BYTES : natural := WIDTH / 8;
31
32 -- RAM type definition
33 type ram_t is array(0 to (MEMORY_SIZE / WIDTH_BYTES) - 1) of std_logic_vector(WIDTH-1 downto 0);
34
35 -- RAM loading
36 impure function init_ram(name : STRING) return ram_t is
37 file ram_file : text open read_mode is name;
38 variable ram_line : line;
39 variable temp_word : std_logic_vector(WIDTH-1 downto 0);
40 variable temp_ram : ram_t := (others => (others => '0'));
41 begin
42 for i in 0 to (MEMORY_SIZE / WIDTH_BYTES) - 1 loop
43 exit when endfile(ram_file);
44 readline(ram_file, ram_line);
45 hread(ram_line, temp_word);
46 temp_ram(i) := temp_word;
47 end loop;
48
49 return temp_ram;
50 end function;
51
52 -- RAM instance
53 signal memory : ram_t := init_ram(RAM_INIT_FILE);
54 attribute ram_style : string;
55 attribute ram_style of memory : signal is "block";
56 attribute ram_decomp : string;
57 attribute ram_decomp of memory : signal is "power";
58
59 -- Others
60 signal obuf : std_logic_vector(WIDTH-1 downto 0);
61 begin
62
63 -- Actual RAM template
64 memory_0: process(clk)
65 begin
66 if rising_edge(clk) then
67 if we = '1' then
68 for i in 0 to 7 loop
69 if sel(i) = '1' then
70 memory(to_integer(unsigned(addr)))((i + 1) * 8 - 1 downto i * 8) <=
71 di((i + 1) * 8 - 1 downto i * 8);
72 end if;
73 end loop;
74 end if;
75 if re = '1' then
76 obuf <= memory(to_integer(unsigned(addr)));
77 end if;
78 do <= obuf;
79 end if;
80 end process;
81
82 end architecture behaviour;