Files
digital_microphone/src/Top.vhd
T
nikit3s 4aa221105a Светодиод с выбираемым источником для поиска обрыва тракта
Генерик LED_SRC переключает индикацию между стробами ФНЧ, CIC и PDM.
По умолчанию рабочий режим, поведение не меняется.
2026-08-17 17:42:42 +03:00

212 lines
5.6 KiB
VHDL

----------------------------------------------------------------------------------
-- Company:
-- Engineer:
-- Create Date:
-- Design Name:
-- Module Name: Top - Behavioral
-- Project Name: DigMic_prj
-- Target Devices: Gowin GW5A-25
-- Description:
-- Цифровой микрофон SPH9855 -> UART.
-- MIC_CLK 3.125 МГц (50/16, Normal mode) -> CIC sinc^4 /50 -> 62.5 кГц ->
-- ФНЧ /5 -> 12 500 Гц, 24 бита -> кадры по 50 отсчётов -> UART 921600.
--
-- Постоянная '1' на выводе данных микрофона даёт полную шкалу 24 бит,
-- так что шкала выхода -- dBFS, как её задаёт даташит микрофона.
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Top is
generic (
SYS_CLK_HZ : integer := 50_000_000;
BAUD_RATE : integer := 921600;
-- Что считает светодиод: 0 -- отсчёты ФНЧ (рабочий режим), 1 -- отсчёты
-- CIC, 2 -- биты PDM. Быстрое мерцание значит, что выбранный строб живой,
-- так обрыв тракта находится перебором без осциллографа внутри кристалла.
LED_SRC : integer := 0
);
port (
clk : in std_logic;
-- Микрофон
MIC_DAT : in std_logic;
MIC_CLK : out std_logic;
MIC_SEL : out std_logic;
-- UART на внешний USB-мост
UART_TX : out std_logic;
LED : out std_logic
);
end entity Top;
architecture Behavioral of Top is
constant PDM_DIV : integer := 16; -- 50 МГц / 16 = 3.125 МГц
constant CIC_R : integer := 50; -- 3.125 МГц / 50 = 62.5 кГц
constant CIC_N : integer := 4;
constant CIC_W : integer := 26;
constant FIR_DEC : integer := 5; -- 62.5 кГц / 5 = 12.5 кГц
signal rst_n : std_logic := '1';
signal pdm_bit : std_logic;
signal pdm_valid : std_logic;
signal cic_data : signed(CIC_W - 1 downto 0);
signal cic_valid : std_logic;
signal fir_data : signed(23 downto 0);
signal fir_valid : std_logic;
signal fir_sat : std_logic;
signal fifo_q : std_logic_vector(23 downto 0);
signal fifo_rd_en : std_logic;
signal fifo_dready : std_logic;
signal fifo_full : std_logic;
signal uart_ena : std_logic;
signal uart_data : std_logic_vector(7 downto 0);
signal uart_busy : std_logic;
signal led_event : std_logic;
begin
rst_n <= '1';
led_event <= pdm_valid when LED_SRC = 2 else
cic_valid when LED_SRC = 1 else
fir_valid;
pdm_rx_inst : entity work.pdm_rx(rtl)
generic map(
CLK_DIV => PDM_DIV,
SEL_HIGH => '0' -- микрофон отдаёт бит по спаду MIC_CLK
)
port map
(
clk => clk,
rst_n => rst_n,
mic_dat => MIC_DAT,
mic_clk => MIC_CLK,
mic_sel => MIC_SEL,
bit_out => pdm_bit,
bit_valid => pdm_valid
);
cic_decim_inst : entity work.cic_decim(rtl)
generic map(
ORDER => CIC_N,
DECIM => CIC_R,
ACC_W => CIC_W
)
port map
(
clk => clk,
rst_n => rst_n,
din => pdm_bit,
din_valid => pdm_valid,
dout => cic_data,
dout_valid => cic_valid
);
fir_decim_inst : entity work.fir_decim(rtl)
generic map(
DIN_W => CIC_W,
DOUT_W => 24,
DECIM => FIR_DEC,
BUF_AW => 8,
ACC_W => 48
)
port map
(
clk => clk,
rst_n => rst_n,
din => cic_data,
din_valid => cic_valid,
dout => fir_data,
dout_valid => fir_valid,
sat => fir_sat
);
fifo_top_inst : entity work.fifo_top(rtl)
generic map(
DWIDTH => 24,
DEPTH => 128,
AF_LEVEL => 50 -- порог начала кадра
)
port map
(
Data => std_logic_vector(fir_data),
WrClk => clk,
RdClk => clk,
WrEn => fir_valid,
RdEn => fifo_rd_en,
Q => fifo_q,
Empty => open,
Almost_Full => fifo_dready,
Full => fifo_full
);
packets_creator_inst : entity work.Packets_creator(Behavioral)
generic map(
SAMPLES_PER_FRAME => 50
)
port map
(
clk => clk,
rst_n => rst_n,
data_ADC => fifo_q,
dready => fifo_dready,
rd_en => fifo_rd_en,
wr_en => fir_valid,
fifo_full => fifo_full,
err_overrun => fir_sat, -- бит1 STATUS: выход упирался в шкалу
busy_uart => uart_busy,
ena_uart => uart_ena,
dout => uart_data,
fault => open
);
uart_inst : entity work.uart(logic)
generic map(
clk_freq => SYS_CLK_HZ,
baud_rate => BAUD_RATE,
os_rate => 16,
d_width => 8,
parity => 0,
parity_eo => '0'
)
port map
(
clk => clk,
reset_n => rst_n,
tx_ena => uart_ena,
tx_data => uart_data,
rx => '1',
rx_busy => open,
rx_error => open,
rx_data => open,
tx_busy => uart_busy,
tx => UART_TX
);
led_status_inst : entity work.led_status(rtl)
generic map(
SYS_CLK_HZ => SYS_CLK_HZ,
SLOW_HZ => 2,
FAST_HZ => 10,
ALIVE_MS => 200
)
port map
(
clk => clk,
data_event => led_event,
led => LED
);
end architecture Behavioral;