168 lines
No EOL
6.9 KiB
VHDL
168 lines
No EOL
6.9 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use work.router_types.all;
|
|
use work.arbiter_functions.all;
|
|
|
|
entity parent_arbiter is
|
|
generic(
|
|
level : natural := 5;
|
|
num_paths_up : positive := 32;
|
|
num_paths_down : positive := 16;
|
|
lsb_size_up : positive := 5;
|
|
lsb_size_down : positive := 4
|
|
);
|
|
port (
|
|
clk, arstN : in std_logic;
|
|
chip_pos : in t_chip_addr;
|
|
core_pos : in t_core_addr;
|
|
packets : in t_DATA(num_paths_up*4+num_paths_down*4-1 downto 0);
|
|
valid_data : in std_logic_vector(num_paths_up*4+num_paths_down*4-1 downto 0);
|
|
avai_paths : in std_logic_vector(num_paths_up*4+num_paths_down*4-1 downto 0);
|
|
arb_complete : out std_logic_vector(num_paths_up*4+num_paths_down*4-1 downto 0);
|
|
buff_wr_in : out t_FIFO_WR_INS(num_paths_up*4+num_paths_down*4-1 downto 0)
|
|
);
|
|
end parent_arbiter;
|
|
|
|
architecture impl of parent_arbiter is
|
|
constant TOT_NUM_PATHS : positive := num_paths_up*4 + num_paths_down*4;
|
|
constant NUM_PORTS_UP : positive := 4;
|
|
constant NUM_PORTS_DOWN : positive := 4;
|
|
|
|
component arbiter_unit is
|
|
generic(
|
|
num_paths_in : positive;
|
|
num_paths_out : positive;
|
|
lsb_sels_size : positive
|
|
);
|
|
port (
|
|
dirs : in std_logic_vector(num_paths_in-1 downto 0);
|
|
packets : in t_DATA(num_paths_in-1 downto 0);
|
|
avai_paths : in std_logic_vector(num_paths_out-1 downto 0);
|
|
out_paths : out t_DATA(num_paths_out-1 downto 0);
|
|
valids_out : out std_logic_vector(num_paths_out-1 downto 0);
|
|
updated_dirs : out std_logic_vector(num_paths_in-1 downto 0)
|
|
);
|
|
end component arbiter_unit;
|
|
|
|
type t_PORT_DIRS is array (natural range <>) of
|
|
std_logic_vector(TOT_NUM_PATHS-1 downto 0);
|
|
signal dirs : t_DATA_DIRS_EXT(TOT_NUM_PATHS-1 downto 0);
|
|
signal port_dirs : t_PORT_DIRS(NUM_DIRS_PARENT-1 downto 0);
|
|
signal updated_dirs : t_DATA_DIRS_EXT(TOT_NUM_PATHS-1 downto 0);
|
|
signal updated_port_dirs : t_PORT_DIRS(NUM_DIRS_PARENT-1 downto 0);
|
|
signal ps_dirs : t_DATA_DIRS_EXT(TOT_NUM_PATHS-1 downto 0);
|
|
signal ps_dirs_nxt : t_DATA_DIRS_EXT(TOT_NUM_PATHS-1 downto 0);
|
|
signal out_packets : t_DATA(TOT_NUM_PATHS-1 downto 0);
|
|
signal packets_1d : t_DATA(TOT_NUM_PATHS-1 downto 0);
|
|
signal packets_1d_nxt : t_DATA(TOT_NUM_PATHS-1 downto 0);
|
|
signal valids_out : std_logic_vector(TOT_NUM_PATHS-1 downto 0);
|
|
begin
|
|
decode_direction: process(chip_pos, core_pos, valid_data, packets)
|
|
variable pack_dest : t_pos_addr;
|
|
--variable header : std_logic_vector(3 downto 0);
|
|
variable is_upstream : boolean;
|
|
begin
|
|
for i in 0 to TOT_NUM_PATHS-1 loop
|
|
if valid_data(i) = '1' then
|
|
--header := packets(i)(63 downto 60);
|
|
pack_dest.chip_pos.x := packets(i)(59 downto 55);
|
|
pack_dest.chip_pos.y := packets(i)(54 downto 50);
|
|
pack_dest.core_pos.x := packets(i)(49 downto 45);
|
|
pack_dest.core_pos.y := packets(i)(44 downto 40);
|
|
pack_dest.copy_pos.x := packets(i)(39 downto 35);
|
|
pack_dest.copy_pos.y := packets(i)(34 downto 30);
|
|
dirs(i) <= single_packet_parent_rout_dir_det(level, pack_dest,
|
|
chip_pos, core_pos);
|
|
else
|
|
dirs(i) <= (others => '0');
|
|
end if;
|
|
end loop;
|
|
end process;
|
|
|
|
ds_ports_arbiter_units: for i in 0 to NUM_PORTS_DOWN-1 generate
|
|
begin
|
|
g_port_dirs: for p in 0 to TOT_NUM_PATHS-1 generate
|
|
port_dirs(i)(p) <= ps_dirs(p)(i);
|
|
end generate;
|
|
|
|
ds_arbiter_unit: arbiter_unit
|
|
generic map(
|
|
num_paths_in => TOT_NUM_PATHS,
|
|
num_paths_out => num_paths_down,
|
|
lsb_sels_size => lsb_size_down
|
|
)
|
|
port map(
|
|
dirs => port_dirs(i),
|
|
packets => packets_1d,
|
|
avai_paths => avai_paths(num_paths_down*(i+1)-1 downto num_paths_down*i),
|
|
out_paths => out_packets(num_paths_down*(i+1)-1 downto num_paths_down*i),
|
|
valids_out => valids_out(num_paths_down*(i+1)-1 downto num_paths_down*i),
|
|
updated_dirs => updated_port_dirs(i)
|
|
);
|
|
end generate;
|
|
|
|
us_ports_arbiter_units: for i in 0 to NUM_PORTS_UP-1 generate
|
|
constant NPOD : positive := NUM_PORTS_DOWN;
|
|
begin
|
|
g_port_dirs: for p in 0 to TOT_NUM_PATHS-1 generate
|
|
port_dirs(i+NPOD)(p) <= ps_dirs(p)(i+NPOD);
|
|
end generate;
|
|
|
|
u_arbiter_unit: arbiter_unit
|
|
generic map(
|
|
num_paths_in => TOT_NUM_PATHS,
|
|
num_paths_out => num_paths_up,
|
|
lsb_sels_size => lsb_size_up
|
|
)
|
|
port map(
|
|
dirs => port_dirs(i+NPOD),
|
|
packets => packets_1d,
|
|
avai_paths => avai_paths(num_paths_up*(i+1)+NPOD*num_paths_down-1 downto num_paths_up*i+NPOD*num_paths_down),
|
|
out_paths => out_packets(num_paths_up*(i+1)+NPOD*num_paths_down-1 downto num_paths_up*i+NPOD*num_paths_down),
|
|
valids_out => valids_out(num_paths_up*(i+1)+NPOD*num_paths_down-1 downto num_paths_up*i+NPOD*num_paths_down),
|
|
updated_dirs => updated_port_dirs(i+NPOD)
|
|
);
|
|
end generate;
|
|
|
|
g_set_buff_wr_in: for i in 0 to TOT_NUM_PATHS-1 generate
|
|
buff_wr_in(i).data <= out_packets(i);
|
|
buff_wr_in(i).wr_req <= valids_out(i);
|
|
end generate;
|
|
|
|
g_updated_dirs: for p in 0 to TOT_NUM_PATHS-1 generate
|
|
g_updated_dir: for i in 0 to NUM_DIRS_PARENT-1 generate
|
|
updated_dirs(p)(i) <= updated_port_dirs(i)(p);
|
|
end generate;
|
|
end generate;
|
|
|
|
set_ps_dirs_nxt: process(dirs, updated_dirs, packets_1d, packets)
|
|
type t_OR_DIRS is array(natural range<>) of std_logic_vector(NUM_DIRS_PARENT-1 downto 0);
|
|
variable or_dirs : t_OR_DIRS(TOT_NUM_PATHS-1 downto 0);
|
|
begin
|
|
for i in 0 to TOT_NUM_PATHS-1 loop
|
|
or_dirs(i)(0) := updated_dirs(i)(0);
|
|
for j in 1 to NUM_DIRS_PARENT-1 loop
|
|
or_dirs(i)(j) := or_dirs(i)(j-1) or updated_dirs(i)(j);
|
|
end loop;
|
|
if or_dirs(i)(NUM_DIRS_PARENT-1) = '0' then
|
|
ps_dirs_nxt(i) <= dirs(i);
|
|
packets_1d_nxt(i) <= packets(i);
|
|
else
|
|
ps_dirs_nxt(i) <= updated_dirs(i);
|
|
packets_1d_nxt(i) <= packets_1d(i);
|
|
end if;
|
|
arb_complete(i) <= not or_dirs(i)(NUM_DIRS_PARENT-1);
|
|
end loop;
|
|
end process;
|
|
|
|
update_signals: process(arstN, clk)
|
|
begin
|
|
if arstN = '0' then
|
|
ps_dirs <= (others => (others => '0'));
|
|
elsif rising_edge(clk) then
|
|
ps_dirs <= ps_dirs_nxt;
|
|
packets_1d <= packets_1d_nxt;
|
|
end if;
|
|
end process;
|
|
end impl; |