URL
https://opencores.org/ocsvn/esoc/esoc/trunk
Subversion Repositories esoc
[/] [esoc/] [trunk/] [Sources/] [logixa/] [esoc_bus_arbiter.vhd] - Rev 46
Go to most recent revision | Compare with Previous | Blame | View Log
-------------------------------------------------------------------------------- ---- ---- ---- Ethernet Switch on Configurable Logic IP Core ---- ---- ---- ---- This file is part of the ESoCL project ---- ---- http://www.opencores.org/cores/esoc/ ---- ---- ---- ---- Description: see design description ESoCL_dd_71022001.pdf ---- ---- ---- ---- To Do: see roadmap description ESoCL_dd_71022001.pdf ---- ---- and/or release bulleting ESoCL_rb_71022001.pdf ---- ---- ---- ---- Author(s): L.Maarsen ---- ---- Bert Maarsen, lmaarsen@opencores.org ---- ---- ---- -------------------------------------------------------------------------------- ---- ---- ---- Copyright (C) 2009 Authors and OPENCORES.ORG ---- ---- ---- ---- This source file may be used and distributed without ---- ---- restriction provided that this copyright statement is not ---- ---- removed from the file and that any derivative work contains ---- ---- the original copyright notice and the associated disclaimer. ---- ---- ---- ---- This source file is free software; you can redistribute it ---- ---- and/or modify it under the terms of the GNU Lesser General ---- ---- Public License as published by the Free Software Foundation; ---- ---- either version 2.1 of the License, or (at your option) any ---- ---- later version. ---- ---- ---- ---- This source is distributed in the hope that it will be ---- ---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- ---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- ---- PURPOSE. See the GNU Lesser General Public License for more ---- ---- details. ---- ---- ---- ---- You should have received a copy of the GNU Lesser General ---- ---- Public License along with this source; if not, download it ---- ---- from http://www.opencores.org/lgpl.shtml ---- ---- ---- -------------------------------------------------------------------------------- -- 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