---------------------------------------------------------------------------------- -- 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;