Files
Progetto-reti-logiche/progetto_reti_logiche.srcs/sim_1/new/project_tb_timing.vhd
T
2026-06-12 20:37:03 +02:00

351 lines
13 KiB
VHDL

-- ============================================================
-- TESTBENCH TIMING - Progetto Reti Logiche 2025/2026
-- ============================================================
-- Verifica il numero di cicli di clock per ciascuna operazione.
--
-- Formule attese (calibrate sull'FSM con stato S_DONE, che aggiunge
-- 1 ciclo a fine operazione per garantire DONE dopo il commit in memoria):
-- OP=10 inserimento: stati = 6 + 2*max(N,1) + 3k
-- (N = task gia' in lista, scanditi dal controllo
-- duplicati; k = task spostati per fare posto)
-- OP=01 rimozione: stati = 6 + 3k (k = task spostati, lista vuota = 2)
-- OP=00 decremento: stati = 4 + 3n (n = task in lista)
--
-- Per ogni test viene stampato:
-- - il numero di cicli misurati
-- - il numero di cicli attesi
-- - PASS o FAIL
-- ============================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity project_tb_timing is
end project_tb_timing;
architecture timing_arch of project_tb_timing is
constant CLOCK_PERIOD : time := 20 ns;
signal tb_clk : std_logic := '0';
signal tb_rst : std_logic := '0';
signal tb_start : std_logic := '0';
signal tb_done : std_logic;
signal tb_o_task_id : std_logic_vector(5 downto 0);
signal tb_task_priority : std_logic_vector(1 downto 0) := "00";
signal tb_op : std_logic_vector(1 downto 0) := "00";
signal tb_i_task_id : std_logic_vector(5 downto 0) := "000000";
signal exc_o_mem_addr : std_logic_vector(15 downto 0);
signal exc_o_mem_data : std_logic_vector(7 downto 0);
signal exc_o_mem_we : std_logic;
signal exc_o_mem_en : std_logic;
signal init_o_mem_addr : std_logic_vector(15 downto 0) := (others => '0');
signal init_o_mem_data : std_logic_vector(7 downto 0) := (others => '0');
signal init_o_mem_we : std_logic := '0';
signal init_o_mem_en : std_logic := '0';
signal tb_o_mem_addr : std_logic_vector(15 downto 0);
signal tb_o_mem_data : std_logic_vector(7 downto 0);
signal tb_o_mem_we : std_logic;
signal tb_o_mem_en : std_logic;
signal tb_i_mem_data : std_logic_vector(7 downto 0);
signal memory_control : std_logic := '0';
type ram_type is array (65535 downto 0) of std_logic_vector(7 downto 0);
signal RAM : ram_type := (others => "00000000");
component project_reti_logiche is
port (
i_clk : in std_logic;
i_rst : in std_logic;
i_start : in std_logic;
i_task_id : in std_logic_vector(5 downto 0);
i_task_priority : in std_logic_vector(1 downto 0);
i_op : in std_logic_vector(1 downto 0);
o_done : out std_logic;
o_task_id : out std_logic_vector(5 downto 0);
o_mem_addr : out std_logic_vector(15 downto 0);
i_mem_data : in std_logic_vector(7 downto 0);
o_mem_data : out std_logic_vector(7 downto 0);
o_mem_we : out std_logic;
o_mem_en : out std_logic
);
end component;
begin
UUT : project_reti_logiche
port map (
i_clk => tb_clk,
i_rst => tb_rst,
i_start => tb_start,
i_task_id => tb_i_task_id,
i_task_priority => tb_task_priority,
i_op => tb_op,
o_done => tb_done,
o_task_id => tb_o_task_id,
o_mem_addr => exc_o_mem_addr,
i_mem_data => tb_i_mem_data,
o_mem_data => exc_o_mem_data,
o_mem_we => exc_o_mem_we,
o_mem_en => exc_o_mem_en
);
tb_clk <= not tb_clk after CLOCK_PERIOD / 2;
MEM : process (tb_clk)
begin
if tb_clk'event and tb_clk = '1' then
if tb_o_mem_en = '1' then
if tb_o_mem_we = '1' then
RAM(to_integer(unsigned(tb_o_mem_addr))) <= tb_o_mem_data after 1 ns;
tb_i_mem_data <= tb_o_mem_data after 1 ns;
else
tb_i_mem_data <= RAM(to_integer(unsigned(tb_o_mem_addr))) after 1 ns;
end if;
end if;
end if;
end process;
memory_signal_swapper : process (memory_control,
init_o_mem_addr, init_o_mem_data, init_o_mem_en, init_o_mem_we,
exc_o_mem_addr, exc_o_mem_data, exc_o_mem_en, exc_o_mem_we)
begin
tb_o_mem_addr <= init_o_mem_addr;
tb_o_mem_data <= init_o_mem_data;
tb_o_mem_en <= init_o_mem_en;
tb_o_mem_we <= init_o_mem_we;
if memory_control = '1' then
tb_o_mem_addr <= exc_o_mem_addr;
tb_o_mem_data <= exc_o_mem_data;
tb_o_mem_en <= exc_o_mem_en;
tb_o_mem_we <= exc_o_mem_we;
end if;
end process;
-- ============================================================
-- Processo principale
-- ============================================================
main : process
-- Cicli misurati e attesi
variable t_start : time;
variable cycles : integer;
variable expected : integer;
-- --------------------------------------------------------
-- Reset
-- --------------------------------------------------------
procedure do_reset is
begin
tb_start <= '0';
tb_rst <= '1';
wait for 100 ns;
tb_rst <= '0';
wait until tb_done = '0';
wait until falling_edge(tb_clk);
end procedure;
-- --------------------------------------------------------
-- Esegue un'operazione e misura i cicli dal primo fronte
-- di clock dopo START=1 fino al fronte che porta DONE=1
-- --------------------------------------------------------
procedure run_and_measure (
op : std_logic_vector(1 downto 0);
task_id : std_logic_vector(5 downto 0);
priority : std_logic_vector(1 downto 0);
exp : integer;
test_num : integer
) is
begin
wait until falling_edge(tb_clk);
tb_op <= op;
tb_i_task_id <= task_id;
tb_task_priority <= priority;
tb_start <= '1';
-- Il primo fronte di clock dopo START campiona l'ingresso
-- ed entra nel primo stato dell'operazione: inizia il conteggio
wait until rising_edge(tb_clk);
t_start := now;
wait until rising_edge(tb_done);
-- DONE viene registrato sul fronte: questo è l'ultimo stato
cycles := (now - t_start) / CLOCK_PERIOD;
expected := exp;
if cycles = expected then
report "[PASS] test=" & integer'image(test_num)
& " | cicli misurati=" & integer'image(cycles)
& " attesi=" & integer'image(expected);
else
report "[FAIL] test=" & integer'image(test_num)
& " | cicli misurati=" & integer'image(cycles)
& " attesi=" & integer'image(expected)
severity failure;
end if;
tb_start <= '0';
wait until falling_edge(tb_done);
end procedure;
-- --------------------------------------------------------
-- Inserisce un task senza misurarlo (solo per preparare la lista)
-- --------------------------------------------------------
procedure insert_silent (
task_id : std_logic_vector(5 downto 0);
priority : std_logic_vector(1 downto 0)
) is
begin
wait until falling_edge(tb_clk);
tb_op <= "10";
tb_i_task_id <= task_id;
tb_task_priority <= priority;
tb_start <= '1';
wait until rising_edge(tb_done);
tb_start <= '0';
wait until falling_edge(tb_done);
end procedure;
begin
memory_control <= '1';
wait for 50 ns;
-- ============================================================
-- OP=10: Inserimento -> stati attesi = 6 + 4k
-- ============================================================
report "==============================";
report "OP=10 Inserimento: 6 + 2*max(N,1) + 3k stati";
report "==============================";
-- N=0, k=0: lista vuota -> 6 + 2 + 0 = 8 stati
-- OP=10 N=0 k=0 (lista vuota)
do_reset;
run_and_measure("10", "000001", "01", 8, 1);
-- N=1, k=1: 1 task con priorità minore -> spostato -> 6 + 2 + 3 = 11
-- OP=10 N=1 k=1 (1 task spostato)
do_reset;
insert_silent("000001", "10");
run_and_measure("10", "000010", "01", 11, 2);
-- N=2, k=2: 2 task da spostare -> 6 + 4 + 6 = 16
-- OP=10 N=2 k=2 (2 task spostati)
do_reset;
insert_silent("000001", "10");
insert_silent("000010", "10");
run_and_measure("10", "000011", "01", 16, 3);
-- N=3, k=3: 3 task da spostare -> 6 + 6 + 9 = 21
-- OP=10 N=3 k=3 (3 task spostati)
do_reset;
insert_silent("000001", "10");
insert_silent("000010", "10");
insert_silent("000011", "10");
run_and_measure("10", "000100", "01", 21, 4);
-- N=2, k=0: inserimento in fondo, lista non vuota -> 6 + 4 + 0 = 10
-- OP=10 N=2 k=0 (inserimento in fondo)
do_reset;
insert_silent("000001", "00");
insert_silent("000010", "01");
run_and_measure("10", "000011", "11", 10, 5);
-- ============================================================
-- OP=01: Rimozione -> stati attesi = 5 + 3k (lista vuota = 1)
-- ============================================================
report "==============================";
report "OP=01 Rimozione: 6 + 3k stati (lista vuota = 2)";
report "==============================";
-- Lista vuota -> 2 stati (CHECK_NUMBER + S_DONE)
-- OP=01 lista vuota
do_reset;
run_and_measure("01", "000000", "00", 2, 6);
-- k=0: 1 solo task, nessuno spostamento -> 6 stati
-- OP=01 k=0 (1 task, nessuno spostamento)
do_reset;
insert_silent("000001", "01");
run_and_measure("01", "000000", "00", 6, 7);
-- k=1: 2 task, 1 da spostare -> 9 stati
-- OP=01 k=1 (1 task spostato)
do_reset;
insert_silent("000001", "01");
insert_silent("000010", "01");
run_and_measure("01", "000000", "00", 9, 8);
-- k=2: 3 task, 2 da spostare -> 12 stati
-- OP=01 k=2 (2 task spostati)
do_reset;
insert_silent("000001", "01");
insert_silent("000010", "01");
insert_silent("000011", "01");
run_and_measure("01", "000000", "00", 12, 9);
-- k=3: 4 task, 3 da spostare -> 15 stati
-- OP=01 k=3 (3 task spostati)
do_reset;
insert_silent("000001", "01");
insert_silent("000010", "01");
insert_silent("000011", "01");
insert_silent("000100", "01");
run_and_measure("01", "000000", "00", 15, 10);
-- ============================================================
-- OP=00: Decremento -> stati attesi = 3 + 3n
-- ============================================================
report "==============================";
report "OP=00 Decremento: 4 + 3n stati";
report "==============================";
-- n=0: lista vuota -> 4 stati
-- OP=00 n=0 (lista vuota)
do_reset;
run_and_measure("00", "000000", "00", 4, 11);
-- n=1 -> 7 stati
-- OP=00 n=1
do_reset;
insert_silent("000001", "01");
run_and_measure("00", "000000", "00", 7, 12);
-- n=2 -> 10 stati
-- OP=00 n=2
do_reset;
insert_silent("000001", "01");
insert_silent("000010", "10");
run_and_measure("00", "000000", "00", 10, 13);
-- n=3 -> 13 stati
-- OP=00 n=3
do_reset;
insert_silent("000001", "01");
insert_silent("000010", "10");
insert_silent("000011", "11");
run_and_measure("00", "000000", "00", 13, 14);
-- n=4 con saturazione (tutti prio=3) -> 4 + 3*4 = 16 stati
-- OP=00 n=4 (tutti gia prio=3, saturazione)
do_reset;
insert_silent("000001", "11");
insert_silent("000010", "11");
insert_silent("000011", "11");
insert_silent("000100", "11");
run_and_measure("00", "000000", "00", 16, 15);
-- ============================================================
-- Fine
-- ============================================================
assert false
report "Tutti i test di timing sono PASSATI"
severity failure;
end process;
end architecture;