В этом примере для CPLD MAX II EPM240T100C5 реализован простой двоичный счётчик. На линейку из 7 светодиодов выводятся числа от 0 до 7 в двоичном виде.
Например, число 3 в двоичном виде выглядит так:
0000011
Это значит, что включены два младших светодиода:
LED[0] и LED[1].
Остальные светодиоды выключены.
CLK0, который в Quartus назначен
на ножку PIN_12. Семь светодиодов подключены к выводам
PIN_15 ... PIN_21.
module top (
input wire CLK0,
output wire [6:0] LED
);
// Делитель частоты.
// Он нужен, чтобы переключение светодиодов было видно глазами.
reg [25:0] div_cnt = 26'd0;
// Основной счётчик числа от 0 до 7.
reg [2:0] number = 3'd0;
always @(posedge CLK0) begin
// Считаем такты входного генератора CLK0.
div_cnt <= div_cnt + 26'd1;
// Когда div_cnt переполняется и снова становится 0,
// меняем число на светодиодах.
if (div_cnt == 26'd0) begin
if (number == 3'd7)
number <= 3'd0;
else
number <= number + 3'd1;
end
end
// Вывод числа на 7 светодиодов.
// LED[0] — младший бит.
// LED[1] — второй бит.
// LED[2] — третий бит.
// LED[3]...LED[6] всегда равны 0.
assign LED = {4'b0000, number};
// Если на плате светодиоды включаются логическим 0,
// строку выше нужно закомментировать,
// а строку ниже раскомментировать:
// assign LED = ~{4'b0000, number};
endmodule
В Pin Planner нужно назначить вход тактирования CLK0 и семь выходов
для светодиодов. Для данного примера используются следующие ножки микросхемы
MAX II EPM240T100C5:
| Сигнал в Verilog | Направление | Назначение | Ножка MAX II | I/O Standard |
|---|---|---|---|---|
CLK0 |
Input | Тактовый вход | PIN_12 |
3.3-V LVTTL |
LED[6] |
Output | Седьмой светодиод | PIN_15 |
3.3-V LVTTL |
LED[5] |
Output | Шестой светодиод | PIN_16 |
3.3-V LVTTL |
LED[4] |
Output | Пятый светодиод | PIN_17 |
3.3-V LVTTL |
LED[3] |
Output | Четвёртый светодиод | PIN_18 |
3.3-V LVTTL |
LED[2] |
Output | Третий светодиод | PIN_19 |
3.3-V LVTTL |
LED[1] |
Output | Второй светодиод | PIN_20 |
3.3-V LVTTL |
LED[0] |
Output | Первый светодиод, младший бит | PIN_21 |
3.3-V LVTTL |
module top (
input wire CLK0,
output wire [6:0] LED
);
Это главный модуль проекта. Вход CLK0 используется как тактовый сигнал.
Выход LED[6:0] управляет семью светодиодами.
Выходы светодиодов идут от младшего бита к старшему:
LED[0] — первый светодиод, младший бит
LED[1] — второй светодиод
LED[2] — третий светодиод
LED[3] — четвёртый светодиод
LED[4] — пятый светодиод
LED[5] — шестой светодиод
LED[6] — седьмой светодиод
reg [25:0] div_cnt = 26'd0;
Тактовый сигнал CLK0 работает быстро. Если менять число на светодиодах
на каждом такте, переключение будет слишком быстрым и глазами его не будет видно.
Поэтому используется счётчик div_cnt. Он считает такты входного генератора
и замедляет переключение светодиодов.
reg [2:0] number = 3'd0;
Переменная number — это основной счётчик. Он имеет размер 3 бита.
Три бита позволяют хранить числа от 0 до 7:
000 = 0
001 = 1
010 = 2
011 = 3
100 = 4
101 = 5
110 = 6
111 = 7
always @(posedge CLK0) begin
div_cnt <= div_cnt + 26'd1;
if (div_cnt == 26'd0) begin
if (number == 3'd7)
number <= 3'd0;
else
number <= number + 3'd1;
end
end
Этот блок выполняется на каждом положительном фронте тактового сигнала
CLK0. Сначала увеличивается счётчик задержки div_cnt.
Когда div_cnt переполняется и снова становится равным нулю,
увеличивается значение number.
Если number дошёл до 7, он снова сбрасывается в 0.
Поэтому счёт идёт по кругу:
0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 → 0 → ...
assign LED = {4'b0000, number};
У нас есть 7 светодиодов, а число занимает только 3 бита. Поэтому к числу слева добавляются четыре нуля.
Фигурные скобки { } в Verilog означают объединение битов.
Например, если:
number = 3'b011
Тогда:
{4'b0000, number} = 7'b0000011
То есть на светодиоды выводится двоичное число 3.
На некоторых платах светодиоды включаются не логической единицей, а логическим нулём. В таком случае строка:
assign LED = {4'b0000, number};
должна быть заменена на:
assign LED = ~{4'b0000, number};
Символ ~ означает инверсию всех битов.
top.v.top как верхний модуль проекта.CLK0 на PIN_12.LED[6] на PIN_15.LED[5] на PIN_16.LED[4] на PIN_17.LED[3] на PIN_18.LED[2] на PIN_19.LED[1] на PIN_20.LED[0] на PIN_21.3.3-V LVTTL.
Ток выхода в Quartus может быть указан как 16mA default.
CPLD получает тактовый сигнал на вход CLK0. Делитель частоты замедляет
переключение, чтобы его было видно глазами. После каждого переполнения делителя
число number увеличивается на единицу. Значение number
выводится на младшие три светодиода в двоичном виде.
number = 0 → LED = 0000000
number = 1 → LED = 0000001
number = 2 → LED = 0000010
number = 3 → LED = 0000011
number = 4 → LED = 0000100
number = 5 → LED = 0000101
number = 6 → LED = 0000110
number = 7 → LED = 0000111