Skip to content

Instantly share code, notes, and snippets.

@russdill
Created June 28, 2014 09:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save russdill/c182ad3dd7ed5db9597d to your computer and use it in GitHub Desktop.
Save russdill/c182ad3dd7ed5db9597d to your computer and use it in GitHub Desktop.
`timescale 1ns / 1ps
module xor_cla #(
parameter N = 4,
parameter W = 6
) (
input [N-1:0] in,
output out,
output outn
);
localparam LUTS = (N + W - 1) / W;
wire [LUTS-1:0] luts;
genvar i;
for (i = 0; i < LUTS; i = i + 1) begin : LUT
if ((i + 1) * W > N)
assign luts[i] = ^in[N-1:(LUTS-1)*W];
else
assign luts[i] = ^in[i*W+:W];
end
if (LUTS > 1)
xor_cla4 #(LUTS) u_cla (luts, out, outn);
else begin
assign out = luts[0];
assign outn = ~luts[0];
end
endmodule
module xor_cla4 #(
parameter N = 1
) (
input [N-1:0] in,
output out,
output outn
);
localparam C = (N + 3) / 4;
wire cin = 0;
wire [C*4-1:0] o;
wire [C*4-1:0] co;
wire [C*4-1:0] di;
wire [C*4-1:0] _in;
wire [C-1:0] _cin;
genvar i;
/*
* For odd bits, o is XOR of all the previous bits, co (carry out) is
* the NXOR of all previous bits. For even bits, this is swapped.
* Basically, when the LUT result is odd, we keep o/co as is. When the
* result is even, we swap them.
*/
if (N & 1) begin
assign outn = co[N-1];
assign out = o[N-1];
end else begin
assign out = co[N-1];
assign outn = o[N-1];
end
assign _in = in;
assign di = {o[N-2:0], ~cin};
for (i = 0; i < C; i = i + 1) begin
assign _cin[i] = i ? co[i*4-1] : cin;
end
CARRY4 u_CARRY4(
.CO(co[3:0]),
.O(o[3:0]),
.CI(),
.CYINIT(_cin[0]),
.DI(di[3:0]),
.S(_in[3:0])
);
if (C > 1) begin
CARRY4 u_CARRY4 [C-1:1] (
.CO(co[C*4-1:4]),
.O(o[C*4-1:4]),
.CI(_cin[C-1:1]),
.CYINIT(),
.DI(di[C*4-1:4]),
.S(_in[C*4-1:4])
);
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment