Модель -- сигма-дельта первого порядка с высокоимпедансным состоянием вне рабочей фазы, так что выборка не в той фазе видна сразу. Три режима дают точно вычислимый ответ: постоянные 1 и 0 -- плюс/минус полная шкала, а чередование 1010 -- ровно ноль, эта частота попадает в нуль АЧХ CIC. Четвёртый режим синусный, проверяется размах. Буфер ФНЧ получил начальное значение: иначе первые свёртки тянули неопределённость через весь тракт.
73 lines
2.8 KiB
VHDL
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;
|