Skip to content

Instantly share code, notes, and snippets.

@patrickroberts
Created December 23, 2017 18:54
Show Gist options
  • Save patrickroberts/3908606ece975eb4c20b4cd8f8b25dd6 to your computer and use it in GitHub Desktop.
Save patrickroberts/3908606ece975eb4c20b4cd8f8b25dd6 to your computer and use it in GitHub Desktop.
Recursive ALU module in Verilog HDL
`timescale 1ns / 1ps
module alu32 (d, Cout, V, a, b, Cin, S);
output[31:0] d;
output Cout, V;
input [31:0] a, b;
input Cin;
input [2:0] S;
wire [31:0] c, g, p;
wire gout, pout;
alu_cell _alu_cells[31:0] (
.d(d),
.g(g),
.p(p),
.a(a),
.b(b),
.c(c),
.S(S)
);
lac #(.LEVEL(4)) _lac(
.c(c),
.gout(gout),
.pout(pout),
.Cin(Cin),
.g(g),
.p(p)
);
overflow _ov(
.Cout(Cout),
.V(V),
.g(gout),
.p(pout),
.c31(c[31]),
.Cin(Cin)
);
endmodule
module alu_cell (d, g, p, a, b, c, S);
output d, g, p;
input a, b, c;
input [2:0] S;
reg g,p,d,cint,bint;
always @(a,b,c,S,p,g) begin
bint = S[0] ^ b;
g = a & bint;
p = a ^ bint;
cint = S[1] & c;
if(S[2]==0) begin
d = p ^ cint;
end
else if(S[2]==1) begin
if((S[1]==0) & (S[0]==0)) begin
d = a | b;
end
else if ((S[1]==0) & (S[0]==1)) begin
d = ~(a | b);
end
else if ((S[1]==1) & (S[0]==0)) begin
d = a & b;
end
else
d = 0;
end
end
endmodule
module overflow (Cout, V, g, p, c31, Cin);
output Cout, V;
input g, p, c31, Cin;
assign Cout = g|(p&Cin);
assign V = Cout^c31;
endmodule
module lac(c, gout, pout, Cin, g, p);
parameter LEVEL = 0;
output[(2<<LEVEL)-1:0] c;
output gout, pout;
input Cin;
input[(2<<LEVEL)-1:0] g, p;
generate
case(LEVEL)
0: begin
assign c[0] = Cin;
assign c[1] = g[0] | (p[0] & Cin);
assign gout = g[1] | (p[1] & g[0]);
assign pout = p[1] & p[0];
end
default: begin
wire[1:0] cint, gint, pint;
lac #(.LEVEL(LEVEL-1)) leaf0 (
.c(c[(1<<LEVEL)-1:0]),
.gout(gint[0]),
.pout(pint[0]),
.Cin(cint[0]),
.g(g[(1<<LEVEL)-1:0]),
.p(p[(1<<LEVEL)-1:0])
);
lac #(.LEVEL(LEVEL-1)) leaf1 (
.c(c[(2<<LEVEL)-1:1<<LEVEL]),
.gout(gint[1]),
.pout(pint[1]),
.Cin(cint[1]),
.g(g[(2<<LEVEL)-1:1<<LEVEL]),
.p(p[(2<<LEVEL)-1:1<<LEVEL])
);
lac #(.LEVEL(0)) root (
.c(cint),
.gout(gout),
.pout(pout),
.Cin(Cin),
.g(gint),
.p(pint)
);
end
endcase
endgenerate
endmodule
@patrickroberts
Copy link
Author

Schematic:

screen shot 2017-12-23 at 1 00 41 pm

Logic table:

screen shot 2017-12-23 at 1 00 52 pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment