From 1f479ff452ed54b5c0cd28bed9b4cc00c3425a9c Mon Sep 17 00:00:00 2001 From: Retrocamara42 Date: Thu, 15 May 2025 06:40:41 -0500 Subject: [PATCH 1/2] fix: ack signals removed, router tb added --- fifo.vhdl | 11 +---- input_buffer.vhdl | 30 +++++++------ router.vhdl | 50 ++++++++++------------ router_components.vhdl | 8 ++-- router_tb.vhdl | 96 +++++++++++++++++++++++++++++++----------- router_types.vhdl | 3 -- routing_functions.vhdl | 94 ++++++++++++++++++++++++++++++++++++++++- test/fifo_tb.vhdl | 16 +++---- 8 files changed, 216 insertions(+), 92 deletions(-) diff --git a/fifo.vhdl b/fifo.vhdl index b27bbae..08dabab 100755 --- a/fifo.vhdl +++ b/fifo.vhdl @@ -7,11 +7,11 @@ entity fifo is generic ( WIDTH : integer := 32; DEPTH : integer := 8; - F_PTR_SIZE : integer := 4 + F_PTR_SIZE : integer := 4 ); port( arstN, clk, wr_req, rd_req : in std_logic; - wr_ack, rd_ack, full, empty : out std_logic; + full, empty : out std_logic; data_in : in std_logic_vector(WIDTH-1 downto 0); data_out : out std_logic_vector(WIDTH-1 downto 0) ); @@ -23,7 +23,6 @@ type T_FIFO is array (0 to DEPTH-1) of std_logic_vector(WIDTH-1 downto 0); signal wr_ptr, rd_ptr : unsigned(F_PTR_SIZE-1 downto 0); signal wr_ptr_nxt, rd_ptr_nxt : unsigned(F_PTR_SIZE-1 downto 0); -signal wr_ack_nxt, rd_ack_nxt : std_logic; signal full_nxt, empty_nxt : std_logic; signal data_out_nxt : std_logic_vector(WIDTH-1 downto 0); signal fifo, fifo_nxt : T_FIFO; @@ -39,8 +38,6 @@ begin fifo <= fifo_nxt; wr_ptr <= wr_ptr_nxt; rd_ptr <= rd_ptr_nxt; - wr_ack <= wr_ack_nxt; - rd_ack <= rd_ack_nxt; full <= full_nxt; empty <= empty_nxt; data_out <= data_out_nxt; @@ -50,10 +47,8 @@ begin update_wr_ptr: process(wr_req, full_nxt, wr_ptr) begin if wr_req = '1' and full_nxt = '0' then - wr_ack_nxt <= '1'; wr_ptr_nxt <= wr_ptr + 1; else - wr_ack_nxt <= '0'; wr_ptr_nxt <= wr_ptr; end if; end process; @@ -82,10 +77,8 @@ begin update_rd_ptr: process(rd_req, empty_nxt, rd_ptr) begin if rd_req = '1' and empty_nxt = '0' then - rd_ack_nxt <= '1'; rd_ptr_nxt <= rd_ptr + 1; else - rd_ack_nxt <= '0'; rd_ptr_nxt <= rd_ptr; end if; end process; diff --git a/input_buffer.vhdl b/input_buffer.vhdl index cc71225..c1f56bb 100644 --- a/input_buffer.vhdl +++ b/input_buffer.vhdl @@ -8,9 +8,9 @@ generic ( DEPTH: integer := 8 ); port ( - rstN, clk, wr_req : in std_logic; + arstN, clk, wr_req : in std_logic; data_valid : inout std_logic; - wr_ack, full : out std_logic; + full : out std_logic; data_in : in std_logic_vector(WIDTH-1 downto 0); data_out : out std_logic_vector(WIDTH-1 downto 0) ); @@ -23,21 +23,20 @@ architecture impl of input_buffer is DEPTH: integer ); port( - rstN, clk, wr_req, rd_req, only_peek : in std_logic; - wr_ack, rd_ack, full, empty : out std_logic; + arstN, clk, wr_req, rd_req : in std_logic; + full, empty : out std_logic; data_in : in std_logic_vector(WIDTH-1 downto 0); data_out : out std_logic_vector(WIDTH-1 downto 0) ); end component fifo; - signal rd_req, rd_ack, empty, only_peek : std_logic; + signal rd_req, rd_req_nxt, empty : std_logic; begin fifo_us: fifo generic map(WIDTH => WIDTH, DEPTH => DEPTH) - port map(rstN => rstN, clk => clk, wr_req => wr_req, wr_ack => wr_ack, - rd_req => rd_req, rd_ack => rd_ack, data_in => data_in, - data_out => data_out, full => full, empty => empty, - only_peek => only_peek); + port map(arstN => arstN, clk => clk, wr_req => wr_req, + rd_req => rd_req, data_in => data_in, + data_out => data_out, full => full, empty => empty); start_read: process(empty, data_valid) begin @@ -46,11 +45,18 @@ begin end if; end process; - read: process(rd_ack) + read: process(rd_req) begin - if rd_ack = '1' then - rd_req <= '0'; + if rd_req = '1' then + rd_req_nxt <= '0'; data_valid <= '1'; end if; end process; + + update_signals: process(clk) + begin + if rising_edge(clk) then + rd_req <= rd_req_nxt; + end if; + end process; end impl; \ No newline at end of file diff --git a/router.vhdl b/router.vhdl index 1fba55c..fd97280 100644 --- a/router.vhdl +++ b/router.vhdl @@ -10,7 +10,6 @@ entity router is generic ( num_paths_up : integer := 1; num_paths_down : integer := 1; - rd_data_b_size : integer := 3; level : integer := 1; buffer_width : integer := 64; buffer_depth : integer := 4; @@ -21,7 +20,7 @@ generic ( ); port ( clk : in std_logic; - rstN : in std_logic; + arstN : in std_logic; buffers_in : inout t_PORT_IN(num_paths_up+num_paths_down*4-1 downto 0); buffers_out : inout t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0) ); @@ -30,35 +29,32 @@ end router; architecture impl of router is constant TOT_NUM_PATHS : positive := num_paths_up + num_paths_down*4; - signal chip_r_x : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - signal chip_r_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - signal core_r_x : std_logic_vector(DEST_ADDR_SIZE-level-1 downto 0); - signal core_r_y : std_logic_vector(DEST_ADDR_SIZE-level-1 downto 0); - signal rd_data, rd_data_nxt : t_DATA(TOT_NUM_PATHS downto 0); - signal rd_data_valid : t_DATA_VAL(TOT_NUM_PATHS downto 0); - signal avai_paths : t_PATHS(TOT_NUM_PATHS downto 0); - signal out_buff_if : t_PORT_IN(TOT_NUM_PATHS-1 downto 0); + signal chip_r_x : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); + signal chip_r_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); + signal core_r_x : std_logic_vector(DEST_ADDR_SIZE-level-1 downto 0); + signal core_r_y : std_logic_vector(DEST_ADDR_SIZE-level-1 downto 0); + signal rd_data, rd_data_nxt : t_DATA(TOT_NUM_PATHS downto 0); + signal rd_data_valid : t_DATA_VAL(TOT_NUM_PATHS downto 0); + signal avai_paths : t_PATHS(TOT_NUM_PATHS downto 0); + signal out_buff_if, out_buff_if_nxt : t_PORT_IN(TOT_NUM_PATHS-1 downto 0); begin -- implements all buffers for each path g_IN_BUFF_GEN: for i in 0 to TOT_NUM_PATHS-1 generate input_buffer_x: input_buffer generic map(WIDTH => buffer_width, DEPTH => buffer_depth) - port map(rstN => rstN, clk => clk, wr_req => buffers_in(i).req, - wr_ack => buffers_in(i).ack, full => buffers_in(i).full, - data_valid => rd_data_valid(i), data_in => buffers_in(i).data_in, - data_out => rd_data_nxt(i)); + port map(arstN => arstN, clk => clk, wr_req => buffers_in(i).req, + full => buffers_in(i).full, data_valid => rd_data_valid(i), + data_in => buffers_in(i).data_in, data_out => rd_data_nxt(i)); end generate; g_OUT_BUFF_GEN: for i in 0 to TOT_NUM_PATHS-1 generate output_fifo: fifo generic map(WIDTH => buffer_width, DEPTH => buffer_depth) - port map(rstN => rstN, clk => clk, wr_req => out_buff_if(i).req, - wr_ack => out_buff_if(i).ack, rd_req => buffers_out(i).req, - rd_ack => buffers_out(i).ack, data_in => out_buff_if(i).data_in, + port map(arstN => arstN, clk => clk, wr_req => out_buff_if(i).req, + rd_req => buffers_out(i).req, data_in => out_buff_if(i).data_in, data_out => buffers_out(i).data_out, full => out_buff_if(i).full, - empty => buffers_out(i).empty, - only_peek => out_buff_if(i).only_peek); + empty => buffers_out(i).empty); end generate; set_avai_paths: process(out_buff_if) @@ -87,18 +83,17 @@ begin end_wr_req: process(out_buff_if) begin for i in 0 to TOT_NUM_PATHS-1 loop - if out_buff_if(i).ack = '1' then - out_buff_if(i).req <= '0'; + if out_buff_if(i).req = '1' then + out_buff_if_nxt(i).req <= '0'; + else + out_buff_if_nxt(i).req <= out_buff_if(i).req; end if; end loop; end process; - switching: process(rstN, clk) - variable rout_dirs : t_DATA_DIRS(tot_num_paths-1 downto 0); - variable avai_pos : t_AVAI_POS(tot_num_paths-1 downto 0); - variable path_index, out_index : integer; + switching: process(arstN, clk) begin - if rstN = '0' then + if arstN = '0' then rd_data <= (others => (others => '0')); rd_data_valid <= (others => '0'); chip_r_x <= std_logic_vector(to_unsigned( @@ -111,8 +106,9 @@ begin val_core_r_y, core_r_y'length)); elsif rising_edge(clk) then rd_data <= rd_data_nxt; + out_buff_if <= out_buff_if_nxt; routing(level, rd_data, rd_data_valid, chip_r_x, chip_r_y, core_r_x, - core_r_y, avai_paths, num_paths_up, num_paths_down, out_buff_if); + core_r_y, avai_paths, num_paths_up, num_paths_down, out_buff_if_nxt); end if; end process; end impl; \ No newline at end of file diff --git a/router_components.vhdl b/router_components.vhdl index 43cc013..6160939 100644 --- a/router_components.vhdl +++ b/router_components.vhdl @@ -9,8 +9,8 @@ package router_components is DEPTH: integer ); port( - rstN, clk, wr_req, rd_req, only_peek : in std_logic; - wr_ack, rd_ack, full, empty : out std_logic; + arstN, clk, wr_req, rd_req : in std_logic; + full, empty : out std_logic; data_in : in std_logic_vector(WIDTH-1 downto 0); data_out : out std_logic_vector(WIDTH-1 downto 0) ); @@ -22,9 +22,9 @@ package router_components is DEPTH: integer ); port( - rstN, clk, wr_req : in std_logic; + arstN, clk, wr_req : in std_logic; data_valid : inout std_logic; - wr_ack, full : out std_logic; + full : out std_logic; data_in : in std_logic_vector(WIDTH-1 downto 0); data_out : out std_logic_vector(WIDTH-1 downto 0) ); diff --git a/router_tb.vhdl b/router_tb.vhdl index 47d513d..a67a0ad 100644 --- a/router_tb.vhdl +++ b/router_tb.vhdl @@ -1,32 +1,78 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; - use work.router_types.all; entity router_tb is -end router_tb; +end; -architecture impl of router_tb is - component router is - generic ( - num_paths_up : integer; - num_paths_down : integer; - rd_data_b_size : integer; - level : integer; - buffer_width : integer; - buffer_depth : integer; - val_chip_r_x : integer; - val_chip_r_y : integer; - val_core_r_x : integer; - val_core_r_y : integer - ); - port ( - clk : in std_logic; - rstN : in std_logic; - buffers_in : inout t_PORT_IN(num_paths_up+num_paths_down*4-1 downto 0); - buffers_out : inout t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0) - ); - end component; -begin -end impl; \ No newline at end of file +architecture bench of router_tb is + -- Clock period + constant clk_period : time := 5 ns; + -- Generics + constant num_paths_up : integer := 1; + constant num_paths_down : integer := 1; + constant level : integer := 1; + constant buffer_width : integer := 64; + constant buffer_depth : integer := 4; + constant val_chip_r_x : integer := 0; + constant val_chip_r_y : integer := 0; + constant val_core_r_x : integer := 0; + constant val_core_r_y : integer := 0; + -- Ports + signal clk : std_logic; + signal arstN : std_logic; + signal buffers_in : t_PORT_IN(num_paths_up+num_paths_down*4-1 downto 0); + signal buffers_out : t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0); +begin + + router_inst : entity work.router + generic map ( + num_paths_up => num_paths_up, + num_paths_down => num_paths_down, + level => level, + buffer_width => buffer_width, + buffer_depth => buffer_depth, + val_chip_r_x => val_chip_r_x, + val_chip_r_y => val_chip_r_y, + val_core_r_x => val_core_r_x, + val_core_r_y => val_core_r_y + ) + port map ( + clk => clk, + arstN => arstN, + buffers_in => buffers_in, + buffers_out => buffers_out + ); + + clock_gen: process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + test: process + begin + buffers_in(0).data_in <= "0001"&"00000"&"00000"&"00001"&"00001"& + std_logic_vector(to_unsigned(3, 40)); + buffers_in(0).req <= '1'; + + buffers_in(1).data_in <= (others => '0'); + buffers_in(1).req <= '0'; + + buffers_in(2).data_in <= "0001"&"00000"&"10000"&"10001"&"00001"& + std_logic_vector(to_unsigned(4, 40)); + buffers_in(2).req <= '1'; + + buffers_in(3).data_in <= (others => '0'); + buffers_in(3).req <= '0'; + + buffers_in(4).data_in <= "0001"&"00000"&"00000"&"00000"&"00001"& + std_logic_vector(to_unsigned(5, 40)); + buffers_in(4).req <= '1'; + wait; + end process; + +end bench; \ No newline at end of file diff --git a/router_types.vhdl b/router_types.vhdl index 10a3db7..60c36d2 100644 --- a/router_types.vhdl +++ b/router_types.vhdl @@ -20,15 +20,12 @@ package router_types is type t_fifo_in is record data_in : WORD; req : std_logic; - ack : std_logic; full : std_logic; - only_peek : std_logic; end record; type t_fifo_out is record data_out : WORD; req : std_logic; - ack : std_logic; empty : std_logic; end record; diff --git a/routing_functions.vhdl b/routing_functions.vhdl index 63c183c..ead80cd 100644 --- a/routing_functions.vhdl +++ b/routing_functions.vhdl @@ -260,11 +260,101 @@ package body routing_functions is dir : in positive; path_index : in integer; num_paths_up : in positive; - num_paths_down : in positive; + num_paths_down : in positive; avai_pos : in t_AVAI_POS ) return integer is variable avai_pos_index : integer; begin + procedure rout_path_determination ( + read_data : in t_DATA;--(tot_num_paths); -- stored in buffers + read_data_valid : in t_DATA_VAL; + rout_dirs : inout t_DATA_DIRS;--(tot_num_paths); -- got from routing function + paths : in t_PATHS; + num_paths_up : in positive; + num_paths_down : in positive; + avai_pos : out t_AVAI_POS + ) is + variable sum_dirs : integer; + variable num_paths : positive; + variable n_j : integer; + variable avai_path : std_logic_vector(NUM_DIRS-1 downto 0); + variable avai_pos_sizes : t_AVAI_POS_SIZ; + begin + num_paths := num_paths_up + num_paths_down*4; + avai_pos_sizes := (others => 0); + for i in 0 to num_paths loop + avai_path := paths(i); + if i < num_paths_up then + if avai_path(0) = '1' then + avai_pos(avai_pos_sizes(0)) := + std_logic_vector(to_unsigned(i,AV_POS_SIZE)); + avai_pos_sizes(0) := avai_pos_sizes(0) + 1; + end if; + elsif i < num_paths_up + num_paths_down then + if avai_path(1) = '1' then + avai_pos(avai_pos_sizes(1)) := + std_logic_vector(to_unsigned(i,AV_POS_SIZE)); + avai_pos_sizes(1) := avai_pos_sizes(1) + 1; + end if; + elsif i < num_paths_up + num_paths_down*2 then + if avai_path(2) = '1' then + avai_pos(avai_pos_sizes(2)) := + std_logic_vector(to_unsigned(i,AV_POS_SIZE)); + avai_pos_sizes(2) := avai_pos_sizes(2) + 1; + end if; + elsif i < num_paths_up + num_paths_down*3 then + if avai_path(3) = '1' then + avai_pos(avai_pos_sizes(3)) := + std_logic_vector(to_unsigned(i,AV_POS_SIZE)); + avai_pos_sizes(3) := avai_pos_sizes(3) + 1; + end if; + else + if avai_path(4) = '1' then + avai_pos(avai_pos_sizes(4)) := + std_logic_vector(to_unsigned(i,AV_POS_SIZE)); + avai_pos_sizes(4) := avai_pos_sizes(4) + 1; + end if; + end if; + end loop; + + for i in 0 to read_data'length-1 loop + if read_data_valid(i) = '1' then + sum_dirs := 0; + for j in 0 to NUM_DIRS loop + sum_dirs := sum_dirs + to_integer(unsigned(rout_dirs(j))); + end loop; + -- unicast + if sum_dirs = 1 then + if rout_dirs(i)(0) = '1' then + n_j := avai_pos_sizes(0); + avai_pos_sizes(0) := avai_pos_sizes(0)-1; + elsif rout_dirs(i)(1) = '1' then + n_j := avai_pos_sizes(1); + avai_pos_sizes(1) := avai_pos_sizes(1)-1; + elsif rout_dirs(i)(2) = '1' then + n_j := avai_pos_sizes(2); + avai_pos_sizes(2) := avai_pos_sizes(2)-1; + elsif rout_dirs(i)(3) = '1' then + n_j := avai_pos_sizes(3); + avai_pos_sizes(3) := avai_pos_sizes(3)-1; + elsif rout_dirs(i)(4) = '1' then + n_j := avai_pos_sizes(4); + avai_pos_sizes(4) := avai_pos_sizes(4)-1; + end if; + if n_j <= 0 then + rout_dirs(i) := (others => '0'); + end if; + -- 1 to 2 multicast + elsif sum_dirs = 2 then + if rout_dirs(i)(2) = '1' and rout_dirs(i)(4) = '1' then + if avai_pos_sizes(2) <= 0 or avai_pos_sizes(4) <= 0 then + rout_dirs(i) := (others => '0'); + end if; + elsif rout_dirs(i)(1) = '1' and rout_dirs(i)(3) = '1' then + if avai_pos_sizes(1) <= 0 or avai_pos_sizes(3) <= 0 then + rout_dirs(i) := (others => '0'); + end if; + elsif rout_dirs(i)(3) = if dir = 0 then return to_integer(unsigned(avai_pos(path_index))); elsif dir = 1 then @@ -296,7 +386,7 @@ package body routing_functions is tot_num_paths := num_paths_up+num_paths_down*4; for i in 0 to tot_num_paths-1 loop out_buff_if(i).data_in <= (others => '0'); - out_buff_if(i).req <= '0'; + out_buff_if(i).req <= '0'; end loop; for j in 0 to NUM_DIRS loop path_index := 0; diff --git a/test/fifo_tb.vhdl b/test/fifo_tb.vhdl index 53cc5dd..a91865f 100755 --- a/test/fifo_tb.vhdl +++ b/test/fifo_tb.vhdl @@ -18,8 +18,6 @@ architecture bench of fifo_tb is signal clk : std_logic; signal wr_req : std_logic; signal rd_req : std_logic; - signal wr_ack : std_logic; - signal rd_ack : std_logic; signal full : std_logic; signal empty : std_logic; signal data_in : std_logic_vector(WIDTH-1 downto 0); @@ -37,8 +35,6 @@ begin clk => clk, wr_req => wr_req, rd_req => rd_req, - wr_ack => wr_ack, - rd_ack => rd_ack, full => full, empty => empty, data_in => data_in, @@ -59,19 +55,19 @@ begin wait for CLK_PERIOD; arstN <= '1'; - for value_sent in 6 downto 0 loop + for value_sent in 10 downto 0 loop wr_req <= '1'; data_in <= std_logic_vector(to_unsigned(value_sent, data_in'length)); - wait until wr_ack = '1'; + wait for clk_period; wr_req <= '0'; - wait until wr_ack = '0'; + wait for clk_period; end loop; - for counter in 0 to 6 loop + for counter in 0 to 10 loop rd_req <= '1'; - wait until rd_ack = '1'; + wait for clk_period; rd_req <= '0'; - wait until rd_ack = '0'; + wait for clk_period; end loop; wait; end process; From 25b49e98323e43d82512f82cc4d052c8cc320a6f Mon Sep 17 00:00:00 2001 From: Retrocamara42 Date: Sun, 18 May 2025 04:17:49 -0500 Subject: [PATCH 2/2] feat: arbiter component created --- arbiter.vhdl | 163 ++++++++++ input_buffer.vhdl | 62 ---- router.vhdl | 121 ++++---- router_components.vhdl | 24 +- router_types.vhdl | 32 +- routing_functions.vhdl | 424 +++----------------------- test/fifo_tb.vhdl | 4 +- router_tb.vhdl => test/router_tb.vhdl | 0 8 files changed, 295 insertions(+), 535 deletions(-) create mode 100644 arbiter.vhdl delete mode 100644 input_buffer.vhdl rename router_tb.vhdl => test/router_tb.vhdl (100%) diff --git a/arbiter.vhdl b/arbiter.vhdl new file mode 100644 index 0000000..8bc0c02 --- /dev/null +++ b/arbiter.vhdl @@ -0,0 +1,163 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.router_types.all; +use work.routing_functions.all; + +entity arbiter is +generic( + level : integer := 1; + num_paths_up : integer := 1; + num_paths_down : integer := 1 +); +port ( + rout_pos : in t_pos_addr; + packets : in t_DATA(num_paths_up+num_paths_down*4-1 downto 0); + avai_paths : in std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0); + data_out : out t_DATA(num_paths_up+num_paths_down*4-1 downto 0); + wr_req : out std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0) +); +end arbiter; + +architecture impl of arbiter is + constant TOT_NUM_PATHS : positive := num_paths_up + num_paths_down*4; + + signal dirs : t_DATA_DIRS(TOT_NUM_PATHS-1 downto 0); + signal ps_dirs : t_DATA_DIRS(TOT_NUM_PATHS-1 downto 0); + signal avai_pos : t_AVAI_POS(TOT_NUM_PATHS-1 downto 0); +begin + get_rout_dir: process(rout_pos, packets) + variable pack_dest : t_pos_addr; + variable header : std_logic_vector(3 downto 0); + begin + for i in 0 to packets'length-1 loop + header := packets(i)(63 downto 60); + if header /= "0000" then + pack_dest.chip_x := packets(i)(59 downto 55); + pack_dest.chip_y := packets(i)(54 downto 50); + pack_dest.core_x := packets(i)(49 downto 45); + pack_dest.core_y := packets(i)(44 downto 40); + pack_dest.copy_x := packets(i)(39 downto 35); + pack_dest.copy_y := packets(i)(34 downto 30); + dirs(i) <= single_packet_rout_dir_det(level, pack_dest, rout_pos); + else + dirs(i) <= (others => '0'); + end if; + end loop; + end process; + + rout_path_determination: process(packets, dirs, avai_paths) + variable sum_dirs : integer; + variable n_j : integer; + variable avai_path : std_logic; + variable avai_pos_sizes : t_AVAI_POS_SIZES; + begin + avai_pos_sizes := (others => 0); + -- find available paths and n_j (avai pos sizes) + for i in 0 to TOT_NUM_PATHS loop + avai_path := avai_paths(i); + if i < num_paths_up then + if avai_path = '1' then + avai_pos(avai_pos_sizes(0)) <= i; + avai_pos_sizes(0) := avai_pos_sizes(0) + 1; + end if; + elsif i < num_paths_up + num_paths_down then + if avai_path = '1' then + avai_pos(avai_pos_sizes(1)) <= i; + avai_pos_sizes(1) := avai_pos_sizes(1) + 1; + end if; + elsif i < num_paths_up + num_paths_down*2 then + if avai_path = '1' then + avai_pos(avai_pos_sizes(2)) <= i; + avai_pos_sizes(2) := avai_pos_sizes(2) + 1; + end if; + elsif i < num_paths_up + num_paths_down*3 then + if avai_path = '1' then + avai_pos(avai_pos_sizes(3)) <= i; + avai_pos_sizes(3) := avai_pos_sizes(3) + 1; + end if; + else + if avai_path = '1' then + avai_pos(avai_pos_sizes(4)) <= 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) + for i in 0 to TOT_NUM_PATHS-1 loop + if dirs(i) /= (others => '0') then + sum_dirs := 0; + for j in 0 to NUM_DIRS loop + sum_dirs := sum_dirs + to_integer(unsigned(dirs(j))); + end loop; + -- unicast + if sum_dirs = 1 then + if dirs(i)(0) = '1' then + n_j := avai_pos_sizes(0); + avai_pos_sizes(0) := avai_pos_sizes(0)-1; + elsif dirs(i)(1) = '1' then + n_j := avai_pos_sizes(1); + avai_pos_sizes(1) := avai_pos_sizes(1)-1; + elsif dirs(i)(2) = '1' then + n_j := avai_pos_sizes(2); + avai_pos_sizes(2) := avai_pos_sizes(2)-1; + elsif dirs(i)(3) = '1' then + n_j := avai_pos_sizes(3); + avai_pos_sizes(3) := avai_pos_sizes(3)-1; + elsif dirs(i)(4) = '1' then + n_j := avai_pos_sizes(4); + avai_pos_sizes(4) := avai_pos_sizes(4)-1; + end if; + if n_j <= 0 then + ps_dirs(i) <= (others => '0'); + end if; + -- 1 to 2 multicast + elsif sum_dirs = 2 then + if dirs(i)(2) = '1' and dirs(i)(4) = '1' then + if avai_pos_sizes(2) <= 0 or avai_pos_sizes(4) <= 0 then + ps_dirs(i) <= (others => '0'); + end if; + elsif 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'); + end if; + elsif dirs(i)(3) = '1' and dirs(i)(4) = '1' then + if avai_pos_sizes(3) <= 0 or avai_pos_sizes(4) <= 0 then + ps_dirs(i) <= (others => '0'); + end if; + elsif dirs(i)(1) = '1' and dirs(i)(2) = '1' then + if avai_pos_sizes(1) <= 0 or avai_pos_sizes(2) <= 0 then + ps_dirs(i) <= (others => '0'); + end if; + end if; + -- 1 to 4 multicast + else + if avai_pos_sizes(1) <= 0 or avai_pos_sizes(2) <= 0 or + avai_pos_sizes(3) <= 0 or avai_pos_sizes(4) <= 0 then + ps_dirs(i) <= (others => '0'); + end if; + end if; + end if; + end loop; + end process; + + set_out_buffer: process(dirs, packets, avai_pos) + variable path_index, out_index : integer; + begin + data_out <= (others => (others => '0')); + wr_req <= (others => '0'); + for j in 0 to NUM_DIRS loop + path_index := 0; + for i in 0 to TOT_NUM_PATHS-1 loop + if dirs(i)(j)='1' then + out_index := retrieve_avai_path_index(j, path_index, + num_paths_up, num_paths_down, avai_pos); + path_index := path_index + 1; + data_out(out_index) <= packets(i); + wr_req(out_index) <= '1'; + end if; + end loop; + end loop; + end process; +end impl; \ No newline at end of file diff --git a/input_buffer.vhdl b/input_buffer.vhdl deleted file mode 100644 index c1f56bb..0000000 --- a/input_buffer.vhdl +++ /dev/null @@ -1,62 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity input_buffer is -generic ( - WIDTH: integer := 32; - DEPTH: integer := 8 -); -port ( - arstN, clk, wr_req : in std_logic; - data_valid : inout std_logic; - full : out std_logic; - data_in : in std_logic_vector(WIDTH-1 downto 0); - data_out : out std_logic_vector(WIDTH-1 downto 0) -); -end input_buffer; - -architecture impl of input_buffer is - component fifo is - generic ( - WIDTH: integer; - DEPTH: integer - ); - port( - arstN, clk, wr_req, rd_req : in std_logic; - full, empty : out std_logic; - data_in : in std_logic_vector(WIDTH-1 downto 0); - data_out : out std_logic_vector(WIDTH-1 downto 0) - ); - end component fifo; - - signal rd_req, rd_req_nxt, empty : std_logic; -begin - fifo_us: fifo - generic map(WIDTH => WIDTH, DEPTH => DEPTH) - port map(arstN => arstN, clk => clk, wr_req => wr_req, - rd_req => rd_req, data_in => data_in, - data_out => data_out, full => full, empty => empty); - - start_read: process(empty, data_valid) - begin - if empty = '0' and data_valid = '0' then - rd_req <= '1'; -- read from fifo - end if; - end process; - - read: process(rd_req) - begin - if rd_req = '1' then - rd_req_nxt <= '0'; - data_valid <= '1'; - end if; - end process; - - update_signals: process(clk) - begin - if rising_edge(clk) then - rd_req <= rd_req_nxt; - end if; - end process; -end impl; \ No newline at end of file diff --git a/router.vhdl b/router.vhdl index fd97280..8ed1573 100644 --- a/router.vhdl +++ b/router.vhdl @@ -13,102 +13,93 @@ generic ( level : integer := 1; buffer_width : integer := 64; buffer_depth : integer := 4; - val_chip_r_x : integer := 0; - val_chip_r_y : integer := 0; - val_core_r_x : integer := 0; - val_core_r_y : integer := 0 + chip_x : std_logic_vector(4 downto 0); + chip_y : std_logic_vecto_nxtr(4 downto 0) ); port ( clk : in std_logic; arstN : in std_logic; - buffers_in : inout t_PORT_IN(num_paths_up+num_paths_down*4-1 downto 0); - buffers_out : inout t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0) + rcv_buffers_in : in t_PORT_IN(num_paths_up+num_paths_down*4-1 downto 0); + snd_buffers_out : out t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0) ); end router; architecture impl of router is - constant TOT_NUM_PATHS : positive := num_paths_up + num_paths_down*4; + constant TOT_NUM_PATHS : positive := num_paths_up + num_paths_down*4; - signal chip_r_x : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - signal chip_r_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - signal core_r_x : std_logic_vector(DEST_ADDR_SIZE-level-1 downto 0); - signal core_r_y : std_logic_vector(DEST_ADDR_SIZE-level-1 downto 0); - signal rd_data, rd_data_nxt : t_DATA(TOT_NUM_PATHS downto 0); - signal rd_data_valid : t_DATA_VAL(TOT_NUM_PATHS downto 0); - signal avai_paths : t_PATHS(TOT_NUM_PATHS downto 0); - signal out_buff_if, out_buff_if_nxt : t_PORT_IN(TOT_NUM_PATHS-1 downto 0); + signal rcv_buffers_out : t_PORT_OUT(TOT_NUM_PATHS-1 downto 0); + signal snd_buffers_in : t_PORT_IN(TOT_NUM_PATHS-1 downto 0); + --signal snd_buffers_in_nxt : t_PORT_IN(TOT_NUM_PATHS-1 downto 0); + signal rout_pos : t_pos_addr; + signal read_data, data_to_send : t_DATA(TOT_NUM_PATHS-1 downto 0); + signal wr_reqs : std_logic_vector(TOT_NUM_PATHS-1 downto 0); + signal avai_paths : std_logic_vector(TOT_NUM_PATHS-1 downto 0); begin - -- implements all buffers for each path g_IN_BUFF_GEN: for i in 0 to TOT_NUM_PATHS-1 generate - input_buffer_x: input_buffer - generic map(WIDTH => buffer_width, DEPTH => buffer_depth) - port map(arstN => arstN, clk => clk, wr_req => buffers_in(i).req, - full => buffers_in(i).full, data_valid => rd_data_valid(i), - data_in => buffers_in(i).data_in, data_out => rd_data_nxt(i)); + input_fifo: fifo + generic map(WIDTH => buffer_width, DEPTH => buffer_depth) + port map(arstN => arstN, clk => clk, wr_req => rcv_buffers_in(i).wr_req, + rd_req => not rcv_buffers_out(i).empty, + data_in => rcv_buffers_in(i).data, + data_out => rcv_buffers_out(i).data, + full => rcv_buffers_out(i).full, empty => rcv_buffers_out(i).empty); end generate; g_OUT_BUFF_GEN: for i in 0 to TOT_NUM_PATHS-1 generate output_fifo: fifo - generic map(WIDTH => buffer_width, DEPTH => buffer_depth) - port map(arstN => arstN, clk => clk, wr_req => out_buff_if(i).req, - rd_req => buffers_out(i).req, data_in => out_buff_if(i).data_in, - data_out => buffers_out(i).data_out, full => out_buff_if(i).full, - empty => buffers_out(i).empty); + generic map(WIDTH => buffer_width, DEPTH => buffer_depth) + port map(arstN => arstN, clk => clk, wr_req => snd_buffers_in(i).wr_req, + rd_req => snd_buffers_in(i).rd_req, data_in => snd_buffers_in(i).data, + data_out => snd_buffers_out(i).data, full => snd_buffers_out(i).full, + empty => snd_buffers_out(i).empty); end generate; - set_avai_paths: process(out_buff_if) - variable ds_ind : integer; - variable dir : positive; + arbiter0: arbiter + generic map( + level => level, + num_paths_up=>num_paths_up, + num_paths_down=>num_paths_down + ) + port map( + rout_pos => rout_pos, + packets => read_data, + avai_paths => avai_paths, + data_out => data_to_send, + wr_req => wr_reqs + ); + + set_read_data: process(rcv_buffers_out) begin for i in 0 to TOT_NUM_PATHS-1 loop - if i < num_paths_up then - avai_paths(i)(0) <= not out_buff_if(i).full; - elsif i < num_paths_up + num_paths_down then - ds_ind := i - num_paths_up; - avai_paths(i)(1) <= not out_buff_if(i).full; - elsif i < num_paths_up + num_paths_down*2 then - ds_ind := i - num_paths_up - num_paths_down; - avai_paths(i)(2) <= not out_buff_if(i).full; - elsif i < num_paths_up + num_paths_down*3 then - ds_ind := i - num_paths_up - num_paths_down*2; - avai_paths(i)(3) <= not out_buff_if(i).full; - else - ds_ind := i - num_paths_up - num_paths_down*3; - avai_paths(i)(4) <= not out_buff_if(i).full; - end if; + read_data(i) <= rcv_buffers_out(i).data; end loop; end process; - end_wr_req: process(out_buff_if) + set_avai_paths: process(snd_buffers_out) begin for i in 0 to TOT_NUM_PATHS-1 loop - if out_buff_if(i).req = '1' then - out_buff_if_nxt(i).req <= '0'; - else - out_buff_if_nxt(i).req <= out_buff_if(i).req; - end if; + avai_paths(i) <= not snd_buffers_out(i).full; + end loop; + end process; + + set_snd_buffers_in: process(wr_reqs, data_to_send) + begin + for i in 0 to TOT_NUM_PATHS-1 loop + snd_buffers_in(i).wr_req <= wr_reqs(i); + snd_buffers_in(i).data <= data_to_send(i); end loop; end process; switching: process(arstN, clk) begin if arstN = '0' then - rd_data <= (others => (others => '0')); - rd_data_valid <= (others => '0'); - chip_r_x <= std_logic_vector(to_unsigned( - val_chip_r_x, chip_r_x'length)); - chip_r_y <= std_logic_vector(to_unsigned( - val_chip_r_y, chip_r_y'length)); - core_r_x <= std_logic_vector(to_unsigned( - val_core_r_x, core_r_x'length)); - core_r_y <= std_logic_vector(to_unsigned( - val_core_r_y, core_r_y'length)); - elsif rising_edge(clk) then - rd_data <= rd_data_nxt; - out_buff_if <= out_buff_if_nxt; - routing(level, rd_data, rd_data_valid, chip_r_x, chip_r_y, core_r_x, - core_r_y, avai_paths, num_paths_up, num_paths_down, out_buff_if_nxt); + rout_pos.chip_x <= chip_x; + rout_pos.chip_y <= chip_y; + rout_pos.core_x <= core_x; + rout_pos.core_y <= core_y; + --elsif rising_edge(clk) then + -- snd_buffers_in <= snd_buffers_in_nxt; end if; end process; end impl; \ No newline at end of file diff --git a/router_components.vhdl b/router_components.vhdl index 6160939..ae06acb 100644 --- a/router_components.vhdl +++ b/router_components.vhdl @@ -1,6 +1,7 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; +use work.router_types.all; package router_components is component fifo is @@ -16,17 +17,18 @@ package router_components is ); end component fifo; - component input_buffer is - generic ( - WIDTH: integer; - DEPTH: integer + component arbiter is + generic( + level : integer := 1; + num_paths_up : integer := 1; + num_paths_down : integer := 1 ); - port( - arstN, clk, wr_req : in std_logic; - data_valid : inout std_logic; - full : out std_logic; - data_in : in std_logic_vector(WIDTH-1 downto 0); - data_out : out std_logic_vector(WIDTH-1 downto 0) + port ( + rout_pos : in t_pos_addr; + packets : in t_DATA(num_paths_up+num_paths_down*4-1 downto 0); + avai_paths : in std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0); + data_out : out t_DATA(num_paths_up+num_paths_down*4-1 downto 0); + wr_req : out std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0) ); - end component input_buffer; + end component arbiter; end package; \ No newline at end of file diff --git a/router_types.vhdl b/router_types.vhdl index 60c36d2..fe579da 100644 --- a/router_types.vhdl +++ b/router_types.vhdl @@ -11,37 +11,35 @@ package router_types is constant CHIP_ADDR_SIZE : integer := 5; -- * subtype WORD is std_logic_vector(63 downto 0); - type t_PATHS is array (integer range <>) of + type t_PATHS is array (integer range <>) of std_logic_vector(NUM_DIRS-1 downto 0); - type t_AVAI_POS is array (integer range <>) of - std_logic_vector(AV_POS_SIZE-1 downto 0); - type t_AVAI_POS_SIZ is array (NUM_DIRS-1 downto 0) of integer; + type t_AVAI_POS is array(integer range <>) of integer; + type t_AVAI_POS_SIZES is array(NUM_DIRS-1 downto 0) of integer; type t_fifo_in is record - data_in : WORD; - req : std_logic; - full : std_logic; + data : WORD; + wr_req : std_logic; + rd_req : std_logic; end record; type t_fifo_out is record - data_out : WORD; - req : std_logic; + data : WORD; empty : std_logic; + full : std_logic; end record; - type t_dest_addr is record - chip_d_x : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - chip_d_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - core_d_x : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); - core_d_y : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); - copy_d_x : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); - copy_d_y : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); + type t_pos_addr is record + chip_x : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); + chip_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); + core_x : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); + core_y : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); + copy_x : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); + copy_y : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); end record; type t_PORT_IN is array (integer range <>) of t_fifo_in; type t_PORT_OUT is array (integer range <>) of t_fifo_out; type t_DATA is array (integer range <>) of WORD; - type t_DATA_VAL is array (integer range <>) of std_logic; type t_DATA_DIRS is array (integer range <>) of std_logic_vector(NUM_DIRS-1 downto 0); end package; diff --git a/routing_functions.vhdl b/routing_functions.vhdl index ead80cd..98647f4 100644 --- a/routing_functions.vhdl +++ b/routing_functions.vhdl @@ -6,49 +6,11 @@ use work.router_types.all; package routing_functions is function single_packet_rout_dir_det ( - level : in positive; - dest : in t_dest_addr; - chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - core_r_x : in std_logic_vector; - core_r_y : in std_logic_vector + level : in positive; + pack_dest : in t_pos_addr; + rout_pos : in t_pos_addr ) return std_logic_vector; - procedure rout_dir_determination ( - level : in positive; - read_data : in t_DATA; - read_data_valid : in t_DATA_VAL; - chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - core_r_x : in std_logic_vector; - core_r_y : in std_logic_vector; - rout_dirs : out t_DATA_DIRS - ); - - procedure rout_path_determination ( - read_data : in t_DATA; -- stored in buffers - read_data_valid : in t_DATA_VAL; - rout_dirs : inout t_DATA_DIRS; -- got from routing function - paths : in t_PATHS; - num_paths_up : in positive; - num_paths_down : in positive; - avai_pos : out t_AVAI_POS - ); - - procedure routing ( - level : in positive; - read_data : in t_DATA; - read_data_valid : in t_DATA_VAL; - chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - core_r_x : in std_logic_vector; - core_r_y : in std_logic_vector; - paths : in t_PATHS; - num_paths_up : in positive; - num_paths_down : in positive; - signal out_buff_if : out t_PORT_IN - ); - function retrieve_avai_path_index ( dir : in positive; path_index : in integer; @@ -56,205 +18,55 @@ package routing_functions is num_paths_down : in positive; avai_pos : in t_AVAI_POS ) return integer; - - procedure set_out_buffer ( - num_paths_up, num_paths_down : in integer; - rd_data : in t_DATA; - rd_data_valid : in t_DATA_VAL; - rout_dirs : in t_DATA_DIRS; - avai_pos : in t_AVAI_POS; - signal out_buff_if : out t_PORT_IN - ); end package; package body routing_functions is function single_packet_rout_dir_det ( - level : in positive; - dest : in t_dest_addr; - chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - core_r_x : in std_logic_vector; - core_r_y : in std_logic_vector + level : in positive; + pack_dest : in t_pos_addr; + rout_pos : in t_pos_addr ) return std_logic_vector is variable dest_x, dest_y, copy_x, copy_y : std_logic; variable is_other_chip, is_cousin_core : boolean; begin - dest_x := dest.core_d_x(level-1); - dest_y := dest.core_d_y(level-1); - copy_x := dest.copy_d_x(level-1); - copy_y := dest.copy_d_y(level-1); - is_other_chip := dest.chip_d_x /= chip_r_x or dest.chip_d_y /= chip_r_y; - is_cousin_core := - dest.core_d_x(DEST_ADDR_SIZE-1 downto level) /= core_r_x or - dest.core_d_y(DEST_ADDR_SIZE-1 downto level) /= core_r_y; - - if is_other_chip or is_cousin_core 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; - - - procedure rout_dir_determination ( - level : in positive; - read_data : in t_DATA; - read_data_valid : in t_DATA_VAL; - chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - core_r_x : in std_logic_vector; - core_r_y : in std_logic_vector; - rout_dirs : out t_DATA_DIRS - ) is - variable dest : t_dest_addr; - begin - for i in 0 to read_data'length-1 loop - if read_data_valid(i) = '1' then - dest.chip_d_x := read_data(i)(59 downto 55); - dest.chip_d_y := read_data(i)(54 downto 50); - dest.core_d_x := read_data(i)(49 downto 45); - dest.core_d_y := read_data(i)(44 downto 40); - dest.copy_d_x := read_data(i)(39 downto 35); - dest.copy_d_y := read_data(i)(34 downto 30); - rout_dirs(i) := single_packet_rout_dir_det ( - level, dest, chip_r_x, chip_r_y, core_r_x, core_r_y); - else - rout_dirs(i) := (others => '0'); - end if; - end loop; - end procedure; - - - procedure rout_path_determination ( - read_data : in t_DATA;--(tot_num_paths); -- stored in buffers - read_data_valid : in t_DATA_VAL; - rout_dirs : inout t_DATA_DIRS;--(tot_num_paths); -- got from routing function - paths : in t_PATHS; - num_paths_up : in positive; - num_paths_down : in positive; - avai_pos : out t_AVAI_POS - ) is - variable sum_dirs : integer; - variable num_paths : positive; - variable n_j : integer; - variable avai_path : std_logic_vector(NUM_DIRS-1 downto 0); - variable avai_pos_sizes : t_AVAI_POS_SIZ; - begin - num_paths := num_paths_up + num_paths_down*4; - avai_pos_sizes := (others => 0); - for i in 0 to num_paths loop - avai_path := paths(i); - if i < num_paths_up then - if avai_path(0) = '1' then - avai_pos(avai_pos_sizes(0)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(0) := avai_pos_sizes(0) + 1; - end if; - elsif i < num_paths_up + num_paths_down then - if avai_path(1) = '1' then - avai_pos(avai_pos_sizes(1)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(1) := avai_pos_sizes(1) + 1; - end if; - elsif i < num_paths_up + num_paths_down*2 then - if avai_path(2) = '1' then - avai_pos(avai_pos_sizes(2)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(2) := avai_pos_sizes(2) + 1; - end if; - elsif i < num_paths_up + num_paths_down*3 then - if avai_path(3) = '1' then - avai_pos(avai_pos_sizes(3)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(3) := avai_pos_sizes(3) + 1; - end if; - else - if avai_path(4) = '1' then - avai_pos(avai_pos_sizes(4)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(4) := avai_pos_sizes(4) + 1; - end if; - end if; - end loop; - - for i in 0 to read_data'length-1 loop - if read_data_valid(i) = '1' then - sum_dirs := 0; - for j in 0 to NUM_DIRS loop - sum_dirs := sum_dirs + to_integer(unsigned(rout_dirs(j))); - end loop; - -- unicast - if sum_dirs = 1 then - if rout_dirs(i)(0) = '1' then - n_j := avai_pos_sizes(0); - avai_pos_sizes(0) := avai_pos_sizes(0)-1; - elsif rout_dirs(i)(1) = '1' then - n_j := avai_pos_sizes(1); - avai_pos_sizes(1) := avai_pos_sizes(1)-1; - elsif rout_dirs(i)(2) = '1' then - n_j := avai_pos_sizes(2); - avai_pos_sizes(2) := avai_pos_sizes(2)-1; - elsif rout_dirs(i)(3) = '1' then - n_j := avai_pos_sizes(3); - avai_pos_sizes(3) := avai_pos_sizes(3)-1; - elsif rout_dirs(i)(4) = '1' then - n_j := avai_pos_sizes(4); - avai_pos_sizes(4) := avai_pos_sizes(4)-1; - end if; - if n_j <= 0 then - rout_dirs(i) := (others => '0'); - end if; - -- 1 to 2 multicast - elsif sum_dirs = 2 then - if rout_dirs(i)(2) = '1' and rout_dirs(i)(4) = '1' then - if avai_pos_sizes(2) <= 0 or avai_pos_sizes(4) <= 0 then - rout_dirs(i) := (others => '0'); - end if; - elsif rout_dirs(i)(1) = '1' and rout_dirs(i)(3) = '1' then - if avai_pos_sizes(1) <= 0 or avai_pos_sizes(3) <= 0 then - rout_dirs(i) := (others => '0'); - end if; - elsif rout_dirs(i)(3) = '1' and rout_dirs(i)(4) = '1' then - if avai_pos_sizes(3) <= 0 or avai_pos_sizes(4) <= 0 then - rout_dirs(i) := (others => '0'); - end if; - elsif rout_dirs(i)(1) = '1' and rout_dirs(i)(2) = '1' then - if avai_pos_sizes(1) <= 0 or avai_pos_sizes(2) <= 0 then - rout_dirs(i) := (others => '0'); - end if; - end if; - -- 1 to 4 multicast + dest_x := pack_dest.core_x(level-1); + dest_y := pack_dest.core_y(level-1); + copy_x := pack_dest.copy_x(level-1); + copy_y := pack_dest.copy_y(level-1); + is_other_chip := pack_dest.chip_x /= rout_pos.chip_x or + pack_dest.chip_y /= rout_pos.chip_y; + is_cousin_core := + pack_dest.core_x(DEST_ADDR_SIZE-1 downto level) /= rout_pos.core_x or + pack_dest.core_y(DEST_ADDR_SIZE-1 downto level) /= rout_pos.core_y; + + if is_other_chip or is_cousin_core 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 - if avai_pos_sizes(1) <= 0 or avai_pos_sizes(2) <= 0 or - avai_pos_sizes(3) <= 0 or avai_pos_sizes(4) <= 0 then - rout_dirs(i) := (others => '0'); - end if; + 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 loop; - end procedure; + end function; function retrieve_avai_path_index ( dir : in positive; @@ -265,164 +77,20 @@ package body routing_functions is ) return integer is variable avai_pos_index : integer; begin - procedure rout_path_determination ( - read_data : in t_DATA;--(tot_num_paths); -- stored in buffers - read_data_valid : in t_DATA_VAL; - rout_dirs : inout t_DATA_DIRS;--(tot_num_paths); -- got from routing function - paths : in t_PATHS; - num_paths_up : in positive; - num_paths_down : in positive; - avai_pos : out t_AVAI_POS - ) is - variable sum_dirs : integer; - variable num_paths : positive; - variable n_j : integer; - variable avai_path : std_logic_vector(NUM_DIRS-1 downto 0); - variable avai_pos_sizes : t_AVAI_POS_SIZ; - begin - num_paths := num_paths_up + num_paths_down*4; - avai_pos_sizes := (others => 0); - for i in 0 to num_paths loop - avai_path := paths(i); - if i < num_paths_up then - if avai_path(0) = '1' then - avai_pos(avai_pos_sizes(0)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(0) := avai_pos_sizes(0) + 1; - end if; - elsif i < num_paths_up + num_paths_down then - if avai_path(1) = '1' then - avai_pos(avai_pos_sizes(1)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(1) := avai_pos_sizes(1) + 1; - end if; - elsif i < num_paths_up + num_paths_down*2 then - if avai_path(2) = '1' then - avai_pos(avai_pos_sizes(2)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(2) := avai_pos_sizes(2) + 1; - end if; - elsif i < num_paths_up + num_paths_down*3 then - if avai_path(3) = '1' then - avai_pos(avai_pos_sizes(3)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(3) := avai_pos_sizes(3) + 1; - end if; - else - if avai_path(4) = '1' then - avai_pos(avai_pos_sizes(4)) := - std_logic_vector(to_unsigned(i,AV_POS_SIZE)); - avai_pos_sizes(4) := avai_pos_sizes(4) + 1; - end if; - end if; - end loop; - - for i in 0 to read_data'length-1 loop - if read_data_valid(i) = '1' then - sum_dirs := 0; - for j in 0 to NUM_DIRS loop - sum_dirs := sum_dirs + to_integer(unsigned(rout_dirs(j))); - end loop; - -- unicast - if sum_dirs = 1 then - if rout_dirs(i)(0) = '1' then - n_j := avai_pos_sizes(0); - avai_pos_sizes(0) := avai_pos_sizes(0)-1; - elsif rout_dirs(i)(1) = '1' then - n_j := avai_pos_sizes(1); - avai_pos_sizes(1) := avai_pos_sizes(1)-1; - elsif rout_dirs(i)(2) = '1' then - n_j := avai_pos_sizes(2); - avai_pos_sizes(2) := avai_pos_sizes(2)-1; - elsif rout_dirs(i)(3) = '1' then - n_j := avai_pos_sizes(3); - avai_pos_sizes(3) := avai_pos_sizes(3)-1; - elsif rout_dirs(i)(4) = '1' then - n_j := avai_pos_sizes(4); - avai_pos_sizes(4) := avai_pos_sizes(4)-1; - end if; - if n_j <= 0 then - rout_dirs(i) := (others => '0'); - end if; - -- 1 to 2 multicast - elsif sum_dirs = 2 then - if rout_dirs(i)(2) = '1' and rout_dirs(i)(4) = '1' then - if avai_pos_sizes(2) <= 0 or avai_pos_sizes(4) <= 0 then - rout_dirs(i) := (others => '0'); - end if; - elsif rout_dirs(i)(1) = '1' and rout_dirs(i)(3) = '1' then - if avai_pos_sizes(1) <= 0 or avai_pos_sizes(3) <= 0 then - rout_dirs(i) := (others => '0'); - end if; - elsif rout_dirs(i)(3) = if dir = 0 then - return to_integer(unsigned(avai_pos(path_index))); + return avai_pos(path_index); elsif dir = 1 then avai_pos_index := path_index+num_paths_up; - return to_integer(unsigned(avai_pos(avai_pos_index))); + return avai_pos(avai_pos_index); elsif dir = 2 then avai_pos_index := path_index+num_paths_up+num_paths_down; - return to_integer(unsigned(avai_pos(avai_pos_index))); + return avai_pos(avai_pos_index); elsif dir = 3 then avai_pos_index := path_index+num_paths_up+num_paths_down*2; - return to_integer(unsigned(avai_pos(avai_pos_index))); + return avai_pos(avai_pos_index); else avai_pos_index := path_index+num_paths_up+num_paths_down*3; - return to_integer(unsigned(avai_pos(avai_pos_index))); + return avai_pos(avai_pos_index); end if; end retrieve_avai_path_index; - - procedure set_out_buffer ( - num_paths_up, num_paths_down : in integer; - rd_data : in t_DATA; - rd_data_valid : in t_DATA_VAL; - rout_dirs : in t_DATA_DIRS; - avai_pos : in t_AVAI_POS; - signal out_buff_if : out t_PORT_IN - ) - is - variable path_index, out_index, tot_num_paths : integer; - begin - tot_num_paths := num_paths_up+num_paths_down*4; - for i in 0 to tot_num_paths-1 loop - out_buff_if(i).data_in <= (others => '0'); - out_buff_if(i).req <= '0'; - end loop; - for j in 0 to NUM_DIRS loop - path_index := 0; - for i in 0 to tot_num_paths-1 loop - if rd_data_valid(i)='1' and rout_dirs(i)(j)='1' then - out_index := retrieve_avai_path_index(j, path_index, - num_paths_up, num_paths_down, avai_pos); - path_index := path_index + 1; - out_buff_if(out_index).data_in <= rd_data(i); - out_buff_if(i).req <= '1'; - end if; - end loop; - end loop; - end set_out_buffer; - - procedure routing ( - level : in positive; - read_data : in t_DATA; - read_data_valid : in t_DATA_VAL; - chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); - core_r_x : in std_logic_vector; - core_r_y : in std_logic_vector; - paths : in t_PATHS; - num_paths_up : in positive; - num_paths_down : in positive; - signal out_buff_if : out t_PORT_IN - ) is - variable rout_dirs : t_DATA_DIRS(num_paths_up+num_paths_down*4 downto 0); - variable avai_pos : t_AVAI_POS(num_paths_up+num_paths_down*4 downto 0); - begin - rout_dir_determination(level, read_data, read_data_valid, chip_r_x, - chip_r_y, core_r_x, core_r_y, rout_dirs); - rout_path_determination(read_data, read_data_valid, rout_dirs, paths, - num_paths_up, num_paths_down, avai_pos); - set_out_buffer(num_paths_up, num_paths_down, read_data, read_data_valid, - rout_dirs, avai_pos, out_buff_if); - end routing; end package body; \ No newline at end of file diff --git a/test/fifo_tb.vhdl b/test/fifo_tb.vhdl index a91865f..0b532cf 100755 --- a/test/fifo_tb.vhdl +++ b/test/fifo_tb.vhdl @@ -66,8 +66,8 @@ begin for counter in 0 to 10 loop rd_req <= '1'; wait for clk_period; - rd_req <= '0'; - wait for clk_period; + --rd_req <= '0'; + --wait for clk_period; end loop; wait; end process; diff --git a/router_tb.vhdl b/test/router_tb.vhdl similarity index 100% rename from router_tb.vhdl rename to test/router_tb.vhdl