⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ahbctrl_mb.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 2 页
字号:
------------------------------------------------------------------------------  This file is a part of the GRLIB VHDL IP LIBRARY--  Copyright (C) 2004 GAISLER RESEARCH----  This program is free software; you can redistribute it and/or modify--  it under the terms of the GNU General Public License as published by--  the Free Software Foundation; either version 2 of the License, or--  (at your option) any later version.----  See the file COPYING for the full details of the license.------------------------------------------------------------------------------   -- Entity:      ahbctrl_mb-- File:        ahbctrl_mb.vhd-- Author:      Jiri Gaisler, Edvin Catovic, Gaisler Research-- Description: Multiple AMBA bus arbiterm decoder and multiplexer------------------------------------------------------------------------------ library ieee;use ieee.std_logic_1164.all;library grlib;use grlib.stdlib.all;use grlib.amba.all;use grlib.devices.all;-- pragma translate_offuse std.textio.all;-- pragma translate_onentity ahbctrl_mb is    generic (    defmast : integer := 0;		-- default master    split   : integer := 0;		-- split support    rrobin  : integer := 0;		-- round-robin arbitration    timeout : integer range 0 to 255 := 0;  -- HREADY timeout    ioaddr  : ahb_addr_type := 16#fff#;  -- I/O area MSB address    iomask  : ahb_addr_type := 16#fff#;  -- I/O area address mask    cfgaddr : ahb_addr_type := 16#ff0#;  -- config area MSB address    cfgmask : ahb_addr_type := 16#ff0#;   -- config area address mask    nahbm   : integer range 1 to NAHBMST := NAHBMST; -- number of masters    nahbs   : integer range 1 to NAHBSLV := NAHBSLV; -- number of slaves    ioen    : integer range 0 to 15 := 1;   -- enable I/O area    disirq  : integer range 0 to 1 := 0;   -- disable interrupt routing    fixbrst : integer range 0 to 1 := 0;   -- support fix-length bursts    debug   : integer range 0 to 2 := 2;   -- report cores to console    fpnpen  : integer range 0 to 1 := 0;   -- full PnP configuration decoding    busndx  : integer range 0 to 3 := 0;    icheck  : integer range 0 to 1 := 1;        devid   : integer := 0		   -- unique device ID  );  port (    rst     : in  std_ulogic;    clk     : in  std_ulogic;    msti    : out ahb_mst_in_type;    msto    : in  ahb_mst_out_bus_vector;    slvi    : out ahb_slv_in_type;    slvo    : in  ahb_slv_out_bus_vector  );end;architecture rtl of ahbctrl_mb is  constant nahbmx : integer := 2**log2(nahbm);type nmstarr is array (1 to 3) of integer range 0 to nahbmx-1;type nvalarr is array (1 to 3) of boolean;  type reg_type is record  hmaster   : integer range 0 to nahbmx -1;  hmasterd  : integer range 0 to nahbmx -1;  hslave    : integer range 0 to nahbs-1;  hmasterlock : std_ulogic;  hready    : std_ulogic;  defslv    : std_ulogic;  htrans    : std_logic_vector(1 downto 0);  haddr     : std_logic_vector(15 downto 2);   cfgsel    : std_ulogic;  cfga11    : std_ulogic;  hrdatam   : std_logic_vector(31 downto 0);   hrdatas   : std_logic_vector(31 downto 0);  beat      : std_logic_vector(3 downto 0);  defmst    : std_ulogic;end record;  type l0_type is array (0 to 15) of std_logic_vector(2 downto 0);  type l1_type is array (0 to 7) of std_logic_vector(3 downto 0);  type l2_type is array (0 to 3) of std_logic_vector(4 downto 0);  type l3_type is array (0 to 1) of std_logic_vector(5 downto 0);  type tztab_type is array (0 to 15) of std_logic_vector(2 downto 0);  constant tztab : tztab_type := ("100", "000", "001", "000",                                  "010", "000", "001", "000",                                  "011", "000", "001", "000",                                  "010", "000", "001", "000");    function tz(vect_in : std_logic_vector) return std_logic_vector is    variable vect : std_logic_vector(63 downto 0);    variable l0 : l0_type;    variable l1 : l1_type;    variable l2 : l2_type;    variable l3 : l3_type;    variable l4 : std_logic_vector(6 downto 0);    variable bci_lsb, bci_msb : std_logic_vector(3 downto 0);    variable bco_lsb, bco_msb : std_logic_vector(2 downto 0);        variable sel : std_logic;  begin    vect := (others => '1');    vect(vect_in'length-1 downto 0) := vect_in;    -- level 0    for i in 0 to 7 loop      bci_lsb := vect(8*i+3 downto 8*i);      bci_msb := vect(8*i+7 downto 8*i+4);      bco_lsb := tztab(conv_integer(bci_lsb));      bco_msb := tztab(conv_integer(bci_msb));      sel := bco_lsb(2);      if sel = '0' then l1(i) := '0' & bco_lsb;      else l1(i) := bco_msb(2) & not bco_msb(2) & bco_msb(1 downto 0); end if;    end loop;    -- level 1    for i in 0 to 3 loop      sel := l1(2*i)(3);      if sel = '0' then l2(i) := '0' & l1(2*i);      else        l2(i) := l1(2*i+1)(3) & not l1(2*i+1)(3) & l1(2*i+1)(2 downto 0);      end if;    end loop;    -- level 2    for i in 0 to 1 loop      sel := l2(2*i)(4);      if sel = '0' then l3(i) := '0' & l2(2*i);      else        l3(i) := l2(2*i+1)(4) & not l2(2*i+1)(4) & l2(2*i+1)(3 downto 0);      end if;    end loop;    --level 3    if l3(0)(5) = '0' then l4 := '0' & l3(0);    else l4 := l3(1)(5) & not l3(1)(5) & l3(1)(4 downto 0); end if;        return(l4);      end;  function lz(vect_in : std_logic_vector) return std_logic_vector is    variable vect : std_logic_vector(vect_in'length-1 downto 0);    variable vect2 : std_logic_vector(vect_in'length-1 downto 0);      begin    vect := vect_in;    for i in vect'right to vect'left loop      vect2(i) := vect(vect'left-i);    end loop;    return(tz(vect2));  end;-- Find next master:--   * 2 arbitration policies: fixed priority or round-robin--   * Fixed priority: priority is fixed, highest index has highest priority--   * Round-robin: arbiter maintains circular queue of masters--   * (master 0, master 1, ..., master (nahbmx-1)). First requesting master--   * in the queue is granted access to the bus and moved to the end of the queue.  --   * splitted masters are not granted--   * bus is re-arbited when current owner does not request the bus,--     or when it performs non-burst accesses--   * fix length burst transfers will not be interrupted--   * incremental bursts should assert hbusreq until last access    procedure selmast(r      : in reg_type;                  msto   : in ahb_mst_out_vector;                  rsplit : in std_logic_vector(0 to nahbmx-1);                  mast   : out integer range 0 to nahbmx-1;                  defmst : out std_ulogic) is  variable nmst    : nmstarr;  variable nvalid  : nvalarr;                    variable rrvec : std_logic_vector(nahbmx*2-1 downto 0);  variable zcnt  : std_logic_vector(log2(nahbmx)+1 downto 0);  variable hpvec : std_logic_vector(nahbmx-1 downto 0);  variable zcnt2 : std_logic_vector(log2(nahbmx) downto 0);  begin    nvalid(1 to 3) := (others => false); nmst(1 to 3) := (others => 0);    mast := r.hmaster;     defmst := '0';        if nahbm = 1 then      mast := 0;    elsif rrobin = 0 then      --hpvec := (others => '0');      --for i in 0 to nahbmx-1 loop      --  if ((rsplit(i) = '0') or (split = 0)) then      --    hpvec(i) := msto(i).hbusreq and msto(i).htrans(1);      --  end if;      --end loop;      --zcnt2 := lz(hpvec)(log2(nahbmx) downto 0);      --if zcnt2(log2(nahbmx)) = '0' then nvalid(1) := true; end if;      --nmst(1) := conv_integer(not (zcnt2(log2(nahbmx)-1 downto 0)));            hpvec := (others => '0');      for i in 0 to nahbmx-1 loop	if ((rsplit(i) = '0') or (split = 0)) then          hpvec(i) := msto(i).hbusreq;        end if;      end loop;      zcnt2 := lz(hpvec)(log2(nahbmx) downto 0);      if zcnt2(log2(nahbmx)) = '0' then nvalid(2) := true; end if;      nmst(2) := conv_integer(not (zcnt2(log2(nahbmx)-1 downto 0)));      for i in 0 to nahbmx-1 loop        if not ((nmst(3) = defmast) and nvalid(3)) then           nmst(3) := i; nvalid(3) := true;         end if;              end loop;          else      --rrvec := (others => '0');      --for i in 0 to nahbmx-1 loop      --  if (rsplit(i) = '0') or (split = 0) then       --    if (i <= r.hmaster) then rrvec(i) := '0';      --    else rrvec(i) := msto(i).hbusreq; end if;-- and msto(i).htrans(1); end if;      --    rrvec(nahbmx+i) := msto(i).hbusreq;-- and msto(i).htrans(1);      --  end if;      --end loop;      --zcnt := tz(rrvec)(log2(nahbmx)+1 downto 0);      --if zcnt(log2(nahbmx)+1) = '0' then nvalid(1) := true; end if;      --nmst(1) := conv_integer(zcnt(log2(nahbmx)-1 downto 0));            rrvec := (others => '0');      for i in 0 to nahbmx-1 loop        if (rsplit(i) = '0') or (split = 0) then           if (i <= r.hmaster) then rrvec(i) := '0';          else rrvec(i) := msto(i).hbusreq; end if;          rrvec(nahbmx+i) := msto(i).hbusreq;        end if;      end loop;      zcnt := tz(rrvec)(log2(nahbmx)+1 downto 0);      if zcnt(log2(nahbmx)+1) = '0' then nvalid(2) := true; end if;      nmst(2) := conv_integer(zcnt(log2(nahbmx)-1 downto 0));                  nmst(3) := r.hmaster; nvalid(3) := true;               end if;    for i in 1 to 3 loop      if nvalid(i) then mast := nmst(i); exit; end if;    end loop;    if (not (nvalid(1) or nvalid(2))) and (split /= 0) then      defmst := orv(rsplit);    end if;          end;                   constant MIMAX : integer := log2x(nahbmx) - 1;  constant SIMAX : integer := log2x(nahbs) - 1;  constant IOAREA : std_logic_vector(11 downto 0) :=   	conv_std_logic_vector(ioaddr, 12);  constant IOMSK  : std_logic_vector(11 downto 0) := 	conv_std_logic_vector(iomask, 12);  constant CFGAREA : std_logic_vector(11 downto 0) := 	conv_std_logic_vector(cfgaddr, 12);  constant CFGMSK  : std_logic_vector(11 downto 0) := 	conv_std_logic_vector(cfgmask, 12);  constant DEBUG2 : boolean := false; -- FIXME     signal r, rin : reg_type;  signal rsplit, rsplitin : std_logic_vector(0 to nahbmx-1);  begin  comb : process(rst, msto, slvo, r, rsplit)  variable v : reg_type;  variable nhmaster, hmaster : integer range 0 to nahbmx -1;  variable hgrant  : std_logic_vector(0 to NAHBMST-1);   -- bus grant  variable hsel    : std_logic_vector(0 to 31);   -- slave select  variable hmbsel  : std_logic_vector(0 to NAHBAMR-1);  variable nslave  : natural range 0 to 31;  variable vsplit  : std_logic_vector(0 to nahbmx-1);  variable bnslave : std_logic_vector(3 downto 0);  variable area    : std_logic_vector(1 downto 0);  variable hready  : std_ulogic;  variable defslv  : std_ulogic;  variable cfgsel  : std_ulogic;  variable hcache  : std_ulogic;  variable hresp   : std_logic_vector(1 downto 0);  variable hrdata  : std_logic_vector(31 downto 0);  variable haddr   : std_logic_vector(31 downto 0);  variable hirq    : std_logic_vector(NAHBIRQ-1 downto 0);  variable arb     : std_ulogic;  variable mstov   : ahb_mst_out_vector;  variable slvov   : ahb_slv_out_vector;  variable vslvi   : ahb_slv_in_type;  variable defmst   : std_ulogic;  variable tmpv : std_logic_vector(0 to nahbmx-1);    begin    v := r; hgrant := (others => '0'); defmst := '0';    mstov := msto(busndx); slvov := slvo(busndx);    haddr := mstov(r.hmaster).haddr;        nhmaster := r.hmaster;        -- bus arbitration--     if (r.hmasterlock = '0') and (-- --       (msto(r.hmaster).htrans = HTRANS_IDLE) or--        (msto(r.hmaster).hbusreq = '0') or--        ( (msto(r.hmaster).htrans = HTRANS_SEQ) and (fixbrst = 1) and--          ( ((msto(r.hmaster).hburst(2 downto 1) = "01") and (r.beat(1 downto 0) = "11")) or--            ((msto(r.hmaster).hburst(2 downto 1) = "10") and (r.beat(2 downto 0) = "111")) or--            ((msto(r.hmaster).hburst(2 downto 1) = "11") and (r.beat(3 downto 0) = "1111")) ) ) or--        ( (msto(r.hmaster).htrans = HTRANS_NONSEQ) and--          (msto(r.hmaster).hburst = HBURST_SINGLE))) then--       selmast(r, msto, rsplit, nhmaster);--     end if;    arb := '0';    if r.hmasterlock = '0' then      case mstov(r.hmaster).htrans is        when HTRANS_IDLE => arb := '1'; --arb := not mstov(r.hmaster).hbusreq; bridge        when HTRANS_NONSEQ =>          case mstov(r.hmaster).hburst is            when HBURST_SINGLE => arb := '1';            when HBURST_INCR => arb := not mstov(r.hmaster).hbusreq;            when others =>          end case;        when HTRANS_SEQ =>          case mstov(r.hmaster).hburst is            when HBURST_WRAP4  | HBURST_INCR4  => if (fixbrst = 1) and (r.beat(1 downto 0) = "11")   then arb := '1'; end if;            when HBURST_WRAP8  | HBURST_INCR8  => if (fixbrst = 1) and (r.beat(2 downto 0) = "111")  then arb := '1'; end if;            when HBURST_WRAP16 | HBURST_INCR16 => if (fixbrst = 1) and (r.beat(3 downto 0) = "1111") then arb := '1'; end if;            when HBURST_INCR => arb := not mstov(r.hmaster).hbusreq;            when others =>          end case;        when others => arb := '0';      end case;    end if;    if ((slvov(r.hslave).hready = '1') and (slvov(r.hslave).hresp(1) = '1') and (r.hmaster = r.hmasterd))    then arb := '1'; end if;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -