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;