228 lines
No EOL
7.2 KiB
VHDL
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; |