diff --git a/router/parent_arbiter.vhdl b/router/parent_arbiter.vhdl index 2a7e3b8..0fb1ff5 100644 --- a/router/parent_arbiter.vhdl +++ b/router/parent_arbiter.vhdl @@ -42,7 +42,7 @@ begin pack_dest.copy_x := packets(i)(39 downto 35); pack_dest.copy_y := packets(i)(34 downto 30); dirs(i) <= single_packet_parent_rout_dir_det(level, - pack_dest, rout_pos); + pack_dest, rout_pos); else dirs(i) <= (others => '0'); end if; @@ -84,19 +84,37 @@ begin avai_pos_nxt(avai_index) <= i; avai_pos_sizes(3) := avai_pos_sizes(3) + 1; end if; - else + 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_nxt(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_nxt(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_nxt(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_nxt(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) for i in 0 to TOT_NUM_PATHS-1 loop sum_dirs := 0; - for j in 0 to NUM_DIRS-1 loop + for j in 0 to NUM_DIRS_PARENT-1 loop sum_dirs := sum_dirs + to_integer(unsigned'('0' & dirs(i)(j))); end loop; -- unicast @@ -109,8 +127,14 @@ begin j := 2; elsif dirs(i)(3) = '1' then j := 3; - else + 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'); @@ -170,7 +194,7 @@ begin buff_wr_in(i).wr_req <= '0'; arb_complete(i) <= '0'; end loop; - for j in 0 to NUM_DIRS-1 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 diff --git a/router/router_types.vhdl b/router/router_types.vhdl index c26a453..be6ad9d 100644 --- a/router/router_types.vhdl +++ b/router/router_types.vhdl @@ -25,7 +25,7 @@ package router_types is integer range 0 to MAX_PATHS_SIZE; type t_EX_AVAI_POS is array(integer range <>) of integer range 0 to MAX_EX_PATHS_SIZE; - type t_EX_AVAI_POS_SIZES is array(NUM_DIRS-1 downto 0) of + 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_fifo_wr_in is record diff --git a/router/routing_functions.vhdl b/router/routing_functions.vhdl index a4f1b46..acaf707 100644 --- a/router/routing_functions.vhdl +++ b/router/routing_functions.vhdl @@ -41,8 +41,14 @@ package body routing_functions is pack_dest : in t_pos_addr; rout_pos : in t_pos_addr ) return std_logic_vector is - variable chip_d_x, chip_d_y, chip_r_x, chip_r_y : std_logic; + variable chip_d_x, chip_d_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); + variable chip_r_x, chip_r_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); begin + chip_r_x := rout_pos.chip_x; + chip_r_y := rout_pos.chip_y; + chip_d_x := pack_dest.chip_x; + chip_d_y := pack_dest.chip_y; + if chip_d_y < chip_r_y then return "10000000"; -- north elsif chip_d_y > chip_r_y then @@ -66,7 +72,7 @@ package body routing_functions is variable dest_x, dest_y, copy_x, copy_y : std_logic; variable is_other_chip : boolean; variable is_cousin_core : boolean; - variable needs_multicast : boolean; + variable needs_multicast : boolean; begin dest_x := pack_dest.core_x(level-1); dest_y := pack_dest.core_y(level-1); @@ -166,9 +172,18 @@ package body routing_functions is elsif dir = 3 then avai_pos_index := path_index+num_paths_down*3; return avai_pos(avai_pos_index); - else + elsif dir = 4 then avai_pos_index := path_index+num_paths_down*4; return avai_pos(avai_pos_index); + elsif dir = 5 then + avai_pos_index := path_index+num_paths_down*4+num_paths_up; + return avai_pos(avai_pos_index); + elsif dir = 6 then + avai_pos_index := path_index+num_paths_down*4+num_paths_up*2; + return avai_pos(avai_pos_index); + else + avai_pos_index := path_index+num_paths_down*4+num_paths_up*3; + return avai_pos(avai_pos_index); end if; end retrieve_ex_avai_path_index; end package body; \ No newline at end of file diff --git a/test/input/noc_tests/pe_to_chip_test/result.ref b/test/input/noc_tests/pe_to_chip_test/result.ref new file mode 100644 index 0000000..72f3966 --- /dev/null +++ b/test/input/noc_tests/pe_to_chip_test/result.ref @@ -0,0 +1 @@ +1 64 0001000001000010001000010000000000000000000000000000000000000100 \ No newline at end of file diff --git a/test/input/noc_tests/pe_to_chip_test/stimuli.txt b/test/input/noc_tests/pe_to_chip_test/stimuli.txt new file mode 100644 index 0000000..f1527e2 --- /dev/null +++ b/test/input/noc_tests/pe_to_chip_test/stimuli.txt @@ -0,0 +1,2 @@ +# is external? | path | data +0 0 0001000001000010001000010000000000000000000000000000000000000100 # south diff --git a/test/input/noc_tests/simple_interchip_test/result.ref b/test/input/noc_tests/simple_interchip_test/result.ref new file mode 100644 index 0000000..848816a --- /dev/null +++ b/test/input/noc_tests/simple_interchip_test/result.ref @@ -0,0 +1 @@ +0 1023 0001000000000000000000000000000000000000000000000000000000000111 \ No newline at end of file diff --git a/test/input/noc_tests/simple_interchip_test/stimuli.txt b/test/input/noc_tests/simple_interchip_test/stimuli.txt new file mode 100644 index 0000000..cf44e80 --- /dev/null +++ b/test/input/noc_tests/simple_interchip_test/stimuli.txt @@ -0,0 +1,2 @@ +# is external? | path | data +1 7 0001000000000000000000000000000000000000000000000000000000000111 diff --git a/test/noc_tb.vhdl b/test/noc_tb.vhdl index 06fd68f..e3b1b3c 100644 --- a/test/noc_tb.vhdl +++ b/test/noc_tb.vhdl @@ -2,6 +2,9 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use std.textio.all; + use work.router_types.all; entity noc_tb is @@ -33,6 +36,70 @@ architecture bench of noc_tb is signal pe_data_out : t_DATA(4**level-1 downto 0); signal pe_rcv_acks : std_logic_vector(4**level-1 downto 0); signal pe_send_reqs : std_logic_vector(4**level-1 downto 0); + + signal c_send_reqs_prev : std_logic_vector(4*num_paths_ext-1 downto 0); + signal pe_send_reqs_prev : std_logic_vector(4**level-1 downto 0); + + file conf_file : text open read_mode is "config.txt"; + file stimuli_file : text open read_mode is "stimuli.txt"; + file reference_file : text open read_mode is "result.ref"; + file log_file : text open write_mode is "simulation.log"; + + procedure log_test_result ( + index : integer; + sollwert, istwert : WORD; + is_external, soll_is_external : boolean; + sollpath, istpath : integer + ) is + variable rowOut : LINE; + begin + write(rowOut, index); + if is_external then + write(rowOut, string'(" = loop (path/fifo - external)")); + else + write(rowOut, string'(" = loop (path/fifo - PE)")); + end if; + WRITELINE(log_file, rowOut); + + write(rowOut, string'("-->")); + write(rowOut, sollwert); + write(rowOut, string'(" = sollwert")); + WRITELINE(log_file, rowOut); + write(rowOut, string'("-->")); + write(rowOut, istwert); + write(rowOut, string'(" = istwert")); + WRITELINE(log_file, rowOut); + + write(rowOut, string'("-->")); + write(rowOut, soll_is_external); + write(rowOut, string'(" = soll is_external")); + WRITELINE(log_file, rowOut); + write(rowOut, string'("-->")); + write(rowOut, is_external); + write(rowOut, string'(" = ist is_external")); + WRITELINE(log_file, rowOut); + + write(rowOut, string'("-->")); + write(rowOut, sollpath); + write(rowOut, string'(" = sollpath")); + WRITELINE(log_file, rowOut); + write(rowOut, string'("-->")); + write(rowOut, istpath); + write(rowOut, string'(" = istpath")); + WRITELINE(log_file, rowOut); + + if istwert = sollwert and is_external = soll_is_external then + write(rowOut, string'("-------------------------->pass")); + WRITELINE(log_file, rowOut); + write(rowOut, string'("******************************")); + WRITELINE(log_file, rowOut); + else + write(rowOut, string'("-------------------------->fail")); + WRITELINE(log_file, rowOut); + write(rowOut, string'("******************************")); + WRITELINE(log_file, rowOut); + end if; + end procedure; begin noc_inst : entity work.noc @@ -70,7 +137,12 @@ begin wait for clk_period/2; end process; - test: process + gen_stimuli: process + variable input_line, rowOut : line; + variable valid_data : boolean; + variable is_external : std_logic_vector(0 downto 0); + variable path : integer; + variable data : std_logic_vector(63 downto 0); begin arstN <= '0'; data_chip_in <= (others => (others => '0')); @@ -82,8 +154,125 @@ begin wait until rising_edge(clk); arstN <= '1'; wait until rising_edge(clk); - data_chip_in(0) <= "0001000000000000000000000000000000000000000000000000000000000111"; - c_rcv_reqs(0) <= '1'; + while not(endfile(stimuli_file)) loop + readline(stimuli_file, input_line); + if input_line.all'length = 0 then + wait until rising_edge(clk); + next; + elsif input_line.all(1) = '#' then + next; + end if; + + read(input_line, is_external, valid_data); + assert valid_data + report "Invalid data in file (is_external)" severity error; + + read(input_line, path, valid_data); + assert valid_data + report "Invalid data in file (path)" severity error; + + read(input_line, data, valid_data); + assert valid_data + report "Invalid data in file (data)" severity error; + + if is_external = "1" then + assert path < num_paths_ext-1 + report "Invalid path index value in file (external)" severity error; + data_chip_in(path) <= data; + c_rcv_reqs(path) <= not c_rcv_reqs(path); + else + assert path < 4**level-1 + report "Invalid path index value in file (ds)" severity error; + pe_data_in(path) <= data; + pe_rcv_reqs(path) <= not pe_rcv_reqs(path); + end if; + exit when endfile(stimuli_file); + end loop; wait; end process; + + validate_results: process(c_send_reqs, pe_send_reqs, + c_send_reqs_prev, pe_send_reqs_prev, + data_chip_out, pe_data_out) + variable input_line : line; + variable valid_data : boolean; + variable istwert, sollwert : WORD; + variable is_external : std_logic_vector(0 downto 0); + variable ist_is_external : boolean; + variable istpath, sollpath : integer; + begin + if c_send_reqs'event or c_send_reqs_prev'event then + for i in 0 to num_paths_ext*4-1 loop + if (c_send_reqs(i) = '0' and c_send_reqs_prev(i) = '1') or + (c_send_reqs(i) = '1' and c_send_reqs_prev(i) = '0') then + istwert := data_chip_out(i); + istpath := i; + readline(reference_file, input_line); + + read(input_line, is_external, valid_data); + assert valid_data report "Invalid data in file (is external)" + severity error; + + ist_is_external := is_external(0) = '1'; + assert ist_is_external report "Invalid result (is external)" + severity warning; + + read(input_line, sollpath, valid_data); + assert valid_data report "Invalid data in file (path)" + severity error; + assert istpath = sollpath report "Invalid result (path)" + severity warning; + + read(input_line, sollwert, valid_data); + assert valid_data report "Invalid data in file (data)" + severity error; + assert istwert = sollwert report "Invalid result (data)" + severity warning; + + log_test_result(i, istwert, sollwert, TRUE, ist_is_external, + sollpath, istpath); + end if; + end loop; + elsif pe_send_reqs'event or pe_send_reqs_prev'event then + for i in 0 to 4**level-1 loop + if (pe_send_reqs(i) = '0' and pe_send_reqs_prev(i) = '1') or + (pe_send_reqs(i) = '1' and pe_send_reqs_prev(i) = '0') then + istwert := pe_data_out(i); + istpath := i; + readline(reference_file, input_line); + + read(input_line, is_external, valid_data); + assert valid_data report "Invalid data in file (is external)" + severity error; + + ist_is_external := is_external(0) = '1'; + assert not ist_is_external report "Invalid result (is external)" + severity warning; + + read(input_line, sollpath, valid_data); + assert valid_data report "Invalid data in file (path)" + severity error; + assert istpath = sollpath report "Invalid result (path)" + severity warning; + + read(input_line, sollwert, valid_data); + assert valid_data report "Invalid data in file (data)" + severity error; + assert istwert = sollwert report "Invalid result (data)" + severity warning; + + log_test_result(i, istwert, sollwert, FALSE, ist_is_external, + sollpath, istpath); + end if; + end loop; + end if; + end process; + + update_signals: process(clk) + begin + if rising_edge(clk) then + c_send_reqs_prev <= c_send_reqs; + pe_send_reqs_prev <= pe_send_reqs; + end if; + end process; end; \ No newline at end of file