paicore_behavioral/arbiter/parent_arbiter.vhdl
2025-07-18 05:09:06 -05:00

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;