OpenCores
URL https://opencores.org/ocsvn/ahb_system_generator/ahb_system_generator/trunk

Subversion Repositories ahb_system_generator

[/] [ahb_system_generator/] [trunk/] [src/] [ahb_arbiter.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
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
--use work.ahb_matrix.all;
43
 
44
entity ahb_arbiter is
45
  generic(
46
    num_arb: in integer:= 2;
47
    num_arb_msts: in integer range 1 to 15:= 4;
48
    def_arb_mst: in integer range 0 to 15:= 2;
49
    num_slvs: in integer range 1 to 15:= 3;
50
    alg_number: in integer range 0 to 5:= 2);
51
  port(
52
    hresetn: in std_logic;
53
    hclk: in std_logic;
54
    remap: in std_logic;
55
    mst_in_v: in mst_out_v_t(num_arb_msts-1 downto 0);
56
    mst_out_v: out mst_in_v_t(num_arb_msts-1 downto 0);
57
    slv_out_v: out slv_in_v_t(num_slvs-1 downto 0);
58
    slv_in_v: in slv_out_v_t(num_slvs-1 downto 0));
59
end;
60
 
61
 
62
architecture rtl of ahb_arbiter is
63
 
64
--*******************************************************************
65
--******************** SIGNAL DECLARATION ***************************
66
--*******************************************************************
67
 
68
signal s_grant_master, grant_master: integer range 0 to 15;
69
signal s_master_sel, master_sel: std_logic_vector(3 downto 0);
70
signal s_r_master_sel, r_master_sel: std_logic_vector(3 downto 0);
71
signal r_master_busy: std_logic_vector(1 downto 0);
72
 
73
signal turn, s_turn: integer range 0 to num_arb_msts-1;
74
signal random: integer range 0 to 2**(nb_bits(num_arb_msts));
75
signal seed, s_seed: std_logic_vector(9 downto 0);
76
 
77
type vecran is array (2**(nb_bits(num_arb_msts)) downto 0) of integer;
78
signal vect_ran: vecran;
79
signal vect_ran_round: vecran;
80
 
81
 
82
signal haddr_page: std_logic_vector(31 downto 0);
83
signal htrans_reg: std_logic_vector(1 downto 0);--"00"|"01"|"10"
84
signal hsel: std_logic_vector(num_slvs-1 downto 0);
85
 
86
 
87
signal s_dec_hready: std_logic;
88
signal req_ored: std_logic;
89
signal hbusreq_msk: std_logic_vector(num_arb_msts-1 downto 0);
90
 
91
signal split_reg: std_logic_vector(num_arb_msts-1 downto 0);
92
 
93
signal r_slv_in_v: slv_in_v_t(num_slvs-1 downto 0);
94
signal mst_in_sel: slv_in_t;
95
signal slv_in_sel: mst_in_t;
96
 
97
--DEAFULT SLAVE BEHAVIOUR                                                 
98
 
99
signal r_def_slave_hsel, def_slave_hsel: std_logic;
100
signal def_slave_hready: std_logic;
101
 
102
signal addr_arb_matrix: addr_matrix_t(0 downto 0);
103
 
104
--*******************************************************************
105
--***************** END OF SIGNAL DECLARATION ************************
106
--*******************************************************************
107
 
108
begin
109
 
110
addr_arb_matrix(0)(num_slvs-1 downto 0) <= arb_matrix(num_arb)(num_slvs-1 downto 0) when (remap='0') else rarb_matrix(num_arb)(num_slvs-1 downto 0);
111
 
112
req_ored_pr:process(hbusreq_msk)
113
variable v_req_ored: std_logic;
114
begin
115
  v_req_ored := '0';
116
  for i in 0 to num_arb_msts-1 loop
117
    v_req_ored := v_req_ored or hbusreq_msk(i);
118
  end loop;
119
  req_ored <= v_req_ored;
120
end process;
121
 
122
bus_req_mask_pr:process(split_reg, grant_master, mst_in_v)
123
begin
124
  for i in 0 to num_arb_msts-1 loop
125
    if (mst_in_v(i).htrans=busy or split_reg(i)='1' or (grant_master/=num_arb_msts and grant_master/=i and mst_in_v(grant_master).hlock='1')) then
126
      hbusreq_msk(i) <= '0';
127
    else
128
      hbusreq_msk(i) <= mst_in_v(i).hbusreq;
129
    end if;
130
  end loop;
131
end process;
132
 
133
 
134
--********************************************************
135
-- synchronization processes (flip flops)
136
--********************************************************
137
s_master_sel <= conv_std_logic_vector(s_grant_master, 4) when (s_dec_hready='1') else master_sel;
138
s_r_master_sel <= master_sel when (s_dec_hready='1' and htrans_reg/=busy) else r_master_sel;
139
 
140
master_pr:process(hresetn, hclk)
141
begin
142
  if hresetn='0' then
143
    grant_master <= def_arb_mst;
144
    master_sel <= conv_std_logic_vector(def_arb_mst, 4);
145
    r_master_sel <= conv_std_logic_vector(def_arb_mst, 4);
146
    turn <= 0;
147
    htrans_reg <= idle;
148
  elsif hclk'event and hclk='1' then
149
    grant_master <= s_grant_master after 1 ns;
150
    master_sel <= s_master_sel after 1 ns;
151
    r_master_sel <= s_r_master_sel after 1 ns;
152
    turn <= s_turn after 1 ns;
153
    if conv_integer(master_sel) /= num_arb_msts then
154
      htrans_reg <= mst_in_sel.htrans after 1 ns;
155
    else
156
      htrans_reg <= idle;
157
    end if;
158
  end if;
159
end process;
160
 
161
update_pr:process(
162
req_ored,
163
hbusreq_msk,
164
grant_master,
165
mst_in_v,
166
htrans_reg,
167
mst_in_sel,
168
slv_in_sel,
169
split_reg,
170
turn,
171
random)
172
variable t_turn, t_grant_master: integer;
173
begin
174
  t_turn := turn;
175
  t_grant_master := grant_master;
176
  --nohready=> grant no change
177
  --hready&busy(real master)=> grant no change
178
  --hready&nobusy&req => arbitration
179
  --hready&nobusy&noreq&default master not splitted => default master                                                    
180
  --hready&nobusy&noreq&default master splitted => dummy master
181
  if (slv_in_sel.hready='1') then
182
    if ((grant_master/=num_arb_msts and mst_in_v(grant_master).htrans/=busy and htrans_reg/=busy) or (grant_master=num_arb_msts)) then
183
      if (req_ored='1') then
184
        case alg_number is
185
          when 0 => --fixed 
186
            fixed_priority(t_turn, t_grant_master, hbusreq_msk, turn);
187
          when 1 => --round robin
188
            round_robin(def_arb_mst, t_turn, t_grant_master, hbusreq_msk, turn);
189
          when 2 => --random
190
            random_priority(def_arb_mst, t_turn, t_grant_master, random, hbusreq_msk, turn);
191
          when 3 => --fair1
192
            if (grant_master/=num_arb_msts and hbusreq_msk(grant_master)='0') or (grant_master=num_arb_msts) then
193
              fixed_priority(t_turn, t_grant_master, hbusreq_msk, turn);
194
            end if;
195
          when 4 => --fair2
196
            if (grant_master/=num_arb_msts and hbusreq_msk(grant_master)='0') or (grant_master=num_arb_msts) then
197
              round_robin(def_arb_mst, t_turn, t_grant_master, hbusreq_msk, turn);
198
            end if;
199
          when 5 => --fair3
200
            if (grant_master/=num_arb_msts and hbusreq_msk(grant_master)='0') or (grant_master=num_arb_msts) then
201
              random_priority(def_arb_mst, t_turn, t_grant_master, random, hbusreq_msk, turn);
202
            end if;
203
          when others => --NOT IMPLEMENTED
204
            assert FALSE report "### NOT IMPLEMENTED!" severity FAILURE;
205
                end case;
206
      elsif (split_reg(def_arb_mst)='0') then--ready+no_busy+no_req=> default if not splitted!!
207
        t_grant_master := def_arb_mst;
208
            t_turn := def_arb_mst;
209
      else--ready+no_busy+no_req+def_master splitted => dummy_master!!
210
        t_grant_master := num_arb_msts;
211
      end if;
212
    --else (busy) then SAME MASTER
213
    end if;
214
  --else (no_ready) then SAME MASTER
215
  end if;
216
  s_grant_master <= t_grant_master;
217
  s_turn <= t_turn;
218
end process;
219
 
220
s_seed_pr:process(seed)
221
begin
222
  for i in 9 downto 1 loop
223
    s_seed(i) <= seed(i-1);
224
  end loop;
225
  s_seed(0) <= not(seed(9) xor seed(6));
226
end process;
227
 
228
seed_pr:process(hresetn, hclk)
229
variable v_random: integer range 0 to 2**(nb_bits(num_arb_msts));
230
begin
231
  if hresetn='0' then
232
    seed <= (others => '0');--"1101010001";
233
    random <= 0;
234
    --synopsys translate_off
235
    for i in 0 to 2**(nb_bits(num_arb_msts)) loop
236
      vect_ran(i) <= 0;
237
      vect_ran_round(i) <= 0;
238
    end loop;
239
    --synopsys translate_on
240
  elsif hclk'event and hclk='1' then
241
    seed <= s_seed after 1 ns;
242
    v_random := conv_integer(seed(nb_bits(num_arb_msts)+3 downto 4));
243
    if v_random < num_arb_msts then
244
      random <= v_random after 1 ns;
245
    else
246
      random <= turn after 1 ns;--(v_random - num_arb_msts);
247
    end if;
248
    --synopsys translate_off
249
    vect_ran(v_random) <= vect_ran(v_random) + 1;
250
    vect_ran_round(random) <= vect_ran_round(random) + 1;
251
    --synopsys translate_on
252
  end if;
253
end process;
254
 
255
 
256
 
257
--synopsys translate_off
258
  assert not (hclk'event and hclk='1' and master_sel=num_arb_msts) report "DUMMY MASTER selection!!!" severity WARNING;
259
  assert not (hclk'event and hclk='1' and master_sel=def_arb_mst) report "DEFAULT MASTER selection!!!" severity WARNING;
260
  assert not (hclk'event and hclk='1' and (master_sel>num_arb_msts or r_master_sel>num_arb_msts)) report "####ERROR in MASTER selection!!!" severity FAILURE;
261
--synopsys translate_on
262
 
263
 
264
--*********************************************************
265
-- MASTER MUXES
266
--*********************************************************
267
 
268
add_pr:process(master_sel, r_master_sel, mst_in_v)
269
variable def_addr: std_logic_vector(31 downto 0);
270
begin
271
 
272
  haddr_page(31 downto 10) <= mst_in_v(def_arb_mst).haddr(31 downto 10);
273
 
274
  mst_in_sel.hwdata <= mst_in_v(def_arb_mst).hwdata;
275
  mst_in_sel.haddr <= mst_in_v(def_arb_mst).haddr;
276
  mst_in_sel.hwrite <= mst_in_v(def_arb_mst).hwrite;
277
  mst_in_sel.hsize <= mst_in_v(def_arb_mst).hsize;
278
  mst_in_sel.hburst <= mst_in_v(def_arb_mst).hburst;
279
  mst_in_sel.hprot <= mst_in_v(def_arb_mst).hprot;
280
  mst_in_sel.htrans <= mst_in_v(def_arb_mst).htrans;
281
  for i in 0 to num_arb_msts-1 loop
282
    if i=conv_integer(r_master_sel) then
283
      mst_in_sel.hwdata <= mst_in_v(i).hwdata;
284
    end if;
285
    if i=conv_integer(master_sel) then
286
      haddr_page(31 downto 10) <= mst_in_v(i).haddr(31 downto 10);
287
      mst_in_sel.haddr <= mst_in_v(i).haddr;
288
      mst_in_sel.hwrite <= mst_in_v(i).hwrite;
289
      mst_in_sel.hsize <= mst_in_v(i).hsize;
290
      mst_in_sel.hburst <= mst_in_v(i).hburst;
291
      mst_in_sel.hprot <= mst_in_v(i).hprot;
292
      mst_in_sel.htrans <= mst_in_v(i).htrans;
293
    end if;
294
  end loop;
295
  if master_sel=num_arb_msts then
296
    mst_in_sel.htrans <= idle;
297
  end if;
298
end process;
299
 
300
process(slv_in_sel, s_grant_master)--N.B.: Request=>Grant comb. path!
301
begin
302
  for i in 0 to num_arb_msts-1 loop
303
    mst_out_v(i).hready <= slv_in_sel.hready;
304
    mst_out_v(i).hresp <= slv_in_sel.hresp;
305
    mst_out_v(i).hrdata <= slv_in_sel.hrdata;
306
    if (s_grant_master=i) then
307
      mst_out_v(i).hgrant <= '1';
308
    else
309
      mst_out_v(i).hgrant <= '0';
310
    end if;
311
  end loop;
312
end process;
313
 
314
--*********************************************************
315
-- SLAVE MUXES
316
--*********************************************************
317
 
318
process(hresetn, hclk)
319
variable v_hready: std_logic;
320
begin
321
  if hresetn='0' then
322
    for i in num_slvs-1 downto 0 loop
323
      r_slv_in_v(i).hsel <= '0';
324
    end loop;
325
  elsif hclk='1' and hclk'event then
326
    if s_dec_hready='1' then
327
          r_def_slave_hsel <= def_slave_hsel;
328
      for i in num_slvs-1 downto 0 loop
329
        r_slv_in_v(i).hsel <= hsel(i) after 1 ns;
330
      end loop;
331
    end if;
332
  end if;
333
end process;
334
 
335
process(r_slv_in_v, slv_in_v, def_slave_hready)
336
begin
337
  s_dec_hready <= def_slave_hready;
338
  for i in num_slvs-1 downto 0 loop
339
    if(r_slv_in_v(i).hsel='1') then
340
      s_dec_hready <= slv_in_v(i).hready;
341
        end if;
342
  end loop;
343
--  hready_t <= slv_in_v(num_slvs).hready;--ready ....
344
  slv_in_sel.hready <= def_slave_hready;
345
  slv_in_sel.hrdata <= (others => '-');--for LOW POWER!!!
346
  slv_in_sel.hresp <= error_resp;--.... and ERROR ....          
347
  for i in num_slvs-1 downto 0 loop
348
    if r_slv_in_v(i).hsel='1' then
349
--      hready_t <= slv_in_v(i).hready;
350
      slv_in_sel.hready <= slv_in_v(i).hready;
351
      slv_in_sel.hresp <= slv_in_v(i).hresp;
352
      slv_in_sel.hrdata <= slv_in_v(i).hrdata;
353
    end if;
354
  end loop;
355
end process;
356
 
357
 
358
--*********************************************************
359
-- SPLIT handling
360
--*********************************************************
361
 
362
process(hresetn, hclk)
363
variable v_split_reg: std_logic_vector(num_arb_msts-1 downto 0);
364
begin
365
  if hresetn='0' then
366
    split_reg <= (others => '0');
367
  elsif hclk'event and hclk='1' then
368
    v_split_reg := split_reg;
369
    for j in num_slvs-1 downto 0 loop
370
      for i in num_arb_msts-1 downto 0 loop
371
        v_split_reg(i) := v_split_reg(i) and not slv_in_v(j).hsplit(i);
372
      end loop;
373
      if (r_slv_in_v(j).hsel='1') then
374
        if (slv_in_v(j).hready='1' and slv_in_v(j).hresp=split_resp and master_sel/=num_arb_msts) then
375
          v_split_reg(conv_integer(master_sel)) := '1';
376
        end if;
377
      end if;
378
    end loop;
379
    split_reg <= v_split_reg after 1 ns;
380
  end if;
381
end process;
382
 
383
--*********************************************************
384
-- AHB DECODER
385
--*********************************************************
386
-- min 1KB of address space for each slave:
387
process(haddr_page, master_sel, mst_in_v, mst_in_sel, s_dec_hready, addr_arb_matrix)
388
  variable addr_low_std : std_logic_vector(31 downto 0);
389
  variable addr_high_std : std_logic_vector(31 downto 0);
390
  variable v_hmastlock: std_logic;
391
begin
392
  v_hmastlock := '0';
393
  for i in num_arb_msts-1 downto 0 loop
394
    if (v_hmastlock='0' and master_sel=conv_std_logic_Vector(i,4) and mst_in_v(i).hlock='1') then
395
      v_hmastlock := '1';
396
    end if;
397
  end loop;
398
  def_slave_hsel <= '1'; --default slave selected
399
  for i in num_slvs-1 downto 0 loop
400
    slv_out_v(i).hmastlock <= v_hmastlock;
401
    slv_out_v(i).haddr <= mst_in_sel.haddr;
402
    slv_out_v(i).hmaster <= master_sel;
403
    slv_out_v(i).hready <= s_dec_hready;
404
    slv_out_v(i).hwrite <= mst_in_sel.hwrite;
405
    slv_out_v(i).hwdata <= mst_in_sel.hwdata;
406
    slv_out_v(i).hsize <= mst_in_sel.hsize;
407
    slv_out_v(i).hburst <= mst_in_sel.hburst;
408
    slv_out_v(i).hprot <= mst_in_sel.hprot;
409
    slv_out_v(i).htrans <= mst_in_sel.htrans;
410
    addr_low_std := conv_std_logic_vector(addr_arb_matrix(0)(i).low, 32);
411
    addr_high_std := conv_std_logic_vector(addr_arb_matrix(0)(i).high, 32);
412
    if (haddr_page(31 downto 10) >= addr_low_std(31 downto 10) and (haddr_page(31 downto 10) <= addr_high_std(31 downto 10))) then
413
      hsel(i) <= '1';
414
      def_slave_hsel <= '0';
415
      slv_out_v(i).hsel <= '1';
416
    else
417
      hsel(i) <= '0';
418
      slv_out_v(i).hsel <= '0';
419
    end if;
420
  end loop;
421
end process;
422
 
423
 
424
--DEFAULT SLAVE BEHAVIOUR
425
 
426
process(hresetn, hclk)
427
begin
428
  if hresetn='0' then
429
    def_slave_hready <= '1';
430
  elsif hclk'event and hclk='1' then
431
    if (def_slave_hsel='1' and s_dec_hready='1' and mst_in_sel.htrans/=idle) then
432
      def_slave_hready <= '0' after 1 ns;
433
    else
434
      def_slave_hready <= '1' after 1 ns;
435
    end if;
436
  end if;
437
end process;
438
 
439
 
440
 
441
--synopsys translate_off
442
 assert not(hclk'event and hclk='1' and r_def_slave_hsel='1') report "####ERROR: NO SLAVE SELECTED!!!" severity error;
443
--synopsys translate_on
444
 
445
end rtl;
446
 
447
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.