library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.router_types.all; package arbiter_functions is function single_packet_rout_dir_det ( level : in integer; pack_dest : in t_pos_addr; chip_pos : in t_chip_addr; core_pos : in t_core_addr; is_upstream : in boolean ) return std_logic_vector; function single_packet_parent_rout_dir_det ( level : in integer; pack_dest : in t_pos_addr; chip_pos : in t_chip_addr; core_pos : in t_core_addr ) return std_logic_vector; end package; package body arbiter_functions is function single_packet_parent_rout_dir_det( level : in integer; pack_dest : in t_pos_addr; chip_pos : in t_chip_addr; core_pos : in t_core_addr ) return std_logic_vector is variable chip_d_x, chip_d_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); variable chip_r_x, chip_r_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); variable is_upstream : boolean; begin is_upstream := true; chip_r_x := chip_pos.x; chip_r_y := chip_pos.y; chip_d_x := pack_dest.chip_pos.x; chip_d_y := pack_dest.chip_pos.y; if to_integer(unsigned(chip_d_y)) < to_integer(unsigned(chip_r_y)) then return "10000000"; -- north elsif to_integer(unsigned(chip_d_y)) > to_integer(unsigned(chip_r_y)) then return "01000000"; -- south elsif to_integer(unsigned(chip_d_x)) < to_integer(unsigned(chip_r_x)) then return "00100000"; -- west elsif to_integer(unsigned(chip_d_x)) > to_integer(unsigned(chip_r_x)) then return "00010000"; -- east else return "000" & single_packet_rout_dir_det( level, pack_dest, chip_pos, core_pos, is_upstream); end if; end function; function single_packet_rout_dir_det ( level : in integer; pack_dest : in t_pos_addr; chip_pos : in t_chip_addr; core_pos : in t_core_addr; is_upstream : in boolean ) return std_logic_vector is variable dest_x, dest_y, copy_x, copy_y : std_logic; variable is_other_chip : boolean; variable is_cousin_core : boolean; variable needs_multicast : boolean; begin dest_x := pack_dest.core_pos.x(level-1); dest_y := pack_dest.core_pos.y(level-1); copy_x := pack_dest.copy_pos.x(level-1); copy_y := pack_dest.copy_pos.y(level-1); if level /= TOP_LEVEL then is_other_chip := pack_dest.chip_pos.x /= chip_pos.x or pack_dest.chip_pos.y /= chip_pos.y; is_cousin_core := (pack_dest.core_pos.x(DEST_ADDR_SIZE-1 downto level) /= core_pos.x(DEST_ADDR_SIZE-1 downto level)) or (pack_dest.core_pos.y(DEST_ADDR_SIZE-1 downto level) /= core_pos.y(DEST_ADDR_SIZE-1 downto level)); needs_multicast := FALSE; for i in level to DEST_ADDR_SIZE-1 loop needs_multicast := needs_multicast or ( pack_dest.copy_pos.x(i) = '1') or ( pack_dest.copy_pos.y(i) = '1'); end loop; else is_other_chip := FALSE; needs_multicast := FALSE; is_cousin_core := FALSE; end if; -- if it comes from upstream, it shouldn't go back to upstream if (not is_upstream) and (is_other_chip or is_cousin_core or needs_multicast) then return "10000"; elsif copy_x = '0' and copy_y = '0' then --unicast if dest_x = '0' and dest_y = '0' then return "01000"; elsif dest_x = '0' and dest_y = '1' then return "00100"; elsif dest_x = '1' and dest_y = '0' then return "00010"; else return "00001"; end if; elsif copy_x = '1' and copy_y = '0' then -- X 1 to 2 multicast if dest_y = '0' then return "01010"; else return "00101"; end if; elsif copy_x = '0' and copy_y = '1' then -- Y 1 to 2 multicast if dest_x = '0' then return "01100"; else return "00011"; end if; else -- 1 to 4 multicast return "01111"; end if; end function; end package body;