diff --git a/Readme.md b/Readme.md index 9cce1a9..1cd447d 100644 --- a/Readme.md +++ b/Readme.md @@ -8,6 +8,14 @@ This project implements a five-level up-down quadtree Network-on-Chip (NoC) with - Supports two packet types: normal and payload - Capable of unicast and multicast communication +## Reminder for Router L1 +FIFO0 -> DS4 -> Pos 11 +FIFO1 -> DS3 -> Pos 10 +FIFO2 -> DS2 -> Pos 01 +FIFO3 -> DS1 -> Pos 00 +FIFO4 -> U -> Upstream +FIFO5 -> U -> Upstream + ## Schematics ### FIFO ![alt text](./drawings/fifo.png) @@ -30,4 +38,4 @@ This project implements a five-level up-down quadtree Network-on-Chip (NoC) with ### Router ![alt text](./drawings/router.png) --- TODO: Testing \ No newline at end of file +-- TODO: Testing Multicast X, Unicast other routers, Broadcast \ No newline at end of file diff --git a/arbiter.vhdl b/arbiter.vhdl index f180189..205a287 100644 --- a/arbiter.vhdl +++ b/arbiter.vhdl @@ -31,8 +31,9 @@ architecture impl of arbiter is 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); + variable pack_dest : t_pos_addr; + variable header : std_logic_vector(3 downto 0); + variable is_upstream : boolean; begin for i in 0 to packets'length-1 loop header := packets(i)(63 downto 60); @@ -43,7 +44,8 @@ begin 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); + is_upstream := i >= num_paths_down*4; + dirs(i) <= single_packet_rout_dir_det(level, pack_dest, rout_pos, is_upstream); else dirs(i) <= (others => '0'); end if; diff --git a/routing_functions.vhdl b/routing_functions.vhdl index 516a725..1280563 100644 --- a/routing_functions.vhdl +++ b/routing_functions.vhdl @@ -8,7 +8,8 @@ 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 + rout_pos : in t_pos_addr; + is_upstream : in boolean ) return std_logic_vector; function retrieve_avai_path_index ( @@ -24,10 +25,13 @@ 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 + rout_pos : in t_pos_addr; + is_upstream : in boolean ) return std_logic_vector is variable dest_x, dest_y, copy_x, copy_y : std_logic; - variable is_other_chip, is_cousin_core : boolean; + variable is_other_chip : boolean; + variable is_cousin_core : boolean; + variable needs_multicast : boolean; begin dest_x := pack_dest.core_x(level-1); dest_y := pack_dest.core_y(level-1); @@ -41,8 +45,13 @@ package body routing_functions is rout_pos.core_y(DEST_ADDR_SIZE-1 downto level)); --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 + needs_multicast := FALSE; + for i in level to DEST_ADDR_SIZE-1 loop + needs_multicast := needs_multicast or (pack_dest.copy_x(i) = '1') or + (pack_dest.copy_y(i) = '1'); + end loop; + + if (not is_upstream) and (is_other_chip or is_cousin_core or needs_multicast) then return "10000"; elsif copy_x = '0' and copy_y = '0' then --unicast if dest_x = '0' and dest_y = '0' then diff --git a/test/input/L1_multicastY/result.ref b/test/input/L1_multicastY/result.ref new file mode 100644 index 0000000..e5dd1e7 --- /dev/null +++ b/test/input/L1_multicastY/result.ref @@ -0,0 +1,3 @@ +0001000000000010101101011001010001000000000000000000000000000011 +0001000000000010101101011001010001000000000000000000000000000011 +0001000000000010101101011001010001000000000000000000000000000011 \ No newline at end of file diff --git a/test/input/L1_multicastY/stimuli.txt b/test/input/L1_multicastY/stimuli.txt new file mode 100644 index 0000000..5a96c89 --- /dev/null +++ b/test/input/L1_multicastY/stimuli.txt @@ -0,0 +1,12 @@ +10001000000000010101101011001010001000000000000000000000000000011 # copy Y, dest 1- -> DS3, DS4 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 +10001000000000010101101011001010001000000000000000000000000000011 +00000000000000000000000000000000000000000000000000000000000000000 +00001000000000010101101011001010001000000000000000000000000000011 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 # R L1 0010- 0010- \ No newline at end of file diff --git a/test/input/L1_unicast/result.ref b/test/input/L1_unicast/result.ref new file mode 100644 index 0000000..cb438cb --- /dev/null +++ b/test/input/L1_unicast/result.ref @@ -0,0 +1,8 @@ +0001000000000000001000010000000000000000000000000000000000000011 +0001000000000000001000000000000000000000000000000000000000001001 +0001000000000000000000010000000000000000000000000000000000000101 +0001000000000000000000000000000000000000000000000000000000000111 +0001000001000010001000010000000000000000000000000000000000000100 +0001000001000010001000010000000000000000000000000000000000001000 +0001000001000010001000010000000000000000000000000000000000000110 +0001000001000010001000010000000000000000000000000000000000001010 \ No newline at end of file diff --git a/test/input/L1_unicast/stimuli.txt b/test/input/L1_unicast/stimuli.txt new file mode 100644 index 0000000..effebf5 --- /dev/null +++ b/test/input/L1_unicast/stimuli.txt @@ -0,0 +1,18 @@ +10001000000000000001000010000000000000000000000000000000000000011 # DS1 +00000000000000000000000000000000000000000000000000000000000000000 +10001000001000010001000010000000000000000000000000000000000000100 # U +00000000000000000000000000000000000000000000000000000000000000000 +10001000000000000000000010000000000000000000000000000000000000101 # DS3 +10001000001000010001000010000000000000000000000000000000000000110 # U +10001000000000000000000000000000000000000000000000000000000000111 # DS4 +00000000000000000000000000000000000000000000000000000000000000000 +10001000001000010001000010000000000000000000000000000000000001000 # U +00000000000000000000000000000000000000000000000000000000000000000 +10001000000000000001000000000000000000000000000000000000000001001 # DS2 +10001000001000010001000010000000000000000000000000000000000001010 # U +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000 # Router L1 00000,00000 \ No newline at end of file diff --git a/test/router_tb.vhdl b/test/router_tb.vhdl index 72f6cb6..279be0e 100644 --- a/test/router_tb.vhdl +++ b/test/router_tb.vhdl @@ -2,6 +2,8 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.router_types.all; +use ieee.std_logic_textio.all; +use std.textio.all; entity router_tb is end; @@ -18,14 +20,18 @@ architecture bench of router_tb is constant fifo_ptr_size: integer := 3; constant chip_x : std_logic_vector(4 downto 0) := (others => '0'); constant chip_y : std_logic_vector(4 downto 0) := (others => '0'); - constant core_x : std_logic_vector(4 downto 0) := (others => '0'); - constant core_y : std_logic_vector(4 downto 0) := (others => '0'); + constant core_x : std_logic_vector(4 downto 0) := "0010-"; + constant core_y : std_logic_vector(4 downto 0) := "0010-"; -- Ports - signal clk : std_logic; - signal arstN : std_logic; - signal rcv_buff_wr_in : t_PORT_WR_IN(num_paths_up+num_paths_down*4-1 downto 0); - signal snd_buff_rd_in : std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0); - signal snd_buff_out : t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0); + signal clk : std_logic; + signal arstN : std_logic; + signal rcv_buff_wr_in : t_PORT_WR_IN(num_paths_up+num_paths_down*4-1 downto 0); + signal snd_buff_rd_in : std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0); + signal snd_buff_out : t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0); + + 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 router_inst : entity work.router @@ -58,62 +64,90 @@ begin wait for clk_period/2; end process; - test: process + test : process + variable input_line, rowOut : line; + variable valid_data : boolean; + variable stimuli : std_logic_vector(64 downto 0); + variable istwert, sollwert : WORD; + variable index_path : integer; + variable test_passed : boolean; begin + test_passed := TRUE; arstN <= '0'; snd_buff_rd_in <= (others => '0'); - wait for clk_period; - -- header|chip_addr_x|chip_addr_y|core_addr_x|core_addr_y|core*_addr & payload - rcv_buff_wr_in(0).data <= "0001"&"00000"&"00000"&"00001"&"00001"& - std_logic_vector(to_unsigned(3, 40)); - rcv_buff_wr_in(0).wr_req <= '1'; -- to DS 4 - - rcv_buff_wr_in(1).data <= (others => '0'); - rcv_buff_wr_in(1).wr_req <= '0'; - - rcv_buff_wr_in(2).data <= "0001"&"00000"&"10000"&"10001"&"00001"& - std_logic_vector(to_unsigned(4, 40)); - rcv_buff_wr_in(2).wr_req <= '1'; -- to upstream - - rcv_buff_wr_in(3).data <= (others => '0'); - rcv_buff_wr_in(3).wr_req <= '0'; - - rcv_buff_wr_in(4).data <= "0001"&"00000"&"00000"&"00000"&"00001"& - std_logic_vector(to_unsigned(5, 40)); - rcv_buff_wr_in(4).wr_req <= '1'; -- to DS2 - - rcv_buff_wr_in(5).data <= "0001"&"00000"&"10000"&"10001"&"00001"& - std_logic_vector(to_unsigned(6, 40)); - rcv_buff_wr_in(5).wr_req <= '1'; -- to upstream + wait until rising_edge(clk); + -- writing and arbitration arstN <= '1'; - wait for clk_period; - rcv_buff_wr_in(0).data <= "0001"&"00000"&"00000"&"00000"&"00000"& - std_logic_vector(to_unsigned(7, 40)); - rcv_buff_wr_in(0).wr_req <= '1'; -- to DS1 - - rcv_buff_wr_in(1).data <= (others => '0'); - rcv_buff_wr_in(1).wr_req <= '0'; - - rcv_buff_wr_in(2).data <= "0001"&"00000"&"10000"&"10001"&"00001"& - std_logic_vector(to_unsigned(8, 40)); - rcv_buff_wr_in(2).wr_req <= '1'; -- to upstream - - rcv_buff_wr_in(3).data <= (others => '0'); - rcv_buff_wr_in(3).wr_req <= '0'; - - rcv_buff_wr_in(4).data <= "0001"&"00000"&"00000"&"00001"&"00000"& - std_logic_vector(to_unsigned(9, 40)); - rcv_buff_wr_in(4).wr_req <= '1'; -- to DS3 - - rcv_buff_wr_in(5).data <= "0001"&"00000"&"10000"&"10001"&"00001"& - std_logic_vector(to_unsigned(10, 40)); - rcv_buff_wr_in(5).wr_req <= '1'; -- to upstream - arstN <= '1'; - wait for clk_period; - for i in 0 to num_paths_down*4+num_paths_up-1 loop - rcv_buff_wr_in(i).data <= (others => '0'); - rcv_buff_wr_in(i).wr_req <= '0'; + index_path := 0; + while not(endfile(stimuli_file)) loop + readline(stimuli_file, input_line); + read(input_line, stimuli, valid_data); + assert valid_data + report "Invalid data in file" severity error; + rcv_buff_wr_in(index_path).data <= stimuli(63 downto 0); + rcv_buff_wr_in(index_path).wr_req <= stimuli(64); + index_path := index_path + 1; + if index_path = num_paths_down*4 + num_paths_up then + wait until rising_edge(clk); + index_path := 0; + end if; + exit when endfile(stimuli_file); end loop; + wait until rising_edge(clk); + wait for clk_period*5; + + -- reading from send fifo and validating + wait until rising_edge(clk); + for i in 0 to num_paths_down*4+num_paths_up-1 loop + while snd_buff_out(i).empty = '0' loop + istwert := snd_buff_out(i).data; + snd_buff_rd_in(i) <= '1'; + wait until rising_edge(clk); + snd_buff_rd_in(i) <= '0'; + wait until rising_edge(clk); + wait until rising_edge(clk); + wait until rising_edge(clk); + readline(reference_file, input_line); + read(input_line, sollwert, valid_data); + assert valid_data report "Invalid data in file" severity error; + assert istwert = sollwert report "Invalid result" severity warning; + write(rowOut, i); + write(rowOut, string'(" = loop (path/fifo)")); + WRITELINE(log_file, rowOut); + write(rowOut, sollwert); + write(rowOut, string'(" = soll")); + WRITELINE(log_file, rowOut); + write(rowOut, istwert); + write(rowOut, string'(" = ist")); + WRITELINE(log_file, rowOut); + if istwert = sollwert then + write(rowOut, string'("-------------------------->pass")); + WRITELINE(log_file, rowOut); + write(rowOut, string'("******************************")); + WRITELINE(log_file, rowOut); + test_passed := test_passed and TRUE; + else + write(rowOut, string'("-------------------------->fail")); + WRITELINE(log_file, rowOut); + write(rowOut, string'("******************************")); + WRITELINE(log_file, rowOut); + test_passed := test_passed and FALSE; + end if; + exit when endfile(reference_file); + end loop; + exit when endfile(reference_file); + end loop; + wait until rising_edge(clk); + if not endfile(reference_file) then + test_passed := FALSE; + end if; + if test_passed then + write(rowOut, string'("All tests passed successfully!")); + WRITELINE(log_file, rowOut); + else + write(rowOut, string'("One or more tests failed")); + WRITELINE(log_file, rowOut); + end if; wait; end process; -end; \ No newline at end of file +end architecture; \ No newline at end of file