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

📄 pci_arb.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 2 页
字号:
   --Necessary definitions from amba.vhd and iface.vhd   --added to pci_arb package with modified names to avoid   --name clashes in GRLIB   constant APB_PRIOS : boolean := APB_EN = 1;   signal owner0, owneri0   : agent_t;  -- current owner in level 0   signal owner1, owneri1   : agent_t;  -- current owner in level 1   signal cown, cowni       : agent_t;  -- current level   signal rearb, rearbi     : std_logic;            -- re-arbitration flag   signal tout, touti       : std_logic_vector(3 downto 0);  -- timeout counter   signal turn, turni       : std_logic;            -- turnaround cycle   signal arb_lvl, arb_lvli : arb_lvl_t := ARB_LVL_C;  -- level registers   type nmstarr is array (0 to 3) of agentno_t;   type nvalarr is array (0 to 3) of boolean;begin  -- rtl   ----------------------------------------------------------------------------   -- PCI ARBITER   ----------------------------------------------------------------------------   -- purpose: Grants the bus depending on the request signals. All agents have   -- equal priority, if another request occurs during a transaction, the bus is   -- granted to the new agent. However, PCI protocol specifies that the master   -- can finish the current transaction within the limit of its latency timer.   arbiter : process(cown, owner0, owner1, req_n, rearb, tout, turn, frame_n,                     arb_lvl, rst_n)      variable owner0v, owner1v : agentno_t;  -- integer variables for current owner      variable new_request      : agentno_t;  -- detected request      variable nmst             : nmstarr;      variable nvalid           : nvalarr;   begin  -- process arbiter      -- default assignments      rearbi  <= rearb;      owneri0 <= owner0;      owneri1 <= owner1;      cowni   <= cown;      touti   <= tout;      turni   <= '0';                    -- no turnaround      -- re-arbitrate once during the transaction,      -- or when timeout counter expired (bus idle).      if (frame_n = '0' and rearb = '0') or turn = '1' then         owner0v        := conv_integer(owner0);         owner1v        := conv_integer(owner1);         new_request    := conv_integer(cown);         nvalid(0 to 3) := (others => false);         nmst(0 to 3)   := (others => 0);         -- Determine next request in both priority levels         rob : for i in NB_AGENTS-1 downto 0 loop            -- consider all masters with valid request            if req_n(i) = '0' then               -- next in prio level 0               if arb_lvl(i) = '0' then                  if i > owner0v then                     nmst(0) := i; nvalid(0) := true;                  elsif i < owner0v then                     nmst(1) := i; nvalid(1) := true;                  end if;               -- next in prio level 1               elsif arb_lvl(i) = '1' then                  if i > owner1v then                     nmst(2) := i; nvalid(2) := true;                  elsif i < owner1v then                     nmst(3) := i; nvalid(3) := true;                  end if;               end if;                  -- arb_lvl            end if;                     -- req_n         end loop rob;         -- select new master         if nvalid(0) then              -- consider level 0 before wrap            new_request    := nmst(0);            owner0v        := nmst(0);         -- consider level 1 only once, except when no request in level 0         elsif owner0v /= NB_AGENTS-1 or not nvalid(1) then            if nvalid(2) then           -- level 1 before wrap               new_request := nmst(2);               owner0v     := NB_AGENTS-1;               owner1v     := nmst(2);            elsif nvalid(3) then        -- level 1 after wrap               new_request := nmst(3);               owner0v     := NB_AGENTS-1;               owner1v     := nmst(3);            end if;         elsif nvalid(1) then           -- level 0 after wrap            new_request    := nmst(1);            owner0v        := nmst(1);         end if;         owneri0 <= conv_std_logic_vector(owner0v, ARB_SIZE);         owneri1 <= conv_std_logic_vector(owner1v, ARB_SIZE);         -- rearbitration if any request asserted & different from current owner         if conv_integer(cown) /= new_request then            -- if idle state: turnaround cycle required by PCI standard            cowni <= conv_std_logic_vector(new_request, ARB_SIZE);            touti <= "0000";                 -- reset timeout counter            if turn = '0' then               rearbi <= '1';           -- only one re-arbitration            end if;         end if;      elsif frame_n = '1' then         rearbi <= '0';      end if;      -- if frame deasserted, but request asserted: count timeout      if req_n = all_ones then          -- no request: prepare timeout counter         touti <= "1111";      elsif frame_n = '1' then          -- request, but no transaction         if tout = "1111" then              -- timeout expired, re-arbitrate            turni <= '1';               -- remove grant, turnaround cycle            touti <= "0000";                 -- next cycle re-arbitrate         else            touti <= tout + 1;         end if;      end if;      grant : for i in 0 to NB_AGENTS-1 loop         if i = conv_integer(cown) and turn = '0' then            gnt_n(i) <= '0';         else            gnt_n(i) <= '1';         end if;      end loop grant;      -- synchronous reset      if rst_n = '0' then         touti    <= "0000";         cowni    <= (others => '0');         owneri0  <= (others => '0');         owneri1  <= (others => '0');         rearbi   <= '0';         turni    <= '0';         new_request := 0;      end if;   end process arbiter;   arb_lvl(NB_AGENTS-1) <= '1';  -- always prio 1.   fixed_prios : if not APB_PRIOS generate  -- assign constant value      arb_lvl(NB_AGENTS-2 downto 0) <= ARB_LVL_C(NB_AGENTS-2 downto 0);   end generate fixed_prios;   -- Generate APB regs and APB slave   apbgen : if APB_PRIOS generate      -- purpose: APB read and write of arb_lvl configuration registers      -- type:    memoryless      -- inputs:  pbi, arb_lvl, prst_n      -- outputs: pbo, arb_lvli      config : process (pbi, arb_lvl, prst_n)      begin  -- process config         arb_lvli <= arb_lvl;         pbo.PRDATA <= (others => '0');  -- default for unimplemented addresses         -- register select at (byte-) addresses 0x80         if pbi.PADDR(7 downto 0) = "10000000" and pbi.PSEL = '1' then -- address select            if (pbi.PWRITE and pbi.PENABLE) = '1' then  -- APB write                  arb_lvli <= pbi.PWDATA(NB_AGENTS-1 downto 0);            end if;            pbo.PRDATA(NB_AGENTS-1 downto 0) <= arb_lvl;         end if;         -- synchronous reset         if prst_n = '0' then            arb_lvli <= ARB_LVL_C;          -- assign default value         end if;      end process config;      -- APB registers      apb_regs : process (pclk)      begin  -- process regs         -- activities triggered by asynchronous reset (active low)         if pclk'event and pclk = '1' then  -- '            arb_lvl(NB_AGENTS-2 downto 0) <= arb_lvli(NB_AGENTS-2 downto 0);         end if;      end process apb_regs;   end generate apbgen;   -- PCI registers   regs0 : process (clk)   begin  -- process regs      if clk'event and clk = '1' then  -- '         tout    <= touti;         owner0  <= owneri0;         owner1  <= owneri1;         cown    <= cowni;         rearb   <= rearbi;         turn    <= turni;      end if;   end process regs0;end rtl;

⌨️ 快捷键说明

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