|
Синтезатор частоты, Как задействовать ЦАП? |
|
|
|
Jan 24 2011, 11:09
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 20-01-11
Из: Махачкала
Пользователь №: 62 364

|
Добрый день. Есть 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. Здесь на форуме была немного открыта подобная тема, но что-то она осталась непродолженной...
Эскизы прикрепленных изображений
|
|
|
|
|
Jan 24 2011, 11:27
|
Частый гость
 
Группа: Свой
Сообщений: 199
Регистрация: 27-05-09
Из: Москва
Пользователь №: 49 648

|
Готовый генератор синуса можно взять здесь: http://opencores.org/projects . Или использовать соответствующие ядро: http://www.altera.com/literature/ug/ug_nco.pdf. Для простоты ну или можно сделать свой собственный, легче взять готовый =).. Насчет клока, на плате THDB-ADA есть перемычки которые задают режим тактирования ЦАПа (с внешнего или внутреннего генератора тактов), если хотите использовать внешний тогда надо поставить перемычку в соответствующие положение и подать с ПЛИСа на выход HSMC нужный тактовый сигнал (надо смотреть по документации куда выводить). Режимы ЦАПа можно посмотреть в даташите (прикрепил), там ничего сложного нет. Выбирается режим (mode), а так же сигналы по которым идет "выброс" значений ЦАПа во внешний мир (WRT1/WRT2) и в параллельным кодом идет сигнал.
Прикрепленные файлы
AD9767.pdf ( 2.45 мегабайт )
Кол-во скачиваний: 26
|
|
|
|
|
Jan 24 2011, 14:26
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 20-01-11
Из: Махачкала
Пользователь №: 62 364

|
Вроде установил режим работы и подал клок на цап. 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. Даташиты ВСЕ у меня есть.
Эскизы прикрепленных изображений
|
|
|
|
|
Jan 24 2011, 16:04
|
Частый гость
 
Группа: Свой
Сообщений: 199
Регистрация: 27-05-09
Из: Москва
Пользователь №: 49 648

|
Цитата(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], которые через него попадут на вход ЦАПа.
|
|
|
|
|
Jan 26 2011, 09:47
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 20-01-11
Из: Махачкала
Пользователь №: 62 364

|
Вибирая ПЗУ 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 - пусто...  На J8 (GPIO1) нашел ножки DAC_WRTA и PLL_OUT_DAC0. На них есть синусоида (может чуть искаженная). На DAC_MODE - "1". Где ошибка?
Эскизы прикрепленных изображений
|
|
|
|
|
Jan 26 2011, 10:05
|

Гуру
     
Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988

|
вот генератор 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
|
|
|
|
|
Jan 26 2011, 12:28
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 20-01-11
Из: Махачкала
Пользователь №: 62 364

|
не. мне не кордика метод нужен.
|
|
|
|
|
Jan 26 2011, 13:43
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 20-01-11
Из: Махачкала
Пользователь №: 62 364

|
Я понимаю. Мне вообще изначально посоветовали 2 метода - DDS и алгоритм Кордика. Второй чуть посложнее на логику. Я реализую пока первый. Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта.
|
|
|
|
|
Jan 27 2011, 06:05
|
Частый гость
 
Группа: Свой
Сообщений: 199
Регистрация: 27-05-09
Из: Москва
Пользователь №: 49 648

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

Группа: Участник
Сообщений: 56
Регистрация: 20-01-11
Из: Махачкала
Пользователь №: 62 364

|
Исправил кое-какие недочеты. 1. подал клок на ОБА входа ЦАПа 2. также и с WRT 3. сделал старший бит слова данных старшим битом ЦАПа. Иначе было: LSB слова сопоставлялся LSB ЦАПа и 2 последних MSB ЦАПа выкидывал. Теперь же выкидываются 2 LSB ЦАПа. Результат лучше :-) Однако какие-то непонятные искажения в синусоиде(скрин с осциллографа прикрепил). Что не так может быть?
Эскизы прикрепленных изображений
|
|
|
|
|
Jan 27 2011, 09:28
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 20-01-11
Из: Махачкала
Пользователь №: 62 364

|
Раза 4 или 5 перепроверял. Думаю с битами в порядке. Ненужные скачки образуются в области нуля синуса. Как будто приближаясь к нулю, к значению модуля синуса прибавляется некоторое значение...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|