10 / 37 · Теория
Комбинационный RTL и полные присваивания
Выразите одну функцию условным оператором и always_comb, найдите пропуски, создающие защёлку.
Уроки доступны бесплатно. Запишитесь, чтобы сохранять прогресс.
Комбинационный выход определяется текущими входами
Прямая запись MUXМультиплексор — комбинационная схема, соединяющая один из нескольких входов с выходом по сигналу выбора. Соответствие битов выбора и номеров входов должно быть задано явно. Подробнее — assign y = sel ? b : a;. Для совместного вычисления нескольких выходов можно использовать always_comb.
always_comb begin
y = a;
if (sel) y = b;
endПредварительное присваивание по умолчанию определяет и путь sel=0. Если оставить только if (sel) y = b;, при sel=0 придётся хранить прошлое y, и функция уже не будет чисто комбинационной. Нельзя игнорировать предупреждения инструмента или полагаться лишь на ключевое слово always_comb.
Код с y=a по умолчанию и выбором b только при sel=1 имеет ту же комбинационную функцию 0/1, что и схема ниже. Выход обязательно определён и при sel=0.
y = sel ? b : a
Не сводите процедурный синтаксис к программному порядку исполнения
В комбинационном блоке промежуточные результаты обычно вычисляют блокирующим присваиванием =. Если нижнее выражение читает ранее присвоенный результат того же блока, зависимость образует комбинационный путь. Различайте его роль и неблокирующее присваиваниеНеблокирующее присваивание обозначается <= в последовательностном RTL. Оно вычисляет правую часть, затем планирует обновление, позволяя регистрам на одном фронте рассчитываться по предыдущему состоянию. Подробнее <= для обновления последовательностных регистровРегистр хранит многобитное состояние. Синхронные регистры в этом курсе записывают определённый вход на фронте тактового сигнала. Подробнее.
always_comb begin
next_y = sel ? b : a;
inverted_y = ~next_y;
endЕщё одно базовое правило — не управлять одним выходом из нескольких блоков. При разделении модулей отслеживайте через интерфейсы единственный драйвер каждого сигнала.
Сначала согласуйте разную ширину данных
Если выбираются 8- и 12-битные данные, явно задайте ширину y и расширение знака. Определяйте диапазоны при проектировании, а не случайно убеждайтесь по диаграмме, что неявное расширение совпало с намерением. Вне модели 0/1 условный оператор при sel=X может отличаться от простого if; двухсостоянийные результаты курса не следует обобщать на все четыре состояния.
Попробуйте сами
В always_comb записано только if(en) y=d;. Как превратить это в комбинационную схему, выдающую 0 при отсутствии enable?
Прочитать объяснение
В начале блока присвойте y ноль, затем при en перезапишите значением d, либо используйте эквивалент assign y = en ? d : 0 с явной шириной. Хранение прежнего значения при en=0 — отдельная спецификация регистра или защёлки; это не та же функция, что выход 0.