Генерик LED_SRC переключает индикацию между стробами ФНЧ, CIC и PDM. По умолчанию рабочий режим, поведение не меняется.
212 lines
5.6 KiB
VHDL
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;
|