~ cd комбинационная логика. операторы. assign
1. Что такое комбинационная логика?
Комбинационная логика — это схема, у которой выход зависит ТОЛЬКО от текущего состояния входов. Никакой памяти, никаких тактовых сигналов.
Пример из жизни: обычный выключатель света. Положение выключателя (вход) сразу определяет, горит лампа (выход) или нет.
В Verilog комбинационная логика описывается двумя способами:
- Непрерывные присвоения (
assign) - always блоками ос специальным условием
always @(*)(но о них позже)
Главное правило: комбинационная схема не хранит состояние. Изменился вход — изменился выход.
2. Ключевое слово assign
assign — это главный инструмент для комбинационной логики. Оно создает непрерывное соединение: как только меняется сигнал справа, сигнал слева пересчитывается мгновенно.
Синтаксис:
assign имя_сигнала = выражение;Пример:
assign o_y = i_a & i_b; // выход o_y всегда равен i_a AND i_bВажно: слева от assign может стоять только wire, но никогда reg. Это логично: провод не хранит, а непрерывно передает.
3. Битовые операторы (побитовые)
Эти операторы работают с каждым битом вектора независимо. Самые популярные:
&— побитовое И (AND)|— побитовое ИЛИ (OR)^— побитовое исключающее ИЛИ (XOR)~— побитовое НЕ (NOT)
Пример:
assign o_result = i_a & i_b; // поразрядное И
assign o_xor = i_a ^ i_b; // поразрядное XORЕсли i_a = 4'b1100, i_b = 4'b1010, то:
i_a & i_b= 4’b1000i_a | i_b= 4’b1110i_a ^ i_b= 4’b0110
4. Алгебраические операторы
Обычная арифметика, но с подвохом — результат зависит от разрядности.
+— сложение-— вычитание*— умножение (занимает много логики)/— деление (для синтеза используется редко, очень дорого)%— остаток от деления
Пример:
assign o_sum = i_a + i_b;
assign o_diff = i_a - i_b;Важно: при сложении может возникнуть переполнение. Если складываешь два 4-битных числа, результат может быть 5-битным. Думай о разрядности!
5. Операторы сдвига
Позволяют двигать биты влево или вправо. Используются для умножения/деления на степени двойки и для работы с последовательными интерфейсами.
<<— логический сдвиг влево (освободившиеся биты заполняются нулями)>>— логический сдвиг вправо (освободившиеся биты заполняются нулями)<<<— арифметический сдвиг влево (то же, что логический)>>>— арифметический сдвиг вправо (сохраняет знак)
Пример:assign o_shl = i_a << 2; // умножили на 4assign o_shr = i_a >> 1; // поделили на 2 (целочисленно)
Интересно: i_a << 2 эквивалентно умножению на 4, но в железе реализуется просто переподключением проводов — никакой логики!
6. Условный оператор (тернарный)
Работает как if-else в одну строку. Очень удобно для мультиплексоров.
Синтаксис:
assign результат = (условие) ? значение_если_истина : значение_если_ложь;Пример:
assign o_mux = (i_sel) ? i_a : i_b; // если i_sel=1, выход = i_a, иначе i_bУсловия можно вкладывать друг в друга:
assign o_out = (i_sel == 2'b00) ? i_a : (i_sel == 2'b01) ? i_b : (i_sel == 2'b10) ? i_c : i_d;В железе это превращается в дерево мультиплексоров.
7. Пример с выбором ответа: Угадай результат
Дан код:
module test;
wire [3:0] i_a = 4'b1010;
wire [3:0] i_b = 4'b1100;
wire [3:0] o_result;
assign o_result = (i_a & i_b) | (i_a ^ i_b);
endmoduleЧему равно o_result в двоичном виде? Ответ: 4’b1110
4’b1010
4’b1110
4’b0110
4’b0000
8. Создаем простой сумматор
Соберем комбинационный сумматор, используя префиксы в портах.
module adder #(
parameter WIDTH = 4
) (
input [WIDTH-1:0] i_a, // первое слагаемое
input [WIDTH-1:0] i_b, // второе слагаемое
input i_cin, // входной перенос
output [WIDTH-1:0] o_sum, // сумма
output o_cout // выходной перенос
);
assign {o_cout, o_sum} = i_a + i_b + i_cin;
endmoduleФигурные скобки {} — это конкатенация (склеивание). Мы складываем три числа и результат (который может быть шире) разбиваем на перенос и сумму.
9. Сводим всё вместе
Сегодня мы разобрали:
- assign — основа комбинационной логики
- Битовые операторы (&, |, ^, ~) — для поразрядной обработки
- Алгебраические (+, -, *, /) — арифметика с учетом разрядности
- Сдвиги (<<, >>, <<<, >>>) — быстрая арифметика и сдвиги
- Тернарный оператор — компактный if-else для мультиплексоров
Комбинационная логика — это фундамент. Научишься ей — сможешь собрать что угодно, от сумматора до процессора. Главное помнить: никакой памяти, только текущие входы.