Initial commit
This commit is contained in:
@@ -0,0 +1,351 @@
|
||||
-- ============================================================
|
||||
-- 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;
|
||||
Reference in New Issue
Block a user