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 + -
显示快捷键?