diff --git a/arbiter.vhdl b/arbiter.vhdl deleted file mode 100644 index 8bc0c02..0000000 --- a/arbiter.vhdl +++ /dev/null @@ -1,163 +0,0 @@ -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/fifo.vhdl b/fifo.vhdl index 08dabab..b27bbae 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; - full, empty : out std_logic; + wr_ack, rd_ack, 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,6 +23,7 @@ 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; @@ -38,6 +39,8 @@ 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; @@ -47,8 +50,10 @@ 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; @@ -77,8 +82,10 @@ 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 new file mode 100644 index 0000000..cc71225 --- /dev/null +++ b/input_buffer.vhdl @@ -0,0 +1,56 @@ +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 ( + rstN, clk, wr_req : in std_logic; + data_valid : inout std_logic; + wr_ack, 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( + rstN, clk, wr_req, rd_req, only_peek : in std_logic; + wr_ack, rd_ack, 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; +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); + + 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_ack) + begin + if rd_ack = '1' then + rd_req <= '0'; + data_valid <= '1'; + end if; + end process; +end impl; \ No newline at end of file diff --git a/router.vhdl b/router.vhdl index 8ed1573..1fba55c 100644 --- a/router.vhdl +++ b/router.vhdl @@ -10,96 +10,109 @@ 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; - chip_x : std_logic_vector(4 downto 0); - chip_y : std_logic_vecto_nxtr(4 downto 0) + val_chip_r_x : integer := 0; + val_chip_r_y : integer := 0; + val_core_r_x : integer := 0; + val_core_r_y : integer := 0 ); port ( clk : in std_logic; - arstN : in std_logic; - 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) + 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 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 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); + 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); begin + -- implements all buffers for each path g_IN_BUFF_GEN: for i in 0 to TOT_NUM_PATHS-1 generate - 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); + 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)); 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 => 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); + 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, + 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); end generate; - 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) + set_avai_paths: process(out_buff_if) + variable ds_ind : integer; + variable dir : positive; begin for i in 0 to TOT_NUM_PATHS-1 loop - read_data(i) <= rcv_buffers_out(i).data; + 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; end loop; end process; - set_avai_paths: process(snd_buffers_out) + end_wr_req: process(out_buff_if) begin for i in 0 to TOT_NUM_PATHS-1 loop - avai_paths(i) <= not snd_buffers_out(i).full; + if out_buff_if(i).ack = '1' then + out_buff_if(i).req <= '0'; + end if; end loop; end process; - set_snd_buffers_in: process(wr_reqs, data_to_send) + 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; 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 - 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; + if rstN = '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; + 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); end if; end process; end impl; \ No newline at end of file diff --git a/router_components.vhdl b/router_components.vhdl index ae06acb..43cc013 100644 --- a/router_components.vhdl +++ b/router_components.vhdl @@ -1,7 +1,6 @@ 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 @@ -10,25 +9,24 @@ package router_components is DEPTH: integer ); port( - arstN, clk, wr_req, rd_req : in std_logic; - full, empty : out std_logic; + rstN, clk, wr_req, rd_req, only_peek : in std_logic; + wr_ack, rd_ack, 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; - component arbiter is - generic( - level : integer := 1; - num_paths_up : integer := 1; - num_paths_down : integer := 1 + component input_buffer is + generic ( + WIDTH: integer; + DEPTH: integer ); - 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) + port( + rstN, clk, wr_req : in std_logic; + data_valid : inout std_logic; + wr_ack, 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 component arbiter; + end component input_buffer; end package; \ No newline at end of file diff --git a/router_tb.vhdl b/router_tb.vhdl new file mode 100644 index 0000000..47d513d --- /dev/null +++ b/router_tb.vhdl @@ -0,0 +1,32 @@ +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; + +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 diff --git a/router_types.vhdl b/router_types.vhdl index fe579da..10a3db7 100644 --- a/router_types.vhdl +++ b/router_types.vhdl @@ -11,35 +11,40 @@ 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 integer; - type t_AVAI_POS_SIZES is array(NUM_DIRS-1 downto 0) of integer; + 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_fifo_in is record - data : WORD; - wr_req : std_logic; - rd_req : std_logic; + 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 : WORD; + data_out : WORD; + req : std_logic; + ack : std_logic; empty : std_logic; - full : std_logic; end record; - 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); + 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); 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 98647f4..63c183c 100644 --- a/routing_functions.vhdl +++ b/routing_functions.vhdl @@ -6,11 +6,49 @@ use work.router_types.all; package routing_functions is function single_packet_rout_dir_det ( - level : in positive; - pack_dest : in t_pos_addr; - rout_pos : in t_pos_addr + 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 ) 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; @@ -18,79 +56,283 @@ 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; - pack_dest : in t_pos_addr; - rout_pos : in t_pos_addr + 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 ) 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 := 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 - 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"; + 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 + 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; + end if; + end if; + end loop; + end procedure; + function retrieve_avai_path_index ( 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 if dir = 0 then - return avai_pos(path_index); + return to_integer(unsigned(avai_pos(path_index))); elsif dir = 1 then avai_pos_index := path_index+num_paths_up; - return avai_pos(avai_pos_index); + return to_integer(unsigned(avai_pos(avai_pos_index))); elsif dir = 2 then avai_pos_index := path_index+num_paths_up+num_paths_down; - return avai_pos(avai_pos_index); + return to_integer(unsigned(avai_pos(avai_pos_index))); elsif dir = 3 then avai_pos_index := path_index+num_paths_up+num_paths_down*2; - return avai_pos(avai_pos_index); + return to_integer(unsigned(avai_pos(avai_pos_index))); else avai_pos_index := path_index+num_paths_up+num_paths_down*3; - return avai_pos(avai_pos_index); + return to_integer(unsigned(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 0b532cf..53cc5dd 100755 --- a/test/fifo_tb.vhdl +++ b/test/fifo_tb.vhdl @@ -18,6 +18,8 @@ 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); @@ -35,6 +37,8 @@ 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, @@ -55,19 +59,19 @@ begin wait for CLK_PERIOD; arstN <= '1'; - for value_sent in 10 downto 0 loop + for value_sent in 6 downto 0 loop wr_req <= '1'; data_in <= std_logic_vector(to_unsigned(value_sent, data_in'length)); - wait for clk_period; + wait until wr_ack = '1'; wr_req <= '0'; - wait for clk_period; + wait until wr_ack = '0'; end loop; - for counter in 0 to 10 loop + for counter in 0 to 6 loop rd_req <= '1'; - wait for clk_period; - --rd_req <= '0'; - --wait for clk_period; + wait until rd_ack = '1'; + rd_req <= '0'; + wait until rd_ack = '0'; end loop; wait; end process; diff --git a/test/router_tb.vhdl b/test/router_tb.vhdl deleted file mode 100644 index a67a0ad..0000000 --- a/test/router_tb.vhdl +++ /dev/null @@ -1,78 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.router_types.all; - -entity router_tb is -end; - -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