📄 ahbctrl_mb.vhd
字号:
if (split /= 0) then for i in 0 to nahbmx-1 loop tmpv(i) := (mstov(i).htrans(1) or (mstov(i).hbusreq)) and not rsplit(i); end loop; if (r.defmst and orv(tmpv)) = '1' then arb := '1'; end if; end if; if (arb = '1') then selmast(r, mstov, rsplit, nhmaster, defmst); elsif (split /= 0) then defmst := r.defmst; end if; if (split = 0) or (defmst = '0') then hgrant(nhmaster) := '1'; end if; -- 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 := slvov(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 ((slvov(i).hconfig(j)(31 downto 20) and slvov(i).hconfig(j)(15 downto 4)) = (haddr(31 downto 20) and slvov(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 ((slvov(i).hconfig(j)(31 downto 20) and slvov(i).hconfig(j)(15 downto 4)) = (haddr(19 downto 8) and slvov(i).hconfig(j)(15 downto 4))) then hsel(i) := '1'; hmbsel(j-NAHBIR) := '1'; end if; when others => end case; end loop; end loop; if r.defmst = '1' then hsel := (others => '0'); end if; 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; if r.defmst = '1' then cfgsel := '0'; defslv := '1'; end if; -- error respons on undecoded area v.hready := '0'; hready := slvov(r.hslave).hready; hresp := slvov(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 := slvov(r.hslave).hrdata; if cfgmask /= 0 then v.hrdatam := msto(conv_integer(r.haddr(10 downto 9)))(conv_integer(r.haddr(8 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2))); if DEBUG2 then if conv_integer(r.haddr(10 downto 9)) = busndx then v.hrdatam := msto(busndx)(conv_integer(r.haddr(8 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2))); else v.hrdatam := (others => '0'); end if; end if; v.hrdatas := slvo(conv_integer(r.haddr(10 downto 9)))(conv_integer(r.haddr(8 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2))); if DEBUG2 then if conv_integer(r.haddr(10 downto 9)) = busndx then v.hrdatas := slvo(busndx)(conv_integer(r.haddr(8 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2))); else v.hrdatas := (others => '0'); end if; end if; if r.haddr(10 downto 4) = "1111111" then v.hrdatas(15 downto 0) := conv_std_logic_vector(LIBVHDL_BUILD, 16); v.hrdatas(31 downto 16) := conv_std_logic_vector(devid, 16); 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 := mstov(nhmaster).hlock; v.hslave := nslave; v.defslv := defslv; if (split = 0) or (r.defmst = '0') then v.htrans := mstov(r.hmaster).htrans; else v.htrans := HTRANS_IDLE; end if; v.cfgsel := cfgsel; v.cfga11 := mstov(r.hmaster).haddr(11); v.haddr := mstov(r.hmaster).haddr(15 downto 2); if (mstov(r.hmaster).htrans = HTRANS_NONSEQ) or (mstov(r.hmaster).htrans = HTRANS_IDLE) then v.beat := "0001"; elsif (mstov(r.hmaster).htrans = HTRANS_SEQ) then if (fixbrst = 1) then v.beat := r.beat + 1; end if; end if; if (split /= 0) then v.defmst := defmst; end if; end if; -- split support vsplit := (others => '0'); if SPLIT /= 0 then vsplit := rsplit; if slvov(r.hslave).hresp = HRESP_SPLIT then vsplit(r.hmasterd) := '1'; end if; for i in 0 to nahbs-1 loop for j in 0 to nahbmx-1 loop vsplit(j) := vsplit(j) and not slvov(i).hsplit(j); end loop; end loop; end if; if r.cfgsel = '1' then hcache := '1'; else hcache := slvov(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 slvov(i).hirq; end loop; for i in 0 to nahbm-1 loop hirq := hirq or mstov(i).hirq; end loop; end if; if (split = 0) or (r.defmst = '0') then vslvi.haddr := haddr; vslvi.htrans := mstov(r.hmaster).htrans; vslvi.hwrite := mstov(r.hmaster).hwrite; vslvi.hsize := mstov(r.hmaster).hsize; vslvi.hburst := mstov(r.hmaster).hburst; vslvi.hready := hready; vslvi.hwdata := mstov(r.hmasterd).hwdata; vslvi.hprot := mstov(r.hmaster).hprot; --vslvi.hmastlock := r.hmasterlock; vslvi.hmastlock := mstov(r.hmaster).hlock; vslvi.hmaster := conv_std_logic_vector(r.hmaster, 4); vslvi.hsel := hsel(0 to NAHBSLV-1); vslvi.hmbsel := hmbsel; vslvi.hcache := hcache; vslvi.hirq := hirq; else vslvi := ahbs_in_none; vslvi.hready := hready; vslvi.hwdata := mstov(r.hmasterd).hwdata; vslvi.hirq := hirq; --vslvi.hmaster := conv_std_logic_vector(defmast, 4); end if; -- reset operation if (rst = '0') then v.defmst := '0'; 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 <= vslvi; rin <= v; rsplitin <= vsplit; end process; reg0 : process(clk) begin if rising_edge(clk) then r <= rin; end if; if (split = 0) then r.defmst <= '0'; 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; diag : process variable k : integer; variable mask : std_logic_vector(11 downto 0); variable device : std_logic_vector(11 downto 0); variable devicei : integer; variable vendor : std_logic_vector( 7 downto 0); variable area : std_logic_vector( 1 downto 0); variable vendori : integer; variable iosize, tmp : integer; variable iounit : string(1 to 5) := " byte"; variable memtype : string(1 to 9); variable iostart : std_logic_vector(11 downto 0) := IOAREA and IOMSK; variable cfgstart : std_logic_vector(11 downto 0) := CFGAREA and CFGMSK; variable L1 : line := new string'(""); variable S1 : string(1 to 255); variable mstov : ahb_mst_out_vector; variable slvov : ahb_slv_out_vector; begin wait for 2 ns; mstov := msto(busndx); slvov := slvo(busndx); if debug = 0 then wait; end if; 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; if debug = 1 then wait; end if; for i in 0 to nahbm-1 loop vendor := mstov(i).hconfig(0)(31 downto 24); vendori := conv_integer(vendor); if vendori /= 0 then device := mstov(i).hconfig(0)(23 downto 12); devicei := conv_integer(device); print("ahbctrl: mst" & tost(i) & ": " & iptable(vendori).vendordesc & iptable(vendori).device_table(devicei)); assert (mstov(i).hindex = i) or (icheck = 0) report "AHB master index error on master " & tost(i) severity failure; end if; end loop; for i in 0 to nahbs-1 loop vendor := slvov(i).hconfig(0)(31 downto 24); vendori := conv_integer(vendor); if vendori /= 0 then device := slvov(i).hconfig(0)(23 downto 12); devicei := conv_integer(device); std.textio.write(L1, "ahbctrl: slv" & tost(i) & ": " & iptable(vendori).vendordesc & iptable(vendori).device_table(devicei)); std.textio.writeline(OUTPUT, L1); for j in NAHBIR to NAHBCFG-1 loop area := slvov(i).hconfig(j)(1 downto 0); case area is when "01" => when "10" => mask := slvov(i).hconfig(j)(15 downto 4); k := 0; while (k<15) and (mask(k) = '0') loop k := k+1; end loop; std.textio.write(L1, "ahbctrl: memory at " & tost( slvov(i).hconfig(j)(31 downto 20))& "00000, size "& tost(2**k) & " Mbyte"); if slvov(i).hconfig(j)(16) = '1' then std.textio.write(L1, string'(", cacheable")); end if; if slvov(i).hconfig(j)(17) = '1' then std.textio.write(L1, string'(", prefetch")); end if; std.textio.writeline(OUTPUT, L1); when "11" => if ioen /= 0 then mask := slvov(i).hconfig(j)(15 downto 4); k := 0; while (k<15) and (mask(k) = '0') loop k := k+1; end loop; iosize := 256 * 2**k; iounit(1) := ' '; if (iosize > 1023) then iosize := iosize/1024; iounit(1) := 'k'; end if; print("ahbctrl: I/O port at " & tost( iostart & ((slvov(i).hconfig(j)(31 downto 20)) and slvov(i).hconfig(j)(15 downto 4))) & "00, size "& tost(iosize) & iounit); end if; when others => end case; end loop; assert (slvov(i).hindex = i) or (icheck = 0) report "AHB slave index error on slave " & tost(i) severity failure; end if; end loop; wait; end process;-- pragma translate_onend;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -