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; use work.quadtree_components.all; entity noc_tb is end; architecture bench of noc_tb is -- Clock period constant clk_period : time := 5 ns; -- Generics constant num_paths_ext : integer := 32; constant buffer_width : integer := 64; constant buffer_depth : integer := 4; constant fifo_ptr_size : integer := 3; constant level : natural := 5; constant top_level : integer := 5; constant chip_x : std_logic_vector(4 downto 0) := "00001"; constant chip_y : std_logic_vector(4 downto 0) := "00001"; -- Ports signal clk : std_logic; signal clks : std_logic_vector(calculate_num_routers(top_level)-1 downto 0); signal arstN : std_logic; signal data_chip_in : t_DATA_EXT(4*num_paths_ext-1 downto 0); signal c_rcv_reqs : std_logic_vector(4*num_paths_ext-1 downto 0); signal c_send_ack : std_logic_vector(4*num_paths_ext-1 downto 0); signal pe_data_in : t_DATA(4**level-1 downto 0); signal pe_rcv_reqs : std_logic_vector(4**level-1 downto 0); signal pe_send_ack : std_logic_vector(4**level-1 downto 0); signal data_chip_out : t_DATA_EXT(4*num_paths_ext-1 downto 0); signal c_rcv_ack : std_logic_vector(4*num_paths_ext-1 downto 0); signal c_send_reqs : std_logic_vector(4*num_paths_ext-1 downto 0); 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_ack_nxt : std_logic_vector(4*num_paths_ext-1 downto 0); signal pe_send_ack_nxt : 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 log_file : text open write_mode is "simulation.log"; procedure log_test_result ( index : integer; istwert : WORD; is_external : std_logic ) is variable rowOut : LINE; begin write(rowOut, is_external); write(rowOut, string'(" ")); write(rowOut, index); write(rowOut, string'(" ")); write(rowOut, istwert); WRITELINE(log_file, rowOut); end procedure; begin noc_inst : entity work.noc generic map ( num_paths_ext => num_paths_ext, buffer_width => buffer_width, buffer_depth => buffer_depth, fifo_ptr_size => fifo_ptr_size, level => level, top_level => top_level, chip_x => chip_x, chip_y => chip_y ) port map ( clks => clks, arstN => arstN, data_chip_in => data_chip_in, c_rcv_reqs => c_rcv_reqs, c_send_ack => c_send_ack, pe_data_in => pe_data_in, pe_rcv_reqs => pe_rcv_reqs, pe_send_ack => pe_send_ack, data_chip_out => data_chip_out, c_rcv_ack => c_rcv_ack, c_send_reqs => c_send_reqs, pe_data_out => pe_data_out, pe_rcv_acks => pe_rcv_acks, pe_send_reqs => pe_send_reqs ); map_clocks: process(clk) begin for i in calculate_num_routers(top_level)-1 downto 0 loop clks(i) <= clk; end loop; end process; clock_gen: process begin clk <= '0'; wait for clk_period/2; clk <= '1'; wait for clk_period/2; end 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); variable wait_for_pe : boolean; variable wait_for_ec : boolean; begin arstN <= '0'; data_chip_in <= (others => (others => '0')); c_rcv_reqs <= (others => '0'); pe_data_in <= (others => (others => '0')); pe_rcv_reqs <= (others => '0'); wait_for_pe := false; wait_for_ec := false; wait until rising_edge(clk); arstN <= '1'; wait until rising_edge(clk); while not(endfile(stimuli_file)) loop readline(stimuli_file, input_line); if input_line.all'length = 0 then if wait_for_pe then wait on pe_rcv_acks; elsif wait_for_ec then wait on c_rcv_ack; end if; wait_for_pe := false; wait_for_ec := false; --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*4-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); wait_for_ec := true; 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); wait_for_pe := true; end if; exit when endfile(stimuli_file); end loop; wait; end process; save_results: process(c_send_reqs, pe_send_reqs, c_send_reqs_prev, pe_send_reqs_prev, data_chip_out, pe_data_out, pe_send_ack, c_send_ack) variable istwert : WORD; 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); log_test_result(i, istwert, '1'); c_send_ack_nxt(i) <= not c_send_ack(i); else c_send_ack_nxt(i) <= c_send_ack(i); end if; end loop; else for i in 0 to num_paths_ext*4-1 loop c_send_ack_nxt(i) <= c_send_ack(i); end loop; end if; if 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); log_test_result(i, istwert, '0'); pe_send_ack_nxt(i) <= not pe_send_ack(i); else pe_send_ack_nxt(i) <= pe_send_ack(i); end if; end loop; else for i in 0 to 4**level-1 loop pe_send_ack_nxt(i) <= pe_send_ack(i); end loop; end if; end process; update_signals: process(clk, arstN) begin if arstN = '0' then c_send_ack <= (others => '0'); pe_send_ack <= (others => '0'); elsif rising_edge(clk) then c_send_reqs_prev <= c_send_reqs; pe_send_reqs_prev <= pe_send_reqs; c_send_ack <= c_send_ack_nxt; pe_send_ack <= pe_send_ack_nxt; end if; end process; end;