Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Синтезатор частоты
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
azizcheg
Добрый день.
Есть Altera Cyclone III Starter Board и THDB-ADA. Мне надо научиться работать с этой плиской. Работаю в Quartus II. Сейчас работаю над тестированием работы АЦП и ЦАП. Сперва - ЦАП. Надо на выходе ЦАПа получить синусоиду, которую надо зафиксировать осциллографом. Для этого синус надо подать на цап в цифровом виде...
На THDB-ADA есть AD9767. Подсказали сгенерировать синус на плиске, и подать ее на цап. Сказали попробовать DDS. Почитал про это на 'http://rf.atnn.ru/s6/DDS_1.htm' и еще кое-где. По схеме получается, что на плис я собираю регистр, аккумулятор фазы, ПЗУ, и использую clock на самой плате StarterBoard. И должен отправить всё это на THDB-ADA в ЦАП.
1. Добавил в схему lpm_add_sub и lpm_ff (аккум-р фазы) и lpm_rom (ПЗУ).
2. У пзу есть файл sin_tab.mif, куда я записал в ячейки 90 значений синуса в hexadecimal-формате.
3. На рисунке (см. аттач.) видны все выходы с ПЗУ, которые пойдут с StarterKit через HSMC на THDB-ADA и далее на параллельный вход AD9767.

Как clock_50MHz с платы плиски отправить на THDB-ADA?
И вроде надо как-то энейблить этот цап?

Кто делал или понимает - подскажите.

P.s. Здесь на форуме была немного открыта подобная тема, но что-то она осталась непродолженной...
almost
Готовый генератор синуса можно взять здесь: http://opencores.org/projects . Или использовать соответствующие ядро: http://www.altera.com/literature/ug/ug_nco.pdf. Для простоты ну или можно сделать свой собственный, легче взять готовый =)..

Насчет клока, на плате THDB-ADA есть перемычки которые задают режим тактирования ЦАПа (с внешнего или внутреннего генератора тактов), если хотите использовать внешний тогда надо поставить перемычку в соответствующие положение и подать с ПЛИСа на выход HSMC нужный тактовый сигнал (надо смотреть по документации куда выводить).


Режимы ЦАПа можно посмотреть в даташите (прикрепил), там ничего сложного нет. Выбирается режим (mode), а так же сигналы по которым идет "выброс" значений ЦАПа во внешний мир (WRT1/WRT2) и в параллельным кодом идет сигнал.
azizcheg
Вроде установил режим работы и подал клок на цап.

1. Там два режима - Dual-Mode и Interleaved Timing. Я выбрал Dual. (Как я понял - в этом режиме будут работать оба канала, но использую только канал)
В проекте добавил элемент VCC и отправил на HSMC и далее на DAC_MODE на ЦАПе.
2. Клок. На схеме я понял (виделил соединенными эллипсами), что клок у ЦАПа может быть от SMA, OSC_SMA и PLL_OUT.
Наверно SMA - это внешний клок, который через такой же коннектор подключается к плате. Второй - незнаю. Третий - PLL_OUT - нужный мне вариант - с плиски. Переключается всё это на плате джемпером JP5. Потом это идет к контакту HSMC на THDB-ADA и через него на плис. В итоге - получаю клок с плиски.

А что делать с входом моей всей этой системы? По логике там должен быть регистр... Как он называется в квартусе..? ram..?
Как подключить после этого выход с ЦАПа на SMA-коннектор? Через "WRT внешний мир"?

P.s. Даташиты ВСЕ у меня есть.
almost
Цитата(azizcheg @ Jan 24 2011, 17:26) *
Вроде установил режим работы и подал клок на цап.

1. Там два режима - Dual-Mode и Interleaved Timing. Я выбрал Dual. (Как я понял - в этом режиме будут работать оба канала, но использую только канал)
В проекте добавил элемент VCC и отправил на HSMC и далее на DAC_MODE на ЦАПе.
2. Клок. На схеме я понял (виделил соединенными эллипсами), что клок у ЦАПа может быть от SMA, OSC_SMA и PLL_OUT.
Наверно SMA - это внешний клок, который через такой же коннектор подключается к плате. Второй - незнаю. Третий - PLL_OUT - нужный мне вариант - с плиски. Переключается всё это на плате джемпером JP5. Потом это идет к контакту HSMC на THDB-ADA и через него на плис. В итоге - получаю клок с плиски.


1. Дуал мод это ЦАП работает на два канала параллельно (т.е. лог. 1 на дак_мод).
2. Ага.

Цитата(azizcheg @ Jan 24 2011, 17:26) *
А что делать с входом моей всей этой системы? По логике там должен быть регистр... Как он называется в квартусе..? ram..?
Как подключить после этого выход с ЦАПа на SMA-коннектор? Через "WRT внешний мир"?


рам это память. Что значит со входом? Вы работаете на ЦАП, т.е. на выход. Надо в параллель кидать на HSMC данные в формате [13..0], которые через него попадут на вход ЦАПа.
azizcheg
Вибирая ПЗУ LPM_ROM, в визарде увидел надпись, что этот тип пзу используется в режиме обратной совместимости (Family supports lpm_rom only in backward-capatibility mode). Альтера рекомендует ALTSYNCRAM wizard. Ну ладно, взял. Протестил, работает.

Сделал с нуля.
1. Clock -> Counter 7bit -> AltSyncRAM -> HSMC -> DAC.
2. Т.к. слова в пзу 12-битные, я на 13-й и 14-й разряды ЦАПа заземлил.
3. Использую DUAL-mode, канал А. Для этого подцепил эту ножку к VCC.
4. WRTA и PLL_OUT_DAC0(клок ЦАПа) повесил на Clock 50 Mhz плиски.
5. POWERON заземлил.

Компилировал, зашил. Подключаю осциллограф к sma-коннектору DA-CHANNEL A - пусто... sad.gif

На J8 (GPIO1) нашел ножки DAC_WRTA и PLL_OUT_DAC0. На них есть синусоида (может чуть искаженная). На DAC_MODE - "1".

Где ошибка?
vadimuzzz
вот генератор sin/cos на кордике, на вход дайте пилу со счетчика. разрядность любая до 32 включительно
CODE

/********************************************************************************
*************/
module cordic_rotate
/********************************************************************************
*************/
#(parameter dw = 12)
/********************************************************************************
*************/
(
input clk,
input reset_n,
input signed [dw-1:0] phase,
input signed [dw-1:0] mag,
input dv,
output signed [dw-1:0] sin_out,
output signed [dw-1:0] cos_out,
output out_valid
);
/********************************************************************************
*************/
typedef logic signed [dw:0] d_type;
localparam p_level = dw-1;
localparam odw = dw+1;
localparam d_type atan_table [0:30] =
'{
pr_round(536870912),
pr_round(316933406),
pr_round(167458907),
pr_round(85004756),
pr_round(42667331),
pr_round(21354465),
pr_round(10679838),
pr_round(5340245),
pr_round(2670163),
pr_round(1335087),
pr_round(667544),
pr_round(333772),
pr_round(166886),
pr_round(83443),
pr_round(41722),
pr_round(20861),
pr_round(10430),
pr_round(5215),
pr_round(2608),
pr_round(1304),
pr_round(652),
pr_round(326),
pr_round(163),
pr_round(81),
pr_round(41),
pr_round(20),
pr_round(10),
pr_round(5),
pr_round(3),
pr_round(1),
pr_round(1)
};
/********************************************************************************
*************/
function integer pr_round;
input integer full_data;
logic one;
logic flag;
begin
one = |full_data[2:0];
flag = ( (!full_data[31])&&(full_data[3]) ) || ( (full_data[31])&&(full_data[3])&&(one) );
pr_round = (flag) ? full_data[31:32-dw-1] + 1 : full_data[31:32-dw-1];
end
endfunction
/********************************************************************************
*************/
reg signed [odw-1:0] x[p_level-1:0];
reg signed [odw-1:0] y[p_level-1:0];
reg signed [odw-1:0] z[p_level-1:0];
integer i;
reg [p_level-1:0] valid_reg;
reg flag[p_level-1:0];
/********************************************************************************
*************/
always_ff @(posedge clk)
begin
if (!reset_n) begin
for(i=0;i<p_level;i++) begin
x[i] <= '0;
y[i] <= '0;
z[i] <= '0;
flag[i] <= 1'b0;
end
end
else if ((dv)||(valid_reg[p_level-1])) begin
x[0] <= mag;
y[0] <= '0;
z[0] <= (phase[dw-1]^phase[dw-2]) ? (2**dw)-2*phase: 2*phase;
flag[0] <= phase[dw-1]^phase[dw-2];
for(i=1;i<p_level;i++) begin
if (z[i-1]<0) begin
x[i] <= x[i-1] + (y[i-1]>>>i);
y[i] <= y[i-1] - (x[i-1]>>>i);
z[i] <= z[i-1] + atan_table[i];
end
else begin
x[i] <= x[i-1] - (y[i-1]>>>i);
y[i] <= y[i-1] + (x[i-1]>>>i);
z[i] <= z[i-1] - atan_table[i];
end
flag[i] <= flag[i-1];
end
end
end
/********************************************************************************
*************/
always_ff @(posedge clk)
begin
if (!reset_n) begin
for(i=0;i<p_level;i++) begin
valid_reg[i] <= 1'b0;
end
end
else begin
valid_reg[0] <= dv;
for(i=1;i<p_level;i++) begin
valid_reg[i] <= valid_reg[i-1];
end
end
end
/********************************************************************************
*************/
assign sin_out = y[p_level-1][odw-1:odw-dw];
assign cos_out = (flag[p_level-1]) ? -$signed(x[p_level-1][odw-1:odw-dw]) : x[p_level-1][odw-1:odw-dw];
assign out_valid = valid_reg[p_level-1];
/********************************************************************************
*************/
endmodule
azizcheg
не. мне не кордика метод нужен.
vadimuzzz
Цитата(azizcheg @ Jan 26 2011, 18:28) *
не. мне не кордика метод нужен.

а какая разница? те же яйца, только памяти ест меньше
azizcheg
Я понимаю.
Мне вообще изначально посоветовали 2 метода - DDS и алгоритм Кордика. Второй чуть посложнее на логику. Я реализую пока первый.
Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта.
vadimuzzz
Цитата(azizcheg @ Jan 26 2011, 19:43) *
Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта.

а чего там инициализировать в dual-mode? подайте на все CLK/WRT сигнал с PLL или с инвертора (относительно клока, по которому счетчик/ПЗУ работает). на шине-то сигналы есть?
almost
Цитата(azizcheg @ Jan 26 2011, 16:43) *
Я понимаю.
Мне вообще изначально посоветовали 2 метода - DDS и алгоритм Кордика. Второй чуть посложнее на логику. Я реализую пока первый.
Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта.


Вот готовый проект DDS на VHDl.
azizcheg
Исправил кое-какие недочеты.
1. подал клок на ОБА входа ЦАПа
2. также и с WRT
3. сделал старший бит слова данных старшим битом ЦАПа. Иначе было: LSB слова сопоставлялся LSB ЦАПа и 2 последних MSB ЦАПа выкидывал. Теперь же выкидываются 2 LSB ЦАПа.

Результат лучше :-) Однако какие-то непонятные искажения в синусоиде(скрин с осциллографа прикрепил).
Что не так может быть?
vadimuzzz
Цитата(azizcheg @ Jan 27 2011, 14:29) *
Что не так может быть?

биты перепутаны?
azizcheg
Раза 4 или 5 перепроверял. Думаю с битами в порядке.
Ненужные скачки образуются в области нуля синуса. Как будто приближаясь к нулю, к значению модуля синуса прибавляется некоторое значение...
vadimuzzz
а схему гоняли в тестбенче?
azizcheg
Блин. Так и есть. Перепутал пин.
Есть синус на выходе! sm.gif
azizcheg
После того, как получил посредством DDS синус на SMA-коннекторе DA-channel-A, сразу же его послал на SMA-вход AD-channel-A AD9248. У ацп установил "0" на OEB_A и клок как и у всей системы. POWERON, как я понял, если включен у ЦАП, значит и у АЦП тоже включен(по схеме вроде так). Вых. шину соединил с вх. шиной "B" ЦАПа.
Но на выходе DA-channel-B что-то не синусное, но "частички" синуса по-моему там есть. (прикрепил рисунок с осциллографа).
Пробовал менять соответствие MSB и LSB - ничего...
Есть догадки?
DmitryR
Unsigned воспринимается как signed.
azizcheg
Цитата(DmitryR @ Feb 1 2011, 12:39) *
Unsigned воспринимается как signed.

А можно немного популярнее? Просто подавая сигнал с одной шины на другую я же не могу учитывать или менять это "sign"
ViKo
Цитата(azizcheg @ Jan 27 2011, 11:46) *
Блин. Так и есть. Перепутал пин.
Есть синус на выходе! sm.gif

Снова то же. Только с более старшим разрядом. Или с самым старшим. Паяете хорошо?
DmitryR
Цитата(azizcheg @ Feb 1 2011, 14:51) *
А можно немного популярнее? Просто подавая сигнал с одной шины на другую я же не могу учитывать или менять это "sign"

Если у вас один блок выдает например синусоиду 16 bit unsigned (0-65535), а другой блок на входе хочет 16 bit signed (-32768 - 32767) то что надо сделать? Правильно, вычесть 32768 по дороге.
azizcheg
Цитата(DmitryR @ Feb 1 2011, 15:16) *
Правильно, вычесть 32768 по дороге.

А может прибавить? sm.gif если верить математике...

Цитата(ViKo @ Feb 1 2011, 15:13) *
Паяете хорошо?

Не паяю же. Всё спаяно и готовое на плате с разъемами и коннекторами.
ViKo
Цитата(azizcheg @ Feb 1 2011, 14:46) *
А может прибавить? если верить математике...
Не паяю же. Всё спаяно и готовое на плате с разъемами и коннекторами.

Старший бит могли и самом проекте потерять
azizcheg
Проблема вылезает вот где.
АЦП не задействован.
При подаче сигнала DDS на ЦАП DA-channel-A появляется нормальный синус. Параллельно, этот же сигнал отправляя на DA-channel-B - появляется сдвиги. Похоже на то, что и говорили вы про signed и unsigned.
Вот что написано в даташите к ЦАПу.
Цитата
DAC TRANSFER FUNCTION
Both DACs in the AD9767 provide complementary current outputs, IOUTA and IOUTB. IOUTA provides a near full-scale current output (IOUTFS) when all bits are high (for example, DAC CODE = 16383), while IOUTB, the complementary output, provides no current. The current output appearing at IOUTA and IOUTB is a function of both the input code and IOUTFS and can be expressed as
IOUTA = (DAC CODE/16384) × IOUTFS (1)
IOUTB = (16383 – DAC CODE)/16384) × IOUTFS (2)
where DAC CODE = 0 to 16383 (decimal representation).

Только вот не разберусь, сколько прибавлять? или отнимать...
На скрине сверху - DA-channel-A, снизу - DA-channel-B.
ViKo
Думаю, у вас в проекте переполнение числа происходит. Нужно иметь на один разряд больше. Ну, и подавать, соответственно, на разряд сдвинутые выходы на DAC.
azizcheg
Цитата(ViKo @ Feb 1 2011, 17:37) *
Думаю, у вас в проекте переполнение числа происходит.

Не думаю. Переполнение сказывалось бы и на канал "A".
Сделал новый проект, где слова - 11-разрядные(скрин ниже). Всё равно не то. wacko.gif
ViKo
Цитата(azizcheg @ Feb 1 2011, 16:59) *
Сделал новый проект, где слова - 11-разрядные(скрин ниже).

А к-т отклонения в каналах осциллографа у вас одинаковый в обоих каналах? Второй сигнал должен был бы иметь амплитуду в 2 раза больше первого.
Все, увидел, разные коэффициенты.
А вы поменяйте местами, что подаете в ЦАПы.
vadimuzzz
Цитата(azizcheg @ Feb 1 2011, 20:20) *
Только вот не разберусь, сколько прибавлять? или отнимать...

старший бит инвертировать
ViKo
Цитата(vadimuzzz @ Feb 1 2011, 17:12) *
старший бит инвертировать

Нет, он там постоянно в одном (нулевом, надо думать) состоянии.
vadimuzzz
Цитата(ViKo @ Feb 1 2011, 21:24) *
Нет, он там постоянно в одном (нулевом, надо думать) состоянии.

если ТС покажет/посмотрит сам сигналы в цифровом виде (в том же сигналтапе), то вопросы отпадут.
ViKo
Цитата(vadimuzzz @ Feb 1 2011, 17:40) *
если ТС покажет/посмотрит сам сигналы в цифровом виде (в том же сигналтапе), то вопросы отпадут.

по картинке видно
azizcheg
Цитата(ViKo)
А вы поменяйте местами, что подаете в ЦАПы.

ЦАП у меня один. Каналы разные. А сигнал один и и тот же и подается параллельно на оба канала ЦАПа.

Цитата(vadimuzzz)
если ТС покажет/посмотрит сам сигналы в цифровом виде (в том же сигналтапе), то вопросы отпадут.

Это что-то типа vecotr waveform? Я не смог там просимулировать систему.
vadimuzzz
сигналтап - это логический анализатор
http://www.altera.com/literature/hb/qts/qts_qii53009.pdf
но в вашем случае, пожалуй, избыточен. а вот тестбенч в моделсиме или хотя бы примитивная диаграмка в waveform viewer жизненно необходимы
ViKo
Цитата(azizcheg @ Feb 2 2011, 08:21) *
ЦАП у меня один. Каналы разные. А сигнал один и и тот же и подается параллельно на оба канала ЦАПа.

Если сигнал один и тот же, так ПЛИС при чем? Потеряли бит по дороге между ПЛИС и одним из ЦАП. Про пайки я уже спрашивал... прозвоните соединения.
Там еще такты есть, может, в них что не так?
azizcheg
Просимулировал. Все такты на месте. Биты каналов ЦАПа один-в-один совпадают. Значит сам ЦАП как-то неправильно, или неодинаково их переводит.
ViKo
Цитата(azizcheg @ Feb 2 2011, 10:03) *
Просимулировал. Все такты на месте. Биты каналов ЦАПа один-в-один совпадают. Значит сам ЦАП как-то неправильно, или неодинаково их переводит.

И какие новости за прошедшие два дня?
azizcheg
Цитата(ViKo @ Feb 4 2011, 10:30) *
И какие новости за прошедшие два дня?

Ничего хорошего sad.gif
Перечитал еще и еще раз pdf'ку на ЦАП. Вроде два абсолютно одинаковых канала (по сути два параллельно работающих ЦАПа). В оба отправляю одни и те же данные - и всё равно на канале "B" искажение. Пробовал и разрядность менять. Не могу понять и поведение сигнала. Что происходит с ним? Переполнение, обрезка, потеря..?
Что касается симулятора. Сначала сделал режим "Functional", потом "Timing". В функц-м режиме всё так, как должно выглядеть. Сверял по таблице синусов. Т.к. это сигнал на ПЛИС, то возможно искажения появляются после этого (ближе к самому ЦАПу или же в нем). Во втором режиме вообще интересно. Ладно то, что не все биты одновременно приходят. Но там вообще не те биты, которые нужны. Из рисунка видно, что сигналы несколько раз "попрыгают", а потом старшие переходят в "1", младшие в "0", а средние так и прыгают с частотой, равной половине тактовой...
Не понятно.
Мысль, что может быть дефект при пайке отпадает.
ViKo
Цитата(azizcheg @ Feb 4 2011, 14:32) *
Ничего хорошего sad.gif

Так на картинках такты у вас гигагерцовые! Скромнее надо быть в своих желаниях. sm.gif
azizcheg
Упс. Ошибочка вышла.
Исправил. И теперь показания и в "timing", и в "functional" одинаковые. В обоих каналах ЦАПа одинаковые биты.

Но это всё на плиске. Т.е. на ее выходе. А вот то, что происходит при попадании этого всего на ЦАП - происходит непонятое...
ViKo
Цитата(azizcheg @ Feb 7 2011, 09:12) *
Упс. Ошибочка вышла.
Исправил. И теперь показания и в "timing", и в "functional" одинаковые. В обоих каналах ЦАПа одинаковые биты.

Теперь вам нужно удостовериться, что выполняются все временные требования для ЦАП - частота тактов, времена предустановки и удержания и т.п.
azizcheg
По логике вещей - если для одного канала соблюдаются - значит и для другого должны быть...

Я пошел искусственным путем.
Я проанализировал синусоиду второго канала. Как я понял - полупериоды были смещены отн-но оси Х. Верхняя часть - вниз, а нижняя - вверх.
Что я сделал. Я добавил компаратор и сумматор. Если значение выше оси Х - отнимал 5000(dec), если ниже - прибавлял 5000. Т.е. сместил полупериоды друг относительно друга.
ViKo
Цитата(azizcheg @ Feb 7 2011, 10:54) *
Я проанализировал синусоиду второго канала. Как я понял - полупериоды были смещены отн-но оси Х. Верхняя часть - вниз, а нижняя - вверх.

Неправильно поняли (как и vadimuzzz чуть раньше). Поднимите верхнюю полуволну вверх - получите синус. Ваш старший бит все время в нуле. Или все время в единице.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.