paicore_behavioral/test/noc_tb.vhdl
2025-07-18 05:09:06 -05:00

228 lines
No EOL
7.2 KiB
VHDL

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;