-
Notifications
You must be signed in to change notification settings - Fork 0
/
avm_memory.vhd
98 lines (78 loc) · 4 KB
/
avm_memory.vhd
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
85
86
87
88
89
90
91
92
93
94
95
96
97
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity avm_memory is
generic (
G_ADDRESS_SIZE : integer; -- Number of bits
G_DATA_SIZE : integer -- Number of bits
);
port (
clk_i : in std_logic;
rst_i : in std_logic;
avm_waitrequest_o : out std_logic;
avm_write_i : in std_logic;
avm_read_i : in std_logic;
avm_address_i : in std_logic_vector(G_ADDRESS_SIZE - 1 downto 0);
avm_writedata_i : in std_logic_vector(G_DATA_SIZE - 1 downto 0);
avm_byteenable_i : in std_logic_vector(G_DATA_SIZE / 8 - 1 downto 0);
avm_burstcount_i : in std_logic_vector(7 downto 0);
avm_readdata_o : out std_logic_vector(G_DATA_SIZE - 1 downto 0);
avm_readdatavalid_o : out std_logic
);
end entity avm_memory;
architecture simulation of avm_memory is
-- This defines a type containing an array of bytes
type mem_type is array (0 to 2 ** G_ADDRESS_SIZE - 1) of std_logic_vector(G_DATA_SIZE - 1 downto 0);
signal write_burstcount : std_logic_vector(7 downto 0);
signal write_address : std_logic_vector(G_ADDRESS_SIZE - 1 downto 0);
signal read_burstcount : std_logic_vector(7 downto 0);
signal read_address : std_logic_vector(G_ADDRESS_SIZE - 1 downto 0);
signal mem_write_burstcount : std_logic_vector(7 downto 0);
signal mem_read_burstcount : std_logic_vector(7 downto 0);
signal mem_write_address : std_logic_vector(G_ADDRESS_SIZE - 1 downto 0);
signal mem_read_address : std_logic_vector(G_ADDRESS_SIZE - 1 downto 0);
begin
mem_write_address <= avm_address_i when write_burstcount = X"00" else
write_address;
mem_read_address <= avm_address_i when read_burstcount = X"00" else
read_address;
mem_write_burstcount <= avm_burstcount_i when write_burstcount = X"00" else
write_burstcount;
mem_read_burstcount <= avm_burstcount_i when read_burstcount = X"00" else
read_burstcount;
avm_waitrequest_o <= '0' when unsigned(read_burstcount) = 0 else
'1';
mem_proc : process (clk_i)
variable mem_v : mem_type := (others => (others => '0'));
begin
if rising_edge(clk_i) then
avm_readdatavalid_o <= '0';
if avm_write_i = '1' and avm_waitrequest_o = '0' then
write_address <= std_logic_vector(unsigned(mem_write_address) + 1);
write_burstcount <= std_logic_vector(unsigned(mem_write_burstcount) - 1);
report "Writing 0x" & to_hstring(avm_writedata_i) &
" to 0x" & to_hstring(mem_write_address) &
" with burstcount " & to_hstring(write_burstcount) &
" and byteenable 0x" & to_hstring(avm_byteenable_i);
for b in 0 to G_DATA_SIZE / 8 - 1 loop
if avm_byteenable_i(b) = '1' then
mem_v(to_integer(unsigned(mem_write_address)))(8 * b + 7 downto 8 * b) := avm_writedata_i(8 * b + 7 downto 8 * b);
end if;
end loop;
end if;
if (avm_read_i = '1' and avm_waitrequest_o = '0') or to_integer(unsigned(read_burstcount)) > 0 then
read_address <= std_logic_vector(unsigned(mem_read_address) + 1);
read_burstcount <= std_logic_vector(unsigned(mem_read_burstcount) - 1);
avm_readdata_o <= mem_v(to_integer(unsigned(mem_read_address)));
avm_readdatavalid_o <= '1';
report "Reading 0x" & to_hstring(mem_v(to_integer(unsigned(mem_read_address)))) &
" from 0x" & to_hstring(mem_read_address) &
" with burstcount " & to_hstring(read_burstcount);
end if;
if rst_i = '1' then
write_burstcount <= (others => '0');
read_burstcount <= (others => '0');
end if;
end if;
end process mem_proc;
end architecture simulation;