Files
Gromov_IA 2672f8b8a8 Стенд: ЦАП PCM5102A, кнопка усиления, линия LVDS, UART через BL616
- вторая ветвь тракта: отсчёты ФНЧ -> пересчёт в 48 828 Гц -> I2S на
  PCM5102A (dac_stream.v, i2s_transmitter.v), тест tb_dac_stream.v;
- кнопка S1 (H11): усиление ветви ЦАП ступенями по +6 дБ, показ ступени
  светодиодом (gain_button.vhd), тест tb_gain_button.vhd;
- микрофон через линию SN65LVDS: точка выборки MIC_SMP_CNT = 12 по
  измерению на плате (pdm_rx.vhd), в tb_top модель линии;
- новая распиновка: MIC_CLK K8, MIC_DAT K9, ЦАП G1/G2/L4/L3, UART_TX C3
  на встроенный мост BL616;
- сборка под GW5A-25 ревизии A, настройки PnR (CPU/SSPI/READY как GPIO);
- отладочный выход PLL 80 МГц на E3.
2026-10-02 14:21:06 +03:00

184 lines
5.5 KiB
VHDL

----------------------------------------------------------------------------------
-- Module Name: tb_gain_button
-- Project Name: DigMic_prj
-- Description:
-- Тест кнопки усиления ЦАП. Такт уменьшен до 100 кГц: показ длится секунды,
-- а в миллисекундах модуль считает сам, так что поведение то же.
--
-- Проверяется:
-- импульс короче времени дребезга -- не нажатие;
-- дребезг на обоих фронтах даёт ровно один шаг, отпускание -- ни одного;
-- ступени идут по кругу 1..GAIN_MAX -> 0;
-- долгое удержание -- один шаг, без автоповтора;
-- показ: N коротких вспышек, для 0 одна длинная, потом светодиод свободен;
-- нажатие во время показа начинает показ заново с новым значением.
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.all;
entity tb_gain_button is
end entity tb_gain_button;
architecture sim of tb_gain_button is
constant CLK_HZ : integer := 100_000;
constant CLK_T : time := 1 sec / CLK_HZ;
constant GMAX : integer := 3;
signal clk : std_logic := '0';
signal run : boolean := true;
signal btn : std_logic := '0';
signal gain : unsigned(3 downto 0);
signal show : std_logic;
signal led : std_logic;
begin
clk <= not clk after CLK_T / 2 when run else '0';
dut : entity work.gain_button(rtl)
generic map(
SYS_CLK_HZ => CLK_HZ,
GAIN_MAX => GMAX,
BTN_ACTIVE => '1',
DEBOUNCE_MS => 20
)
port map
(
clk => clk,
btn => btn,
gain => gain,
show => show,
led => led
);
stim_proc : process
variable errors : integer := 0;
variable want : integer := 0;
-- Фронт кнопки с дребезгом: четыре отскока по 1-2 мс
procedure bounce(level : std_logic) is
begin
for i in 1 to 4 loop
btn <= level;
wait for 2 ms;
btn <= not level;
wait for 1 ms;
end loop;
btn <= level;
end procedure;
procedure press is
begin
bounce('1');
wait for 100 ms;
bounce('0');
wait for 50 ms;
end procedure;
procedure check_gain(expect : integer; what : string) is
begin
if to_integer(gain) /= expect then
report what & ": gain " & integer'image(to_integer(gain)) &
", want " & integer'image(expect) severity error;
errors := errors + 1;
end if;
end procedure;
-- Вспышки до конца показа: для 0 одна длинная, иначе expect коротких
procedure check_flashes(expect : integer) is
variable n : integer := 0;
variable t0 : time;
variable w : time;
variable wn : time;
begin
if expect = 0 then
wn := 1000 ms;
else
wn := 150 ms;
end if;
if show /= '1' then
report "no display after press" severity error;
errors := errors + 1;
return;
end if;
loop
wait until led = '1' or show = '0';
exit when show = '0';
t0 := now;
wait until led = '0';
w := now - t0;
n := n + 1;
if w < wn - 3 ms or w > wn + 3 ms then
report "flash " & integer'image(n) & " lasts " & time'image(w) &
", want " & time'image(wn) severity error;
errors := errors + 1;
end if;
end loop;
if (expect = 0 and n /= 1) or (expect > 0 and n /= expect) then
report "flashes " & integer'image(n) & " for gain " &
integer'image(expect) severity error;
errors := errors + 1;
else
report "gain " & integer'image(expect) & ": " & integer'image(n) &
" flash(es) of " & time'image(wn);
end if;
end procedure;
begin
wait for 50 ms;
check_gain(0, "after power-up");
assert show = '0' report "display active without a press" severity error;
-- Короткий импульс -- помеха, не нажатие
btn <= '1';
wait for 5 ms;
btn <= '0';
wait for 100 ms;
check_gain(0, "after 5 ms glitch");
if show /= '0' then
report "glitch started a display" severity error;
errors := errors + 1;
end if;
-- По кругу: 1, 2, 3, 0, 1
for k in 1 to GMAX + 2 loop
press;
want := (want + 1) mod (GMAX + 1);
check_gain(want, "press " & integer'image(k));
check_flashes(want);
end loop;
-- Долгое удержание -- один шаг
bounce('1');
wait for 2 sec;
bounce('0');
wait for 50 ms;
want := (want + 1) mod (GMAX + 1);
check_gain(want, "long hold");
if show = '1' then
wait until show = '0';
end if;
-- Нажатие посреди показа: показ заново, с новым значением
press;
want := (want + 1) mod (GMAX + 1);
wait for 700 ms;
press;
want := (want + 1) mod (GMAX + 1);
check_gain(want, "press during display");
check_flashes(want);
if errors = 0 then
report "TEST PASSED";
else
report "TEST FAILED: errors = " & integer'image(errors) severity error;
end if;
run <= false;
stop;
end process stim_proc;
end architecture sim;