library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity sysbus is port( clk: in std_logic; rst: in std_logic; -- master port 0 m0_addr: in std_logic_vector(15 downto 0); m0_wdata: in std_logic_vector(15 downto 0); m0_rdata: out std_logic_vector(15 downto 0); m0_re: in std_logic; m0_we: in std_logic; m0_busy: out std_logic; -- master port 1 m1_addr: in std_logic_vector(15 downto 0); m1_wdata: in std_logic_vector(15 downto 0); m1_rdata: out std_logic_vector(15 downto 0); m1_re: in std_logic; m1_we: in std_logic; m1_busy: out std_logic; -- actual bus bus_addr: out std_logic_vector(15 downto 0); bus_wdata: out std_logic_vector(15 downto 0); bus_rdata: in std_logic_vector(15 downto 0); bus_re: out std_logic; bus_we: out std_logic ); end entity sysbus; architecture behavior of sysbus is type bus_state is (IDLE, READING, PENDING); signal owner_next, owner: std_logic_vector(0 to 1); signal state_next, state: bus_state; signal pend_addr, pend_addr_next: std_logic_vector(15 downto 0); signal pend_wdata, pend_wdata_next: std_logic_vector(15 downto 0); signal pend, pend_next: std_logic_vector(0 to 1); signal were: std_logic_vector(0 to 3); begin were <= m0_we & m1_we & m0_re & m1_re; process(were, m0_addr, m0_wdata, m1_addr, m1_wdata, bus_rdata, state, owner, pend, pend_addr, pend_wdata) begin if pend = "00" then m0_busy <= '0'; m1_busy <= '0'; else m0_busy <= '1'; m1_busy <= '1'; end if; pend_next <= pend; pend_addr_next <= pend_addr; pend_wdata_next <= pend_wdata; owner_next <= "00"; state_next <= IDLE; bus_we <= '0'; bus_re <= '0'; -- some defaults bus_addr <= x"0000"; bus_wdata <= x"0000"; m0_rdata <= x"0000"; m1_rdata <= x"0000"; case state is when READING => if owner = "10" then bus_addr <= m0_addr; m0_rdata <= bus_rdata; m1_busy <= '1'; else bus_addr <= m1_addr; m1_rdata <= bus_rdata; m0_busy <= '1'; end if; if pend = "00" then state_next <= IDLE; else state_next <= PENDING; end if; when PENDING => bus_addr <= pend_addr; bus_we <= '1'; bus_wdata <= pend_wdata; pend_next <= "00"; state_next <= IDLE; when IDLE => case were is when "0000" => -- chill when "1000" => bus_addr <= m0_addr; bus_wdata <= m0_wdata; bus_we <= '1'; bus_re <= '0'; when "0100" => bus_addr <= m1_addr; bus_wdata <= m1_wdata; bus_we <= '1'; bus_re <= '0'; when "1100" => bus_addr <= m0_addr; bus_wdata <= m0_wdata; bus_we <= '1'; bus_re <= '0'; pend_next <= "01"; pend_addr_next <= m1_addr; pend_wdata_next <= m1_wdata; state_next <= PENDING; when "0010" => state_next <= READING; owner_next <= "10"; bus_addr <= m0_addr; bus_we <= '0'; bus_re <= '1'; m1_busy <= '1'; when "0001" => state_next <= READING; owner_next <= "01"; bus_addr <= m1_addr; bus_we <= '0'; bus_re <= '1'; m0_busy <= '1'; when "0011" => state_next <= READING; owner_next <= "10"; bus_addr <= m0_addr; bus_we <= '0'; bus_re <= '1'; m1_busy <= '1'; when "1001" => state_next <= READING; owner_next <= "01"; bus_addr <= m1_addr; bus_we <= '0'; bus_re <= '1'; pend_next <= "10"; pend_addr_next <= m0_addr; pend_wdata_next <= m0_wdata; m0_busy <= '1'; when "0110" => state_next <= READING; owner_next <= "10"; bus_addr <= m0_addr; bus_we <= '0'; bus_re <= '1'; pend_next <= "01"; pend_addr_next <= m1_addr; pend_wdata_next <= m1_wdata; m1_busy <= '1'; when others => -- blarg end case; end case; end process; process(clk, rst) begin if rst = '1' then state <= IDLE; owner <= "00"; pend <= "00"; pend_addr <= x"0000"; pend_wdata <= x"0000"; elsif rising_edge(clk) then state <= state_next; owner <= owner_next; pend <= pend_next; pend_addr <= pend_addr_next; pend_wdata <= pend_wdata_next; end if; end process; end behavior;