算术逻辑单元(arithmetic and logic unit) 是能实现多组算术运算和逻辑运算的组合逻辑电路,简称ALU。
module ALU(A, B, Cin, Sum, Cout, Operate, Mode);
input [3:0] A, B; // two operands of ALU
input Cin; //carry in at the LSB
input [3:0] Operate; //determine f(.) of sum = f(a, b)
input Mode; //arithmetic(mode = 1'b1) or logic operation(mode = 1'b0)
output [3:0] Sum; //result of ALU
output Cout; //carry produced by ALU operation
// carry generation bits and propogation bits.
wire [3:0] G, P;
// carry bits;
reg [2:0] C;
reg Cout;
// function for carry generation:
function gen;
input A, B;
input [1:0] Oper;
begin
case(Oper)
2'b00: gen = A;
2'b01: gen = A & B;
2'b10: gen = A & (~B);
2'b11: gen = 1'b0;
endcase
end
endfunction
// function for carry propergation:
function prop;
input A, B;
input [1:0] Oper;
begin
case(Oper)
2'b00: prop = 1;
2'b01: prop = A | (~B);
2'b10: prop = A | B;
2'b11: prop = A;
endcase
end
endfunction
// producing carry generation bits;
assign G[0] = gen(A[0], B[0], Operate[1:0]);
assign G[1] = gen(A[1], B[1], Operate[1:0]);
assign G[2] = gen(A[2], B[2], Operate[1:0]);
assign G[3] = gen(A[3], B[3], Operate[1:0]);
// producing carry propogation bits;
assign P[0] = prop(A[0], B[0], Operate[3:2]);
assign P[1] = prop(A[1], B[1], Operate[3:2]);
assign P[2] = prop(A[2], B[2], Operate[3:2]);
assign P[3] = prop(A[3], B[3], Operate[3:2]);
// producing carry bits with carry-look-ahead;
always @(G or P or Cin, Mode)
begin
if (Mode) begin
C[0] = G[0] | P[0] & Cin;
C[1] = G[1] | P[1] & G[0] | P[1] & P[0] & Cin;
C[2] = G[2] | P[2] & G[1] | P[2] & P[1] & G[0] | P[2] & P[1] & P[0] & Cin;
Cout = G[3] | P[3] & G[2] | P[3] & P[2] & G[1] | P[3] & P[2] & P[1] & G[0] | P[3] &
P[2] & P[1] & P[0] & Cin;
end
else begin
C[0] = 1'b0;
C[1] = 1'b0;
C[2] = 1'b0;
Cout = 1'b0;
end
end
// calculate the operation results;
assign Sum[0] = (~G[0] & P[0]) ^ Cin;
assign Sum[1] = (~G[1] & P[1]) ^ C[0];
assign Sum[2] = (~G[2] & P[2]) ^ C[1];
assign Sum[3] = (~G[3] & P[3]) ^ C[2];
endmodule
module ALU(A, B, Cin, Sum, Cout, Operate, Mode);
input [3:0] A, B; //输入信号:两个四位的操作对象A、B
input Cin; //输入进位信号
input [3:0] Operate; //输入信号,决定输出sum的操作
input Mode; //算数操作(mode = 1'b1) 或者 逻辑操作(mode = 1'b0)
output [3:0] Sum; //输出ALU计算结果
output Cout; //输出ALU操作产生的进位信号
wire [3:0] G, P; //进位生成位和增长位
reg [2:0] C;
reg Cout;
function gen; //进位信号生成函数
input A, B; //函数输入信号A、B
input [1:0] Oper; //函数输入操作信号Oper
begin
case(Oper)
2'b00: gen = A; //生成A信号
2'b01: gen = A & B; //生成A和B相与信号
2'b10: gen = A & (~B); //生成A和~B相与信号
2'b11: gen = 1'b0; //生成低电平信号
endcase
end
endfunction
function prop; //进位信号增长函数
input A, B; //函数输入信号A、B
input [1:0] Oper; //函数输入操作信号Oper
begin
case(Oper)
2'b00: prop = 1; //返回高电平信号
2'b01: prop = A | (~B); //返回A和~B相或信号
2'b10: prop = A | B; //返回A和B相或信号
2'b11: prop = A; //返回A信号
endcase
end
endfunction
//产生进位生成位信号
assign G[0] = gen(A[0], B[0], Operate[1:0]);
assign G[1] = gen(A[1], B[1], Operate[1:0]);
assign G[2] = gen(A[2], B[2], Operate[1:0]);
assign G[3] = gen(A[3], B[3], Operate[1:0]);
//产生进位增长位信号
assign P[0] = prop(A[0], B[0], Operate[3:2]);
assign P[1] = prop(A[1], B[1], Operate[3:2]);
assign P[2] = prop(A[2], B[2], Operate[3:2]);
assign P[3] = prop(A[3], B[3], Operate[3:2]);
//产生带进位提前的进位
always @(G or P or Cin, Mode)
begin
if (Mode) begin
C[0] = G[0] | P[0] & Cin;
C[1] = G[1] | P[1] & G[0] | P[1] & P[0] & Cin;
C[2] = G[2] | P[2] & G[1] | P[2] & P[1] & G[0] | P[2] & P[1] & P[0] & Cin;
Cout = G[3] | P[3] & G[2] | P[3] & P[2] & G[1] | P[3] & P[2] & P[1] & G[0] | P[3] &
P[2] & P[1] & P[0] & Cin;
end
else begin
C[0] = 1'b0;
C[1] = 1'b0;
C[2] = 1'b0;
Cout = 1'b0;
end
end
//计算操作结果
assign Sum[0] = (~G[0] & P[0]) ^ Cin;
assign Sum[1] = (~G[1] & P[1]) ^ C[0];
assign Sum[2] = (~G[2] & P[2]) ^ C[1];
assign Sum[3] = (~G[3] & P[3]) ^ C[2];
endmodule