Я учусь использовать FPGA (плата разработки Papilio, на которой установлен xilinx spartan3e, использующий vhdl).
Мне нужно разделить входящий импульс на (жестко закодированное) число.
Я вижу 3 варианта - примерно, как псевдокод (на примере 10 отсчетов):
- Инициализируйте до 0, при увеличении входного фронта на 1, сравните с 10; если они равны, сбросьте в 0 и запустите выходной импульс
- Инициализировать до 10, при уменьшении входного фронта на 1, сравнить с 0; если они равны, сбросьте на 10 и запустите выходной импульс
- Инициализируйте до 9, но убедитесь, что есть хотя бы 1 ведущий бит «0», который является моим выходным битом. Нарастающий фронт на входе уменьшается на 1. Нарастающий фронт выходного бита сбрасывается.
Рабочий цикл не важен.
Один из них лучше, чем другие? Есть ли еще лучший метод, о котором я не думал?
Есть ли «стандартный» способ, который даст компилятору наилучшие шансы на оптимизацию?
Ответы:
Оптимизация до этого уровня разобьет ваше сердце. Результат может измениться из-за технологии используемой ПЛИС, других факторов в ПЛИС, а также из-за факторов, находящихся вне вашего контроля, в том числе из числа случайных чисел сборщика.
Сказав это, я считаю, что вариант 3 будет лучшим. Опции 1 и 2 имеют вентиль компаратора / ИЛИ, проходящий между счетчиками, чтобы он мог сигнализировать о достижении целевого числа. Вариант 2 может быть немного быстрее, чем 1, поскольку все они могут быть прямыми ИЛИ вместе без каких-либо инверторов, но опять вы сталкиваетесь с небольшими технологическими различиями, где он может быть быстрее до И или XOR.
Вариант 3 пропускает сравнение из-за низкой стоимости одного дополнительного бита в счетчике. Это должно стоить того, если вы не ограничены в шлепанцах.
Интересный факт о счетчиках состоит в том, что они имеют тенденцию группироваться в определенный размер устройства в логическом блоке, и вы увидите изменение синхронизации больше, чем ожидалось, если этот дополнительный бит вытолкнет вас из этой группы.
источник
Еще одним вариантом будет инициализация счетчика до 6 (= 2 4 - 10), сосчитать, а затем сбросить, когда активируется выход переноса (т. Е. Все FF - единичные).
Преимущество этого состоит в том, что это не требует дополнительной FF, и у многих FGPA есть специальная вспомогательная логика, чтобы ускорить этот вид операции переноса в схеме счетчика или сумматора.
источник
Зависит. Например: задержка распространения триггера для 0 → 1 и 1 → 0 может быть разной, и, следовательно, задержки перехода счетчика для 000 → 001 и 001 → 000 могут немного отличаться. Это может быть выше или ниже, в зависимости от технологии cmos, используемой в FPGA. Таким образом, вы должны синтезировать и выяснить, какой из них имеет лучшие временные характеристики.
источник
С точки зрения автора компилятора: если вы используете
integer
, внутреннее представление не определено, и компилятор может выбрать наиболее эффективную реализацию.Если вы форсируете определенное внутреннее представление, оптимизатор все равно попытается улучшить его, но оно начнется с несколько худшей точки зрения.
Некоторые FPGA имеют возможности «предварительной загрузки», где регистры могут быть инициализированы произвольными значениями, и в этом случае инициализацияN- 1 обратный отсчет и использование самого верхнего бита переноса в качестве выхода и сброса (в следующем цикле) более эффективен, чем реализация как сумматора, так и компаратора. Без предварительной загрузки сумматор может быть лучше.
Если вы не знаете внутреннюю структуру, ресурсы, выделенные для другой логики (многие FPGA имеют выделенную логику с умножением и сложением с плавающей запятой, которую вы также можете использовать для реализации счетчика, если у вас есть оставшиеся единицы) и полностью уверены, что вы не будете переключаться для другой модели ответ «не думай об этом».
источник