1 |
2 |
federico.a |
|
2 |
|
|
--*******************************************************************
|
3 |
|
|
--** ****
|
4 |
|
|
--** AHB system generator ****
|
5 |
|
|
--** ****
|
6 |
|
|
--** Author: Federico Aglietti ****
|
7 |
|
|
--** federico.aglietti\@opencores.org ****
|
8 |
|
|
--** ****
|
9 |
|
|
--*******************************************************************
|
10 |
|
|
--** ****
|
11 |
|
|
--** Copyright (C) 2004 Federico Aglietti ****
|
12 |
|
|
--** federico.aglietti\@opencores.org ****
|
13 |
|
|
--** ****
|
14 |
|
|
--** This source file may be used and distributed without ****
|
15 |
|
|
--** restriction provided that this copyright statement is not ****
|
16 |
|
|
--** removed from the file and that any derivative work contains ****
|
17 |
|
|
--** the original copyright notice and the associated disclaimer.****
|
18 |
|
|
--** ****
|
19 |
|
|
--** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ****
|
20 |
|
|
--** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ****
|
21 |
|
|
--** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ****
|
22 |
|
|
--** FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ****
|
23 |
|
|
--** OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ****
|
24 |
|
|
--** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ****
|
25 |
|
|
--** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ****
|
26 |
|
|
--** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ****
|
27 |
|
|
--** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ****
|
28 |
|
|
--** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ****
|
29 |
|
|
--** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ****
|
30 |
|
|
--** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ****
|
31 |
|
|
--** POSSIBILITY OF SUCH DAMAGE. ****
|
32 |
|
|
--** ****
|
33 |
|
|
--*******************************************************************
|
34 |
|
|
library ieee;
|
35 |
|
|
use ieee.std_logic_1164.all;
|
36 |
|
|
use ieee.std_logic_arith.all;
|
37 |
|
|
use ieee.std_logic_unsigned.all;
|
38 |
|
|
|
39 |
|
|
use work.ahb_funct.all;
|
40 |
|
|
use work.ahb_package.all;
|
41 |
|
|
use work.ahb_configure.all;
|
42 |
|
|
|
43 |
|
|
entity ahb_slave_wait is
|
44 |
|
|
generic (
|
45 |
|
|
num_slv: in integer range 0 to 15:= 1;
|
46 |
|
|
fifohempty_level: in integer:= 2;
|
47 |
|
|
fifohfull_level: in integer:= 5;
|
48 |
|
|
fifo_length: in integer:= 8);
|
49 |
|
|
port(
|
50 |
|
|
hresetn: in std_logic;
|
51 |
|
|
hclk: in std_logic;
|
52 |
|
|
remap: in std_logic;
|
53 |
|
|
slv_in: in slv_in_t;
|
54 |
|
|
slv_out: out slv_out_t;
|
55 |
|
|
slv_err: out std_logic;
|
56 |
|
|
mst_running: in std_logic;
|
57 |
|
|
prior_in: in std_logic;
|
58 |
|
|
slv_running: out std_logic;
|
59 |
|
|
s_wrap_out: out wrap_out_t;
|
60 |
|
|
s_wrap_in: in wrap_in_t);
|
61 |
|
|
end ahb_slave_wait;
|
62 |
|
|
|
63 |
|
|
|
64 |
|
|
architecture rtl of ahb_slave_wait is
|
65 |
|
|
|
66 |
|
|
--parameters fixed for single-wait slave
|
67 |
|
|
constant num_slvs: integer:= 1;
|
68 |
|
|
constant num_ahb: integer:= 0;
|
69 |
|
|
constant def_slv: integer:= 0;
|
70 |
|
|
constant alg_number: integer range 0 to 2:= 0;
|
71 |
|
|
|
72 |
|
|
|
73 |
|
|
type slv_fsm is (data_cycle,error_cycle);
|
74 |
|
|
signal slv_state, s_slv_state: slv_fsm;
|
75 |
|
|
|
76 |
|
|
signal r_slv_in_v, s_slv_in_v: slv_in_v_t(num_slvs-1 downto 0);
|
77 |
|
|
|
78 |
|
|
signal hready_t, r_hready: std_logic;
|
79 |
|
|
signal hresp_t: std_logic_vector(1 downto 0);
|
80 |
|
|
signal dec_error: std_logic;
|
81 |
|
|
|
82 |
|
|
--***************************************************************
|
83 |
|
|
--arbitration signals
|
84 |
|
|
--***************************************************************
|
85 |
|
|
signal s_grant_slave, grant_slave: integer range 0 to num_slvs-1;
|
86 |
|
|
signal s_turn, turn: integer range 0 to num_slvs-1;
|
87 |
|
|
signal req_ored: std_logic;
|
88 |
|
|
|
89 |
|
|
signal slv_req: std_logic_vector(num_slvs-1 downto 0);
|
90 |
|
|
|
91 |
|
|
signal addr_slv_matrix: addr_matrix_t(0 downto 0);
|
92 |
|
|
|
93 |
|
|
begin
|
94 |
|
|
|
95 |
|
|
addr_slv_matrix(0)(num_slvs-1 downto 0) <= slv_matrix(0)(num_slv downto num_slv) when (remap='0') else slv_matrix(1)(num_slv downto num_slv);
|
96 |
|
|
|
97 |
|
|
--***************************
|
98 |
|
|
--******* slave state *******
|
99 |
|
|
--***************************
|
100 |
|
|
process(slv_state, dec_error)
|
101 |
|
|
begin
|
102 |
|
|
s_slv_state <= slv_state;
|
103 |
|
|
case slv_state is
|
104 |
|
|
when data_cycle =>
|
105 |
|
|
if (dec_error='1') then
|
106 |
|
|
s_slv_state <= error_cycle;
|
107 |
|
|
end if;
|
108 |
|
|
when error_cycle =>
|
109 |
|
|
s_slv_state <= data_cycle;
|
110 |
|
|
when others =>
|
111 |
|
|
end case;
|
112 |
|
|
end process;
|
113 |
|
|
|
114 |
|
|
process(hresetn, hclk)
|
115 |
|
|
begin
|
116 |
|
|
if hresetn='0' then
|
117 |
|
|
r_hready <= '1';
|
118 |
|
|
elsif hclk'event and hclk='1' then
|
119 |
|
|
r_hready <= hready_t after 1 ns;
|
120 |
|
|
end if;
|
121 |
|
|
end process;
|
122 |
|
|
|
123 |
|
|
process(hresetn, hclk)
|
124 |
|
|
begin
|
125 |
|
|
if hresetn='0' then
|
126 |
|
|
slv_state <= data_cycle;
|
127 |
|
|
elsif hclk'event and hclk='1' then
|
128 |
|
|
slv_state <= s_slv_state after 1 ns;
|
129 |
|
|
end if;
|
130 |
|
|
end process;
|
131 |
|
|
|
132 |
|
|
|
133 |
|
|
process(addr_slv_matrix, r_slv_in_v, grant_slave)
|
134 |
|
|
variable v_error: std_logic;
|
135 |
|
|
begin
|
136 |
|
|
v_error:= '0';
|
137 |
|
|
if (r_slv_in_v(grant_slave).hsel='1') then
|
138 |
|
|
if (r_slv_in_v(grant_slave).hsize/=bits32) then
|
139 |
|
|
v_error:= '1';
|
140 |
|
|
end if;
|
141 |
|
|
if (r_slv_in_v(grant_slave).haddr(1 downto 0)/="00") then
|
142 |
|
|
v_error:= '1';
|
143 |
|
|
end if;
|
144 |
|
|
if (r_slv_in_v(grant_slave).haddr(31 downto 10)<conv_std_logic_vector(addr_slv_matrix(num_ahb)(grant_slave).low, 32)(31 downto 10)) then
|
145 |
|
|
v_error:= '1';
|
146 |
|
|
end if;
|
147 |
|
|
if (r_slv_in_v(grant_slave).haddr(31 downto 10)>conv_std_logic_vector(addr_slv_matrix(num_ahb)(grant_slave).high, 32)(31 downto 10)) then
|
148 |
|
|
v_error:= '1';
|
149 |
|
|
end if;
|
150 |
|
|
end if;
|
151 |
|
|
dec_error <= v_error;
|
152 |
|
|
end process;
|
153 |
|
|
|
154 |
|
|
--***************************
|
155 |
|
|
--********** hready *********
|
156 |
|
|
--***************************
|
157 |
|
|
|
158 |
|
|
hready_t <= '1' when
|
159 |
|
|
(slv_state=error_cycle or
|
160 |
|
|
r_slv_in_v(grant_slave).htrans=idle or
|
161 |
|
|
r_slv_in_v(grant_slave).htrans=busy or
|
162 |
|
|
((r_slv_in_v(grant_slave).htrans=nonseq or r_slv_in_v(grant_slave).htrans=seq) and dec_error='0' and
|
163 |
|
|
((r_slv_in_v(grant_slave).hwrite='1' and s_wrap_in.take_ok='1') or (r_slv_in_v(grant_slave).hwrite='0' and s_wrap_in.ask_ok='1')))) else '0';
|
164 |
|
|
|
165 |
|
|
--***************************
|
166 |
|
|
--********** hresp **********
|
167 |
|
|
--***************************
|
168 |
|
|
|
169 |
|
|
hresp_t <= error_resp when (dec_error='1' or slv_state=error_cycle) else ok_resp;
|
170 |
|
|
slv_err <= '1' when (slv_state=error_cycle) else '0';
|
171 |
|
|
|
172 |
|
|
--***************************
|
173 |
|
|
--******* s_wrap_out ********
|
174 |
|
|
--***************************
|
175 |
|
|
process(r_slv_in_v, slv_in, slv_state, grant_slave, dec_error)
|
176 |
|
|
begin
|
177 |
|
|
s_wrap_out.addr <= r_slv_in_v(grant_slave).haddr;--to improve for LOW POWER!!
|
178 |
|
|
s_wrap_out.wdata <= slv_in.hwdata;--to improve for LOW POWER!!
|
179 |
|
|
s_wrap_out.take <= '0';
|
180 |
|
|
s_wrap_out.ask <= '0';
|
181 |
|
|
if (slv_state=data_cycle and dec_error='0' and slv_in.htrans/=busy and r_slv_in_v(grant_slave).hsel='1' and (r_slv_in_v(grant_slave).htrans=nonseq or r_slv_in_v(grant_slave).htrans=seq)) then
|
182 |
|
|
s_wrap_out.take <= r_slv_in_v(grant_slave).hwrite;
|
183 |
|
|
s_wrap_out.ask <= not r_slv_in_v(grant_slave).hwrite;
|
184 |
|
|
end if;
|
185 |
|
|
end process;
|
186 |
|
|
|
187 |
|
|
|
188 |
|
|
--***************************
|
189 |
|
|
--********** output *********
|
190 |
|
|
--***************************
|
191 |
|
|
process(s_wrap_in, hready_t, hresp_t, grant_slave, r_slv_in_v)
|
192 |
|
|
begin
|
193 |
|
|
for i in num_slvs-1 downto 0 loop
|
194 |
|
|
slv_out.hsplit <= (others => '0');
|
195 |
|
|
slv_out.hrdata <= s_wrap_in.rdata;
|
196 |
|
|
slv_out.hresp <= ok_resp;
|
197 |
|
|
slv_out.hready <= '1';
|
198 |
|
|
if (i=grant_slave) then
|
199 |
|
|
slv_out.hresp <= hresp_t;
|
200 |
|
|
slv_out.hready <= hready_t;
|
201 |
|
|
--easiest behaviour: wait for granting!!
|
202 |
|
|
elsif (r_slv_in_v(i).hsel='1' and r_slv_in_v(i).htrans/=idle and r_slv_in_v(i).htrans/=busy) then
|
203 |
|
|
slv_out.hready <= '0';
|
204 |
|
|
end if;
|
205 |
|
|
end loop;
|
206 |
|
|
end process;
|
207 |
|
|
|
208 |
|
|
--***************************
|
209 |
|
|
--********** input **********
|
210 |
|
|
--***************************
|
211 |
|
|
process(hresetn, hclk)
|
212 |
|
|
begin
|
213 |
|
|
if hresetn='0' then
|
214 |
|
|
for i in num_slvs-1 downto 0 loop
|
215 |
|
|
r_slv_in_v(i).hsel <= '0';
|
216 |
|
|
r_slv_in_v(i).hready <= '0';
|
217 |
|
|
r_slv_in_v(i).haddr <= (others=>'0');
|
218 |
|
|
r_slv_in_v(i).hwrite <= '0';
|
219 |
|
|
r_slv_in_v(i).htrans <= idle;
|
220 |
|
|
r_slv_in_v(i).hsize <= bits32;
|
221 |
|
|
r_slv_in_v(i).hburst <= incr;
|
222 |
|
|
r_slv_in_v(i).hprot <= "0011";
|
223 |
|
|
end loop;
|
224 |
|
|
elsif hclk'event and hclk='1' then
|
225 |
|
|
for i in num_slvs-1 downto 0 loop
|
226 |
|
|
r_slv_in_v(i).hready <= slv_in.hready after 1 ns;
|
227 |
|
|
if (slv_in.hready='1') then-- and slv_in.hsel='1'
|
228 |
|
|
r_slv_in_v(i).hsel <= slv_in.hsel after 1 ns;
|
229 |
|
|
r_slv_in_v(i).hburst <= slv_in.hburst after 1 ns;
|
230 |
|
|
r_slv_in_v(i).hprot <= slv_in.hprot after 1 ns;
|
231 |
|
|
r_slv_in_v(i).hsize <= slv_in.hsize after 1 ns;
|
232 |
|
|
r_slv_in_v(i).hwrite <= slv_in.hwrite after 1 ns;
|
233 |
|
|
end if;
|
234 |
|
|
if (slv_in.hready='1' and r_slv_in_v(i).htrans/=busy) then-- and slv_in.hsel='1'
|
235 |
|
|
r_slv_in_v(i).haddr <= slv_in.haddr after 1 ns;
|
236 |
|
|
end if;
|
237 |
|
|
if (slv_in.hready='1') then-- and slv_in.hsel='1'
|
238 |
|
|
r_slv_in_v(i).htrans <= slv_in.htrans after 1 ns;
|
239 |
|
|
end if;
|
240 |
|
|
end loop;
|
241 |
|
|
end if;
|
242 |
|
|
end process;
|
243 |
|
|
|
244 |
|
|
--------------------------------------------------------------------------
|
245 |
|
|
-- SLAVES RESPONSES AND ARBITRATION
|
246 |
|
|
--------------------------------------------------------------------------
|
247 |
|
|
|
248 |
|
|
process(r_slv_in_v)
|
249 |
|
|
begin
|
250 |
|
|
for i in num_slvs-1 downto 0 loop
|
251 |
|
|
slv_req(i) <= '0';
|
252 |
|
|
if (r_slv_in_v(i).hsel='1' and (r_slv_in_v(i).htrans=nonseq or r_slv_in_v(i).htrans=seq)) then
|
253 |
|
|
slv_req(i) <= '1';
|
254 |
|
|
end if;
|
255 |
|
|
end loop;
|
256 |
|
|
end process;
|
257 |
|
|
|
258 |
|
|
process(slv_req)
|
259 |
|
|
variable v_req_ored: std_logic;
|
260 |
|
|
begin
|
261 |
|
|
v_req_ored := '0';
|
262 |
|
|
for i in num_slvs-1 downto 0 loop
|
263 |
|
|
v_req_ored := v_req_ored or slv_req(i);
|
264 |
|
|
end loop;
|
265 |
|
|
req_ored <= v_req_ored;
|
266 |
|
|
end process;
|
267 |
|
|
|
268 |
|
|
update_pr:process(turn, grant_slave, r_hready, req_ored, slv_req, r_slv_in_v)
|
269 |
|
|
variable t_turn, t_grant_slave: integer;
|
270 |
|
|
begin
|
271 |
|
|
t_turn := turn;
|
272 |
|
|
t_grant_slave := grant_slave;
|
273 |
|
|
if (r_hready='1' and req_ored='1' and r_slv_in_v(grant_slave).htrans/=busy and not(slv_req(grant_slave) and r_slv_in_v(grant_slave).hmastlock)='1') then
|
274 |
|
|
case alg_number is
|
275 |
|
|
when 0 => --fixed
|
276 |
|
|
fixed_priority(t_turn, t_grant_slave, slv_req, turn);
|
277 |
|
|
-- when 1 => --round robin
|
278 |
|
|
-- round_robin(def_slv, t_turn, t_grant_slave, slv_req, turn);
|
279 |
|
|
when others => --NOT IMPLEMENTED
|
280 |
|
|
assert FALSE report "### NOT IMPLEMENTED!" severity FAILURE;
|
281 |
|
|
end case;
|
282 |
|
|
--else (no_ready) then SAME SLAVE
|
283 |
|
|
end if;
|
284 |
|
|
s_turn <= t_turn;
|
285 |
|
|
s_grant_slave <= t_grant_slave;
|
286 |
|
|
end process;
|
287 |
|
|
|
288 |
|
|
process(hresetn, hclk)
|
289 |
|
|
begin
|
290 |
|
|
if hresetn='0' then
|
291 |
|
|
grant_slave <= 0;
|
292 |
|
|
turn <= 0;
|
293 |
|
|
elsif hclk'event and hclk='1' then
|
294 |
|
|
grant_slave <= s_grant_slave after 1 ns;
|
295 |
|
|
turn <= s_turn after 1 ns;
|
296 |
|
|
end if;
|
297 |
|
|
end process;
|
298 |
|
|
|
299 |
|
|
end rtl;
|
300 |
|
|
|
301 |
|
|
|