Skip to content

Problem 02: Clock divider

Viktor Prutyanov edited this page Feb 28, 2019 · 6 revisions

Делитель частоты

В этом задании мы сделаем параметризуемый делитель частоты.

Подготовка

Выберите какое-нибудь число X в интервале [10; 16]. В этом задании мы будем делать делитель частоты на 2^X.

Перейдите в каталог problems/02_clock_div в вашей локальной копии репозитория.

Задача №1

Создайте файл clk_div.v с модулем clk_div. Этот модуль должен иметь один вход для тактового сигнала и один выход для тактового сигнала с частотой в 2^X раз меньше. Например, вот так:

module clk_div(
    input clk,

    output clk_out
);

Напоминание: для того чтобы поделить частоту на 2^X, используйте регистр шириной X и увеличивайте его на 1 внутри always-блока.

Задача №2

Создайте экземпляр модуля и нужные для его работы соединения опишите в файле testbench.v.

Задача №3

В модуле testbench принимается, что период тактового сигнала clk - 2 нс. Подсчитайте, через сколько наносекунд симуляция должна остановиться, чтобы прошло хотя бы несколько тактов поделенной частоты. С помощью директивы $finish реализуйте это.

Задача №4

Скомпилируйте код с помощью make pset02. Запустите симуляцию командой make test. С помощью GTKwave проверьте, что делитель частоты работает.

Задача №5

Попробуйте превратить модуль clk_div в параметризованный модуль.

Предположим, что заголовок модуля выглядел следующим образом:

module clk_div(
    input clk,

    output clk_out
);

Измените первую строку объявления таким образом:

module clk_div #(parameter X = 12)(
    input clk,

    output clk_out
);

Теперь внутри модуля можно пользоваться параметром X. Например, можно сделать разрядность счетчика параметризуемой:

reg [X-1:0]cnt;

Таким образом, можно на этапе создания экземпляра делителя частоты определять, на сколько будет делиться частота:

clk_div #(.X(16)) clk_div(.clk(clk), .clk1(clk_out));

Если создавать экземпляр как раньше, то параметр X будет иметь значение по умолчанию, в данном случае - 12.

Задача №6

Перекомпилируйте код несколько раз с разными значениями делителя, посмотрите на получившиеся сигналы в GTKWave и проверьте, что всё работает.

Вопрос: какой коэффициент заполнения получился у сигнала clk_out при разных значениях параметра?