74181
IC 74181 is 4-bit ALU.
Direction | Width | Name | Description | |
input | [3:0] | A | Input A | |
input | [3:0] | B | Input B | |
input | [3:0] | S | Selected function | |
input | M | Mode: 0 = logic | 1 = arithmetic | |
input | Cn | Carry-in | ||
output | [3:0] | F | Result | |
output | X | Carry generate | ||
output | Y | Carry propagate | ||
output | AeqB | A == B | ||
output | Cnp4 Carry-out (Cn+4) |
S3 | S2 | S1 | S0 | Logic Function | Logic Description | Arith Function | Arith Description |
-- | -- | -- | -- | -------------------- | ------------------------ | ---------------------- | --------------------- |
0 | 0 | 0 | 0 | !(A | B) | NOR | A | Transfer A |
0 | 0 | 0 | 1 | !(A & B) | NAND | A + !B | A - B - 1 |
0 | 0 | 1 | 0 | !A & B | NOT A AND B | A + !B + Cn | A - B |
0 | 0 | 1 | 1 | !A | NOT A | A - 1 + Cn | A - 1 |
0 | 1 | 0 | 0 | !B | NOT B | A + A | Double A |
0 | 1 | 0 | 1 | A ^ B | XOR | A + A + !B | A + A - B - 1 |
0 | 1 | 1 | 0 | !A | B | NOT A OR B | A + A + !B + Cn | A + A - B |
0 | 1 | 1 | 1 | !(A ^ B) | XNOR | 2A - 1 + Cn | Double A minus 1 |
1 | 0 | 0 | 0 | A & B | AND | A + B | Add |
1 | 0 | 0 | 1 | !(A | !B) | OR with NOT B | A + B + 1 | Add with carry |
1 | 0 | 1 | 0 | A | Transfer A | A + 1 | Increment A |
1 | 0 | 1 | 1 | A | !B | A OR NOT B | A + !B + 1 | A - B + 1 |
1 | 1 | 0 | 0 | B | Transfer B | 1 | Always 1 (Set) |
1 | 1 | 0 | 1 | A | B | OR | 0 | Always 0 (Clear) |
1 | 1 | 1 | 0 | A & !B | A AND NOT B | !B | NOT B |
1 | 1 | 1 | 1 | !(A ^ B) | XNOR | !B + Cn | NOT B + carry |
Verilog equivalent, without carry and other important signals:
module alu74181(
input [3:0]s,
input ci, M,
input [3:0] a, b,
output reg [3:0] y
);
reg [3:0] p, g;
always @(*) begin
p[0] <= ~(a[0] | (s[0] & b[0]) | (s[1] & ~b[0]));
p[1] <= ~(a[1] | (s[0] & b[1]) | (s[1] & ~b[1]));
p[2] <= ~(a[2] | (s[0] & b[2]) | (s[1] & ~b[2]));
p[3] <= ~(a[3] | (s[0] & b[3]) | (s[1] & ~b[3]));
g[0] <= ~((a[0] & ~b[0] & s[2]) | (a[0] & b[0] & s[3]));
g[1] <= ~((a[1] & ~b[1] & s[2]) | (a[1] & b[1] & s[3]));
g[2] <= ~((a[2] & ~b[2] & s[2]) | (a[2] & b[2] & s[3]));
g[3] <= ~((a[3] & ~b[3] & s[2]) | (a[3] & b[3] & s[3]));
y[0] = (p[0] ^ g[0]) ^ ~(~ci & ~M);
y[1] = (p[1] ^ g[1]) ^ ~((~ci & ~M & g[0]) | (~M & p[0]));
y[2] = (p[2] ^ g[2]) ^ ~((~ci & ~M & g[0] & g[1]) | (~M & p[1]) | (~M & p[0] & g[1]));
y[3] = (p[3] ^ g[3]) ^ ~((~ci & ~M & g[0] & g[1] & g[2]) | (~M & p[2]) | (~M & p[1] & g[2]) | (~M & p[0] & g[1] & g[2]));
end
endmodule // alu74181
Complete verilog, not checked yet:
module alu74181 (
input wire [3:0] A,
input wire [3:0] B,
input wire [3:0] S,
input wire M, // Mode: 0 = logic, 1 = arithmetic
input wire Cn, // Carry-in
output wire [3:0] F, // Result
output wire X, // Carry generate
output wire Y, // Carry propagate
output wire AeqB, // A == B
output wire Cnp4 // Carry-out (Cn+4)
);
wire [3:0] TU;
wire [3:0] TV;
wire [3:0] TX;
// TU[n] = ~(A[n] | (B[n] & S[0]) | (~B[n] & S[1]))
assign TU[0] = ~(A[0] | ( B[0] & S[0]) | (~B[0] & S[1]));
assign TU[1] = ~(A[1] | ( B[1] & S[0]) | (~B[1] & S[1]));
assign TU[2] = ~(A[2] | ( B[2] & S[0]) | (~B[2] & S[1]));
assign TU[3] = ~(A[3] | ( B[3] & S[0]) | (~B[3] & S[1]));
// TV[n] = ~((A[n] & ~B[n] & S[2]) | (A[n] & B[n] & S[3]))
assign TV[0] = ~((A[0] & ~B[0] & S[2]) | (A[0] & B[0] & S[3]));
assign TV[1] = ~((A[1] & ~B[1] & S[2]) | (A[1] & B[1] & S[3]));
assign TV[2] = ~((A[2] & ~B[2] & S[2]) | (A[2] & B[2] & S[3]));
assign TV[3] = ~((A[3] & ~B[3] & S[2]) | (A[3] & B[3] & S[3]));
// TX[n] = TU[n] ^ TV[n]
assign TX = TU ^ TV;
// TY = TU0&TV1&TV2&TV3 | TU1&TV2&TV3 | TU2&TV3 | TU3
wire TY = (TU[0] & TV[1] & TV[2] & TV[3]) |
(TU[1] & TV[2] & TV[3]) |
(TU[2] & TV[3]) |
TU[3];
// F[n] = TX[n] ^ carry logic
assign F[0] = TX[0] ^ ~(M & Cn);
assign F[1] = TX[1] ^ ~((TU[0] & M) | (TV[0] & M & Cn));
assign F[2] = TX[2] ^ ~((TU[1] & M) |
(TU[0] & TV[1] & M) |
(TV[0] & TV[1] & M & Cn));
assign F[3] = TX[3] ^ ~((TU[2] & M) |
(TU[1] & TV[2] & M) |
(TU[0] & TV[1] & TV[2] & M) |
(TV[0] & TV[1] & TV[2] & M & Cn));
// Status outputs
assign X = ~(TV[0] & TV[1] & TV[2] & TV[3]); // Carry generate (G)
assign Y = ~TY; // Carry propagate (P)
assign AeqB = F[0] & F[1] & F[2] & F[3]; // A == B
assign Cnp4 = TY | (TV[0] & TV[1] & TV[2] & TV[3] & Cn); // Carry-out (Cn+4)
endmodule