Verilog 32-битный ALU с флагами переполнения, знака и нуля
У меня есть задание с просьбой создать модуль, как описано в заголовке. Мне нужно сложить, вычесть, И и XOR два входа и установить необходимые флаги. Назначение не было ясным на 100%, но я предполагаю, что флаг переполнения сделает все остальное недействительным, поэтому мне не нужно беспокоиться ни о чем, что выходит за 32-битный результат. Моя проблема связана с флагами обнуления и переполнения, которые никогда не устанавливаются, что бы я ни пытался. Я собрал некоторые методы, которые я нашел в Интернете, но я не уверен, что эти методы неправильные или я их кодирую неправильно. Все компилируется и запускается, но мои флаги никогда не устанавливаются независимо от того, какие входы я использую. Я взял только один класс Verilog и не помню многих ограничений, поэтому любая помощь будет оценена.
module alu(clk, rst, CTRL, A, B, Overflow, Z_flag, Negative, d_out);
input wire clk , rst;
input wire [1:0] CTRL;
input wire signed [31:0] A, B;
output wire Negative;
output reg Z_flag;
output reg [1:0] Overflow;
output wire [31:0] d_out;
reg signed [32+32:0] Result;
assign Negative = Result[31]; // Negative Flag
assign d_out [31:0] = Result [31:0];
always@(posedge clk)
begin
if(!rst)
begin
if(rst)
begin
Result [31:0] <= 0;
end
case(CTRL)
2'b00:
begin
Result [32:0] <= {A[31], A [31:0]} + {B[31], B [31:0]}; // Add A + B
if(Result [32:31] == (2'b11 | 2'b10)) Overflow <= 1'b1;
else Overflow <= 1'b0;
end
2'b01:
begin
Result [32:0] <= {A[31], A [31:0]} - {B[31], B [31:0]}; // Subtract A - B
if((Result[32+32]) && (~Result [32+31:31] != 0)) Overflow <= 1'b1;
else if ((~Result[32+32]) && (Result [32+31:31] != 0)) Overflow <= 1'b1;
else Overflow <= 1'b0;
end
2'b10:
begin
Result [31:0] <= A [31:0] & B [31:0]; // Bitwise AND
end
2'b11:
begin
Result [31:0] <= A [31:0] ^ B [31:0]; // Bitwise XOR
end
endcase
if (Result == "32h'00000000") Z_flag <= 1'b1; // Zero detection
else Z_flag <= 1'b0;
end
end
Вот мой стенд:
module ALU_stimulus;
reg clk;
reg rst;
reg [1:0] CTRL;
reg [31:0] A;
reg [31:0] B;
wire Overflow;
wire Z_flag;
wire Negative;
wire [31:0] d_out;
alu uut (
.clk(clk),
.rst(rst),
.CTRL(CTRL),
.A(A),
.B(B),
.Overflow(Overflow),
.Z_flag(Z_flag),
.Negative(Negative),
.d_out(d_out)
);
initial begin
clk = 0;
rst = 0;
CTRL = 0;
A = 0;
B = 0;
#100;
clk=1'b1;
A=32'h00000000;
B=32'h00000000;
rst=1'b0;
CTRL=2'b00;
#100;
clk=1'b0;
#100 $stop;
end
endmodule
1 ответ
Для простоты примера рассмотрим 4-битные значения с расширением знака 1 бит.
1 + 1 = 2; Без переполнения
0 0001; //1
0 0001; //1
0 0010; //2
7+7= 14; Максимальное переполнение для 4-битного значения составляет 7
0 0111; //1
0 0111; //1
0 1110; //-2
-1 + -1 = -2; Нет недолива
1 1111 //-1
1 1111 //-1
1 1110 //-2
-8+-8 = -16 Минимальное значение недостаточного значения -8
1 1000 //-8
1 1000 //-8
1 0000 // 0
Глядя на MSB (расширение знака и MSB) мы можем увидеть:
00 => normal
01 => Overflow
10 => Underflow
11 => normal