blob: d1516c669ad9b56c85f7c8980762eca4b4e93ad4 (
plain)
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std_unsigned.all;
-- This arbitrates fairly between two Masters connected to a single Slave
entity avm_arbit is
generic (
G_ADDRESS_SIZE : integer;
G_DATA_SIZE : integer
);
port (
clk_i : in std_logic;
rst_i : in std_logic;
-- Slave interface 0 (input)
s0_avm_write_i : in std_logic;
s0_avm_read_i : in std_logic;
s0_avm_address_i : in std_logic_vector(G_ADDRESS_SIZE-1 downto 0);
s0_avm_writedata_i : in std_logic_vector(G_DATA_SIZE-1 downto 0);
s0_avm_byteenable_i : in std_logic_vector(G_DATA_SIZE/8-1 downto 0);
s0_avm_burstcount_i : in std_logic_vector(7 downto 0);
s0_avm_readdata_o : out std_logic_vector(G_DATA_SIZE-1 downto 0);
s0_avm_readdatavalid_o : out std_logic;
s0_avm_waitrequest_o : out std_logic;
-- Slave interface 1 (input)
s1_avm_write_i : in std_logic;
s1_avm_read_i : in std_logic;
s1_avm_address_i : in std_logic_vector(G_ADDRESS_SIZE-1 downto 0);
s1_avm_writedata_i : in std_logic_vector(G_DATA_SIZE-1 downto 0);
s1_avm_byteenable_i : in std_logic_vector(G_DATA_SIZE/8-1 downto 0);
s1_avm_burstcount_i : in std_logic_vector(7 downto 0);
s1_avm_readdata_o : out std_logic_vector(G_DATA_SIZE-1 downto 0);
s1_avm_readdatavalid_o : out std_logic;
s1_avm_waitrequest_o : out std_logic;
-- Master interface (output)
m_avm_write_o : out std_logic;
m_avm_read_o : out std_logic;
m_avm_address_o : out std_logic_vector(G_ADDRESS_SIZE-1 downto 0);
m_avm_writedata_o : out std_logic_vector(G_DATA_SIZE-1 downto 0);
m_avm_byteenable_o : out std_logic_vector(G_DATA_SIZE/8-1 downto 0);
m_avm_burstcount_o : out std_logic_vector(7 downto 0);
m_avm_readdata_i : in std_logic_vector(G_DATA_SIZE-1 downto 0);
m_avm_readdatavalid_i : in std_logic;
m_avm_waitrequest_i : in std_logic
);
end entity avm_arbit;
architecture synthesis of avm_arbit is
signal s0_active_req : std_logic;
signal s1_active_req : std_logic;
signal s0_active_grant : std_logic := '0';
signal s1_active_grant : std_logic := '0';
signal active_grants : std_logic_vector(1 downto 0);
signal last_grant : std_logic := '0';
signal burstcount : std_logic_vector(7 downto 0);
begin
s0_avm_waitrequest_o <= not s0_active_grant;
s1_avm_waitrequest_o <= not s1_active_grant;
s0_active_req <= s0_avm_write_i or s0_avm_read_i;
s1_active_req <= s1_avm_write_i or s1_avm_read_i;
p_burstcount : process (clk_i)
begin
if rising_edge(clk_i) then
if burstcount = X"00" then
if s0_avm_write_i and not s0_avm_waitrequest_o then
burstcount <= s0_avm_burstcount_i;
end if;
if s1_avm_write_i and not s1_avm_waitrequest_o then
burstcount <= s1_avm_burstcount_i;
end if;
else
if (s0_avm_write_i and not s0_avm_waitrequest_o) or
s0_avm_readdatavalid_o or
(s1_avm_write_i and not s1_avm_waitrequest_o) or
s1_avm_readdatavalid_o then
burstcount <= burstcount - 1;
end if;
end if;
if rst_i = '1' then
burstcount <= X"00";
end if;
end if;
end process p_burstcount;
active_grants <= s0_active_grant & s1_active_grant;
p_grant : process (clk_i)
begin
if rising_edge(clk_i) then
case active_grants is
when "00" =>
if s0_active_req = '1' and last_grant = '1' then
s0_active_grant <= '1';
last_grant <= '1';
end if;
if s1_active_req = '1' and last_grant = '0' then
s1_active_grant <= '1';
last_grant <= '0';
end if;
when "01" =>
if burstcount = X"01" then
if (s1_avm_write_i and not s1_avm_waitrequest_o) or
s1_avm_readdatavalid_o then
s1_active_grant <= '0';
end if;
end if;
when "10" =>
if burstcount = X"01" then
if (s0_avm_write_i and not s0_avm_waitrequest_o) or
s0_avm_readdatavalid_o then
s0_active_grant <= '0';
end if;
end if;
when others =>
report "S0 and S1 both active"
severity failure;
end case;
if rst_i = '1' then
s0_active_grant <= '0';
s1_active_grant <= '0';
last_grant <= '0';
end if;
end if;
end process p_grant;
m_avm_write_o <= s0_avm_write_i when last_grant = '0' else s1_avm_write_i;
m_avm_read_o <= s0_avm_read_i when last_grant = '0' else s1_avm_read_i;
m_avm_address_o <= s0_avm_address_i when last_grant = '0' else s1_avm_address_i;
m_avm_writedata_o <= s0_avm_writedata_i when last_grant = '0' else s1_avm_writedata_i;
m_avm_byteenable_o <= s0_avm_byteenable_i when last_grant = '0' else s1_avm_byteenable_i;
m_avm_burstcount_o <= s0_avm_burstcount_i when last_grant = '0' else s1_avm_burstcount_i;
s0_avm_readdata_o <= m_avm_readdata_i;
s0_avm_readdatavalid_o <= m_avm_readdatavalid_i when last_grant = '0' else '0';
s1_avm_readdata_o <= m_avm_readdata_i;
s1_avm_readdatavalid_o <= m_avm_readdatavalid_i when last_grant = '1' else '0';
end architecture synthesis;
|