I want some feedback about my code (anything is welcome). It is working, but it feels like a clumsy implementation. Because I am self-learning from a book without an answers section, it becomes difficult to know how to proceed.
module prefix_adder #(parameter N=4)
(input logic [2**N-1:0] a, b,
input logic cin,
output logic [2**N-1:0] s);
genvar i, j;
logic [2**N-1:0] g[N:0], p[N:0];
assign p[0][0] = 0;
assign g[0][0] = cin;
generate
for (j=0; j<(N**2-1); j++) begin
assign p[0][j+1] = a[j] | b[j];
assign g[0][j+1] = a[j] & b[j];
end
endgenerate
generate
for(i=1; i<=N; i++) begin
for (j=0; j<N**2; j++) begin
if(j%2**i <= 2**(i+1) && j%2**i >= 2**(i-1)) begin
assign p[i][j] = p[i-1][j] & p[i-1][j-1-(j%(2**i))+2**(i-1)];
assign g[i][j] = g[i-1][j] | p[i-1][j] & g[i-1][j-1-(j%(2**i))+2**(i-1)];
end
else begin
assign p[i][j] = p[i-1][j];
assign g[i][j] = g[i-1][j];
end
end
end
endgenerate
generate
for (j=0; j<N**2; j++) begin
assign s[j] = a[j] ^ b[j] ^ g[N][j];
end
endgenerate
endmodule