Перейти к содержанию
    

Генератор синуса на FPGA Altera

1. Вообще, насколько я себе представляю, 16 разрядов мало для 110 дБ. Вот вроде бы по науке соотношение сигнал/ошибка будет, если правильно помню, порядка 2 дБ + 6 дБ * N, где N - число разрядов. Как следствие, 16 разрядов дадут что-то около 98 дБ, а для 110 нужно не менее 18 разрядов. Я бы сделал для подстраховки разрядов 20, чтобы иметь небольшой запас на точность вычислений.

 

2. Так частота "плавает" или просто неточно задается? Как я уже написал, нужно так выбрать частоту дискретизации, чтобы у сигнала был ощутимый набег фазы, порядка 45-60 градусов. В этом случае округление значения косинуса не приведет к заметным изменениям задающей частоты. Чтобы было понятнее, поясню на примере. Вот есть частота синусоиды 200 Гц. А частота дискретизации, скажем, 56000 Гц.

cos(2*pi*200/56000) будет 0,999748235. Приведение к Q0.16 даст 65519,50033. Обрезание до целого даст 65519, что эквивалентно значению косинуса 0,999740601, или исходной частоте 203,0098173 Гц.

 

Если все то же самое проделать с частотой дискретизации 1600 Гц, на которой 200 Гц дает набег фазы в 1/8 периода, то частота составит 200,0052204 Гц. Если же взять частоту под набег фазы в 1/6 периода, 1200 Гц, то косинус будет равен половинке и вообще не даст погрешности.

 

так как у Вас достаточно широкий диапазон синтезируемых частот, то целесообразно сделать несколько кратных частот дискретизации, близких к синтезируемым, исходя из указанного соображения.

 

1. Нормально вышло. Точность достаточная для наших практических целей. Хоть и реально меньше, но соответствует 16 разрядам.

2. Частота задаётся статически не правильно, но я с этим разобрался, был формат Q16.16 на предыдущее значение синуса и Q16.16 на коэффициент умножения, сделал коэффициент в Q1.31 стало гораздо точнее.

Но частота по времени плавает чуток - на доли герца, примерно плавает на 0.5Гц с периодом в 0.5-1 секунду при 12345.567Гц требуемой на 192кГц дискретизации. Но это уже не критично, просил для саморазвития. Просто, интересно стало почему плавает. =)

 

 

NСО не приемлем из за большого потребления ресурсов (по памяти не влезло). Всё-таки нужно 18 каналов сделать с разными частотами и фазами каждый. На канал 15-25кбит требуется, в 200кбитный Циклон никак не влазило.

Изменено пользователем Porty

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как проверяли, что плавает то? Может, если через FFT проверяли, то из за плавающего окна FFT плавает результат самого FFT. У меня такое бывало, как раз с DTMF детекторами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как проверяли, что плавает то? Может, если через FFT проверяли, то из за плавающего окна FFT плавает результат самого FFT. У меня такое бывало, как раз с DTMF детекторами.

 

Да, это FFT себя так ведёт когда разница фаз синусоиды относительно окна FFT почти совпадает с разницей в 2 герца, отсюда и колебания по частоте. Повезло значит =) Когда писал компонент для ФФТ не парился и взял готовые генераторы и окна с готовыми примерами которые были вылезаны и отшлифованы так чтоб при параметрах в примере было всё ну идеальнее некуда. :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А с алгоритмом CORDIC - не знакомы? занимает не более 2к ячеек

алгоритмом ньютона я вписался в 200 ячеек на каждый индивидуальный канал + 200 ячеек на мультиплексор с умножителем из 8 дсп блоков на 4 канала, итого на 18 каналов вышло 4 916 ячеек и 36 умножителей. Точность каждого канала -130дб, THD - 0.0001%

Кордик изначально пробовал в NCO - изначально он мне не понравился из за размеров потребляемых ресурсов

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

алгоритмом ньютона я вписался в 200 ячеек на каждый индивидуальный канал + 200 ячеек на мультиплексор с умножителем из 8 дсп блоков на 4 канала, итого на 18 каналов вышло 4 916 ячеек и 36 умножителей. Точность каждого канала -130дб, THD - 0.0001%

Кордик изначально пробовал в NCO - изначально он мне не понравился из за размеров потребляемых ресурсов

 

У меня в корлике разрядность данных была 16. соответственно конвейер состоял из 16 звеньев. Использовал только операции суммирование/вычитание и сдвиг регистров - занимает ресурсов 1700 ячеек (Cyclone I)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня в корлике разрядность данных была 16. соответственно конвейер состоял из 16 звеньев. Использовал только операции суммирование/вычитание и сдвиг регистров - занимает ресурсов 1700 ячеек (Cyclone I)

16 звеньев это 16 независимых по частоте и фазе каналов?

Что такое звено?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 звеньев это 16 независимых по частоте и фазе каналов?

Что такое звено?

 

Советую ознакомиться с алгоритмом CORDIC - там каждая итерация рассчета фазы - одно звено.

Кордик рпссчитывает значение синуса и косинуса для заданного угла...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Cделал такой же генератор, на 14 бит целочисленный с подставкой.

 

Как вы SNR считаете? Я получил сигнал в ModelSim

взял от него DFT (без всяких окон) и просуммировал все по модулю

отфитинговал сигнал синусом

Нашел разницу между синусом и сигналом с ModelSim

Взял DFT от этой разницы и тоже просуммировал модули

Поделил одно на другое 10log(S/N) получилось 16дБл

10 - потомучто интегрирую

 

Как же правильно оценить мой синус?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот мой пример

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.numeric_std.all;

 

entity sinnw is

port (

clk : in std_logic;

reset : in std_logic;

en : in std_logic;

sine : out std_logic_vector(13 downto 0));

 

end sinnw;

 

architecture behave_sine_cos of sinnw is

 

signal sine_s : unsigned(13 downto 0);

 

begin -- behave_sine_cos

 

registers: process (clk, reset)

variable y_1, y_2, sine_m : integer;

variable sine_d : integer;

 

begin -- process registers

if reset = '0' then -- asynchronous reset (active low)

y_1 := 0;

y_2 := -103;

sine <= "00000000000000";

elsif clk'event and clk = '1' then -- rising clock edge

if (en = '1') then

sine_d := 16383*y_1;

sine_m := sine_d/8192-y_2;

y_2 := y_1;

y_1 := sine_m;

sine_s <= to_unsigned(sine_m,14)+ 8192;

sine <= std_logic_vector((sine_s)); --

end if;

end if;

end process registers;

 

end behave_sine_cos;

 

Но только синтезится без встроеного умножителя, поэтому 170 логических элементов

Квартус пишет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2+6*14=86ДБл

Такое примерно число получается если от основной гармоники

генератора отнять палку от референтного синуса и поделить

на референтный синус.

Или то же самое в 3-х сигмах.

Но мне кажется, что честнее весь спектр учитывать. Нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...