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

Первый проект делителя частоты в Quartus

Здравствуйте! Только начинаю знакомиться с тем, что такое ПЛИС и как заставить её работать. В процессе ознакомления возникает много вопросов.

После прочтения основ по простейшим логическим элементам, триггерам и составлению из них регистров/счётчиков, решил перейти непосредственно к практике и попробовать написать маленький проектик в пакете Quartus II. Программировать решил на Verilog'e, т.к. он мне показался наиболее интуитивно понятным.

 

Первый мой опыт - реализация делителя частоты:

 

// Делитель частоты на 10 [f/10]
// Получение от кварцевого резонатора частотой 28 МГц частоту 2,8 МГц

module freq_2800
(
    clk,
    freq_2800
);

input clk;
output freq_2800;

reg out = 0;
reg [2:0] count = 0;

always @ (negedge clk)
    begin
        if (count == 3'b100)
            begin
                count <= 0;
                out <= !out;
            end
        else count <= count + 1'b1;
    end

assign freq_2800 = out;

endmodule

Сделал симуляцию в Квартусе (до МоделСим руки не дошли). Вроде как, программа работает корректно, хотя сомневаюсь, что сам код оптимален.

 

Вопрос возник вот в чём: структурную схему проекта можно посмотреть в Tools/Netlist Viewers/RTL Viewer.

Захотелось понять как эта программа выглядит на логических элементах и триггерах и тут у меня пока тупик. Не совсем понятно как Квартус это реализует, синхронный счётчик на каких триггерах он реализует (JK или D) и вообще как эта программа выглядит в виде схемы.

 

Заранее спасибо всем откликнувшимся!

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


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

Вопрос возник вот в чём: структурную схему проекта можно посмотреть в Tools/Netlist Viewers/RTL Viewer.

Захотелось понять как эта программа выглядит на логических элементах и триггерах и тут у меня пока тупик. Не совсем понятно как Квартус это реализует, синхронный счётчик на каких триггерах он реализует (JK или D) и вообще как эта программа выглядит в виде схемы.

 

Заранее спасибо всем откликнувшимся!

Это не структурная схема, это как раз то что Вам нужно. Я. правда, предпочитаю "technology map viewer", но суть одна. Просто нужно более детализировать вид. Cначала Вам показываются блоки. Наводите на интересующий блок правой кнопкой мыши и выбираете "display contents" или "hierarchy down"

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


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

А где посмотреть, из чего состоят такие элементы, как LESS_THAN, ADDER, EQUAL ?

elementsy.gif

 

Видимо, триггеры, сумматоры и элементы LESS_THAN и EQUAL реализуются в логическом элементе (LE) с помощью таблицы LUT и триггера.

 

счётчик на каких триггерах он реализует (JK или D)

В Квартусе, судя по "technology map viewer" и RTL Viewer именно Д-триггеры.

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

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


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

RTL Viewer - это результат синтеза Вашего кода в элементный базис общего вида.

Technology Map Viewer - это результат синтеза Вашего кода в элементный базис выбранной Вами ПЛИСки (той, которую вы выбрали в Assignments->Device).

 

В ПЛИС используются D-триггеры. Соответственно, все вариации (JK/RS/T) триггеров реализуются также на D-триггерах с логической обвязкой, приводящий функционирование D-триггера к заданному (JK/SR/T).

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


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

Пацаев и spectr, спабо вам за ответы.

 

Посмотрел что мне выдаёт Technology Map Viewer в Квартусе и немного ужаснулся. Даже моих очень поверхностных знаний цифровой логики хватило, чтобы понять, что там присутсвует избыточность логических элементов и всё это можно реализовать проще.

 

Не подскажите в чем дело: в написании самого кода на verilog или в интерпритации этого кода Квартусом?

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


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

В написании кода.

Можно вместо

if (count == 3'b100)

поставить

if (count[2])

.

Константу 3'b100 где-то хранить надо, а потом еще сравнивать. А интересует только 1 в старшем разряде.

При ее появлении регистр же обнуляется, кода 3'b101 там не будет :)

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


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

Посмотрел что мне выдаёт Technology Map Viewer в Квартусе и немного ужаснулся. Даже моих очень поверхностных знаний цифровой логики хватило, чтобы понять, что там присутсвует избыточность логических элементов и всё это можно реализовать проще.

 

Не подскажите в чем дело: в написании самого кода на verilog или в интерпритации этого кода Квартусом?

 

Вот пример выдачи Technology Map Viewera:

post-1437-1296722490_thumb.png

Видимо, говоря об избыточности логики, Вы имели в виду что-то наподобие того, что раскрыто в синем блоке. А синий блок - это не что иное как программируемая LUT-таблица ячейки ПЛИС, и все эти внутренности получены путем синтеза таблицы истинности, реализующей требуемую логику. Technology Map Viewer же позволяет посмотреть как использована эта таблица (какая логическая функция на ней реализована после синтеза) в более-менее человекопонятном виде (хотя можно посмотреть и саму таблицу истинности, вплоть до Карты Карно (правый клик на синем блоке -> Properties -> Truth Table / Karnaugh Map).

 

По поводу интерпретации кода Квартусом. Конечно, лучше стараться писать достаточно оптимальную логику - это приведет к более предсказуемым результатам. :) Но по большому счету современные синтезаторы - достаточно умная штука и в большинстве случаев они сделают все вполне приемлемо.

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


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

reg out = 0;

reg [2:0] count = 0;

И, насколько понимаю, установка начальных значений регистров используется только для симуляции, синтезатор же такое не ест. После заливки в ПЛИС кода содержимое регистров не обязательно будет нулевым, поэтому нужно вводить сигнал сброса там, где это нужно.

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


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

И, насколько понимаю, установка начальных значений регистров используется только для симуляции, синтезатор же такое не ест. После заливки в ПЛИС кода содержимое регистров не обязательно будет нулевым, поэтому нужно вводить сигнал сброса там, где это нужно.

Согласен с Пацаев, для altera, насколько я помню, по умолчанию 1.

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

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


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

для altera, насколько я помню, по умолчанию 1.

насколько я помню, 0.

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


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

У Альтеры все триггеры в исходном состоянии сидят в нуле, если это принудительно не оговорено логикой проекта (ноль на входе PRN триггера).

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


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

ViKo, spectr, правы, документацию сейчас перечитал специально.
Изменено пользователем bogaev_roman

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


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

Вот пример выдачи Technology Map Viewera:

post-1437-1296722490_thumb.png

Видимо, говоря об избыточности логики, Вы имели в виду что-то наподобие того, что раскрыто в синем блоке. А синий блок - это не что иное как программируемая LUT-таблица ячейки ПЛИС, и все эти внутренности получены путем синтеза таблицы истинности, реализующей требуемую логику. Technology Map Viewer же позволяет посмотреть как использована эта таблица (какая логическая функция на ней реализована после синтеза) в более-менее человекопонятном виде (хотя можно посмотреть и саму таблицу истинности, вплоть до Карты Карно (правый клик на синем блоке -> Properties -> Truth Table / Karnaugh Map).

 

По поводу интерпретации кода Квартусом. Конечно, лучше стараться писать достаточно оптимальную логику - это приведет к более предсказуемым результатам. :) Но по большому счету современные синтезаторы - достаточно умная штука и в большинстве случаев они сделают все вполне приемлемо.

Да, именно в них! Спасибо, после этого объяснения в голове наступает некоторое прояснение...

 

И, насколько понимаю, установка начальных значений регистров используется только для симуляции, синтезатор же такое не ест. После заливки в ПЛИС кода содержимое регистров не обязательно будет нулевым, поэтому нужно вводить сигнал сброса там, где это нужно.

Не подскажите как это должно выглядеть в виде кода Verilog?

 

 

Наконец-то разобрался с картами карно и решил графическим способом изобразить двоично-десятичный счётчик, который был разобран в этой статье:

http://pspicelib.narod.ru/10_Compone...chapter3/7.htm

Пересчитал всё изначально сам. С написанным в статье полученные результаты для ножек J и K JK-триггера совпали. Нашёл только одну незначащую для конечного рещультата опечатку в таблице. Рисую схему в схемном редакторе Квартуса. Задаю тактовую и запускаю временную симуляцию...

Вообщем, счётчик почему-то не работает =((( Вместо меандра имею крестики. Это, как я понимаю, не может определить значение выходов q1 - q4 =((

Не подскажете почему так??? Хотел попробовать реализовать эту схему на AHDL, но пока ещё в нём не разобрался (((

 

 

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


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

Не подскажите как это должно выглядеть в виде кода Verilog?

Примерно так:

always @(posedge clk)
if (rst) cnt<=0;
else ....

При уровне rst=1 и фронте clk присваивается начальное значение счетчика равным 0. Ну а в остальных случаях он работает согласно заданному алгоритму.

Вообщем, счётчик почему-то не работает =((( Вместо меандра имею крестики. Это, как я понимаю, не может определить значение выходов q1 - q4 =((

Кресты возможно из-за того, что Вы не задали начальное значение для каждого триггера. И лично мне не понятно, как Вы реализуете в схемном редакторе схемы с JK-триггерами, если в ПЛИС есть только D-триггеры, а остальные получаются из них посредством обвязки? Или там готовая библиотека JK-триггера?

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


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

Опять наткнулся на проблему: есть кварц 28 МГц от когорого тактируется ПЛИС, на выходе нужно получить частоту 50 кГц в форме меандра и точно такую же частоту, только в зависимости от команды сдвинутую на x/10 относительно длительности импульса исходного сигнала.

В итоге из 28 МГц я получаю 50 кГц, так же вывожу опоруную частоту 1 МГц в форме меандра (50 кГц * 20) относительно которой я буду осуществлять сдвиг и, соответственно саму сдвинутую по оси Х частоту 50 кГц.

 

// ----------------------------------------------------------------------------------------
// Из тактовой частоты 28 МГц получаем на выходе 2 частоты (50 кГц и 1 МГц) в форме меандра
// ----------------------------------------------------------------------------------------
module frequency_1
(
    clk,
    freq_1,
    freq_1_div_20,
    freq_1_shift
);

input clk;
output freq_1;
output freq_1_div_20;
output freq_1_shift;

reg [8:0] count_1 = 0;
reg out_1 = 0;
reg [3:0] count_2 = 0;
reg out_2 = 0;
reg [3:0] count_3 = 0;
reg out_3 = 0;

// ----------------------------------------------------------------------------------------
// Получение на выходе частоты 50 кГц в форме меандра [clk/560]
// ----------------------------------------------------------------------------------------
always @ (negedge clk)
    begin
        if (count_1 == 9'b1_0001_0111)
            begin
                count_1 <= 0;
                out_1 <= !out_1;
            end
        else count_1 <= count_1 + 1'b1;
    end

// ----------------------------------------------------------------------------------------
// Получение на выходе частоты 1 МГц в форме меандра [clk/28]
// ----------------------------------------------------------------------------------------
always @ (negedge clk)
    begin
        if (count_2 == 4'b1101)
            begin
                count_2 <= 0;
                out_2 <= !out_2;
            end
        else count_2 <= count_2 + 1'b1;
    end

// ----------------------------------------------------------------------------------------
// Получение на выходе частоты freq_1_shift с заданным сдвигом относительно freq_1
// ----------------------------------------------------------------------------------------
always @ (negedge freq_1_div_20)
    begin
        if (count_3 < 4'b0010)
            out_3 <= !out_1;
        else if (count_3 == 4'b0010)
            out_3 <= out_1;
        else if (count_3 == 4'b1010)
            begin
                out_3 <= !out_1;
                count_3 <= 0;
            end
        else count_3 <= count_3 + 1'b1;
    end
        
// ----------------------------------------------------------------------------------------
assign freq_1 = out_1;
assign freq_1_div_20 = out_2;
assign freq_1_shift = out_3;

endmodule

 

К сожалению, сдвинутой частоты во временном анализе я не получаю :cranky: :wacko: Подскажите пожалуйста, что не так делаю...

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


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

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

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

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

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

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

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

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

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

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