Порядок CIC 3 вместо 4: аккумуляторы шире 18 бит не работают в кристалле
Тракт молча отдавал нули: CIC с 26-битными аккумуляторами в железе не считает, хотя синтез, трассировка, тайминг и симуляция чистые. Порог найден перебором на плате с приёмом по UART: 26, 24 и 20 бит мертвы, 18, 16 и 10 работают. Порядок 3 требует ровно 18 бит вместо 24 и попадает в рабочую область. Характеристики от этого стали лучше: подавление в задерживании 76 дБ вместо 72, сворачиваемых полос 92 дБ вместо 77, полоса та же 0.032 дБ. Коэффициенты ФНЧ пересчитаны под sinc^3, сдвиг выхода уменьшен до 13 -- усиление CIC теперь 50^3, и коэффициенты по-прежнему укладываются в 18 бит. Сброс по включению убран: он тоже убивает тракт, проверено прошивкой в обе стороны. Маяк светодиода вынесен в условную генерацию, чтобы его широкий счётчик не собирался в рабочем режиме. Проверено на плате: 1481 кадр за 6 с, 74050 отсчётов, CRC без ошибок, STATUS чистый, на входе живой звук.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
Прошивка принимает поток PDM с микрофона SPH9855LM4H-C, приводит его к
|
||||
**24 бит / 12 500 Гц** и отдаёт отсчёты кадрами по UART.
|
||||
|
||||
MIC_CLK 3.125 МГц -> CIC sinc^4 /50 -> 62.5 кГц -> ФНЧ /5 -> **12 500 Гц** ->
|
||||
MIC_CLK 3.125 МГц -> CIC sinc^3 /50 -> 62.5 кГц -> ФНЧ /5 -> **12 500 Гц** ->
|
||||
кадры по 50 отсчётов -> UART 921600.
|
||||
|
||||
## Тактирование и частоты
|
||||
@@ -12,7 +12,7 @@ MIC_CLK 3.125 МГц -> CIC sinc^4 /50 -> 62.5 кГц -> ФНЧ /5 -> **12 500
|
||||
|:--|:--|:--|
|
||||
| Системный клок | 50 МГц (E2) | генератор платы |
|
||||
| MIC_CLK | 3.125 МГц = 50/16 | Normal mode микрофона 1.1...4.8 МГц |
|
||||
| CIC | sinc^4, децимация 50 | до 62.5 кГц, без умножителей |
|
||||
| CIC | sinc^3, децимация 50 | до 62.5 кГц, без умножителей, аккумуляторы 18 бит |
|
||||
| ФНЧ | 221 отвод, децимация 5 | до 12 500 Гц |
|
||||
| Выходная ЧД | 12 500 Гц | |
|
||||
| UART | 921600, 8N1 | 157 байт на кадр, 250 кадров/с, 39.25 кБ/с (43% канала) |
|
||||
@@ -31,11 +31,15 @@ CIC снимает поток до 62.5 кГц, а всю избирательн
|
||||
| Показатель | Значение |
|
||||
|:--|:--|
|
||||
| неравномерность полосы 0...5000 Гц | 0.032 дБ |
|
||||
| подавление от 6250 Гц | 72 дБ |
|
||||
| подавление сворачиваемых полос | 77 дБ |
|
||||
| подавление от 6250 Гц | 76 дБ |
|
||||
| подавление сворачиваемых полос | 92 дБ |
|
||||
|
||||
Спад CIC в полосе (до 0.36 дБ на краю) не компенсируется отдельным звеном:
|
||||
он задан прямо в желаемой АЧХ при расчёте ФНЧ.
|
||||
Спад CIC в полосе не компенсируется отдельным звеном: он задан прямо в желаемой
|
||||
АЧХ при расчёте ФНЧ, поэтому смена порядка CIC требует только перезапуска
|
||||
генератора коэффициентов.
|
||||
|
||||
Порядок 3, а не 4, выбран не из соображений АЧХ — характеристики с ним даже
|
||||
лучше — а по ограничению кристалла, см. ниже.
|
||||
|
||||
Коэффициенты и разрядности лежат в `src/fir_coefs_pkg.vhd`, файл генерируется:
|
||||
|
||||
@@ -46,7 +50,7 @@ py -3 tools/gen_fir_coefs.py
|
||||
## Шкала
|
||||
|
||||
Постоянная `'1'` на выводе данных микрофона даёт полную шкалу 24 бит
|
||||
(код 8 388 567). Отсюда шкала выхода — dBFS, ровно та, в которой микрофон
|
||||
(код 8 388 596). Отсюда шкала выхода — dBFS, ровно та, в которой микрофон
|
||||
специфицирован. Вольт в тракте нет, `V_REF` в приёмных скриптах не нужен.
|
||||
|
||||
## Формат кадра UART
|
||||
@@ -85,6 +89,21 @@ B3 (`FPGA_UART_RX`, контакт 19).
|
||||
выборка идёт в середине низкой фазы. Если вывод SELECT посажен на питание
|
||||
платой, поменять `SEL_HIGH` в `Top.vhd` на `'1'` — точка выборки переедет сама.
|
||||
|
||||
## Два ограничения кристалла, добытые на железе
|
||||
|
||||
Оба проявляются одинаково: синтез и трассировка проходят без замечаний, тайминг
|
||||
чистый, симуляция верная, а в кристалле тракт молча отдаёт нули.
|
||||
|
||||
**Разрядность аккумуляторов CIC не выше 18 бит.** Проверено перебором на плате
|
||||
с приёмом по UART: 26, 24 и 20 бит — тракт мёртв, 18, 16 и 10 бит — работает.
|
||||
Отсюда порядок 3: требуется `ORDER*log2(DECIM)+1`, для 3 и 50 это ровно 18, для
|
||||
4 было бы 24. На аккумулятор ФНЧ (40 бит) ограничение не распространяется — он
|
||||
проверен на железе и считает верно.
|
||||
|
||||
**Сброс по включению ставить нельзя.** Добавление счётчика, держащего `rst_n`
|
||||
в нуле первые 256 тактов, убивает тракт целиком. С константой `'1'` всё
|
||||
работает. Проверено прошивкой в обе стороны.
|
||||
|
||||
## Сборка
|
||||
|
||||
Выводы `clk` (E2) и `LED` (E8) на этом корпусе сидят на двойных функциях
|
||||
@@ -93,8 +112,9 @@ B3 (`FPGA_UART_RX`, контакт 19).
|
||||
в `gw_sh` -- `set_option -use_cpu_as_gpio 1 -use_sspi_as_gpio 1
|
||||
-use_ready_as_gpio 1`.
|
||||
|
||||
Занято на GW5A-25: 778 LUT/ALU (4%), 616 регистров (3%), 5 BSRAM (9%),
|
||||
1 DSP (4%). Fmax 164 МГц при требуемых 50, нарушений установки и удержания нет.
|
||||
Занято на GW5A-25: 649 LUT/ALU (3%), 461 регистр (2%), 4 BSRAM (8%), 1 DSP (4%).
|
||||
Тайминг сходится с запасом, но полагаться на него как на признак исправности
|
||||
нельзя — см. раздел про ограничения кристалла выше.
|
||||
|
||||
## Состав
|
||||
|
||||
@@ -102,7 +122,7 @@ B3 (`FPGA_UART_RX`, контакт 19).
|
||||
|:--|:--|
|
||||
| `src/Top.vhd` | верхний уровень: только экземпляры и связи |
|
||||
| `src/pdm_rx.vhd` | тактирование микрофона и выборка бита в нужной фазе |
|
||||
| `src/cic_decim.vhd` | CIC sinc^4, децимация 50 |
|
||||
| `src/cic_decim.vhd` | CIC sinc^3, децимация 50 |
|
||||
| `src/fir_decim.vhd` | ФНЧ с децимацией 5, последовательная свёртка |
|
||||
| `src/fir_coefs_pkg.vhd` | коэффициенты ФНЧ, генерируется |
|
||||
| `src/fifo_top.vhd` | буфер отсчётов, заглушка под IP-ядро Gowin |
|
||||
|
||||
+18
-23
@@ -8,7 +8,7 @@
|
||||
-- Target Devices: Gowin GW5A-25
|
||||
-- Description:
|
||||
-- Цифровой микрофон SPH9855 -> UART.
|
||||
-- MIC_CLK 3.125 МГц (50/16, Normal mode) -> CIC sinc^4 /50 -> 62.5 кГц ->
|
||||
-- MIC_CLK 3.125 МГц (50/16, Normal mode) -> CIC sinc^3 /50 -> 62.5 кГц ->
|
||||
-- ФНЧ /5 -> 12 500 Гц, 24 бита -> кадры по 50 отсчётов -> UART 921600.
|
||||
--
|
||||
-- Постоянная '1' на выводе данных микрофона даёт полную шкалу 24 бит,
|
||||
@@ -51,16 +51,14 @@ 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 CIC_N : integer := 3;
|
||||
constant CIC_W : integer := 18;
|
||||
constant FIR_DEC : integer := 5; -- 62.5 кГц / 5 = 12.5 кГц
|
||||
|
||||
-- Сброс по включению. Раньше здесь была константа '1', и тогда состояние
|
||||
-- модулей после конфигурации определялось только начальными значениями
|
||||
-- регистров. Для UART это критично: до первого кадра он молчит, и уровень
|
||||
-- на линии задаёт его сдвиговый регистр, который обязан быть в единицах.
|
||||
signal rst_n : std_logic := '0';
|
||||
signal rst_cnt : unsigned(7 downto 0) := (others => '0');
|
||||
-- Сброса нет намеренно: состояние задают начальные значения регистров.
|
||||
-- Пробовал сброс по включению от счётчика -- на железе тракт от него молча
|
||||
-- умирает, кадры перестают идти. Проверено прошивкой в обе стороны.
|
||||
signal rst_n : std_logic := '1';
|
||||
|
||||
signal pdm_bit : std_logic;
|
||||
signal pdm_valid : std_logic;
|
||||
@@ -89,26 +87,17 @@ architecture Behavioral of Top is
|
||||
|
||||
begin
|
||||
|
||||
por_proc : process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst_cnt = 255 then
|
||||
rst_n <= '1';
|
||||
else
|
||||
rst_cnt <= rst_cnt + 1;
|
||||
rst_n <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process por_proc;
|
||||
|
||||
led_event <= pdm_valid when LED_SRC = 2 else
|
||||
cic_valid when LED_SRC = 1 else
|
||||
fir_valid;
|
||||
|
||||
LED <= beacon when LED_SRC = 3 else led_chain;
|
||||
-- Маяк собирается только когда выбран: его счётчик широкий и тикает каждый
|
||||
-- такт, а такие в этом кристалле надёжно работать не обязаны
|
||||
beacon_gen : if LED_SRC = 3 generate
|
||||
LED <= beacon;
|
||||
|
||||
-- Маяк: полпериода = SYS_CLK_HZ/2 тактов, то есть ровно 1 Гц на выводе.
|
||||
-- Ни от чего, кроме clk, не зависит.
|
||||
beacon_proc : process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
@@ -120,6 +109,11 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
end process beacon_proc;
|
||||
end generate beacon_gen;
|
||||
|
||||
chain_gen : if LED_SRC /= 3 generate
|
||||
LED <= led_chain;
|
||||
end generate chain_gen;
|
||||
|
||||
pdm_rx_inst : entity work.pdm_rx(rtl)
|
||||
generic map(
|
||||
@@ -159,7 +153,7 @@ begin
|
||||
DOUT_W => 24,
|
||||
DECIM => FIR_DEC,
|
||||
BUF_AW => 8,
|
||||
ACC_W => 48
|
||||
ACC_W => 40
|
||||
)
|
||||
port map
|
||||
(
|
||||
@@ -234,6 +228,7 @@ begin
|
||||
tx => UART_TX
|
||||
);
|
||||
|
||||
|
||||
led_status_inst : entity work.led_status(rtl)
|
||||
generic map(
|
||||
SYS_CLK_HZ => SYS_CLK_HZ,
|
||||
|
||||
+6
-4
@@ -11,10 +11,12 @@
|
||||
-- частоте PDM, гребёнки -- на пониженной. Умножителей не требует, нули АЧХ
|
||||
-- стоят ровно на частотах, которые складываются в полосу при децимации.
|
||||
--
|
||||
-- Разрядность: ORDER*log2(DECIM) + 1 бит на знак. Для 4 и 50 это 24 бита,
|
||||
-- ACC_W взят с запасом. Переполнение внутри тракта штатно: результат верен
|
||||
-- за счёт дополнительного кода, пока ACC_W не меньше требуемого.
|
||||
-- Постоянному '1' на входе отвечает DECIM^ORDER = 6 250 000.
|
||||
-- Разрядность: ORDER*log2(DECIM) + 1 бит на знак. Для 3 и 50 это 18 бит.
|
||||
-- Шире 18 бит на этом кристалле нельзя: аккумуляторы от 20 бит и выше
|
||||
-- Gowin укладывает неверно, тракт молча отдаёт нули (проверено на железе).
|
||||
-- Переполнение внутри тракта штатно: результат верен за счёт дополнительного
|
||||
-- кода, пока ACC_W не меньше требуемого.
|
||||
-- Постоянному '1' на входе отвечает DECIM^ORDER = 125 000.
|
||||
--
|
||||
-- Каждая ступень защёлкнута отдельно -- это только задержка на ORDER
|
||||
-- отсчётов, зато нет длинной цепи сумматоров в одном такте.
|
||||
|
||||
+61
-61
@@ -9,8 +9,8 @@
|
||||
-- вход 62500 Гц -> выход 12500 Гц, отводов 221, симметричный
|
||||
-- полоса 0..5000 Гц, задерживание от 6250 Гц
|
||||
-- неравномерность полосы с учётом CIC: 0.032 дБ
|
||||
-- подавление в полосе задерживания: -72.1 дБ
|
||||
-- худшее подавление сворачиваемых полос: -77.5 дБ
|
||||
-- подавление в полосе задерживания: -76.3 дБ
|
||||
-- худшее подавление сворачиваемых полос: -92.1 дБ
|
||||
----------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
@@ -20,72 +20,72 @@ package fir_coefs_pkg is
|
||||
|
||||
constant FIR_NTAPS : integer := 221;
|
||||
constant FIR_COEF_W : integer := 18;
|
||||
constant FIR_SHIFT : integer := 17;
|
||||
constant FIR_SHIFT : integer := 13;
|
||||
|
||||
-- Отклик тракта на постоянную '1' на выводе данных микрофона:
|
||||
-- сумма коэффициентов x усиление CIC, округлённая как в fir_decim.
|
||||
constant FIR_SUM : integer := 175921;
|
||||
constant FIR_DC_CODE : integer := 8388567;
|
||||
constant FIR_SUM : integer := 549755;
|
||||
constant FIR_DC_CODE : integer := 8388596;
|
||||
|
||||
type fir_coefs_t is array (0 to FIR_NTAPS - 1) of signed(FIR_COEF_W - 1 downto 0);
|
||||
|
||||
constant FIR_COEFS : fir_coefs_t := (
|
||||
"000000000000000001", "000000000000000010", "000000000000000100", "000000000000000111", -- 0
|
||||
"000000000000001000", "000000000000001000", "000000000000000110", "000000000000000001", -- 4
|
||||
"111111111111111010", "111111111111110100", "111111111111101110", "111111111111101101", -- 8
|
||||
"111111111111110010", "111111111111111011", "000000000000001000", "000000000000010110", -- 12
|
||||
"000000000000011111", "000000000000100000", "000000000000010111", "000000000000000101", -- 16
|
||||
"111111111111101101", "111111111111010111", "111111111111001010", "111111111111001100", -- 20
|
||||
"111111111111011111", "000000000000000000", "000000000000100110", "000000000001000111", -- 24
|
||||
"000000000001010110", "000000000001001100", "000000000000101000", "111111111111110001", -- 28
|
||||
"111111111110110111", "111111111110001100", "111111111101111111", "111111111110011010", -- 32
|
||||
"111111111111011010", "000000000000101111", "000000000010000000", "000000000010110011", -- 36
|
||||
"000000000010110100", "000000000001111011", "000000000000010100", "111111111110011001", -- 40
|
||||
"111111111100101111", "111111111011111011", "111111111100010100", "111111111101111100", -- 44
|
||||
"000000000000011010", "000000000011000010", "000000000101000001", "000000000101100111", -- 48
|
||||
"000000000100011111", "000000000001110100", "111111111110010000", "111111111010110111", -- 52
|
||||
"111111111000101111", "111111111000101100", "111111111010111110", "111111111111000110", -- 56
|
||||
"000000000011111100", "000000001000000011", "000000001010000001", "000000001001000000", -- 60
|
||||
"000000000101000001", "111111111111000010", "111111111000101111", "111111110100001000", -- 64
|
||||
"111111110010110100", "111111110101100100", "111111111011111011", "000000000100001101", -- 68
|
||||
"000000001100000000", "000000010000110000", "000000010000101010", "000000001011010000", -- 72
|
||||
"000000000001101101", "111111110110101001", "111111101101011100", "111111101001001100", -- 76
|
||||
"111111101011110001", "111111110101000101", "000000000010111000", "000000010001001111", -- 80
|
||||
"000000011011101011", "000000011110011001", "000000010111101101", "000000001000101000", -- 84
|
||||
"111111110100111111", "111111100010100000", "111111010111001101", "111111010111100110", -- 88
|
||||
"111111100101001000", "111111111101001111", "000000011001110001", "000000110010010000", -- 92
|
||||
"000000111110001111", "000000110111110101", "000000011101110100", "111111110100110100", -- 96
|
||||
"111111000110110101", "111110100001011001", "111110010010011110", "111110100100111011", -- 100
|
||||
"111111011101011111", "000000111000110011", "000010101011011110", "000100100011111001", -- 104
|
||||
"000110001101101111", "000111010110001001", "000111110000000101", "000111010110001001", -- 108
|
||||
"000110001101101111", "000100100011111001", "000010101011011110", "000000111000110011", -- 112
|
||||
"111111011101011111", "111110100100111011", "111110010010011110", "111110100001011001", -- 116
|
||||
"111111000110110101", "111111110100110100", "000000011101110100", "000000110111110101", -- 120
|
||||
"000000111110001111", "000000110010010000", "000000011001110001", "111111111101001111", -- 124
|
||||
"111111100101001000", "111111010111100110", "111111010111001101", "111111100010100000", -- 128
|
||||
"111111110100111111", "000000001000101000", "000000010111101101", "000000011110011001", -- 132
|
||||
"000000011011101011", "000000010001001111", "000000000010111000", "111111110101000101", -- 136
|
||||
"111111101011110001", "111111101001001100", "111111101101011100", "111111110110101001", -- 140
|
||||
"000000000001101101", "000000001011010000", "000000010000101010", "000000010000110000", -- 144
|
||||
"000000001100000000", "000000000100001101", "111111111011111011", "111111110101100100", -- 148
|
||||
"111111110010110100", "111111110100001000", "111111111000101111", "111111111111000010", -- 152
|
||||
"000000000101000001", "000000001001000000", "000000001010000001", "000000001000000011", -- 156
|
||||
"000000000011111100", "111111111111000110", "111111111010111110", "111111111000101100", -- 160
|
||||
"111111111000101111", "111111111010110111", "111111111110010000", "000000000001110100", -- 164
|
||||
"000000000100011111", "000000000101100111", "000000000101000001", "000000000011000010", -- 168
|
||||
"000000000000011010", "111111111101111100", "111111111100010100", "111111111011111011", -- 172
|
||||
"111111111100101111", "111111111110011001", "000000000000010100", "000000000001111011", -- 176
|
||||
"000000000010110100", "000000000010110011", "000000000010000000", "000000000000101111", -- 180
|
||||
"111111111111011010", "111111111110011010", "111111111101111111", "111111111110001100", -- 184
|
||||
"111111111110110111", "111111111111110001", "000000000000101000", "000000000001001100", -- 188
|
||||
"000000000001010110", "000000000001000111", "000000000000100110", "000000000000000000", -- 192
|
||||
"111111111111011111", "111111111111001100", "111111111111001010", "111111111111010111", -- 196
|
||||
"111111111111101101", "000000000000000101", "000000000000010111", "000000000000100000", -- 200
|
||||
"000000000000011111", "000000000000010110", "000000000000001000", "111111111111111011", -- 204
|
||||
"111111111111110010", "111111111111101101", "111111111111101110", "111111111111110100", -- 208
|
||||
"111111111111111010", "000000000000000001", "000000000000000110", "000000000000001000", -- 212
|
||||
"000000000000001000", "000000000000000111", "000000000000000100", "000000000000000010", -- 216
|
||||
"000000000000000001" -- 220
|
||||
"000000000000000011", "000000000000000111", "000000000000001110", "000000000000010100", -- 0
|
||||
"000000000000011001", "000000000000011001", "000000000000010010", "000000000000000011", -- 4
|
||||
"111111111111101111", "111111111111011010", "111111111111001011", "111111111111000111", -- 8
|
||||
"111111111111010100", "111111111111110010", "000000000000011011", "000000000001000011", -- 12
|
||||
"000000000001100000", "000000000001100011", "000000000001000111", "000000000000001110", -- 16
|
||||
"111111111111000110", "111111111110000011", "111111111101011011", "111111111101100001", -- 20
|
||||
"111111111110011011", "000000000000000000", "000000000001110111", "000000000011011011", -- 24
|
||||
"000000000100001001", "000000000011101001", "000000000001111010", "111111111111010010", -- 28
|
||||
"111111111100011111", "111111111010011001", "111111111001110011", "111111111011000111", -- 32
|
||||
"111111111110001100", "000000000010010001", "000000000110001011", "000000001000101001", -- 36
|
||||
"000000001000101011", "000000000101111011", "000000000000111100", "111111111011000000", -- 40
|
||||
"111111110101111011", "111111110011011011", "111111110100101001", "111111111001101001", -- 44
|
||||
"000000000001010001", "000000001001011001", "000000001111011110", "000000010001010011", -- 48
|
||||
"000000001101110101", "000000000101100100", "111111111010100110", "111111110000001000", -- 52
|
||||
"111111101001100110", "111111101001011110", "111111110000100001", "111111111101010000", -- 56
|
||||
"000000001100001101", "000000011000110110", "000000011110111001", "000000011011110000", -- 60
|
||||
"000000001111011100", "111111111100111101", "111111101001100100", "111111011011010101", -- 64
|
||||
"111111010111010100", "111111011111110110", "111111110011011110", "000000001101000100", -- 68
|
||||
"000000100101000100", "000000110011101101", "000000110011010111", "000000100010101000", -- 72
|
||||
"000000000101001011", "111111100011000011", "111111000110101010", "111110111001100111", -- 76
|
||||
"111111000001101010", "111111011110011101", "000000001001000010", "000000110101010100", -- 80
|
||||
"000001010101011011", "000001011101101111", "000001001000111110", "000000011010011000", -- 84
|
||||
"111111011101110010", "111110100100110011", "111110000010000100", "111110000011011110", -- 88
|
||||
"111110101101011000", "111111110111111011", "000001001111111101", "000010011011011000", -- 92
|
||||
"000011000000000100", "000010101011111000", "000001011011001110", "111111011100011010", -- 96
|
||||
"111101001110011111", "111011011011010101", "111010101110000110", "111011101000011010", -- 100
|
||||
"111110011000101100", "000010110100100011", "001000011000100101", "001110001110010000", -- 104
|
||||
"010011010110100000", "010110110111000011", "011000000110110111", "010110110111000011", -- 108
|
||||
"010011010110100000", "001110001110010000", "001000011000100101", "000010110100100011", -- 112
|
||||
"111110011000101100", "111011101000011010", "111010101110000110", "111011011011010101", -- 116
|
||||
"111101001110011111", "111111011100011010", "000001011011001110", "000010101011111000", -- 120
|
||||
"000011000000000100", "000010011011011000", "000001001111111101", "111111110111111011", -- 124
|
||||
"111110101101011000", "111110000011011110", "111110000010000100", "111110100100110011", -- 128
|
||||
"111111011101110010", "000000011010011000", "000001001000111110", "000001011101101111", -- 132
|
||||
"000001010101011011", "000000110101010100", "000000001001000010", "111111011110011101", -- 136
|
||||
"111111000001101010", "111110111001100111", "111111000110101010", "111111100011000011", -- 140
|
||||
"000000000101001011", "000000100010101000", "000000110011010111", "000000110011101101", -- 144
|
||||
"000000100101000100", "000000001101000100", "111111110011011110", "111111011111110110", -- 148
|
||||
"111111010111010100", "111111011011010101", "111111101001100100", "111111111100111101", -- 152
|
||||
"000000001111011100", "000000011011110000", "000000011110111001", "000000011000110110", -- 156
|
||||
"000000001100001101", "111111111101010000", "111111110000100001", "111111101001011110", -- 160
|
||||
"111111101001100110", "111111110000001000", "111111111010100110", "000000000101100100", -- 164
|
||||
"000000001101110101", "000000010001010011", "000000001111011110", "000000001001011001", -- 168
|
||||
"000000000001010001", "111111111001101001", "111111110100101001", "111111110011011011", -- 172
|
||||
"111111110101111011", "111111111011000000", "000000000000111100", "000000000101111011", -- 176
|
||||
"000000001000101011", "000000001000101001", "000000000110001011", "000000000010010001", -- 180
|
||||
"111111111110001100", "111111111011000111", "111111111001110011", "111111111010011001", -- 184
|
||||
"111111111100011111", "111111111111010010", "000000000001111010", "000000000011101001", -- 188
|
||||
"000000000100001001", "000000000011011011", "000000000001110111", "000000000000000000", -- 192
|
||||
"111111111110011011", "111111111101100001", "111111111101011011", "111111111110000011", -- 196
|
||||
"111111111111000110", "000000000000001110", "000000000001000111", "000000000001100011", -- 200
|
||||
"000000000001100000", "000000000001000011", "000000000000011011", "111111111111110010", -- 204
|
||||
"111111111111010100", "111111111111000111", "111111111111001011", "111111111111011010", -- 208
|
||||
"111111111111101111", "000000000000000011", "000000000000010010", "000000000000011001", -- 212
|
||||
"000000000000011001", "000000000000010100", "000000000000001110", "000000000000000111", -- 216
|
||||
"000000000000000011" -- 220
|
||||
);
|
||||
|
||||
end package fir_coefs_pkg;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Расчёт ФНЧ-дециматора /5 и генерация src/fir_coefs_pkg.vhd.
|
||||
|
||||
Фильтр стоит после CIC sinc^4 /50 и решает две задачи сразу:
|
||||
Фильтр стоит после CIC sinc^3 /50 и решает две задачи сразу:
|
||||
- давит всё выше 6250 Гц, куда после децимации на 5 сворачивается
|
||||
шум сигма-дельта модулятора микрофона (CIC там ничего не подавляет);
|
||||
- выравнивает спад CIC в полосе (задаётся желаемая АЧХ 1/H_cic).
|
||||
|
||||
Масштаб выбран так, чтобы постоянная '1' на входе PDM давала полную шкалу
|
||||
24 бит: коэффициенты домножены на 2^23 / 50^4 и сумма подогнана точно.
|
||||
24 бит: коэффициенты домножены на 2^23 / 50^3 и сумма подогнана точно.
|
||||
|
||||
Запуск: py -3 tools/gen_fir_coefs.py
|
||||
"""
|
||||
@@ -21,7 +21,7 @@ from scipy.signal import firls, freqz
|
||||
# --- параметры тракта, должны совпадать с Top.vhd ---
|
||||
F_PDM = 3_125_000.0 # PDM_CLK = 50 МГц / 16
|
||||
R_CIC = 50 # децимация CIC
|
||||
N_CIC = 4 # порядок CIC
|
||||
N_CIC = 3 # порядок CIC
|
||||
FS_IN = F_PDM / R_CIC # 62500 Гц на входе FIR
|
||||
DECIM = 5 # децимация FIR
|
||||
FS_OUT = FS_IN / DECIM # 12500 Гц
|
||||
@@ -29,7 +29,7 @@ FS_OUT = FS_IN / DECIM # 12500 Гц
|
||||
# --- параметры фильтра ---
|
||||
NTAPS = 221 # нечётное: линейная фаза, симметрия
|
||||
COEF_W = 18 # разрядность коэффициента
|
||||
SHIFT = 17 # выход = (сумма произведений) >> SHIFT
|
||||
SHIFT = 13 # выход = (сумма произведений) >> SHIFT
|
||||
PASS = 5000.0 # граница полосы пропускания
|
||||
STOP = 6250.0 # граница полосы задерживания = FS_OUT/2
|
||||
WSTOP = 300.0 # вес полосы задерживания
|
||||
|
||||
Reference in New Issue
Block a user