我正在基于现有的RISC ISA在verilog中设计一个16位ALU。ISA规定,当操作是无符号数时,进位标志被设置,当操作是带符号数时溢出标志被设置。有趣的是,ISA实现了ADD
和SUB
指令,可以对有符号和无符号数字进行操作。由于有符号和无符号只是一种解释方式,我的初步想法是像下面这样做。这个想法是溢出和进位只是一种解释方式,所以可以为两者使用相同的函数。
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
在这种情况下,使用2s补码表示的答案是正确的,并且不需要设置标志位。但在无符号解释中,答案是错误的,应该设置进位标志位。我一直理解进位和溢出是相同的,只是不同的解释,但现在我不确定了。一个现代ALU如何处理这种边缘情况?
01001
是0111 + 0100
的结果,则应设置溢出标志,但如果它是1000 + 0001
的结果,则应清除它。 - Nate Eldredge0111 + 0010 = 1001
等于7+9,那么溢出标志位仍然会被设置,你只需要忽略它。同样地,如果你打算进行有符号算术运算,你应该检查溢出标志位并忽略进位标志位。 - Nate Eldredge