Add multi master sys bus
This commit is contained in:
		
							
								
								
									
										197
									
								
								sysbus/sysbus.vhdl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								sysbus/sysbus.vhdl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| 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; | ||||
|     owner_next <= "00"; | ||||
|  | ||||
|     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 | ||||
|           m0_rdata <= bus_rdata; | ||||
|           m1_busy <= '1'; | ||||
|         else | ||||
|           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'; | ||||
|  | ||||
|           when "0001" => | ||||
|             state_next <= READING; | ||||
|             owner_next <= "01"; | ||||
|  | ||||
|             bus_addr <= m1_addr; | ||||
|             bus_we <= '0'; | ||||
|             bus_re <= '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; | ||||
		Reference in New Issue
	
	Block a user