Понимание разницы между флагами переполнения и переноса
Я разрабатываю 16-битный ALU в Verilog на основе существующей RISC ISA. ISA сообщает, что флаг переноса устанавливается, когда операция не подписана, а переполнение устанавливается, когда операция подписана. Интересно то, что ISA реализует
ADD
а также
SUB
инструкции, которые работают как с числами со знаком, так и с числами без знака. Поскольку signed vs unsigned - это просто вопрос интерпретации, моя первоначальная идея заключалась в том, чтобы сделать что-то вроде ниже. Идея в том, что переполнение и перенос - это только вопрос интерпретации, поэтому используйте одну и ту же функцию для обоих.
module ALU();
input wire [15:0]x;
input wire [15:0]y;
input wire [8:0]opcode;
output reg [15:0] result;
output reg CFlag; // Carry
output reg FFlag; // Overflow
if(opcode == ADD) begin
result = x + y;
// x and y have the same sign, result has a different sign.
CFlag = FFlag = (x[15] ~^ y[15]) & res[15] ^ x[15];
end
endmodule
Но как насчет этого пограничного случая (показанного в 4 бита)?
x = -1
y = 1
1111 + 0001 = 0000
В этом случае ответ будет правильным в 2-х комплименте, и установка флага не требуется. Но ответ неверен в беззнаковой интерпретации, и флаг переноса должен быть установлен. Я всегда понимал, что перенос и переполнение - это одно и то же, просто разные интерпретации, но теперь я не уверен. Как современный ALU справится с этим крайним случаем?
1 ответ
Перенос и перелив - это совсем не одно и то же.
Перенос указывает, что результат математически неверен при интерпретации как беззнаковый, переполнение указывает, что результат математически неверен при интерпретации как знаковый. Итак, в качестве примеров для вашего 4-битного ALU:
1111 + 0001 = 0000
должен установить перенос (15 + 1 = 0 ложно) и очистить переполнение (-1 + 1 = 0 верно).0111 + 0010 = 1001
должен очистить перенос (7 + 2 = 9 верно) и установить переполнение (7 + 2 = -7 неверно).1001 + 1001 = 0010
должен установить оба (9 + 9 = 2 и -7 + -7 = 2 ложны).