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

Добрый день.

Есть 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. Здесь на форуме была немного открыта подобная тема, но что-то она осталась непродолженной...

post-62364-1295863044_thumb.jpg

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


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

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

 

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

 

 

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

AD9767.pdf

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


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

Вроде установил режим работы и подал клок на цап.

 

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. Даташиты ВСЕ у меня есть.

post-62364-1295878932_thumb.jpg

post-62364-1295878948_thumb.jpg

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


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

Вроде установил режим работы и подал клок на цап.

 

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], которые через него попадут на вход ЦАПа.

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


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

Вибирая ПЗУ 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".

 

Где ошибка?

post-62364-1296032748_thumb.jpg

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


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

вот генератор 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

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


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

не. мне не кордика метод нужен.

а какая разница? те же яйца, только памяти ест меньше

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


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

Я понимаю.

Мне вообще изначально посоветовали 2 метода - DDS и алгоритм Кордика. Второй чуть посложнее на логику. Я реализую пока первый.

Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта.

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


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

Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта.

а чего там инициализировать в dual-mode? подайте на все CLK/WRT сигнал с PLL или с инвертора (относительно клока, по которому счетчик/ПЗУ работает). на шине-то сигналы есть?

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


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

Я понимаю.

Мне вообще изначально посоветовали 2 метода - DDS и алгоритм Кордика. Второй чуть посложнее на логику. Я реализую пока первый.

Но, собственно проблема инициализации ЦАП (AD9767), мешает мне получить результат. В общем... тема еще открыта.

 

Вот готовый проект DDS на VHDl.

dds_synthesizer_latest.tar.gz

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


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

Исправил кое-какие недочеты.

1. подал клок на ОБА входа ЦАПа

2. также и с WRT

3. сделал старший бит слова данных старшим битом ЦАПа. Иначе было: LSB слова сопоставлялся LSB ЦАПа и 2 последних MSB ЦАПа выкидывал. Теперь же выкидываются 2 LSB ЦАПа.

 

Результат лучше :-) Однако какие-то непонятные искажения в синусоиде(скрин с осциллографа прикрепил).

Что не так может быть?

post-62364-1296116975_thumb.jpg

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


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

Раза 4 или 5 перепроверял. Думаю с битами в порядке.

Ненужные скачки образуются в области нуля синуса. Как будто приближаясь к нулю, к значению модуля синуса прибавляется некоторое значение...

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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