diff --git a/router/arbiter.vhdl b/router/arbiter.vhdl index 6aab419..a4e4d36 100644 --- a/router/arbiter.vhdl +++ b/router/arbiter.vhdl @@ -7,7 +7,7 @@ use work.routing_functions.all; entity arbiter is generic( level : integer := 1; - num_paths_up : integer := 2; + num_paths_up : integer := 1; num_paths_down : integer := 1 ); port ( @@ -22,38 +22,36 @@ port ( end arbiter; architecture impl of arbiter is - constant TOT_NUM_PATHS : integer := num_paths_up + num_paths_down*4; - constant NUM_PORTS_UP : integer := 1; - constant NUM_PORTS_DOWN : integer := 4; + constant TOT_NUM_PATHS : integer := num_paths_up + num_paths_down*4; signal dirs : t_DATA_DIRS(TOT_NUM_PATHS-1 downto 0); -begin +begin get_rout_dir: 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); - is_upstream := i >= num_paths_down*4; - dirs(i) <= single_packet_rout_dir_det(level, pack_dest, chip_pos, - core_pos, is_upstream); - else - dirs(i) <= (others => '0'); - end if; - end loop; - end process; - + 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); + is_upstream := i >= num_paths_down*4; + dirs(i) <= single_packet_rout_dir_det(level, pack_dest, chip_pos, + core_pos, is_upstream); + else + dirs(i) <= (others => '0'); + end if; + end loop; + end process; + rout_path_determination: process(packets, dirs, avai_paths) variable sum_dirs : integer; - variable dir_index : integer; + variable j : integer; variable avai_path : std_logic; variable avai_pos_sizes : t_AVAI_POS_SIZES; variable avai_index : integer; @@ -65,25 +63,39 @@ begin avai_pos_sizes := (others => 0); avai_pos := (others => 0); -- find available paths and n_j (avai pos sizes) - for j in 0 to NUM_PORTS_DOWN-1 loop - for i in 0 to num_paths_down-1 loop - avai_path := avai_paths(i+num_paths_down*j); + for i in 0 to TOT_NUM_PATHS-1 loop + avai_path := avai_paths(i); + if i < num_paths_down then if avai_path = '1' then - avai_index := avai_pos_sizes(j) + num_paths_down*j; - avai_pos(avai_index) := i+num_paths_down*j; - avai_pos_sizes(j) := avai_pos_sizes(j) + 1; + avai_index := avai_pos_sizes(0); + avai_pos(avai_index) := i; + avai_pos_sizes(0) := avai_pos_sizes(0) + 1; end if; - end loop; - end loop; - for j in NUM_PORTS_DOWN to NUM_PORTS_DOWN+NUM_PORTS_UP-1 loop - for i in 0 to num_paths_up-1 loop - avai_path := avai_paths(i+num_paths_down*4);--+num_paths_up*(j-NUM_PORTS_DOWN)); + elsif i < num_paths_down*2 then if avai_path = '1' then - avai_index := avai_pos_sizes(j) + num_paths_down*4; - avai_pos(avai_index) := i+num_paths_down*4;--+num_paths_up*(j-NUM_PORTS_DOWN); - avai_pos_sizes(j) := avai_pos_sizes(j) + 1; + avai_index := avai_pos_sizes(1) + num_paths_down; + avai_pos(avai_index) := i; + avai_pos_sizes(1) := avai_pos_sizes(1) + 1; end if; - end loop; + elsif i < num_paths_down*3 then + if avai_path = '1' then + avai_index := avai_pos_sizes(2) + num_paths_down*2; + avai_pos(avai_index) := i; + avai_pos_sizes(2) := avai_pos_sizes(2) + 1; + end if; + elsif i < num_paths_down*4 then + if avai_path = '1' then + avai_index := avai_pos_sizes(3) + num_paths_down*3; + avai_pos(avai_index) := i; + avai_pos_sizes(3) := avai_pos_sizes(3) + 1; + end if; + else + if avai_path = '1' then + avai_index := avai_pos_sizes(4) + num_paths_down*4; + avai_pos(avai_index) := i; + avai_pos_sizes(4) := avai_pos_sizes(4) + 1; + end if; + end if; end loop; -- set rout_dirs to 0 when no more avai_pos (avai_pos_sizes(i) = 0) @@ -94,17 +106,22 @@ begin end loop; -- unicast if sum_dirs = 1 then - dir_index := 0; - for j in 0 to NUM_DIRS-1 loop - if dirs(i)(j) = '1' then - dir_index := j; - end if; - end loop; - if avai_pos_sizes(dir_index) <= 0 then + if dirs(i)(0) = '1' then + j := 0; + elsif dirs(i)(1) = '1' then + j := 1; + elsif dirs(i)(2) = '1' then + j := 2; + elsif dirs(i)(3) = '1' then + j := 3; + else + j := 4; + end if; + if avai_pos_sizes(j) <= 0 then ps_dirs(i) := (others => '0'); else ps_dirs(i) := dirs(i); - avai_pos_sizes(dir_index) := avai_pos_sizes(dir_index)-1; + avai_pos_sizes(j) := avai_pos_sizes(j)-1; end if; -- 1 to 2 multicast elsif sum_dirs = 2 then diff --git a/router/direction_decoder.vhdl b/router/direction_decoder.vhdl new file mode 100644 index 0000000..004c521 --- /dev/null +++ b/router/direction_decoder.vhdl @@ -0,0 +1,71 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.router_types.all; +use work.routing_functions.all; + +entity direction_decoder is +generic( + level : integer := 5; + num_paths : integer := 192; + num_paths_down : integer := 1 +); +port ( + chip_pos : in t_chip_addr; + core_pos : in t_core_addr; + packets : in t_DATA(num_paths-1 downto 0); + valid_data : in std_logic_vector(num_paths-1 downto 0); + dirs : out t_DATA_DIRS_EXT(num_paths-1 downto 0) +); +end direction_decoder; + +architecture impl of direction_decoder is +begin + if TOP_LEVEL = level generate + L5_get_rout_dir: process(chip_pos, core_pos, valid_data, packets) + variable pack_dest : t_pos_addr; + --variable header : std_logic_vector(3 downto 0); + begin + for i in 0 to 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; + end generate; + + if TOP_LEVEL > level generate + get_rout_dir: 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 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); + is_upstream := i >= num_paths_down*4; + dirs(i) <= single_packet_rout_dir_det(level, pack_dest, chip_pos, + core_pos, is_upstream); + else + dirs(i) <= (others => '0'); + end if; + end loop; + end process; + end generate; +end impl; \ No newline at end of file diff --git a/router/parent_arbiter.vhdl b/router/parent_arbiter.vhdl index a5a34df..908b047 100644 --- a/router/parent_arbiter.vhdl +++ b/router/parent_arbiter.vhdl @@ -23,14 +23,12 @@ end parent_arbiter; architecture impl of parent_arbiter is constant TOT_NUM_PATHS : integer := num_paths_up*4 + num_paths_down*4; - constant NUM_PORTS_UP : integer := 4; - constant NUM_PORTS_DOWN : integer := 4; signal dirs : t_DATA_DIRS_EXT(TOT_NUM_PATHS-1 downto 0); begin L5_get_rout_dir: process(chip_pos, core_pos, valid_data, packets) - variable pack_dest : t_pos_addr; - --variable header : std_logic_vector(3 downto 0); + variable pack_dest : t_pos_addr; + --variable header : std_logic_vector(3 downto 0); begin for i in 0 to TOT_NUM_PATHS-1 loop if valid_data(i) = '1' then @@ -51,7 +49,7 @@ begin rout_path_determination: process(packets, dirs, avai_paths) variable sum_dirs : integer; - variable dir_index : integer; + variable j : integer; variable avai_path : std_logic; variable avai_pos_sizes : t_EX_AVAI_POS_SIZES; variable avai_index : integer; @@ -63,25 +61,57 @@ begin avai_pos_sizes := (others => 0); avai_pos := (others => 0); -- find available paths and n_j (avai pos sizes) - for j in 0 to NUM_PORTS_DOWN-1 loop - for i in 0 to num_paths_down-1 loop - avai_path := avai_paths(i+num_paths_down*j); + for i in 0 to TOT_NUM_PATHS-1 loop + avai_path := avai_paths(i); + if i < num_paths_down then if avai_path = '1' then - avai_index := avai_pos_sizes(j) + num_paths_down*j; - avai_pos(avai_index) := i+num_paths_down*j; - avai_pos_sizes(j) := avai_pos_sizes(j) + 1; + avai_index := avai_pos_sizes(0); + avai_pos(avai_index) := i; + avai_pos_sizes(0) := avai_pos_sizes(0) + 1; end if; - end loop; - end loop; - for j in NUM_PORTS_DOWN to NUM_PORTS_DOWN+NUM_PORTS_UP-1 loop - for i in 0 to num_paths_up-1 loop - avai_path := avai_paths(i+num_paths_down*4+num_paths_up*(j-NUM_PORTS_DOWN)); + elsif i < num_paths_down*2 then if avai_path = '1' then - avai_index := avai_pos_sizes(j)+num_paths_down*4+num_paths_up*(j-NUM_PORTS_DOWN); - avai_pos(avai_index) := i+num_paths_down*4+num_paths_up*(j-NUM_PORTS_DOWN); - avai_pos_sizes(j) := avai_pos_sizes(j) + 1; + avai_index := avai_pos_sizes(1) + num_paths_down; + avai_pos(avai_index) := i; + avai_pos_sizes(1) := avai_pos_sizes(1) + 1; end if; - end loop; + elsif i < num_paths_down*3 then + if avai_path = '1' then + avai_index := avai_pos_sizes(2) + num_paths_down*2; + avai_pos(avai_index) := i; + avai_pos_sizes(2) := avai_pos_sizes(2) + 1; + end if; + elsif i < num_paths_down*4 then + if avai_path = '1' then + avai_index := avai_pos_sizes(3) + num_paths_down*3; + avai_pos(avai_index) := i; + avai_pos_sizes(3) := avai_pos_sizes(3) + 1; + end if; + elsif i < num_paths_down*4 + num_paths_up then + if avai_path = '1' then + avai_index := avai_pos_sizes(4) + num_paths_down*4; + avai_pos(avai_index) := i; + avai_pos_sizes(4) := avai_pos_sizes(4) + 1; + end if; + elsif i < num_paths_down*4 + num_paths_up*2 then + if avai_path = '1' then + avai_index := avai_pos_sizes(5)+num_paths_down*4+num_paths_up; + avai_pos(avai_index) := i; + avai_pos_sizes(5) := avai_pos_sizes(5) + 1; + end if; + elsif i < num_paths_down*4 + num_paths_up*3 then + if avai_path = '1' then + avai_index:=avai_pos_sizes(6)+num_paths_down*4+num_paths_up*2; + avai_pos(avai_index) := i; + avai_pos_sizes(6) := avai_pos_sizes(6) + 1; + end if; + else + if avai_path = '1' then + avai_index:=avai_pos_sizes(7)+num_paths_down*4+num_paths_up*3; + avai_pos(avai_index) := i; + avai_pos_sizes(7) := avai_pos_sizes(7) + 1; + end if; + end if; end loop; -- set rout_dirs to 0 when no more avai_pos (avai_pos_sizes(i) = 0) @@ -92,17 +122,28 @@ begin end loop; -- unicast if sum_dirs = 1 then - dir_index := 0; - for j in 0 to NUM_DIRS_PARENT-1 loop - if dirs(i)(j) = '1' then - dir_index := j; - end if; - end loop; - if avai_pos_sizes(dir_index) <= 0 then + if dirs(i)(0) = '1' then + j := 0; + elsif dirs(i)(1) = '1' then + j := 1; + elsif dirs(i)(2) = '1' then + j := 2; + elsif dirs(i)(3) = '1' then + j := 3; + elsif dirs(i)(4) = '1' then + j := 4; + elsif dirs(i)(5) = '1' then + j := 5; + elsif dirs(i)(6) = '1' then + j := 6; + else + j := 7; + end if; + if avai_pos_sizes(j) <= 0 then ps_dirs(i) := (others => '0'); else ps_dirs(i) := dirs(i); - avai_pos_sizes(dir_index) := avai_pos_sizes(dir_index)-1; + avai_pos_sizes(j) := avai_pos_sizes(j)-1; end if; -- 1 to 2 multicast elsif sum_dirs = 2 then diff --git a/router/parent_router.vhdl b/router/parent_router.vhdl index 8ae2867..b0e696e 100644 --- a/router/parent_router.vhdl +++ b/router/parent_router.vhdl @@ -36,7 +36,7 @@ architecture impl of parent_router is constant TOT_NUM_PATHS : integer := num_paths_up*4 + num_paths_down*4; constant chip_pos : t_chip_addr := (x => chip_x, y=> chip_y); - signal core_pos : t_core_addr; + signal core_pos : t_addr; signal rcv_buff_out : t_FIFO_OUTS(TOT_NUM_PATHS-1 downto 0); signal snd_buff_wr_in : t_FIFO_WR_INS(TOT_NUM_PATHS-1 downto 0); signal snd_buff_out : t_FIFO_OUTS(TOT_NUM_PATHS-1 downto 0); @@ -263,6 +263,6 @@ begin end if; end process; - core_pos.x <= core_x(DEST_ADDR_SIZE-1 downto 1); - core_pos.y <= core_y(DEST_ADDR_SIZE-1 downto 1); + core_pos.x <= core_x; + core_pos.y <= core_y; end impl; \ No newline at end of file diff --git a/router/path_selector.vhdl b/router/path_selector.vhdl new file mode 100644 index 0000000..40d516d --- /dev/null +++ b/router/path_selector.vhdl @@ -0,0 +1,169 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.router_types.all; +use work.routing_functions.all; + +entity path_selector is +generic( + level : integer := 5; + num_paths_up : integer := 32; + num_paths_down : integer := 16 +); +port ( + packets : in t_DATA(num_paths_up*4+num_paths_down*4-1 downto 0); + dirs : in t_DATA_DIRS_EXT(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 path_selector; + +architecture impl of path_selector is + constant TOT_NUM_PATHS : integer := num_paths_up*4 + num_paths_down*4; + + type t_PATH_RANGES is array(integer range <>) of + integer range 0 to TOT_NUM_PATHS; + constant PATH_RANGES : t_PATH_RANGES := ( + 0, + num_paths_down, + num_paths_down*2, + num_paths_down*3, + num_paths_down*4, + num_paths_down*4+num_paths_up, + num_paths_down*4+num_paths_up*2, + num_paths_down*4+num_paths_up*3, + num_paths_down*4+num_paths_up*4 + ); +begin + rout_path_determination: process(packets, dirs, avai_paths) + + variable sum_dirs : integer; + variable j : integer; + variable avai_path : std_logic; + variable avai_pos_sizes : t_EX_AVAI_POS_SIZES; + variable avai_index : integer; + variable ps_dirs : t_DATA_DIRS_EXT(TOT_NUM_PATHS-1 downto 0); + variable avai_pos : t_EX_AVAI_POS(TOT_NUM_PATHS-1 downto 0); + variable path_index : integer; + variable out_index : integer; + begin + avai_pos_sizes := (others => 0); + avai_pos := (others => 0); + -- find available paths and n_j (avai pos sizes) + for j in 0 to NUM_DIRS_PARENT-1 loop + for i in PATH_RANGES(j) to PATH_RANGES(j+1)-1 loop + avai_path := avai_paths(i); + if avai_path = '1' then + avai_index := avai_pos_sizes(j); + avai_pos(avai_index) := i; + avai_pos_sizes(j) := avai_pos_sizes(j) + 1; + end if; + end loop; + end loop; + + -- set rout_dirs to 0 when no more avai_pos (avai_pos_sizes(i) = 0) + for i in 0 to TOT_NUM_PATHS-1 loop + sum_dirs := 0; + for j in 0 to NUM_DIRS_PARENT-1 loop + sum_dirs := sum_dirs + to_integer(unsigned'('0' & dirs(i)(j))); + end loop; + -- unicast + if sum_dirs = 1 then + if dirs(i)(0) = '1' then + j := 0; + elsif dirs(i)(1) = '1' then + j := 1; + elsif dirs(i)(2) = '1' then + j := 2; + elsif dirs(i)(3) = '1' then + j := 3; + elsif dirs(i)(4) = '1' then + j := 4; + elsif dirs(i)(5) = '1' then + j := 5; + elsif dirs(i)(6) = '1' then + j := 6; + else + j := 7; + end if; + if avai_pos_sizes(j) <= 0 then + ps_dirs(i) := (others => '0'); + else + ps_dirs(i) := dirs(i); + avai_pos_sizes(j) := avai_pos_sizes(j)-1; + end if; + -- 1 to 2 multicast + elsif sum_dirs = 2 then + if dirs(i)(1) = '1' and dirs(i)(3) = '1' then + if avai_pos_sizes(1) <= 0 or avai_pos_sizes(3) <= 0 then + ps_dirs(i) := (others => '0'); + else + ps_dirs(i) := dirs(i); + avai_pos_sizes(1) := avai_pos_sizes(1)-1; + avai_pos_sizes(3) := avai_pos_sizes(3)-1; + end if; + elsif dirs(i)(0) = '1' and dirs(i)(2) = '1' then + if avai_pos_sizes(0) <= 0 or avai_pos_sizes(2) <= 0 then + ps_dirs(i) := (others => '0'); + else + ps_dirs(i) := dirs(i); + avai_pos_sizes(0) := avai_pos_sizes(0)-1; + avai_pos_sizes(2) := avai_pos_sizes(2)-1; + end if; + elsif dirs(i)(2) = '1' and dirs(i)(3) = '1' then + if avai_pos_sizes(2) <= 0 or avai_pos_sizes(3) <= 0 then + ps_dirs(i) := (others => '0'); + else + ps_dirs(i) := dirs(i); + avai_pos_sizes(2) := avai_pos_sizes(2)-1; + avai_pos_sizes(3) := avai_pos_sizes(3)-1; + end if; + --elsif dirs(i)(1) = '1' and dirs(i)(2) = '1' then + else + if avai_pos_sizes(0) <= 0 or avai_pos_sizes(1) <= 0 then + ps_dirs(i) := (others => '0'); + else + ps_dirs(i) := dirs(i); + avai_pos_sizes(0) := avai_pos_sizes(0)-1; + avai_pos_sizes(1) := avai_pos_sizes(1)-1; + end if; + end if; + -- 1 to 4 multicast + elsif sum_dirs = 4 then + if avai_pos_sizes(0) <= 0 or avai_pos_sizes(1) <= 0 or + avai_pos_sizes(2) <= 0 or avai_pos_sizes(3) <= 0 then + ps_dirs(i) := (others => '0'); + else + ps_dirs(i) := dirs(i); + avai_pos_sizes(0) := avai_pos_sizes(0)-1; + avai_pos_sizes(1) := avai_pos_sizes(1)-1; + avai_pos_sizes(2) := avai_pos_sizes(2)-1; + avai_pos_sizes(3) := avai_pos_sizes(3)-1; + end if; + else + ps_dirs(i) := (others => '0'); + end if; + end loop; + + -- set out buffer + for i in 0 to TOT_NUM_PATHS-1 loop + buff_wr_in(i).data <= (others => '0'); + buff_wr_in(i).wr_req <= '0'; + arb_complete(i) <= '0'; + end loop; + for j in 0 to NUM_DIRS_PARENT-1 loop + path_index := 0; + for i in 0 to TOT_NUM_PATHS-1 loop + if ps_dirs(i)(j)='1' then + out_index := retrieve_ex_avai_path_index(j, path_index, + num_paths_up, num_paths_down, avai_pos); + path_index := path_index + 1; + buff_wr_in(out_index).data <= packets(i); + buff_wr_in(out_index).wr_req <= '1'; + arb_complete(i) <= '1'; + end if; + end loop; + end loop; + end process; +end impl; \ No newline at end of file diff --git a/router/router_types.vhdl b/router/router_types.vhdl index 1305855..5bf23a9 100644 --- a/router/router_types.vhdl +++ b/router/router_types.vhdl @@ -30,8 +30,6 @@ package router_types is integer range 0 to MAX_EX_PATHS_SIZE; type t_EX_AVAI_POS_SIZES is array(NUM_DIRS_PARENT-1 downto 0) of integer range 0 to MAX_EX_PATHS_SIZE; - type t_PATH_RANGES is array(integer range <>) of - integer range 0 to MAX_EX_PATHS_SIZE; type t_fifo_wr_in is record data : WORD;