119 lines
No EOL
4.7 KiB
VHDL
119 lines
No EOL
4.7 KiB
VHDL
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; |