From c92fb604c97c607199e7bb0ae26d98d0970b6929 Mon Sep 17 00:00:00 2001 From: Retrocamara42 Date: Sun, 8 Jun 2025 09:37:06 -0500 Subject: [PATCH 1/2] feat: generating stimuli with a file --- .../simple_interchip_test/result.ref | 1 + .../simple_interchip_test/stimuli.txt | 2 + test/noc_tb.vhdl | 64 ++++++++++++++++++- 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 test/input/noc_tests/simple_interchip_test/result.ref create mode 100644 test/input/noc_tests/simple_interchip_test/stimuli.txt 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..8a690f9 --- /dev/null +++ b/test/input/noc_tests/simple_interchip_test/result.ref @@ -0,0 +1 @@ +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..07afe51 --- /dev/null +++ b/test/input/noc_tests/simple_interchip_test/stimuli.txt @@ -0,0 +1,2 @@ +# external? | path | req | data +1 7 1 0001000000000000000000000000000000000000000000000000000000000111 diff --git a/test/noc_tb.vhdl b/test/noc_tb.vhdl index 06fd68f..d2df89f 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,11 @@ 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); + + 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"; begin noc_inst : entity work.noc @@ -70,7 +78,14 @@ 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 : boolean; + variable path : unsigned(7 downto 0); + variable ind_path : integer; + variable req : std_logic_vector(0 downto 0); + variable data : std_logic_vector(64 downto 0); begin arstN <= '0'; data_chip_in <= (others => (others => '0')); @@ -82,8 +97,51 @@ 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(1) = '#' then + next; + end if; + + read(input_line, is_external, valid_data); + assert valid_data + report "Invalid data in file (is_external)" severity error; + + hread(input_line, path, valid_data); + assert valid_data + report "Invalid data in file (path)" severity error; + ind_path := to_integer(path); + + hread(input_line, req, valid_data); + assert valid_data + report "Invalid data in file (req)" severity error; + + hread(input_line, data, valid_data); + assert valid_data + report "Invalid data in file (data)" severity error; + + if is_external then + assert ind_path < num_paths_ext + report "Invalid path index value in file (external)" severity error; + data_chip_in(ind_path) <= data; + c_rcv_reqs(ind_path) <= req(0); + else + assert ind_path < num_paths_ext/2 -- downstream + report "Invalid path index value in file (ds)" severity error; + pe_data_in(ind_path) <= data; + pe_rcv_reqs(ind_path) <= req(0); + end if; + + if input_line.all'length = 0 then + wait until rising_edge(clk); + end if; + exit when endfile(stimuli_file); + end loop; wait; end process; + + validate_results: process + begin + + end process; end; \ No newline at end of file From bc015007bcaea3a34e305d9744710997fc67a25f Mon Sep 17 00:00:00 2001 From: Retrocamara42 Date: Mon, 9 Jun 2025 11:36:12 -0500 Subject: [PATCH 2/2] fix: testbench now works well, tests for interchip and pe to ext tranmissions --- router/parent_arbiter.vhdl | 34 +++- router/router_types.vhdl | 2 +- router/routing_functions.vhdl | 21 +- .../noc_tests/pe_to_chip_test/result.ref | 1 + .../noc_tests/pe_to_chip_test/stimuli.txt | 2 + .../simple_interchip_test/result.ref | 2 +- .../simple_interchip_test/stimuli.txt | 4 +- test/noc_tb.vhdl | 183 +++++++++++++++--- 8 files changed, 211 insertions(+), 38 deletions(-) create mode 100644 test/input/noc_tests/pe_to_chip_test/result.ref create mode 100644 test/input/noc_tests/pe_to_chip_test/stimuli.txt 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 index 8a690f9..848816a 100644 --- a/test/input/noc_tests/simple_interchip_test/result.ref +++ b/test/input/noc_tests/simple_interchip_test/result.ref @@ -1 +1 @@ -0001000000000000000000000000000000000000000000000000000000000111 \ No newline at end of file +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 index 07afe51..cf44e80 100644 --- a/test/input/noc_tests/simple_interchip_test/stimuli.txt +++ b/test/input/noc_tests/simple_interchip_test/stimuli.txt @@ -1,2 +1,2 @@ -# external? | path | req | data -1 7 1 0001000000000000000000000000000000000000000000000000000000000111 +# is external? | path | data +1 7 0001000000000000000000000000000000000000000000000000000000000111 diff --git a/test/noc_tb.vhdl b/test/noc_tb.vhdl index d2df89f..e3b1b3c 100644 --- a/test/noc_tb.vhdl +++ b/test/noc_tb.vhdl @@ -36,11 +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 @@ -81,11 +140,9 @@ begin gen_stimuli: process variable input_line, rowOut : line; variable valid_data : boolean; - variable is_external : boolean; - variable path : unsigned(7 downto 0); - variable ind_path : integer; - variable req : std_logic_vector(0 downto 0); - variable data : std_logic_vector(64 downto 0); + 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')); @@ -99,7 +156,10 @@ begin wait until rising_edge(clk); while not(endfile(stimuli_file)) loop readline(stimuli_file, input_line); - if input_line.all(1) = '#' then + if input_line.all'length = 0 then + wait until rising_edge(clk); + next; + elsif input_line.all(1) = '#' then next; end if; @@ -107,41 +167,112 @@ begin assert valid_data report "Invalid data in file (is_external)" severity error; - hread(input_line, path, valid_data); + read(input_line, path, valid_data); assert valid_data report "Invalid data in file (path)" severity error; - ind_path := to_integer(path); - hread(input_line, req, valid_data); - assert valid_data - report "Invalid data in file (req)" severity error; - - hread(input_line, data, valid_data); + read(input_line, data, valid_data); assert valid_data report "Invalid data in file (data)" severity error; - if is_external then - assert ind_path < num_paths_ext + if is_external = "1" then + assert path < num_paths_ext-1 report "Invalid path index value in file (external)" severity error; - data_chip_in(ind_path) <= data; - c_rcv_reqs(ind_path) <= req(0); + data_chip_in(path) <= data; + c_rcv_reqs(path) <= not c_rcv_reqs(path); else - assert ind_path < num_paths_ext/2 -- downstream + assert path < 4**level-1 report "Invalid path index value in file (ds)" severity error; - pe_data_in(ind_path) <= data; - pe_rcv_reqs(ind_path) <= req(0); - end if; - - if input_line.all'length = 0 then - wait until rising_edge(clk); + 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 + 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