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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [grlib/] [amba/] [ahbctrl.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
------------------------------------------------------------------------------
2
--  This file is a part of the GRLIB VHDL IP LIBRARY
3
--  Copyright (C) 2003, Gaisler Research
4
--
5
--  This program is free software; you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation; either version 2 of the License, or
8
--  (at your option) any later version.
9
--
10
--  This program is distributed in the hope that it will be useful,
11
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--  GNU General Public License for more details.
14
--
15
--  You should have received a copy of the GNU General Public License
16
--  along with this program; if not, write to the Free Software
17
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
----------------------------------------------------------------------------   
19
-- Entity:      ahbctrl
20
-- File:        ahbctrl.vhd
21
-- Author:      Jiri Gaisler, Gaisler Research
22
-- Modified:    Edvin Catovic, Gaisler Research
23
-- Description: AMBA arbiter, decoder and multiplexer with plug&play support
24
------------------------------------------------------------------------------ 
25
 
26
library ieee;
27
use ieee.std_logic_1164.all;
28
library grlib;
29
use grlib.stdlib.all;
30
use grlib.amba.all;
31
-- pragma translate_off
32
use grlib.devices.all;
33
use std.textio.all;
34
-- pragma translate_on
35
 
36
entity ahbctrl is
37
  generic (
38
    defmast     : integer := 0;          -- default master
39
    split       : integer := 0;          -- split support
40
    rrobin      : integer := 0;          -- round-robin arbitration
41
    timeout     : integer range 0 to 255 := 0;  -- HREADY timeout
42
    ioaddr      : ahb_addr_type := 16#fff#;  -- I/O area MSB address
43
    iomask      : ahb_addr_type := 16#fff#;  -- I/O area address mask
44
    cfgaddr     : ahb_addr_type := 16#ff0#;  -- config area MSB address
45
    cfgmask     : ahb_addr_type := 16#ff0#;  -- config area address mask
46
    nahbm       : integer range 1 to NAHBMST := NAHBMST; -- number of masters
47
    nahbs       : integer range 1 to NAHBSLV := NAHBSLV; -- number of slaves
48
    ioen        : integer range 0 to 15 := 1;    -- enable I/O area
49
    disirq      : integer range 0 to 1 := 0;     -- disable interrupt routing
50
    fixbrst     : integer range 0 to 1 := 0;     -- support fix-length bursts
51
    debug       : integer range 0 to 2 := 2;     -- report cores to console
52
    fpnpen      : integer range 0 to 1 := 0; -- full PnP configuration decoding
53
    icheck      : integer range 0 to 1 := 1;
54
    devid       : integer := 0;               -- unique device ID
55
    enbusmon    : integer range 0 to 1 := 0; --enable bus monitor
56
    assertwarn  : integer range 0 to 1 := 0; --enable assertions for warnings 
57
    asserterr   : integer range 0 to 1 := 0; --enable assertions for errors
58
    hmstdisable : integer := 0; --disable master checks           
59
    hslvdisable : integer := 0; --disable slave checks
60
    arbdisable  : integer := 0; --disable arbiter checks
61
    mprio       : integer := 0; --master with highest priority
62
    enebterm    : integer range 0 to 1 := 0  --enable early burst termination
63
  );
64
  port (
65
    rst     : in  std_ulogic;
66
    clk     : in  std_ulogic;
67
    msti    : out ahb_mst_in_type;
68
    msto    : in  ahb_mst_out_vector;
69
    slvi    : out ahb_slv_in_type;
70
    slvo    : in  ahb_slv_out_vector;
71
    testen  : in  std_ulogic := '0';
72
    testrst : in  std_ulogic := '1';
73
    scanen  : in  std_ulogic := '0';
74
    testoen : in  std_ulogic := '1'
75
  );
76
end;
77
 
78
architecture rtl of ahbctrl is
79
 
80
constant nahbmx : integer := 2**log2(nahbm);
81
type nmstarr is array (1 to 3) of integer range 0 to nahbmx-1;
82
type nvalarr is array (1 to 3) of boolean;
83
 
84
type reg_type is record
85
  hmaster      : integer range 0 to nahbmx -1;
86
  hmasterd     : integer range 0 to nahbmx -1;
87
  hslave       : integer range 0 to nahbs-1;
88
  hmasterlock  : std_ulogic;
89
  hmasterlockd : std_ulogic;
90
  hready       : std_ulogic;
91
  defslv       : std_ulogic;
92
  htrans       : std_logic_vector(1 downto 0);
93
  haddr        : std_logic_vector(15 downto 2);
94
  cfgsel       : std_ulogic;
95
  cfga11       : std_ulogic;
96
  hrdatam      : std_logic_vector(31 downto 0);
97
  hrdatas      : std_logic_vector(31 downto 0);
98
  beat         : std_logic_vector(3 downto 0);
99
  defmst       : std_ulogic;
100
  ldefmst      : std_ulogic;
101
end record;
102
 
103
  constant primst : std_logic_vector(NAHBMST downto 0) := conv_std_logic_vector(mprio, NAHBMST+1);
104
  type l0_type is array (0 to 15) of std_logic_vector(2 downto 0);
105
  type l1_type is array (0 to 7) of std_logic_vector(3 downto 0);
106
  type l2_type is array (0 to 3) of std_logic_vector(4 downto 0);
107
  type l3_type is array (0 to 1) of std_logic_vector(5 downto 0);
108
 
109
  type tztab_type is array (0 to 15) of std_logic_vector(2 downto 0);
110
 
111
 
112
  --returns the index number of the highest priority request
113
  --signal in the two lsb bits when indexed with a 4-bit
114
  --request vector with the highest priority signal on the
115
  --lsb. the returned msb bit indicates if a request was
116
  --active ('1' = no request active corresponds to "0000")
117
  constant tztab : tztab_type := ("100", "000", "001", "000",
118
                                  "010", "000", "001", "000",
119
                                  "011", "000", "001", "000",
120
                                  "010", "000", "001", "000");
121
 
122
 
123
  --calculate the number of the highest priority request signal(up to 64
124
  --requests are supported) in vect_in using a divide and conquer
125
  --algorithm. The lower the index in the vector the higher the priority
126
  --of the signal. First 4-bit slices are indexed in tztab and the msb
127
  --indicates whether there is an active request or not. Then the resulting
128
  --3 bit vectors are compared in pairs (the one corresponding to (3:0) with
129
  --(7:4), (11:8) with (15:12) and so on). If the least significant of the two
130
  --contains an active signal a '0' is added to the msb side (the vector
131
  --becomes one bit wider at each level) to the next level to indicate that
132
  --there are active signals in the lower nibble of the two. Otherwise
133
  --the msb is removed from the vector corresponding to the higher nibble
134
  --and "10" is added if it does not contain active requests and "01" if
135
  --does contain active signals. Thus the msb still indicates if the new
136
  --slice contains active signals and a '1' is added if it is the higher
137
  --part. This results in a 6-bit vector containing the index number
138
  --of the highest priority master in 5:0 if bit 6 is '0' otherwise
139
  --no master requested the bus.
140
  function tz(vect_in : std_logic_vector) return std_logic_vector is
141
    variable vect : std_logic_vector(63 downto 0);
142
    variable l0 : l0_type;
143
    variable l1 : l1_type;
144
    variable l2 : l2_type;
145
    variable l3 : l3_type;
146
    variable l4 : std_logic_vector(6 downto 0);
147
    variable bci_lsb, bci_msb : std_logic_vector(3 downto 0);
148
    variable bco_lsb, bco_msb : std_logic_vector(2 downto 0);
149
    variable sel : std_logic;
150
  begin
151
 
152
    vect := (others => '1');
153
    vect(vect_in'length-1 downto 0) := vect_in;
154
 
155
    -- level 0
156
    for i in 0 to 7 loop
157
      bci_lsb := vect(8*i+3 downto 8*i);
158
      bci_msb := vect(8*i+7 downto 8*i+4);
159
      --lookup the highest priority request in each nibble
160
      bco_lsb := tztab(conv_integer(bci_lsb));
161
      bco_msb := tztab(conv_integer(bci_msb));
162
      --select which of two nibbles contain the highest priority ACTIVE
163
      --signal, and forward the corresponding vector to the next level
164
      sel := bco_lsb(2);
165
      if sel = '0' then l1(i) := '0' & bco_lsb;
166
      else l1(i) := bco_msb(2) & not bco_msb(2) & bco_msb(1 downto 0); end if;
167
    end loop;
168
 
169
    -- level 1
170
    for i in 0 to 3 loop
171
      sel := l1(2*i)(3);
172
      --select which of two 8-bit vectors contain the
173
      --highest priority ACTIVE signal. the msb set at the previous level
174
      --for each 8-bit slice determines this
175
      if sel = '0' then l2(i) := '0' & l1(2*i);
176
      else
177
        l2(i) := l1(2*i+1)(3) & not l1(2*i+1)(3) & l1(2*i+1)(2 downto 0);
178
      end if;
179
    end loop;
180
 
181
    -- level 2
182
    for i in 0 to 1 loop
183
      --16-bit vectors, the msb set at the previous level for each 16-bit
184
      --slice determines the higher priority slice
185
      sel := l2(2*i)(4);
186
      if sel = '0' then l3(i) := '0' & l2(2*i);
187
      else
188
        l3(i) := l2(2*i+1)(4) & not l2(2*i+1)(4) & l2(2*i+1)(3 downto 0);
189
      end if;
190
    end loop;
191
 
192
    --level 3
193
    --32-bit vectors, the msb set at the previous level for each 32-bit
194
    --slice determines the higher priority slice
195
    if l3(0)(5) = '0' then l4 := '0' & l3(0);
196
    else l4 := l3(1)(5) & not l3(1)(5) & l3(1)(4 downto 0); end if;
197
 
198
    return(l4);
199
  end;
200
 
201
  --invert the bit order of the hbusreq signals located in vect_in
202
  --since the highest hbusreq has the highest priority but the
203
  --algorithm in tz has the highest priority on lsb
204
  function lz(vect_in : std_logic_vector) return std_logic_vector is
205
    variable vect : std_logic_vector(vect_in'length-1 downto 0);
206
    variable vect2 : std_logic_vector(vect_in'length-1 downto 0);
207
  begin
208
    vect := vect_in;
209
    for i in vect'right to vect'left loop
210
      vect2(i) := vect(vect'left-i);
211
    end loop;
212
    return(tz(vect2));
213
  end;
214
 
215
-- Find next master:
216
--   * 2 arbitration policies: fixed priority or round-robin
217
--   * Fixed priority: priority is fixed, highest index has highest priority
218
--   * Round-robin: arbiter maintains circular queue of masters
219
--   * (master 0, master 1, ..., master (nahbmx-1)). First requesting master
220
--   * in the queue is granted access to the bus and moved to the end of the queue.  
221
--   * splitted masters are not granted
222
--   * bus is re-arbited when current owner does not request the bus,
223
--     or when it performs non-burst accesses
224
--   * fix length burst transfers will not be interrupted
225
--   * incremental bursts should assert hbusreq until last access
226
 
227
  procedure selmast(r      : in reg_type;
228
                  msto   : in ahb_mst_out_vector;
229
                  rsplit : in std_logic_vector(0 to nahbmx-1);
230
                  mast   : out integer range 0 to nahbmx-1;
231
                  defmst : out std_ulogic) is
232
  variable nmst    : nmstarr;
233
  variable nvalid  : nvalarr;
234
 
235
  variable rrvec : std_logic_vector(nahbmx*2-1 downto 0);
236
  variable zcnt  : std_logic_vector(log2(nahbmx)+1 downto 0);
237
  variable hpvec : std_logic_vector(nahbmx-1 downto 0);
238
  variable zcnt2 : std_logic_vector(log2(nahbmx) downto 0);
239
 
240
  begin
241
 
242
    nvalid(1 to 3) := (others => false); nmst(1 to 3) := (others => 0);
243
    mast := r.hmaster;
244
    defmst := '0';
245
 
246
    if nahbm = 1 then
247
      mast := 0;
248
    elsif rrobin = 0 then
249
      hpvec := (others => '0');
250
      for i in 0 to nahbmx-1 loop
251
        --masters which have received split are not granted
252
        if ((rsplit(i) = '0') or (split = 0)) then
253
          hpvec(i) := msto(i).hbusreq;
254
        end if;
255
      end loop;
256
      --check if any bus requests are active (nvalid(2) set to true)
257
      --and determine the index (zcnt2) of the highest priority master
258
      zcnt2 := lz(hpvec)(log2(nahbmx) downto 0);
259
      if zcnt2(log2(nahbmx)) = '0' then nvalid(2) := true; end if;
260
      nmst(2) := conv_integer(not (zcnt2(log2(nahbmx)-1 downto 0)));
261
      --find the default master number
262
      for i in 0 to nahbmx-1 loop
263
        if not ((nmst(3) = defmast) and nvalid(3)) then
264
          nmst(3) := i; nvalid(3) := true;
265
        end if;
266
      end loop;
267
    else
268
      rrvec := (others => '0');
269
      --mask requests up to and including current master. Concatenate
270
      --an unmasked request vector above the masked vector. Otherwise
271
      --the rules are the same as for fixed priority
272
      for i in 0 to nahbmx-1 loop
273
        if ((rsplit(i) = '0') or (split = 0)) then
274
          if (i <= r.hmaster) then rrvec(i) := '0';
275
          else rrvec(i) := msto(i).hbusreq; end if;
276
          rrvec(nahbmx+i) := msto(i).hbusreq;
277
        end if;
278
      end loop;
279
      --find the next master uzing tz which gives priority to lower
280
      --indexes
281
      zcnt := tz(rrvec)(log2(nahbmx)+1 downto 0);
282
      --was there a master requesting the bus?
283
      if zcnt(log2(nahbmx)+1) = '0' then nvalid(2) := true; end if;
284
      nmst(2) := conv_integer(zcnt(log2(nahbmx)-1 downto 0));
285
      --if no other master is requesting the bus select the current one
286
      nmst(3) := r.hmaster; nvalid(3) := true;
287
      --check if any masters configured with higher priority are requesting
288
      --the bus
289
      if mprio /= 0 then
290
        for i in 0 to nahbm-1 loop
291
          if (((rsplit(i) = '0') or (split = 0)) and (primst(i) = '1')) then
292
            if msto(i).hbusreq = '1' then nmst(1) := i; nvalid(1) := true; end if;
293
          end if;
294
        end loop;
295
      end if;
296
    end if;
297
 
298
    --select the next master. If for round robin a high priority master
299
    --(mprio) requested the bus if nvalid(1) is true. Otherwise
300
    --if nvalid(2) is true at least one master was requesting the bus
301
    --and the one with highest priority was selected. If none of these
302
    --were true then the default master is selected (nvalid(3) true)
303
    for i in 1 to 3 loop
304
      if nvalid(i) then mast := nmst(i); exit; end if;
305
    end loop;
306
 
307
    --if no master was requesting the bus and split is enabled
308
    --then select builtin dummy master which only does
309
    --idle transfers
310
    if (not (nvalid(1) or nvalid(2))) and (split /= 0) then
311
      defmst := orv(rsplit);
312
    end if;
313
 
314
  end;
315
 
316
  constant MIMAX : integer := log2x(nahbmx) - 1;
317
  constant SIMAX : integer := log2x(nahbs) - 1;
318
  constant IOAREA : std_logic_vector(11 downto 0) :=
319
        conv_std_logic_vector(ioaddr, 12);
320
  constant IOMSK  : std_logic_vector(11 downto 0) :=
321
        conv_std_logic_vector(iomask, 12);
322
  constant CFGAREA : std_logic_vector(11 downto 0) :=
323
        conv_std_logic_vector(cfgaddr, 12);
324
  constant CFGMSK  : std_logic_vector(11 downto 0) :=
325
        conv_std_logic_vector(cfgmask, 12);
326
  constant FULLPNP : boolean := (fpnpen /= 0);
327
 
328
  signal r, rin : reg_type;
329
  signal rsplit, rsplitin : std_logic_vector(0 to nahbmx-1);
330
 
331
-- pragma translate_off
332
  signal lmsti : ahb_mst_in_type;
333
  signal lslvi : ahb_slv_in_type;
334
-- pragma translate_on
335
 
336
begin
337
 
338
  comb : process(rst, msto, slvo, r, rsplit, testen, testrst, scanen, testoen)
339
  variable v : reg_type;
340
  variable nhmaster, hmaster : integer range 0 to nahbmx -1;
341
  variable hgrant  : std_logic_vector(0 to NAHBMST-1);   -- bus grant
342
  variable hsel    : std_logic_vector(0 to 31);   -- slave select
343
  variable hmbsel  : std_logic_vector(0 to NAHBAMR-1);
344
  variable nslave  : natural range 0 to 31;
345
  variable vsplit  : std_logic_vector(0 to nahbmx-1);
346
  variable bnslave : std_logic_vector(3 downto 0);
347
  variable area    : std_logic_vector(1 downto 0);
348
  variable hready  : std_ulogic;
349
  variable defslv  : std_ulogic;
350
  variable cfgsel  : std_ulogic;
351
  variable hcache  : std_ulogic;
352
  variable hresp   : std_logic_vector(1 downto 0);
353
  variable hrdata  : std_logic_vector(31 downto 0);
354
  variable haddr   : std_logic_vector(31 downto 0);
355
  variable hirq    : std_logic_vector(NAHBIRQ-1 downto 0);
356
  variable arb     : std_ulogic;
357
  variable hconfndx : integer range 0 to 7;
358
  variable vslvi   : ahb_slv_in_type;
359
  variable defmst   : std_ulogic;
360
  variable tmpv     : std_logic_vector(0 to nahbmx-1);
361
 
362
  begin
363
 
364
    v := r; hgrant := (others => '0'); defmst := '0';
365
    haddr := msto(r.hmaster).haddr;
366
 
367
    nhmaster := r.hmaster;
368
 
369
    --determine if bus should be rearbitrated. This is done if the current
370
    --master is not performing a locked transfer and if not in the middle
371
    --of burst
372
    arb := '0';
373
    if (r.hmasterlock or r.ldefmst) = '0' then
374
      case msto(r.hmaster).htrans is
375
        when HTRANS_IDLE => arb := '1';
376
        when HTRANS_NONSEQ =>
377
          case msto(r.hmaster).hburst is
378
            when HBURST_SINGLE => arb := '1';
379
            when HBURST_INCR => arb := not msto(r.hmaster).hbusreq;
380
            when others =>
381
          end case;
382
        when HTRANS_SEQ =>
383
          case msto(r.hmaster).hburst is
384
            when HBURST_WRAP4  | HBURST_INCR4  => if (fixbrst = 1) and (r.beat(1 downto 0) = "11")   then arb := '1'; end if;
385
            when HBURST_WRAP8  | HBURST_INCR8  => if (fixbrst = 1) and (r.beat(2 downto 0) = "111")  then arb := '1'; end if;
386
            when HBURST_WRAP16 | HBURST_INCR16 => if (fixbrst = 1) and (r.beat(3 downto 0) = "1111") then arb := '1'; end if;
387
            when HBURST_INCR => arb := not msto(r.hmaster).hbusreq;
388
            when others =>
389
          end case;
390
        when others => arb := '0';
391
      end case;
392
-- pragma translate_off 
393
      if enebterm = 1 then arb := '1'; end if;
394
-- pragma translate_on
395
    end if;
396
 
397
    if (split /= 0) then
398
      for i in 0 to nahbmx-1 loop
399
        tmpv(i) := (msto(i).htrans(1) or (msto(i).hbusreq)) and not rsplit(i) and not r.ldefmst;
400
      end loop;
401
      if (r.defmst and orv(tmpv))  = '1' then arb := '1'; end if;
402
    end if;
403
 
404
    --rearbitrate bus with selmast. If not arbitrated one must
405
    --ensure that the dummy master is selected for locked splits. 
406
    if (arb = '1') then
407
      selmast(r, msto, rsplit, nhmaster, defmst);
408
    elsif (split /= 0) then
409
      defmst := r.defmst;
410
    end if;
411
 
412
    -- slave decoding
413
 
414
    hsel := (others => '0'); hmbsel := (others => '0');
415
 
416
    for i in 0 to nahbs-1 loop
417
      for j in NAHBIR to NAHBCFG-1 loop
418
        area := slvo(i).hconfig(j)(1 downto 0);
419
        case area is
420
        when "10" =>
421
          if ((ioen = 0) or ((IOAREA and IOMSK) /= (haddr(31 downto 20) and IOMSK))) and
422
             ((slvo(i).hconfig(j)(31 downto 20) and slvo(i).hconfig(j)(15 downto 4)) =
423
              (haddr(31 downto 20) and slvo(i).hconfig(j)(15 downto 4))) and
424
              (slvo(i).hconfig(j)(15 downto 4) /= "000000000000")
425
          then hsel(i) := '1'; hmbsel(j-NAHBIR) := '1'; end if;
426
        when "11" =>
427
          if ((ioen /= 0) and ((IOAREA and IOMSK) = (haddr(31 downto 20) and IOMSK))) and
428
             ((slvo(i).hconfig(j)(31 downto 20) and slvo(i).hconfig(j)(15 downto 4)) =
429
              (haddr(19 downto  8) and slvo(i).hconfig(j)(15 downto 4))) and
430
              (slvo(i).hconfig(j)(15 downto 4) /= "000000000000")
431
          then hsel(i) := '1'; hmbsel(j-NAHBIR) := '1'; end if;
432
        when others =>
433
        end case;
434
      end loop;
435
    end loop;
436
 
437
    if r.defmst = '1' then hsel := (others => '0'); end if;
438
 
439
    bnslave(0) := hsel(1) or hsel(3) or hsel(5) or hsel(7) or
440
                  hsel(9) or hsel(11) or hsel(13) or hsel(15);
441
    bnslave(1) := hsel(2) or hsel(3) or hsel(6) or hsel(7) or
442
                  hsel(10) or hsel(11) or hsel(14) or hsel(15);
443
    bnslave(2) := hsel(4) or hsel(5) or hsel(6) or hsel(7) or
444
                  hsel(12) or hsel(13) or hsel(14) or hsel(15);
445
    bnslave(3) := hsel(8) or hsel(9) or hsel(10) or hsel(11) or
446
                  hsel(12) or hsel(13) or hsel(14) or hsel(15);
447
    nslave := conv_integer(bnslave(SIMAX downto 0));
448
 
449
    if ((((IOAREA and IOMSK) = (haddr(31 downto 20) and IOMSK)) and (ioen /= 0))
450
      or ((IOAREA = haddr(31 downto 20)) and (ioen = 0))) and
451
       ((CFGAREA and CFGMSK) = (haddr(19 downto  8) and CFGMSK))
452
       and (cfgmask /= 0)
453
    then cfgsel := '1'; hsel := (others => '0');
454
    else cfgsel := '0'; end if;
455
 
456
    if (nslave = 0) and (hsel(0) = '0') and (cfgsel = '0') then defslv := '1';
457
    else defslv := '0'; end if;
458
 
459
    if r.defmst = '1' then
460
      cfgsel := '0'; defslv := '1';
461
    end if;
462
 
463
-- error response on undecoded area
464
 
465
    v.hready := '0';
466
    hready := slvo(r.hslave).hready; hresp := slvo(r.hslave).hresp;
467
    if r.defslv = '1' then
468
      -- default slave
469
      if (r.htrans = HTRANS_IDLE) or (r.htrans = HTRANS_BUSY) then
470
        hresp := HRESP_OKAY; hready := '1';
471
      else
472
        -- return two-cycle error in case of unimplemented slave access
473
        hresp := HRESP_ERROR; hready := r.hready; v.hready := not r.hready;
474
      end if;
475
    end if;
476
 
477
    hrdata := slvo(r.hslave).hrdata;
478
 
479
    if cfgmask /= 0 then
480
--      v.hrdatam := msto(conv_integer(r.haddr(MIMAX+5 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2)));
481
--      if r.haddr(11 downto MIMAX+6) /= zero32(11 downto MIMAX+6) then v.hrdatam := (others => '0'); end if;
482
 
483
--       if (r.haddr(10 downto MIMAX+6) = zero32(10 downto MIMAX+6)) and (r.haddr(4 downto 2) = "000")
484
      if FULLPNP then hconfndx := conv_integer(r.haddr(4 downto 2)); else hconfndx := 0; end if;
485
      if (r.haddr(10 downto MIMAX+6) = zero32(10 downto MIMAX+6)) and (FULLPNP or (r.haddr(4 downto 2) = "000"))
486
      then v.hrdatam := msto(conv_integer(r.haddr(MIMAX+5 downto 5))).hconfig(hconfndx);
487
      else v.hrdatam := (others => '0'); end if;
488
 
489
--      v.hrdatas := slvo(conv_integer(r.haddr(SIMAX+5 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2)));
490
--      if r.haddr(11 downto SIMAX+6) /= ('1' & zero32(10 downto SIMAX+6)) then v.hrdatas := (others => '0'); end if;
491
 
492
      --if (r.haddr(10 downto SIMAX+6) = zero32(10 downto SIMAX+6)) and
493
      if (r.haddr(10 downto SIMAX+6) = zero32(10 downto SIMAX+6)) and
494
        (FULLPNP or (r.haddr(4 downto 2) = "000") or (r.haddr(4) = '1'))
495
      then v.hrdatas := slvo(conv_integer(r.haddr(SIMAX+5 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2)));
496
      else v.hrdatas := (others => '0'); end if;
497
 
498
      if r.haddr(10 downto 4) = "1111111" then
499
         v.hrdatas(15 downto 0) := conv_std_logic_vector(LIBVHDL_BUILD, 16);
500
         v.hrdatas(31 downto 16) := conv_std_logic_vector(devid, 16);
501
      end if;
502
      if r.cfgsel = '1' then
503
        hrdata := (others => '0');
504
        -- default slave
505
        if (r.htrans = HTRANS_IDLE) or (r.htrans = HTRANS_BUSY) then
506
          hresp := HRESP_OKAY; hready := '1';
507
        else
508
          -- return two-cycle read/write respons
509
          hresp := HRESP_OKAY; hready := r.hready; v.hready := not r.hready;
510
        end if;
511
        if r.cfga11 = '0' then hrdata := r.hrdatam;
512
        else hrdata := r.hrdatas; end if;
513
      end if;
514
    end if;
515
 
516
    --degrant all masters when split occurs for locked access
517
    if (r.hmasterlockd = '1') then
518
      if (hresp = HRESP_RETRY) or ((split /= 0) and (hresp = HRESP_SPLIT)) then
519
        nhmaster := r.hmaster;
520
      end if;
521
      if split /= 0 then
522
        if hresp = HRESP_SPLIT then
523
          v.ldefmst := '1'; defmst := '1';
524
        end if;
525
      end if;
526
    end if;
527
 
528
    if r.ldefmst = '1' then
529
      if orv(rsplit) = '0' then
530
        v.ldefmst := '0'; defmst := '0';
531
      end if;
532
    end if;
533
 
534
    if (split = 0) or (defmst = '0') then hgrant(nhmaster) := '1'; end if;
535
 
536
    -- latch active master and slave
537
    if hready = '1' then
538
      v.hmaster := nhmaster; v.hmasterd := r.hmaster;
539
      v.hslave := nslave; v.defslv := defslv;
540
      v.hmasterlockd := r.hmasterlock;
541
      if (split = 0) or (r.defmst = '0') then v.htrans := msto(r.hmaster).htrans;
542
      else v.htrans := HTRANS_IDLE; end if;
543
      v.cfgsel := cfgsel;
544
      v.cfga11 := msto(r.hmaster).haddr(11);
545
      v.haddr := msto(r.hmaster).haddr(15 downto 2);
546
      if (msto(r.hmaster).htrans = HTRANS_NONSEQ) or (msto(r.hmaster).htrans = HTRANS_IDLE) then
547
        v.beat := "0001";
548
      elsif (msto(r.hmaster).htrans = HTRANS_SEQ) then
549
        if (fixbrst = 1) then v.beat := r.beat + 1; end if;
550
      end if;
551
      if (split /= 0) then v.defmst := defmst; end if;
552
    end if;
553
 
554
    --assign new hmasterlock, v.hmaster is used because if hready
555
    --then master can have changed, and when not hready then the
556
    --previous master will still be selected
557
    v.hmasterlock := msto(v.hmaster).hlock or (r.hmasterlock and not hready);
558
 
559
    -- split support
560
    vsplit := (others => '0');
561
    if SPLIT /= 0 then
562
      vsplit := rsplit;
563
      if slvo(r.hslave).hresp = HRESP_SPLIT then vsplit(r.hmasterd) := '1'; end if;
564
      for i in 0 to nahbs-1 loop
565
        for j in 0 to nahbmx-1 loop
566
          vsplit(j) := vsplit(j) and not slvo(i).hsplit(j);
567
        end loop;
568
      end loop;
569
    end if;
570
 
571
    if r.cfgsel = '1' then hcache := '1'; else hcache := slvo(v.hslave).hcache; end if;
572
 
573
    -- interrupt merging
574
    hirq := (others => '0');
575
    if disirq = 0 then
576
      for i in 0 to nahbs-1 loop hirq := hirq or slvo(i).hirq; end loop;
577
      for i in 0 to nahbm-1 loop hirq := hirq or msto(i).hirq; end loop;
578
    end if;
579
 
580
    if (split = 0) or (r.defmst = '0') then
581
      vslvi.haddr      := haddr;
582
      vslvi.htrans     := msto(r.hmaster).htrans;
583
      vslvi.hwrite     := msto(r.hmaster).hwrite;
584
      vslvi.hsize      := msto(r.hmaster).hsize;
585
      vslvi.hburst     := msto(r.hmaster).hburst;
586
      vslvi.hready     := hready;
587
      vslvi.hwdata     := msto(r.hmasterd).hwdata;
588
      vslvi.hprot      := msto(r.hmaster).hprot;
589
--      vslvi.hmastlock  := msto(r.hmaster).hlock;
590
      vslvi.hmastlock  := r.hmasterlock;
591
      vslvi.hmaster    := conv_std_logic_vector(r.hmaster, 4);
592
      vslvi.hsel       := hsel(0 to NAHBSLV-1);
593
      vslvi.hmbsel     := hmbsel;
594
      vslvi.hcache     := hcache;
595
      vslvi.hirq       := hirq;
596
    else
597
      vslvi := ahbs_in_none;
598
      vslvi.hready := hready;
599
      vslvi.hwdata := msto(r.hmasterd).hwdata;
600
      vslvi.hirq   := hirq;
601
    end if;
602
    vslvi.testen  := testen;
603
    vslvi.testrst := testrst;
604
    vslvi.scanen  := scanen and testen;
605
    vslvi.testoen := testoen;
606
 
607
    -- reset operation
608
    if (rst = '0') then
609
      v.hmaster := 0; v.hmasterlock := '0'; vsplit := (others => '0');
610
      v.htrans := HTRANS_IDLE;  v.defslv := '0'; -- v.beat := "0001";
611
      v.hslave := 0; v.cfgsel := '0'; v.defmst := '0';
612
      v.ldefmst := '0';
613
    end if;
614
 
615
    -- drive master inputs
616
    msti.hgrant  <= hgrant;
617
    msti.hready  <= hready;
618
    msti.hresp   <= hresp;
619
    msti.hrdata  <= hrdata;
620
    msti.hcache  <= hcache;
621
    msti.hirq    <= hirq;
622
    msti.testen  <= testen;
623
    msti.testrst <= testrst;
624
    msti.scanen  <= scanen and testen;
625
    msti.testoen <= testoen;
626
 
627
    -- drive slave inputs
628
    slvi     <= vslvi;
629
 
630
-- pragma translate_off
631
    --drive internal signals to bus monitor
632
    lslvi         <= vslvi;
633
 
634
    lmsti.hgrant  <= hgrant;
635
    lmsti.hready  <= hready;
636
    lmsti.hresp   <= hresp;
637
    lmsti.hrdata  <= hrdata;
638
    lmsti.hcache  <= hcache;
639
    lmsti.hirq    <= hirq;
640
-- pragma translate_on
641
 
642
    rin <= v; rsplitin <= vsplit;
643
 
644
  end process;
645
 
646
 
647
  reg0 : process(clk)
648
  begin
649
    if rising_edge(clk) then r <= rin; end if;
650
    if (split = 0) then r.defmst <= '0'; end if;
651
  end process;
652
 
653
  splitreg : if SPLIT /= 0 generate
654
    reg1 : process(clk)
655
    begin if rising_edge(clk) then rsplit <= rsplitin; end if; end process;
656
  end generate;
657
 
658
  nosplitreg : if SPLIT = 0 generate
659
    rsplit <= (others => '0');
660
  end generate;
661
 
662
-- pragma translate_off
663
--  diag : process
664
--  variable k : integer;
665
--  variable mask : std_logic_vector(11 downto 0);
666
--  variable iostart : std_logic_vector(11 downto 0) := IOAREA and IOMSK;
667
--  variable cfgstart : std_logic_vector(11 downto 0) := CFGAREA and CFGMSK;
668
--  begin
669
--    wait for 2 ns;
670
--    k := 0; mask := IOMSK;
671
--    while (k<12) and (mask(k) = '0') loop k := k+1; end loop; 
672
--    print("ahbctrl: AHB arbiter/multiplexer rev 1");
673
--    if ioen /= 0 then
674
--      print("ahbctrl: Common I/O area at " & tost(iostart) & "00000, " & tost(2**k) & " Mbyte");
675
--    else
676
--      print("ahbctrl: Common I/O area disabled");
677
--    end if;
678
--    if cfgmask /= 0 then
679
--      print("ahbctrl: Configuration area at " & tost(iostart & cfgstart) & "00, 4 kbyte");
680
--    else
681
--      print("ahbctrl: Configuration area disabled");
682
--    end if;
683
--    wait;
684
--  end process;
685
 
686
  mon0 : if enbusmon /= 0 generate
687
    mon : ahbmon
688
      generic map(
689
        asserterr   => asserterr,
690
        assertwarn  => assertwarn,
691
        hmstdisable => hmstdisable,
692
        hslvdisable => hslvdisable,
693
        arbdisable  => arbdisable,
694
        nahbm       => nahbm,
695
        nahbs       => nahbs)
696
      port map(
697
        rst         => rst,
698
        clk         => clk,
699
        ahbmi       => lmsti,
700
        ahbmo       => msto,
701
        ahbsi       => lslvi,
702
        ahbso       => slvo,
703
        err         => open);
704
  end generate;
705
 
706
  diag : process
707
  variable k : integer;
708
  variable mask : std_logic_vector(11 downto 0);
709
  variable device : std_logic_vector(11 downto 0);
710
  variable devicei : integer;
711
  variable vendor : std_logic_vector( 7 downto 0);
712
  variable area : std_logic_vector( 1 downto 0);
713
  variable vendori : integer;
714
  variable iosize, tmp : integer;
715
  variable iounit : string(1 to 5) := " byte";
716
  variable memtype : string(1 to 9);
717
  variable iostart : std_logic_vector(11 downto 0) := IOAREA and IOMSK;
718
  variable cfgstart : std_logic_vector(11 downto 0) := CFGAREA and CFGMSK;
719
  variable L1 : line := new string'("");
720
  variable S1 : string(1 to 255);
721
 
722
  begin
723
    wait for 2 ns;
724
    if debug = 0 then wait; end if;
725
    k := 0; mask := IOMSK;
726
    while (k<12) and (mask(k) = '0') loop k := k+1; end loop;
727
    print("ahbctrl: AHB arbiter/multiplexer rev 1");
728
    if ioen /= 0 then
729
      print("ahbctrl: Common I/O area at " & tost(iostart) & "00000, " & tost(2**k) & " Mbyte");
730
    else
731
      print("ahbctrl: Common I/O area disabled");
732
    end if;
733
    print("ahbctrl: AHB masters: " & tost(nahbm) & ", AHB slaves: " & tost(nahbs));
734
    if cfgmask /= 0 then
735
      print("ahbctrl: Configuration area at " & tost(iostart & cfgstart) & "00, 4 kbyte");
736
    else
737
      print("ahbctrl: Configuration area disabled");
738
    end if;
739
    if debug = 1 then wait; end if;
740
    for i in 0 to nahbm-1 loop
741
      vendor := msto(i).hconfig(0)(31 downto 24);
742
      vendori := conv_integer(vendor);
743
      if vendori /= 0 then
744
        device := msto(i).hconfig(0)(23 downto 12);
745
        devicei := conv_integer(device);
746
        print("ahbctrl: mst" & tost(i) & ": " & iptable(vendori).vendordesc &
747
           iptable(vendori).device_table(devicei));
748
        assert (msto(i).hindex = i) or (icheck = 0)
749
        report "AHB master index error on master " & tost(i) severity failure;
750
      end if;
751
    end loop;
752
    for i in 0 to nahbs-1 loop
753
      vendor := slvo(i).hconfig(0)(31 downto 24);
754
      vendori := conv_integer(vendor);
755
      if vendori /= 0 then
756
        device := slvo(i).hconfig(0)(23 downto 12);
757
        devicei := conv_integer(device);
758
        std.textio.write(L1, "ahbctrl: slv" & tost(i) & ": " & iptable(vendori).vendordesc &
759
           iptable(vendori).device_table(devicei));
760
        std.textio.writeline(OUTPUT, L1);
761
        for j in NAHBIR to NAHBCFG-1 loop
762
          area := slvo(i).hconfig(j)(1 downto 0);
763
          mask := slvo(i).hconfig(j)(15 downto 4);
764
          if (mask /= "000000000000") then
765
            case area is
766
            when "01" =>
767
            when "10" =>
768
              k := 0;
769
              while (k<15) and (mask(k) = '0') loop k := k+1; end loop;
770
              std.textio.write(L1, "ahbctrl:       memory at " & tost( slvo(i).hconfig(j)(31 downto 20))&
771
                "00000, size "& tost(2**k) & " Mbyte");
772
              if slvo(i).hconfig(j)(16) = '1' then
773
                std.textio.write(L1, string'(", cacheable"));
774
              end if;
775
              if slvo(i).hconfig(j)(17) = '1' then
776
                std.textio.write(L1, string'(", prefetch"));
777
               end if;
778
              std.textio.writeline(OUTPUT, L1);
779
            when "11" =>
780
              if ioen /= 0 then
781
                k := 0;
782
                while (k<15) and (mask(k) = '0') loop k := k+1; end loop;
783
                iosize := 256 * 2**k; iounit(1) := ' ';
784
                if (iosize > 1023) then
785
                  iosize := iosize/1024; iounit(1) := 'k';
786
                end if;
787
                print("ahbctrl:       I/O port at " & tost( iostart &
788
                  ((slvo(i).hconfig(j)(31 downto 20)) and slvo(i).hconfig(j)(15 downto 4))) &
789
                  "00, size "& tost(iosize) & iounit);
790
              end if;
791
            when others =>
792
            end case;
793
          end if;
794
        end loop;
795
        assert (slvo(i).hindex = i) or (icheck = 0)
796
        report "AHB slave index error on slave " & tost(i) severity failure;
797
      end if;
798
    end loop;
799
    wait;
800
  end process;
801
 
802
-- pragma translate_on
803
 
804
end;
805
 

powered by: WebSVN 2.1.0

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