Skip to content

ПЛИС I: Tang Primer 25K и первый Verilog

Паспорт модуля

ПараметрЗначение
Аудитория🔴 (🟡 — по готовности после М13); пройдены М5–М8
Аутентичная задачаосвоить цикл «код → симуляция → синтез → плата», чтобы в М16–М17 перенести на ПЛИС уже построенную машину
Объём4 занятия × 90 мин
ОборудованиеSipeed Tang Primer 25K (Gowin GW5A-25) с док-платой, Gowin EDA (или открытый тулчейн Yosys/Apicula — проверить поддержку GW5A на момент запуска), Icarus Verilog + GTKWave, кнопки/светодиоды дока
ОграниченияI/O ПЛИС — 3,3 В, к 5-В макетке не подключать напрямую; частоты и назначение выводов — строго по документации платы (constraints-файл комплекта)
Аутентичная задача. После модуля обучающиеся смогут: описать, просимулировать и прошить в ПЛИС синхронную схему с кнопочным вводом — и объяснить, чем always @(posedge clk) отличается от строки программы.

Цели

Обучающиеся …Блум—АндерсонМиллерПроверка
1различают комбинационное (assign, always @*) и последовательностное (posedge) описаниепониматьзнаетквиз + разбор чужого кода
2проходят полный маршрут: RTL → тестбенч → волны → синтез → платаприменятьпоказывает как«дыхание» светодиода на плате
3реализуют делитель частоты и счётчик с индикациейприменятьпоказывает каксекундный счётчик на светодиодах
4вводят кнопку через двухтриггерный синхронизатор и антидребезгприменятьпоказывает каксчётчик нажатий: N нажатий = N приращений

Путь и ядро

ТемаРазминкаЯдро
1Парадигма HDLметастабильность (М5 — интервальный возврат!)worked example blink; всё параллельно, порядок строк ≠ порядок событий
2Симуляция прежде платы3 вопроса зан. 1тестбенч, $dumpfile, GTKWave; правило курса: на плату едет только просимулированное
3Счётчик и делителькод blink по памяти27-разрядный делитель от штатного генератора платы (частоту взять из документации дока и constraints комплекта)
4Кнопки честно3 вопроса зан. 2–3синхронизатор 2FF + счётчик-антидребезг; сверка «N нажатий = N событий» — то же испытание, что у 555 в М6

Worked example (разбирается построчно):

module blink #(parameter DIV = 24) (
    input  wire clk,          // генератор платы (см. constraints комплекта)
    output wire led
);
    reg [DIV:0] cnt = 0;
    always @(posedge clk) cnt <= cnt + 1'b1;
    assign led = cnt[DIV];    // старший бит = медленный меандр
endmodule
// Синхронизатор + антидребезг — эталон комплекта для ЛЮБОГО асинхронного входа
module debounce (input wire clk, input wire btn_raw, output reg pressed);
    reg s0, s1; reg [15:0] hold;
    always @(posedge clk) begin
        s0 <= btn_raw; s1 <= s0;            // 2FF против метастабильности (М5!)
        hold <= s1 ? hold + 1'b1 : 16'd0;   // стабильность уровня
        pressed <= &hold;                   // ~единицы мс при мегагерцах — рассчитать под свой клок
    end
endmodule
Главная смена парадигмы: Verilog-модуль — это чертёж схемы, все always-блоки существуют одновременно, как корпуса на макетке. Обучающиеся, прошедшие линию А, принимают это быстрее «чистых программистов» — они уже думают проводами. Это измеримая гипотеза программы (см. «Данные»): сравнить время до рабочего счётчика у прошедших/не прошедших М5–М8.
Типичные ошибки: блокирующие = в тактируемом блоке — симуляция «работает», синтез живёт своей жизнью (правило: в posedge только <=); защёлки из неполных if в комбинационном always @* — читать предупреждения синтезатора как ошибки; кнопка без синхронизатора «иногда» добавляет 2 — вероятностная ошибка, которую не поймать перезапуском (мост к М5); constraints с чужим назначением выводов — риск конфликта уровней на доке.

Уровни

Глоссарий