Altifigence Academy

10 / 37 · Теория

Комбинационный RTL и полные присваивания

Выразите одну функцию условным оператором и always_comb, найдите пропуски, создающие защёлку.

Комбинационный выход определяется текущими входами

Прямая запись MUXМультиплексор — комбинационная схема, соединяющая один из нескольких входов с выходом по сигналу выбора. Соответствие битов выбора и номеров входов должно быть задано явно. Подробнее — assign y = sel ? b : a;. Для совместного вычисления нескольких выходов можно использовать always_comb.

SystemVerilog
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. Оно вычисляет правую часть, затем планирует обновление, позволяя регистрам на одном фронте рассчитываться по предыдущему состоянию. Подробнее <= для обновления последовательностных регистровРегистр хранит многобитное состояние. Синхронные регистры в этом курсе записывают определённый вход на фронте тактового сигнала. Подробнее.

SystemVerilog
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.

Выбор действует в этом браузере. Его можно изменить внизу страницы.