Files
DESD/LAB3/sim/tb_volume_multiplier.vhd
2025-05-21 20:37:47 +02:00

178 lines
6.1 KiB
VHDL

----------------------------------------------------------------------------------
-- Testbench for volume_multiplier
----------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY tb_volume_multiplier IS
END tb_volume_multiplier;
ARCHITECTURE Behavioral OF tb_volume_multiplier IS
CONSTANT TDATA_WIDTH : POSITIVE := 24;
CONSTANT VOLUME_WIDTH : POSITIVE := 10;
CONSTANT VOLUME_STEP_2 : POSITIVE := 6;
CONSTANT N_SAMPLES : INTEGER := 8;
CONSTANT N_VOLUMES : INTEGER := 10;
-- Output width calculation (as in DUT)
CONSTANT TDATA_OUT_WIDTH : INTEGER := TDATA_WIDTH - 1 + 2 ** (VOLUME_WIDTH - VOLUME_STEP_2 - 1) + 1;
COMPONENT volume_multiplier IS
GENERIC (
TDATA_WIDTH : POSITIVE := 24;
VOLUME_WIDTH : POSITIVE := 10;
VOLUME_STEP_2 : POSITIVE := 6
);
PORT (
aclk : IN STD_LOGIC;
aresetn : IN STD_LOGIC;
s_axis_tvalid : IN STD_LOGIC;
s_axis_tdata : IN STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0);
s_axis_tlast : IN STD_LOGIC;
s_axis_tready : OUT STD_LOGIC;
m_axis_tvalid : OUT STD_LOGIC;
m_axis_tdata : OUT STD_LOGIC_VECTOR(TDATA_OUT_WIDTH - 1 DOWNTO 0);
m_axis_tlast : OUT STD_LOGIC;
m_axis_tready : IN STD_LOGIC;
volume : IN STD_LOGIC_VECTOR(VOLUME_WIDTH - 1 DOWNTO 0)
);
END COMPONENT;
SIGNAL aclk : STD_LOGIC := '0';
SIGNAL aresetn : STD_LOGIC := '0';
SIGNAL s_axis_tvalid : STD_LOGIC := '0';
SIGNAL s_axis_tdata : STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0) := (OTHERS => '0');
SIGNAL s_axis_tlast : STD_LOGIC := '0';
SIGNAL s_axis_tready : STD_LOGIC;
SIGNAL m_axis_tvalid : STD_LOGIC;
SIGNAL m_axis_tdata : STD_LOGIC_VECTOR(TDATA_OUT_WIDTH - 1 DOWNTO 0);
SIGNAL m_axis_tlast : STD_LOGIC;
SIGNAL m_axis_tready : STD_LOGIC := '1';
SIGNAL volume : STD_LOGIC_VECTOR(VOLUME_WIDTH - 1 DOWNTO 0) := (OTHERS => '0');
-- Test input samples
TYPE sample_mem_type IS ARRAY(0 TO N_SAMPLES-1) OF STD_LOGIC_VECTOR(TDATA_WIDTH-1 DOWNTO 0);
SIGNAL sample_mem : sample_mem_type := (
x"000100", -- +256
x"FFFE00", -- -512
x"000001", -- +1
x"FFFFFF", -- -1 (2's comp)
x"7FFFFF", -- max positive
x"800000", -- max negative
x"000A00", -- +2560
x"FFF600" -- -2560
);
-- Vettore di memoria per i valori di volume
TYPE volume_mem_type IS ARRAY(0 TO N_VOLUMES-1) OF STD_LOGIC_VECTOR(VOLUME_WIDTH-1 DOWNTO 0);
SIGNAL volume_mem : volume_mem_type := (
std_logic_vector(to_unsigned(0, VOLUME_WIDTH)), -- 0.25x (forte attenuazione)
std_logic_vector(to_unsigned(64, VOLUME_WIDTH)), -- 0.375x (attenuazione media)
std_logic_vector(to_unsigned(479, VOLUME_WIDTH)), -- 0.4375x (leggera attenuazione)
std_logic_vector(to_unsigned(480, VOLUME_WIDTH)), -- 0.5x (volume neutro)
std_logic_vector(to_unsigned(513, VOLUME_WIDTH)), -- Circa 0.5x (volume neutro)
std_logic_vector(to_unsigned(576, VOLUME_WIDTH)), -- 0.5625x (leggero aumento)
std_logic_vector(to_unsigned(640, VOLUME_WIDTH)), -- 0.625x (aumento medio)
std_logic_vector(to_unsigned(768, VOLUME_WIDTH)), -- 0.75x (aumento forte)
std_logic_vector(to_unsigned(896, VOLUME_WIDTH)), -- 0.875x (aumento molto forte)
std_logic_vector(to_unsigned(1023, VOLUME_WIDTH)) -- 1x (massimo volume)
);
BEGIN
-- Clock generation
aclk <= NOT aclk AFTER 5 ns;
-- DUT instantiation
uut: volume_multiplier
GENERIC MAP (
TDATA_WIDTH => TDATA_WIDTH,
VOLUME_WIDTH => VOLUME_WIDTH,
VOLUME_STEP_2 => VOLUME_STEP_2
)
PORT MAP (
aclk => aclk,
aresetn => aresetn,
s_axis_tvalid => s_axis_tvalid,
s_axis_tdata => s_axis_tdata,
s_axis_tlast => s_axis_tlast,
s_axis_tready => s_axis_tready,
m_axis_tvalid => m_axis_tvalid,
m_axis_tdata => m_axis_tdata,
m_axis_tlast => m_axis_tlast,
m_axis_tready => m_axis_tready,
volume => volume
);
-- Stimulus process
stimulus : PROCESS
BEGIN
-- Reset
WAIT FOR 10 ns;
aresetn <= '1';
WAIT UNTIL rising_edge(aclk);
-- Set volume to mid (no gain/loss)
volume <= volume_mem(0);
WAIT UNTIL rising_edge(aclk);
-- Send all samples
FOR i IN 0 TO N_SAMPLES-1 LOOP
s_axis_tdata <= sample_mem(i);
s_axis_tvalid <= '1';
IF i = N_SAMPLES-1 THEN
s_axis_tlast <= '1';
ELSE
s_axis_tlast <= '0';
END IF;
-- Wait for handshake
WAIT UNTIL rising_edge(aclk);
WHILE s_axis_tready = '0' LOOP
WAIT UNTIL rising_edge(aclk);
END LOOP;
END LOOP;
s_axis_tvalid <= '0';
s_axis_tlast <= '0';
-- Change volume (attenuate)
WAIT FOR 20 ns;
volume <= volume_mem(1);
-- Send one more sample
WAIT UNTIL rising_edge(aclk);
s_axis_tdata <= x"000100";
s_axis_tvalid <= '1';
s_axis_tlast <= '1';
WAIT UNTIL rising_edge(aclk);
WHILE s_axis_tready = '0' LOOP
WAIT UNTIL rising_edge(aclk);
END LOOP;
s_axis_tvalid <= '0';
s_axis_tlast <= '0';
FOR i IN 2 TO N_VOLUMES-1 LOOP
WAIT FOR 20 ns;
volume <= volume_mem(i);
WAIT UNTIL rising_edge(aclk);
END LOOP;
-- Wait and finish
WAIT FOR 100 ns;
WAIT;
END PROCESS;
-- Optionally, block m_axis_tready to test backpressure
PROCESS
BEGIN
WAIT FOR 60 ns;
WAIT UNTIL rising_edge(aclk);
m_axis_tready <= '0';
WAIT FOR 20 ns;
WAIT UNTIL rising_edge(aclk);
m_axis_tready <= '1';
WAIT;
END PROCESS;
END Behavioral;