51 / 63 · Теория
АЛУ и флаги zero, negative, carry, overflow
Постройте ADD/SUB на общем сумматоре, разделите carry и знаковое переполнение и выведите условия сравнения.
Уроки доступны бесплатно. Запишитесь, чтобы сохранять прогресс.
Предварительные знания: дополнительный кодДополнительный код представляет знаковые целые битовой последовательностью фиксированной ширины. Для n бит диапазон составляет от −2^(n−1) до 2^(n−1)−1. Подробнее, сумматоры, комбинационный MUXМультиплексор — комбинационная схема, соединяющая один из нескольких входов с выходом по сигналу выбора. Соответствие битов выбора и номеров входов должно быть задано явно. Подробнее и расширение разрядности.
АЛУ формирует результат и флаги состояния
АЛУ выбирает результат одной из схем операций и выдаёт биты состояния для его интерпретации. Входы и результат имеют ширину ; поддерживаются ADD, SUB, AND, OR, XOR. Арифметический результат всегда усекается до младших битов. Одни биты можно прочитать как unsignedБеззнаковая интерпретация (unsigned) рассматривает битовую последовательность как неотрицательное целое. Диапазон n бит — от 0 до 2^n−1; знаковая интерпретация тех же битов может дать другое число. Подробнее или signed в дополнительном коде, поэтому carry и overflow выдаются отдельно. Два сумматора для разных знаковых интерпретаций не нужны.
Флаги: , . Z — свёртка NOR всего выбранного результата, N — старший бит. N=1 означает отрицательную signed-интерпретацию сохранённых битов. При переполнении этот знак может отличаться от знака точной суммы неограниченной разрядности.
Разделение carry и overflow
При сложении C — старший бит расширенной суммы .
V равен 1, когда знаки входов одинаковы, а знак результата другой. Для старших битов :
В 8 битах даёт R=0, C=1, V=0. В знаковой интерпретации это , без выхода за диапазон. Напротив, даёт R=0x80, C=0, V=1: unsigned 128 помещается, но превышен signed-максимум 127. Объединение C и V потеряет это различие.
Для вычитания инвертируетсяИнверсия — операция NOT, меняющая 0 на 1 и 1 на 0. Черта над формулой означает применение NOT ко всему выражению под ней. Подробнее только W-битный B, затем он расширяется нулём: . Инверсия всех W+1 битов изменила бы смысл старшего carry. Здесь C=1 определён как отсутствие займа. Поэтому unsigned означает .
Знаковое переполнение при вычитании возможно только для разных знаков. Команда сравнения может использовать флаги SUB, не сохраняя R. Signed равно , signed — . Например, сохраняется как +127, но V=1 исправляет ошибку проверки одного N.
Пример 8-битного ADD: unsigned-результат представим, signed-результат выходит за диапазон. Убедитесь, что для одной суммы одновременно возможны C=0 и V=1.
- A=7F · B=01: со знаком: 127 + 1
- 9-битная сумма T: 0_10000000
- 8-битный результат R: 80 → со знаком −128
- Флаги состояния: Z=0 · N=1 · C=0 · V=1
Общий сумматор и явные правила выхода
RTL ниже предполагает W≥2. Opcode 0–4 означают ADD, SUB, AND, OR, XOR. Логические операции задают C,V=0. Неиспользуемый opcode даёт R=0, поэтому Z=1, остальные флаги 0. Это контракт данного АЛУ, а не имитация набора команд конкретного процессора.
module alu #(parameter int W = 8) (
input logic [W-1:0] a, b,
input logic [2:0] op,
output logic [W-1:0] y,
output logic z, n, c, v
);
logic sub;
logic [W-1:0] bx;
logic [W:0] sum;
always_comb begin
sub = (op == 3'd1);
bx = b ^ {W{sub}};
sum = {1'b0, a} + {1'b0, bx}
+ {{W{1'b0}}, sub};
y = '0;
c = 1'b0;
v = 1'b0;
case (op)
3'd0, 3'd1: begin
y = sum[W-1:0];
c = sum[W];
if (sub)
v = (a[W-1] ^ b[W-1]) & (a[W-1] ^ y[W-1]);
else
v = ~(a[W-1] ^ b[W-1]) & (a[W-1] ^ y[W-1]);
end
3'd2: y = a & b;
3'd3: y = a | b;
3'd4: y = a ^ b;
default: y = '0;
endcase
z = ~(|y);
n = y[W-1];
end
endmoduleУсловная инверсия B и начальный перенос выражают ADD/SUB одной суммирующей структурой. Сначала каждая ветвь задаёт y, затем вычисляются Z,N, что даёт согласованные флаги и логическим операциям. Присваивания по умолчанию определяют все пути и предотвращают защёлкиЗащёлка — элемент хранения, который следует за входом, пока управляющий сигнал активен, и удерживает значение, когда он неактивен. Этим она отличается от триггера, записывающего данные только на фронте. Подробнее. РегистровРегистр хранит многобитное состояние. Синхронные регистры в этом курсе записывают определённый вход на фронте тактового сигнала. Подробнее здесь нет, поэтому нет задержки в тактовых циклах, но физическая задержка распространения существует. Результат должен пройти и MUX операции, и детектор нуля до срока setup следующего регистра.
Для проверки сочетайте 0, максимум unsigned, максимум и минимум signed, а также соседние граничные значения. R сравнивайте с эталоном по модулю , C — с расширенной unsigned-суммой, V — с выходом за signed-диапазон. Даже при правильном R определения флагов могут быть ошибочны.
Практический пример разделения знака, нуля, unsigned carry и signed overflow приведён в описании условных флагов Arm.
Попробуйте сами
Для 8-битного АЛУ найдите R,Z,N,C,V: (1) 0x7F+0x01, (2) 0xFF+0x01, (3) 0x00−0x01, (4) 0x80−0x01. Почему при знаковом сравнении входов (4) одного N недостаточно?
Прочитать объяснение
В порядке (R,Z,N,C,V): (1) (0x80,0,1,0,1), (2) (0x00,1,0,1,0), (3) (0xFF,0,1,0,0), (4) (0x7F,0,0,1,1). В (3) есть unsigned-заём, поэтому C=0; signed −1 представимо. В (4) unsigned 128−1=127 не требует займа, C=1. Но signed −128−1=−129 вне диапазона, V=1, и N=0 сохранённого R не отражает знак точной разности. Условие signed A<B даёт N xor V=1, то есть верный результат сравнения.