Skip to content

Instantly share code, notes, and snippets.

@russdill
Created June 28, 2014 09:31
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/4309bde92774f2a9f894 to your computer and use it in GitHub Desktop.
Save russdill/4309bde92774f2a9f894 to your computer and use it in GitHub Desktop.
`timescale 1ns / 1ps
module nonzero_cla #(
parameter N = 7,
parameter W = 6 /* Number of inputs per LUT */
) (
input [N-1:0] in,
output out
);
if (N <= W)
assign out = |in;
else begin
localparam LUTS = (N + W - 2) / W;
localparam C = (LUTS + 3) / 4;
wire [C*4-1:0] co;
wire [C*4-1:0] _in;
wire [C-1:0] _cin;
wire [LUTS-1:0] luts;
genvar i;
assign out = co[LUTS-1];
/*
* We invert the signal because we want mux target zero, DI
* (which contains 1's) if any bits are set, or mux target
* one (carry in) if no bits are set.
* Note, we offset by one because we pass in[0] to cyinit
*/
for (i = 0; i < LUTS; i = i + 1) begin : LUT
if ((i + 1) * W + 1 > N)
/* partial LUT */
assign luts[i] = ~|in[N-1:(LUTS-1)*W+1];
else
assign luts[i] = ~|in[1+i*W+:W];
end
assign _in = luts;
for (i = 0; i < C; i = i + 1) begin : CIN
assign _cin[i] = i ? co[i*4-1] : in[0];
end
CARRY4 u_CARRY4 (
.CO(co[3:0]),
.O(),
.CI(),
.CYINIT(_cin[0]),
.DI(4'b1111),
.S(_in[3:0])
);
if (C > 1) begin
CARRY4 u_CARRY4 [C-1:1] (
.CO(co[C-1:4]),
.O(),
.CI(_cin[C-1:1]),
.CYINIT(),
.DI(4'b1111),
.S(_in[C-1:4])
);
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment