Setup и hold: почему у схемы есть предел частоты
Понимаем, почему нельзя просто поднять тактовую частоту, и что физически ограничивает скорость схемы.
Критический путь — самая длинная комбинационная цепочка между двумя триггерами; её задержка задаёт минимальный период такта, а значит, максимальную частоту всей схемы.
Начинающие думают: «схема работает — значит, можно просто поставить такт побыстрее». Но у каждой схемы есть жёсткий предел частоты, и упирается он в физику. Сигнал не распространяется мгновенно: ему нужно время, чтобы пройти через вентили от одного триггера до следующего. Если такт «торопит» триггер защёлкнуть данные раньше, чем они доехали, схема считает неверно. Разберём, откуда берётся этот предел.
Setup и hold — окно стабильности триггера
У каждого триггера есть два временных требования к входу d относительно фронта такта:
- Setup time — данные должны быть стабильны до фронта на это время. Триггеру нужно «увидеть» вход заранее.
- Hold time — данные должны оставаться стабильны ещё немного после фронта, пока триггер их «защёлкивает».
setup | | hold
данные ======X X====== (X — момент фронта)
| |
clk: ________|‾‾‾‾|________
^фронт
Если данные изменились внутри окна setup..hold — нарушение!Если сигнал не успел установиться (нарушение setup) или дёрнулся слишком рано после фронта (нарушение hold), триггер может защёлкнуть неверное или нестабильное значение. Setup-нарушения обычно лечатся снижением частоты, hold-нарушения — задача инструмента трассировки.
Критический путь и максимальная частота
Между двумя триггерами стоит комбинационная логика со своей задержкой. Период такта обязан быть длиннее, чем самая медленная такая цепочка плюс накладные расходы. Самую медленную цепочку называют критическим путём. Считаем максимальную частоту:
# Оценка максимальной тактовой частоты по задержкам (в наносекундах)
t_clk_to_q = 0.5 # задержка триггера-источника (выход после фронта)
t_logic = 4.0 # задержка комбинационной логики (критический путь)
t_routing = 1.5 # задержка проводов (трассировка)
t_setup = 0.3 # требование setup триггера-приёмника
t_period_min = t_clk_to_q + t_logic + t_routing + t_setup
f_max_mhz = 1000.0 / t_period_min # 1000 нс/такт -> МГц
print(f"Минимальный период такта: {t_period_min:.1f} нс")
print(f"Максимальная частота: {f_max_mhz:.1f} МГц")Вывод:
Минимальный период такта: 6.3 нс Максимальная частота: 158.7 МГц
Итог: эта схема не пойдёт быстрее ~159 МГц. Чтобы разогнать её, надо укоротить критический путь — например, конвейеризацией (разбить логику регистрами, как в прошлом разделе). Инструмент сообщает запас по таймингу как slack: положительный — есть запас, отрицательный — нарушение, схему так гонять нельзя.
Как работает под капотом
Смоделируем зависимость: чем длиннее логика на критическом пути, тем ниже достижимая частота. Это объясняет, почему «тяжёлые» вычисления за один такт замедляют всю схему:
overhead = 0.5 + 1.5 + 0.3 # clk-to-q + routing + setup = 2.3 нс
print("логика (нс) | период (нс) | f_max (МГц)")
print("-----------+-------------+------------")
for t_logic in [1.0, 2.0, 4.0, 8.0, 16.0]:
period = overhead + t_logic
fmax = 1000.0 / period
print(f" {t_logic:4.1f} | {period:4.1f} | {fmax:6.1f}")Вывод:
логика (нс) | период (нс) | f_max (МГц)
-----------+-------------+------------
1.0 | 3.3 | 303.0
2.0 | 4.3 | 232.6
4.0 | 6.3 | 158.7
8.0 | 10.3 | 97.1
16.0 | 18.3 | 54.6
Чётко видно: удлинение критического пути роняет частоту. 1 нс логики — 303 МГц, 16 нс — всего 55 МГц. Поэтому FPGA-инженеры борются за короткие пути: конвейеризируют, упрощают логику, помогают трассировке. Это объясняет и то, почему FPGA обычно медленнее ASIC по частоте — длинные пути через программируемую матрицу соединений.
Частые ошибки
- Игнорировать отчёт по таймингу. Если slack отрицательный, схема не будет надёжно работать на заданной частоте — даже если в симуляции «всё хорошо» (симуляция часто игнорирует задержки).
- Грузить много логики в один такт. Длинная цепочка вычислений за такт убивает частоту; разбивайте конвейером.
- Считать частоту фиксированной. Максимальная частота — следствие вашей схемы и трассировки, а не свойство FPGA «вообще».
Итог
- Setup/hold — окно, в котором данные на входе триггера должны быть стабильны относительно фронта.
- Критический путь — самая медленная логика между триггерами; он задаёт минимальный период такта.
- Максимальная частота = 1 / (clk-to-q + логика + трассировка + setup).
- Укоротить путь (конвейер, упрощение) — поднять частоту; slack показывает запас.