Files
nikit3s 61488b41e2 Тестбенч: модель микрофона и сквозная проверка тракта
Модель -- сигма-дельта первого порядка с высокоимпедансным состоянием вне
рабочей фазы, так что выборка не в той фазе видна сразу. Три режима дают
точно вычислимый ответ: постоянные 1 и 0 -- плюс/минус полная шкала, а
чередование 1010 -- ровно ноль, эта частота попадает в нуль АЧХ CIC.
Четвёртый режим синусный, проверяется размах.

Буфер ФНЧ получил начальное значение: иначе первые свёртки тянули
неопределённость через весь тракт.
2026-08-14 16:07:41 +03:00

73 lines
2.8 KiB
VHDL

----------------------------------------------------------------------------------
-- Module Name: pdm_mic_model
-- Project Name: DigMic_prj
-- Description:
-- Поведенческая модель PDM-микрофона: сигма-дельта модулятор первого порядка
-- с передачей сигнала 1 и шумом (1 - z^-1). Что подаётся на модулятор,
-- выбирает вход mode.
--
-- Вывод данных как в даташите: бит выставляется через TDD после рабочего
-- фронта (при SELECT = '0' -- по спаду) и через TDZ после противоположного
-- уходит в высокоимпедансное. Так тестбенч ловит выборку не в той фазе.
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
entity pdm_mic_model is
generic (
F_PDM : real := 3_125_000.0;
SEL_HIGH : std_logic := '0';
AMP : real := 0.5; -- амплитуда синуса в долях шкалы
FREQ : real := 1000.0; -- частота синуса, Гц
TDD : time := 18 ns; -- задержка выдачи после рабочего фронта
TDZ : time := 15 ns -- задержка ухода в Z
);
port (
mic_clk : in std_logic;
mode : in integer; -- 0 +шкала, 1 -шкала, 2 ноль, 3 синус
mic_dat : out std_logic
);
end entity pdm_mic_model;
architecture model of pdm_mic_model is
constant T_HALF : time := (1 sec / integer(F_PDM)) / 2;
begin
mod_proc : process
variable e : real := 0.0; -- накопитель ошибки
variable y : real := 0.0; -- предыдущий выход
variable x : real;
variable n : integer := 0;
variable b : std_logic;
begin
if SEL_HIGH = '1' then
wait until rising_edge(mic_clk);
else
wait until falling_edge(mic_clk);
end if;
case mode is
when 0 => x := 1.0;
when 1 => x := - 1.0;
when 2 => x := 0.0;
when others => x := AMP * sin(2.0 * MATH_PI * FREQ * real(n) / F_PDM);
end case;
e := e + x - y;
if e >= 0.0 then
y := 1.0;
b := '1';
else
y := - 1.0;
b := '0';
end if;
n := n + 1;
-- Обе точки одной формой сигнала: раздельными присваиваниями инерционная
-- задержка второго вычистила бы транзакцию первого
mic_dat <= b after TDD, 'Z' after T_HALF + TDZ;
end process mod_proc;
end architecture model;