azizcheg 0 24 января, 2011 Опубликовано 24 января, 2011 · Жалоба Добрый день. Есть 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 0 24 января, 2011 Опубликовано 24 января, 2011 · Жалоба Готовый генератор синуса можно взять здесь: http://opencores.org/projects . Или использовать соответствующие ядро: http://www.altera.com/literature/ug/ug_nco.pdf. Для простоты ну или можно сделать свой собственный, легче взять готовый =).. Насчет клока, на плате THDB-ADA есть перемычки которые задают режим тактирования ЦАПа (с внешнего или внутреннего генератора тактов), если хотите использовать внешний тогда надо поставить перемычку в соответствующие положение и подать с ПЛИСа на выход HSMC нужный тактовый сигнал (надо смотреть по документации куда выводить). Режимы ЦАПа можно посмотреть в даташите (прикрепил), там ничего сложного нет. Выбирается режим (mode), а так же сигналы по которым идет "выброс" значений ЦАПа во внешний мир (WRT1/WRT2) и в параллельным кодом идет сигнал. AD9767.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
azizcheg 0 24 января, 2011 Опубликовано 24 января, 2011 · Жалоба Вроде установил режим работы и подал клок на цап. 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 0 24 января, 2011 Опубликовано 24 января, 2011 · Жалоба Вроде установил режим работы и подал клок на цап. 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. Ага. А что делать с входом моей всей этой системы? По логике там должен быть регистр... Как он называется в квартусе..? ram..? Как подключить после этого выход с ЦАПа на SMA-коннектор? Через "WRT внешний мир"? рам это память. Что значит со входом? Вы работаете на ЦАП, т.е. на выход. Надо в параллель кидать на HSMC данные в формате [13..0], которые через него попадут на вход ЦАПа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
azizcheg 0 26 января, 2011 Опубликовано 26 января, 2011 · Жалоба Вибирая ПЗУ 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". Где ошибка? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 26 января, 2011 Опубликовано 26 января, 2011 · Жалоба вот генератор sin/cos на кордике, на вход дайте пилу со счетчика. разрядность любая до 32 включительно /******************************************************************************** *************/ 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 0 26 января, 2011 Опубликовано 26 января, 2011 · Жалоба не. мне не кордика метод нужен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 26 января, 2011 Опубликовано 26 января, 2011 · Жалоба не. мне не кордика метод нужен. а какая разница? те же яйца, только памяти ест меньше Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
azizcheg 0 26 января, 2011 Опубликовано 26 января, 2011 · Жалоба Я понимаю. Мне вообще изначально посоветовали 2 метода - DDS и алгоритм Кордика. Второй чуть посложнее на логику. Я реализую пока первый. Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 26 января, 2011 Опубликовано 26 января, 2011 · Жалоба Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта. а чего там инициализировать в dual-mode? подайте на все CLK/WRT сигнал с PLL или с инвертора (относительно клока, по которому счетчик/ПЗУ работает). на шине-то сигналы есть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
almost 0 27 января, 2011 Опубликовано 27 января, 2011 · Жалоба Я понимаю. Мне вообще изначально посоветовали 2 метода - DDS и алгоритм Кордика. Второй чуть посложнее на логику. Я реализую пока первый. Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта. Вот готовый проект DDS на VHDl. dds_synthesizer_latest.tar.gz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
azizcheg 0 27 января, 2011 Опубликовано 27 января, 2011 · Жалоба Исправил кое-какие недочеты. 1. подал клок на ОБА входа ЦАПа 2. также и с WRT 3. сделал старший бит слова данных старшим битом ЦАПа. Иначе было: LSB слова сопоставлялся LSB ЦАПа и 2 последних MSB ЦАПа выкидывал. Теперь же выкидываются 2 LSB ЦАПа. Результат лучше :-) Однако какие-то непонятные искажения в синусоиде(скрин с осциллографа прикрепил). Что не так может быть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 27 января, 2011 Опубликовано 27 января, 2011 · Жалоба Что не так может быть? биты перепутаны? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
azizcheg 0 27 января, 2011 Опубликовано 27 января, 2011 · Жалоба Раза 4 или 5 перепроверял. Думаю с битами в порядке. Ненужные скачки образуются в области нуля синуса. Как будто приближаясь к нулю, к значению модуля синуса прибавляется некоторое значение... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 27 января, 2011 Опубликовано 27 января, 2011 · Жалоба а схему гоняли в тестбенче? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться