URL
https://opencores.org/ocsvn/esoc/esoc/trunk
Subversion Repositories esoc
[/] [esoc/] [trunk/] [Sources/] [logixa/] [esoc_bus_arbiter.vhd] - Rev 56
Go to most recent revision | Compare with Previous | Blame | View Log
-------------------------------------------------------------------------------- -- -- This VHDL file was generated by EASE/HDL 7.4 Revision 4 from HDL Works B.V. -- -- Ease library : work -- HDL library : work -- Host name : S212065 -- User name : df768 -- Time stamp : Tue Aug 19 08:05:18 2014 -- -- Designed by : L.Maarsen -- Company : LogiXA -- Project info : eSoC -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Object : Entity work.esoc_bus_arbiter -- Last modified : Mon Apr 14 12:48:27 2014. -------------------------------------------------------------------------------- library ieee, std, work; use ieee.std_logic_1164.all; use std.textio.all; use ieee.numeric_std.all; use work.package_esoc_configuration.all; entity esoc_bus_arbiter is generic( id : integer := 0); port( bus_eof : in std_logic; bus_gnt_rd : out std_logic_vector(esoc_port_count-1 downto 0); bus_gnt_wr : out std_logic_vector(esoc_port_count-1 downto 0); bus_req : in std_logic_vector(esoc_port_count-1 downto 0); bus_sof : in std_logic; clk_bus : in std_logic; clk_control : in std_logic; ctrl_address : in std_logic_vector(15 downto 0); ctrl_rd : in std_logic; ctrl_rddata : out std_logic_vector(31 downto 0); ctrl_wait : out std_logic; ctrl_wr : in std_logic; ctrl_wrdata : in std_logic_vector(31 downto 0); reset : in std_logic); end entity esoc_bus_arbiter; -------------------------------------------------------------------------------- -- Object : Architecture work.esoc_bus_arbiter.esoc_bus_arbiter -- Last modified : Mon Apr 14 12:48:27 2014. -------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------- -- architecture and declarations --------------------------------------------------------------------------------------------------------------- architecture esoc_bus_arbiter of esoc_bus_arbiter is --------------------------------------------------------------------------------------------------------------- -- registers --------------------------------------------------------------------------------------------------------------- constant reg_arb_port_disable_add: integer := 7; signal reg_arb_port_disable_dat: std_logic_vector(31 downto 0); constant reg_arb_port_disable_rst: std_logic_vector(31 downto 0) := X"00000000"; constant reg_arb_port_weight_add: integer := 0; signal reg_arb_port_weight_dat: std_logic_vector(31 downto 0); constant reg_arb_port_weight_rst: std_logic_vector(31 downto 0) := X"00000000"; --------------------------------------------------------------------------------------------------------------- -- signals --------------------------------------------------------------------------------------------------------------- signal port_select: integer range esoc_port_count-1 downto 0; signal port_request: std_logic; signal port_request_weight: std_logic_vector(1 downto 0); type states_data_bus is (idle, wait_sof, wait_eof); signal state_data_bus: states_data_bus; signal ctrl_rddata_i: std_logic_vector(ctrl_rddata'high downto 0); signal ctrl_wait_i: std_logic; signal ctrl_bus_enable: std_logic; begin --============================================================================================================= -- Process : process data bus access request, use weight factor for each port and approve access -- Description : --============================================================================================================= req_scan: process(clk_bus, reset) begin if reset = '1' then port_select <= 0; port_request <= '0'; port_request_weight <= (others => '0'); bus_gnt_wr <= (others => '0'); bus_gnt_rd <= (others => '0'); state_data_bus <= idle; elsif clk_bus'event and clk_bus = '1' then -- scan request outputs from all ESOC ports, if asserted wait for free data bus if bus_req(port_select) = '1' and reg_arb_port_disable_dat(port_select) = '0' then port_request <= '1'; -- request output deasserted, current weight factor zero? determine next port to check, use weight factor of current port else port_request <= '0'; -- check weight of processed port, scan port again or go to next port with appropriate weight? if to_integer(unsigned(port_request_weight)) = 0 then if port_select = esoc_port_count-1 then port_select <= 0; port_request_weight <= reg_arb_port_weight_dat(1) & reg_arb_port_weight_dat(0); else port_select <= port_select + 1; port_request_weight <= reg_arb_port_weight_dat(2*(port_select+1)+1) & reg_arb_port_weight_dat(2*(port_select+1)); end if; -- weight not 0, do not proceed with next port, but decrease weight of actual port else port_request_weight <= std_logic_vector(to_unsigned(to_integer(unsigned(port_request_weight))-1,2)); end if; end if; -- monitor the data bus state and control the scan process case state_data_bus is when idle => -- if there is a bus request, give a write grant to selected port, a read grant to all other ports and wait for SOF and EOF if port_request = '1' then bus_gnt_wr(port_select) <= '1'; bus_gnt_rd <= (others => '1'); state_data_bus <= wait_sof; end if; when wait_sof => -- wait for start of packet, no further actions required yet (future) if bus_sof = '1' then state_data_bus <= wait_eof; end if; when wait_eof => -- End of packet detect? Terminate and go back to idle. if bus_eof = '1' then bus_gnt_wr <= (others => '0'); bus_gnt_rd <= (others => '0'); state_data_bus <= idle; end if; when others => state_data_bus <= idle; end case; end if; end process; --============================================================================================================= -- Process : access registers when addressed or provide data from other units to the readdata bus -- Description : --============================================================================================================= registers: process(clk_control, reset) begin if reset = '1' then -- all ports have weight 1 after reset reg_arb_port_disable_dat <= reg_arb_port_disable_rst; reg_arb_port_weight_dat <= reg_arb_port_weight_rst; ctrl_rddata_i <= (others => '0'); ctrl_wait_i <= '1'; ctrl_bus_enable <= '0'; elsif clk_control'event and clk_control = '1' then ctrl_wait_i <= '1'; ctrl_bus_enable <= '0'; -- continu if memory space of this entity is addressed if to_integer(unsigned(ctrl_address)) >= (esoc_bus_arbiter_base + (id * esoc_bus_arbiter_size)) and to_integer(unsigned(ctrl_address)) < (esoc_bus_arbiter_base + (id * esoc_bus_arbiter_size) + esoc_bus_arbiter_size) then ctrl_bus_enable <= '1'; -- -- READ CYCLE started, unit addressed? -- if ctrl_rd = '1' then -- Check register address and provide data when addressed case to_integer(unsigned(ctrl_address))- esoc_bus_arbiter_base - (id * esoc_bus_arbiter_size) is when reg_arb_port_disable_add => ctrl_rddata_i <= reg_arb_port_disable_dat; ctrl_wait_i <= '0'; when reg_arb_port_weight_add => ctrl_rddata_i <= reg_arb_port_weight_dat; ctrl_wait_i <= '0'; when others => NULL; end case; -- -- WRITE CYCLE started, unit addressed? -- elsif ctrl_wr = '1' then -- Check address and accept data when addressed case to_integer(unsigned(ctrl_address))- esoc_bus_arbiter_base - (id * esoc_bus_arbiter_size) is when reg_arb_port_disable_add => reg_arb_port_disable_dat <= ctrl_wrdata; ctrl_wait_i <= '0'; when reg_arb_port_weight_add => reg_arb_port_weight_dat <= ctrl_wrdata; ctrl_wait_i <= '0'; when others => NULL; end case; end if; end if; end if; end process; -- Create tristate outputs ctrl_wait <= ctrl_wait_i when ctrl_bus_enable = '1' else 'Z'; ctrl_rddata <= ctrl_rddata_i when ctrl_bus_enable = '1' else (others => 'Z'); end architecture esoc_bus_arbiter ; -- of esoc_bus_arbiter
Go to most recent revision | Compare with Previous | Blame | View Log