OpenCores
URL https://opencores.org/ocsvn/nocem/nocem/trunk

Subversion Repositories nocem

[/] [nocem/] [trunk/] [VHDL/] [simple_pkt_local_arb.vhd] - Rev 8

Compare with Previous | Blame | View Log

 
-----------------------------------------------------------------------------
-- NoCem -- Network on Chip Emulation Tool for System on Chip Research 
-- and Implementations
-- 
-- Copyright (C) 2006  Graham Schelle, Dirk Grunwald
-- 
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; either version 2
-- of the License, or (at your option) any later version.
-- 
-- This program 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 General Public License for more details.
-- 
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
-- 02110-1301, USA.
-- 
-- The authors can be contacted by email: <schelleg,grunwald>@cs.colorado.edu 
-- 
-- or by mail: Campus Box 430, Department of Computer Science,
-- University of Colorado at Boulder, Boulder, Colorado 80309
-------------------------------------------------------------------------------- 
 
 
-- 
-- Filename: simple_pkt_local_arb.vhd
-- 
-- Description: nonVC design arbiter
-- 
 
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
 
use work.pkg_nocem.all;
 
 
entity simple_pkt_local_arb is
    Port ( 
 
		-- local arb info (should be held constant on incoming signal)
		local_arb_addr : std_logic_vector(NOCEM_AW-1 downto 0);
 
		-- needed to mux outputs for the accompanying switch
 		arb_grant_output : out arb_decision_array(4 downto 0);
 
 
	   n_pkt_cntrl_in : in pkt_cntrl_word;
	   n_pkt_cntrl_out : out pkt_cntrl_word;
	   n_channel_cntrl_in  : in channel_cntrl_word;
	   n_channel_cntrl_out : out channel_cntrl_word;
 
	   s_pkt_cntrl_in : in pkt_cntrl_word;
	   s_pkt_cntrl_out : out pkt_cntrl_word;
	   s_channel_cntrl_in  : in channel_cntrl_word;
	   s_channel_cntrl_out : out channel_cntrl_word;
 
	   e_pkt_cntrl_in : in pkt_cntrl_word;
	   e_pkt_cntrl_out : out pkt_cntrl_word;
	   e_channel_cntrl_in  : in channel_cntrl_word;
	   e_channel_cntrl_out : out channel_cntrl_word;
 
	   w_pkt_cntrl_in : in pkt_cntrl_word;
	   w_pkt_cntrl_out : out pkt_cntrl_word;
	   w_channel_cntrl_in  : in channel_cntrl_word;
	   w_channel_cntrl_out : out channel_cntrl_word;
 
 
	   ap_pkt_cntrl_in : in pkt_cntrl_word;
	   ap_pkt_cntrl_out : out pkt_cntrl_word;
	   ap_channel_cntrl_in  : in channel_cntrl_word;
	   ap_channel_cntrl_out : out channel_cntrl_word;
 
	 	clk : in std_logic;
      rst : in std_logic
		);
end simple_pkt_local_arb;
 
architecture Behavioral of simple_pkt_local_arb is
 
 
signal local_addr_x : std_logic_vector(NOCEM_AW/2 -1 downto 0);
signal local_addr_y : std_logic_vector(NOCEM_AW/2 -1 downto 0);
 
 
 
 
	-- since much of the work is repetitive, can use looping w/ indexing 
	-- to save massive repetitive coding
 
		--many operations can be easily written if inputs are in array form
		signal dest_local_port    			: arb_decision_array(4 downto 0);
		signal dest_addr_array    			: node_addr_array(4 downto 0);
		signal datain_valid_array 			: std_logic_vector(4 downto 0);
		signal pkt_cntrl_valid_array 		: std_logic_vector(4 downto 0);
		signal pkt_cntrl_data_array      : pkt_cntrl_array(4 downto 0);
		signal arb_decision_enum     : arb_decision_array(4 downto 0);
		signal channel_cntrl_in_array_i  : channel_cntrl_array(4 downto 0);
		signal channel_cntrl_out_array_i : channel_cntrl_array(4 downto 0);
 
 
 --signal srcToDstTimes2 : node_addr_array(4 downto 0);
 
 
 
begin
 
 
 
  	datain_valid_array(NOCEM_NORTH_IX) <= n_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
  	datain_valid_array(NOCEM_SOUTH_IX) <= s_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
	datain_valid_array(NOCEM_EAST_IX)  <= e_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
	datain_valid_array(NOCEM_WEST_IX)  <= w_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
	datain_valid_array(NOCEM_AP_IX)    <= ap_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
 
  	channel_cntrl_in_array_i(NOCEM_NORTH_IX) <= n_channel_cntrl_in;
  	channel_cntrl_in_array_i(NOCEM_SOUTH_IX) <= s_channel_cntrl_in;
	channel_cntrl_in_array_i(NOCEM_EAST_IX)  <= e_channel_cntrl_in;
	channel_cntrl_in_array_i(NOCEM_WEST_IX)  <= w_channel_cntrl_in;
	channel_cntrl_in_array_i(NOCEM_AP_IX)    <= ap_channel_cntrl_in;
 
  	n_channel_cntrl_out  <= channel_cntrl_out_array_i(NOCEM_NORTH_IX);
  	s_channel_cntrl_out  <= channel_cntrl_out_array_i(NOCEM_SOUTH_IX);
	e_channel_cntrl_out  <= channel_cntrl_out_array_i(NOCEM_EAST_IX);
	w_channel_cntrl_out  <= channel_cntrl_out_array_i(NOCEM_WEST_IX);
	ap_channel_cntrl_out <= channel_cntrl_out_array_i(NOCEM_AP_IX);
 
  	pkt_cntrl_valid_array(NOCEM_NORTH_IX) <= n_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
  	pkt_cntrl_valid_array(NOCEM_SOUTH_IX) <= s_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
	pkt_cntrl_valid_array(NOCEM_EAST_IX)  <= e_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
	pkt_cntrl_valid_array(NOCEM_WEST_IX)  <= w_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
	pkt_cntrl_valid_array(NOCEM_AP_IX)    <= ap_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
 
  	pkt_cntrl_data_array(NOCEM_NORTH_IX) <= n_pkt_cntrl_in;
  	pkt_cntrl_data_array(NOCEM_SOUTH_IX) <= s_pkt_cntrl_in;
	pkt_cntrl_data_array(NOCEM_EAST_IX)  <= e_pkt_cntrl_in;
	pkt_cntrl_data_array(NOCEM_WEST_IX)  <= w_pkt_cntrl_in;
	pkt_cntrl_data_array(NOCEM_AP_IX)    <= ap_pkt_cntrl_in;
 
	arb_decision_enum(NOCEM_AP_IX) <= ARB_AP;
	arb_decision_enum(NOCEM_NORTH_IX) <= ARB_NORTH;
	arb_decision_enum(NOCEM_SOUTH_IX) <= ARB_SOUTH;
	arb_decision_enum(NOCEM_EAST_IX) <= ARB_EAST;
	arb_decision_enum(NOCEM_WEST_IX) <= ARB_WEST;
 
 
 
 
	--local address breakdown for readibility....
	local_addr_x <= local_arb_addr(NOCEM_AW-1 downto NOCEM_AW/2);
	local_addr_y <= local_arb_addr(NOCEM_AW/2 -1 downto 0);
 
	-- simply pass on the pkt_cntrl signals to the switch 
	-- (may modify in other configs)
   n_pkt_cntrl_out <= n_pkt_cntrl_in;
	s_pkt_cntrl_out <= s_pkt_cntrl_in;
	e_pkt_cntrl_out <= e_pkt_cntrl_in;
	w_pkt_cntrl_out <= w_pkt_cntrl_in;
	ap_pkt_cntrl_out <= ap_pkt_cntrl_in;
 
 
 
 
-- process to generate destination address from pkt_cntrl line
 
dest_addr_gen_process : process (pkt_cntrl_valid_array, pkt_cntrl_data_array)
begin
 
	l1: for I in 4 downto 0 loop
		if pkt_cntrl_valid_array(I) = '1' then
			 dest_addr_array(I) <= pkt_cntrl_data_array(I)(NOCEM_PKTCNTRL_DEST_ADDR_HIX downto NOCEM_PKTCNTRL_DEST_ADDR_LIX);
		else
			 dest_addr_array(I) <= (others => '0');
		end if;	
	end loop;
 
 
end process;
 
 
 
 
 
 
 
-- process to determine routing based on incoming addr and data valid
-- decision determined by topology and datain destination address
 
port_dest_gen_process : process (datain_valid_array, local_addr_x, local_addr_y, dest_addr_array)
begin
 
 
 
		-- DOUBLE TORUS: north/south have loop around, east/west have looparound....
		if NOCEM_TOPOLOGY_TYPE = NOCEM_TOPOLOGY_DTORUS then 
			l20 : for I in 4 downto 0 loop 
				dest_local_port(I) <= ARB_NODECISION;
 
				if datain_valid_array(I) = '1' then
 
					-- src > dst address. go east if ROWS >= 2(SRC-DST) . go west if ROWS < 2(SRC-DST)
					if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) < local_addr_x then							
 
							if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(local_addr_x - dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2)) sll 1) then				
								dest_local_port(I) <= ARB_EAST;	
							else
								dest_local_port(I) <= ARB_WEST;
							end if;
					end if;
 
					-- dst > src address. go east if ROWS >= 2(DST-SRC) . go west if ROWS < 2(DST-SRC)
					if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) > local_addr_x then
 
							if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2)- local_addr_x) sll 1) then				
								dest_local_port(I) <= ARB_EAST;	
							else
								dest_local_port(I) <= ARB_WEST;
							end if;
 
					end if;	
 
					-- src > dst address. go north if ROWS >= 2(SRC-DST) . go south if ROWS < 2(SRC-DST)  
					if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) < local_addr_y  and 
						dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
 
							if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(local_addr_y - dest_addr_array(I)(NOCEM_AW/2 -1 downto 0)) sll 1) then				
								dest_local_port(I) <= ARB_NORTH;	
							else
								dest_local_port(I) <= ARB_SOUTH;
							end if;						
					end if;
 
					if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) > local_addr_y and 
						dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
 
							-- dst > src address. go north if ROWS >= 2(DST-SRC) . go south if ROWS < 2(DST-SRC) 
							if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) - local_addr_y) sll 1) then				
								dest_local_port(I) <= ARB_NORTH;	
							else
								dest_local_port(I) <= ARB_SOUTH;
							end if;
					end if;			
 
					if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) = local_addr_y and 
						dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then			
 
							dest_local_port(I) <= ARB_AP;				
					end if;
 
				else
					dest_local_port(I) <= ARB_NODECISION;
 
				end if;
 
			end loop;
 
		end if;
 
		-- TORUS: north/south have loop around, east/west do not....
		if NOCEM_TOPOLOGY_TYPE = NOCEM_TOPOLOGY_TORUS then 
			l21 : for I in 4 downto 0 loop 
				dest_local_port(I) <= ARB_NODECISION;
 
				if datain_valid_array(I) = '1' then
 
					if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) < local_addr_x then
						dest_local_port(I) <= ARB_WEST;
					end if;
 
					if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) > local_addr_x then
						dest_local_port(I) <= ARB_EAST;
					end if;	
 
					-- src > dst address. go north if ROWS >= 2(SRC-DST) . go south if ROWS < 2(SRC-DST)  
					if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) < local_addr_y  and 
						dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
 
							if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(local_addr_y - dest_addr_array(I)(NOCEM_AW/2 -1 downto 0)) sll 1) then				
								dest_local_port(I) <= ARB_NORTH;	
							else
								dest_local_port(I) <= ARB_SOUTH;
							end if;						
					end if;
 
					if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) > local_addr_y and 
						dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
 
							-- dst > src address. go north if ROWS >= 2(DST-SRC) . go south if ROWS < 2(DST-SRC) 
							if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) - local_addr_y) sll 1) then				
								dest_local_port(I) <= ARB_NORTH;	
							else
								dest_local_port(I) <= ARB_SOUTH;
							end if;
					end if;			
 
					if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) = local_addr_y and 
						dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then			
 
							dest_local_port(I) <= ARB_AP;				
					end if;
 
				else
					dest_local_port(I) <= ARB_NODECISION;
 
				end if;
 
			end loop;
 
		end if;
 
 
 
		-- MESH: simple deterministic routing....
		if NOCEM_TOPOLOGY_TYPE = NOCEM_TOPOLOGY_MESH then 
			l22 : for I in 4 downto 0 loop 
 
				dest_local_port(I) <= ARB_NODECISION;
				if datain_valid_array(I) = '1' then
 
					if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) < local_addr_x then
						dest_local_port(I) <= ARB_WEST;
					end if;
 
					if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) > local_addr_x then
						dest_local_port(I) <= ARB_EAST;
					end if;	
 
					if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) < local_addr_y  and 
						dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
 
						dest_local_port(I) <= ARB_SOUTH;
					end if;
 
					if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) > local_addr_y and 
						dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
 
						dest_local_port(I) <= ARB_NORTH;
					end if;			
 
					if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) = local_addr_y and 
						dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then			
 
						dest_local_port(I) <= ARB_AP;				
					end if;
 
				else
					dest_local_port(I) <= ARB_NODECISION;
 
				end if;
 
 
			end loop;
 
		end if;
 
 
 
 
 
 
 
 
 
end process;
 
 
arb_gen_process : process (channel_cntrl_in_array_i, dest_local_port)
begin
 
 
 
	arb_grant_output <= (others => ARB_NODECISION);
	channel_cntrl_out_array_i <= (others => (others => '0'));
 
 
 
l3: for I in 4 downto 0 loop
 
	-- I iterates over the OUTPUT ports
	if channel_cntrl_in_array_i(I)(NOCEM_CHFIFO_DATA_FULL_N_IX) = '1' then
 
		if dest_local_port(NOCEM_AP_IX) = arb_decision_enum(I) then
			--arb grant will push data through switch
			arb_grant_output(I) <= ARB_AP;
 
			-- do read enable for selected incoming data
			channel_cntrl_out_array_i(NOCEM_AP_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
			channel_cntrl_out_array_i(NOCEM_AP_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
 
			-- do write enable for outgoing port
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
 
		elsif dest_local_port(NOCEM_NORTH_IX) = arb_decision_enum(I) then
			arb_grant_output(I) <= ARB_NORTH;
			channel_cntrl_out_array_i(NOCEM_NORTH_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
			channel_cntrl_out_array_i(NOCEM_NORTH_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
 
 
		elsif dest_local_port(NOCEM_SOUTH_IX) = arb_decision_enum(I) then
			arb_grant_output(I) <= ARB_SOUTH;
			channel_cntrl_out_array_i(NOCEM_SOUTH_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
			channel_cntrl_out_array_i(NOCEM_SOUTH_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
 
		elsif dest_local_port(NOCEM_EAST_IX) = arb_decision_enum(I) then
			arb_grant_output(I) <= ARB_EAST;
			channel_cntrl_out_array_i(NOCEM_EAST_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
			channel_cntrl_out_array_i(NOCEM_EAST_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
 
		elsif dest_local_port(NOCEM_WEST_IX) = arb_decision_enum(I) then
			arb_grant_output(I) <= ARB_WEST;	 			
			channel_cntrl_out_array_i(NOCEM_WEST_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
			channel_cntrl_out_array_i(NOCEM_WEST_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
		   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
 
		end if;
	end if;
 
 
 
 
end loop;
 
 
 
end process;
 
 
end Behavioral;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.