ahbctrl.vhd

来自「The GRLIB IP Library is an integrated se」· VHDL 代码 · 共 496 行 · 第 1/2 页

VHD
496
字号
	conv_std_logic_vector(cfgaddr, 12);  constant CFGMSK  : std_logic_vector(11 downto 0) := 	conv_std_logic_vector(cfgmask, 12);  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);  begin    v := r; hgrant := (others => '0');    haddr := msto(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;    hgrant(nhmaster) := '1';    -- slave decoding    hsel := (others => '0'); hmbsel := (others => '0');    for i in 0 to nahbs-1 loop      for j in NAHBIR to NAHBCFG-1 loop        area := slvo(i).hconfig(j)(1 downto 0);        case area is	when "10" =>          if ((ioen = 0) or ((IOAREA and IOMSK) /= (haddr(31 downto 20) and IOMSK))) and             ((slvo(i).hconfig(j)(31 downto 20) and slvo(i).hconfig(j)(15 downto 4)) =               (haddr(31 downto 20) and slvo(i).hconfig(j)(15 downto 4)))          then hsel(i) := '1'; hmbsel(j-NAHBIR) := '1'; end if;	when "11" =>          if ((ioen /= 0) and ((IOAREA and IOMSK) = (haddr(31 downto 20) and IOMSK))) and             ((slvo(i).hconfig(j)(31 downto 20) and slvo(i).hconfig(j)(15 downto 4)) =               (haddr(19 downto  8) and slvo(i).hconfig(j)(15 downto 4)))          then hsel(i) := '1'; hmbsel(j-NAHBIR) := '1'; end if;	when others =>        end case;      end loop;    end loop;    bnslave(0) := hsel(1) or hsel(3) or hsel(5) or hsel(7) or                  hsel(9) or hsel(11) or hsel(13) or hsel(15);    bnslave(1) := hsel(2) or hsel(3) or hsel(6) or hsel(7) or                  hsel(10) or hsel(11) or hsel(14) or hsel(15);    bnslave(2) := hsel(4) or hsel(5) or hsel(6) or hsel(7) or                  hsel(12) or hsel(13) or hsel(14) or hsel(15);    bnslave(3) := hsel(8) or hsel(9) or hsel(10) or hsel(11) or                  hsel(12) or hsel(13) or hsel(14) or hsel(15);    nslave := conv_integer(bnslave(SIMAX downto 0));    if ((((IOAREA and IOMSK) = (haddr(31 downto 20) and IOMSK)) and (ioen /= 0))      or ((IOAREA = haddr(31 downto 20)) and (ioen = 0))) and       ((CFGAREA and CFGMSK) = (haddr(19 downto  8) and CFGMSK))       and (cfgmask /= 0)    then cfgsel := '1'; hsel := (others => '0');    else cfgsel := '0'; end if;    if (nslave = 0) and (hsel(0) = '0') and (cfgsel = '0') then defslv := '1';    else defslv := '0'; end if;-- error respons on undecoded area    v.hready := '0';     hready := slvo(r.hslave).hready; hresp := slvo(r.hslave).hresp;    if r.defslv = '1' then      -- default slave      if (r.htrans = HTRANS_IDLE) or (r.htrans = HTRANS_BUSY) then        hresp := HRESP_OKAY; hready := '1';      else	-- return two-cycle error in case of unimplemented slave access	hresp := HRESP_ERROR; hready := r.hready; v.hready := not r.hready;      end if;    end if;    hrdata := slvo(r.hslave).hrdata;    if cfgmask /= 0 then--      v.hrdatam := msto(conv_integer(r.haddr(MIMAX+5 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2)));--      if r.haddr(11 downto MIMAX+6) /= zero32(11 downto MIMAX+6) then v.hrdatam := (others => '0'); end if;      if (r.haddr(10 downto MIMAX+6) = zero32(10 downto MIMAX+6)) and (r.haddr(4 downto 2) = "000")      then v.hrdatam := msto(conv_integer(r.haddr(MIMAX+5 downto 5))).hconfig(0);      else v.hrdatam := (others => '0'); end if;--      v.hrdatas := slvo(conv_integer(r.haddr(SIMAX+5 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2)));--      if r.haddr(11 downto SIMAX+6) /= ('1' & zero32(10 downto SIMAX+6)) then v.hrdatas := (others => '0'); end if;      if (r.haddr(10 downto SIMAX+6) = zero32(10 downto SIMAX+6)) and 	((r.haddr(4 downto 2) = "000") or (r.haddr(4) = '1'))      then v.hrdatas := slvo(conv_integer(r.haddr(SIMAX+5 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2)));      else v.hrdatas := (others => '0'); end if;      if r.cfgsel = '1' then        hrdata := (others => '0');         -- default slave        if (r.htrans = HTRANS_IDLE) or (r.htrans = HTRANS_BUSY) then          hresp := HRESP_OKAY; hready := '1';        else  	  -- return two-cycle read/write respons 	  hresp := HRESP_OKAY; hready := r.hready; v.hready := not r.hready;        end if;        if r.cfga11 = '0' then hrdata := r.hrdatam;        else hrdata := r.hrdatas; end if;      end if;    end if;    -- latch active master and slave    if hready = '1' then       v.hmaster := nhmaster; v.hmasterd := r.hmaster;      v.hmasterlock := msto(nhmaster).hlock; v.hslave := nslave; v.defslv := defslv;      v.htrans := msto(r.hmaster).htrans; v.cfgsel := cfgsel;      v.cfga11 := msto(r.hmaster).haddr(11);      v.haddr := msto(r.hmaster).haddr(15 downto 2);      if (msto(r.hmaster).htrans = HTRANS_NONSEQ) or (msto(r.hmaster).htrans = HTRANS_IDLE) then        v.beat := "0001";      elsif (msto(r.hmaster).htrans = HTRANS_SEQ) then        if (fixbrst = 1) then v.beat := r.beat + 1; end if;      end if;    end if;          -- split support    vsplit := (others => '0');    if SPLIT /= 0 then      vsplit := rsplit;      if slvo(r.hslave).hresp = HRESP_SPLIT then vsplit(r.hmasterd) := '1'; end if;      for i in 0 to nahbs-1 loop	vsplit := vsplit and not slvo(i).hsplit(nahbmx-1 downto 0);      end loop;    end if;    if r.cfgsel = '1' then hcache := '1'; else hcache := slvo(v.hslave).hcache; end if;        -- interrupt merging    hirq := (others => '0');    if disirq = 0 then      for i in 0 to nahbs-1 loop hirq := hirq or slvo(i).hirq; end loop;      for i in 0 to nahbm-1 loop hirq := hirq or msto(i).hirq; end loop;    end if;    -- reset operation    if (rst = '0') then      v.hmaster := 0; v.hmasterlock := '0'; vsplit := (others => '0');      v.htrans := HTRANS_IDLE;  v.defslv := '0'; -- v.beat := "0001";      v.hslave := 0; v.cfgsel := '0';     end if;        -- drive master inputs    msti.hgrant  <= hgrant;    msti.hready  <= hready;    msti.hresp   <= hresp;    msti.hrdata  <= hrdata;    msti.hcache  <= hcache;    msti.hirq    <= hirq;     -- drive slave inputs    slvi.haddr     <= haddr;    slvi.htrans    <= msto(r.hmaster).htrans;    slvi.hwrite    <= msto(r.hmaster).hwrite;    slvi.hsize     <= msto(r.hmaster).hsize;    slvi.hburst    <= msto(r.hmaster).hburst;    slvi.hready    <= hready;    slvi.hwdata    <= msto(r.hmasterd).hwdata;    slvi.hprot     <= msto(r.hmaster).hprot;    slvi.hmastlock <= r.hmasterlock;    slvi.hmaster   <= conv_std_logic_vector(r.hmaster, 4);    slvi.hsel      <= hsel(0 to NAHBSLV-1);     slvi.hmbsel    <= hmbsel;     slvi.hcache    <= hcache;     slvi.hirq      <= hirq;     rin <= v; rsplitin <= vsplit;   end process;  reg0 : process(clk)  begin if rising_edge(clk) then r <= rin; end if; end process;  splitreg : if SPLIT /= 0 generate    reg1 : process(clk)    begin if rising_edge(clk) then rsplit <= rsplitin; end if; end process;  end generate;  nosplitreg : if SPLIT = 0 generate    rsplit <= (others => '0');  end generate;  -- pragma translate_off  diag : process  variable k : integer;  variable mask : std_logic_vector(11 downto 0);  variable iostart : std_logic_vector(11 downto 0) := IOAREA and IOMSK;  variable cfgstart : std_logic_vector(11 downto 0) := CFGAREA and CFGMSK;  begin    wait for 2 ns;    k := 0; mask := IOMSK;    while (k<12) and (mask(k) = '0') loop k := k+1; end loop;     print("ahbctrl: AHB arbiter/multiplexer rev 1");    if ioen /= 0 then      print("ahbctrl: Common I/O area at " & tost(iostart) & "00000, " & tost(2**k) & " Mbyte");    else      print("ahbctrl: Common I/O area disabled");    end if;    if cfgmask /= 0 then      print("ahbctrl: Configuration area at " & tost(iostart & cfgstart) & "00, 4 kbyte");    else      print("ahbctrl: Configuration area disabled");    end if;    wait;  end process;-- pragma translate_onend;

⌨️ 快捷键说明

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