# Electronic – Generate gate with a parametrized number of inputs

verilog

I'm trying to generate a multi-input gate for which the inputs can be selected when the design is elaborated.

Let me give an example to (hopefully) make this more clear:

``````module selectable_xor(input [7:0] in, output out);

parameter [7:0] SELECT = 8'b10010100;

// this should be generated for the default value of SELECT:
assign out = in ^ in ^ in

endmodule
``````

So, `out` should be the output of a XOR gate which has those bits of `in` as input for which the corresponding bit in `SELECT` is set.

I'm attempting something like the following:

``````generate
genvar gen_i;
assign out = 1'b0;

for (gen_i = 0; gen_i < 8; gen_i = gen_i + 1)
if (SELECT[gen_i])
assign out = out ^ in[gen_i];
endgenerate
``````

But this produces undefined values for the `out` signal.

Is there any good way to generate a gate with a variable number of inputs in Verilog?

PS: About the use case: I'm trying to implement a LFSR for which the polynomial is a parameter.

Edit: The consensus seems to be that I should use the following equivalent expression and trust the synthesizer to optimize it to the circuit I want:

``````assign out = ^(in & SELECT);
``````

Although I do trust that any decent synthesizer will be able to do this, I still would like to know if there is a way in Verilog to actually code this circuit myself.

Consider that, instead of the XOR-gate above, I wanted to code an OR-gate. The equivalent expression is:

``````assign out = |(in & SELECT);
``````

Ok, that's practically the same as for the XOR-gate. For an AND-gate, however, the expression is different:

``````assign out = &(in | ~SELECT);
``````

My point is that for every type of gate, I might have to come up with a different equivalent expression. I'd rather have a general way to code a gate for which the inputs can be parametrized because then I can use the same technique for any type of gate.

Edit 2: Since my bounty expires tomorrow, I will edit this question one more time to bump it. This is a comment I left to explain what I want which I hope will be more visible in the question's body:

What I want has nothing to do with physical resources. When I talk
about "gates" I mean the Verilog concept. I want to be able to define
a gate with inputs depending on some parameter. More specifically, I
want this gate to have `in[i]` as an input iff `SELECT[i]` is set. I
do not want an equivalent expression that might be optimized to the gate I want. As I've said before, this equivalent expression might
as well be implemented as 8 AND-gates and an 8-input XOR-gate because
that's what's actually coded. I hope this clarifies things 🙂

If I understood your question correctly, I think the following module does what you want. You can very simply specify the gate by its operator (`^`,`&`,`|`, etc) and nothing else. Plus only the desired assignments are generated (which is I think what you are looking for).

```````timescale 1 ns / 1 ps

module selectable_gate(input [7:0] in, output out);

parameter [7:0] SELECT = 8'b10010100;

function integer count_ones;
input [7:0] v;
integer ret;
integer i;
begin
ret = 0;
for(i=0;i<8;i=i+1) begin
if (v[i]) begin
ret = ret+1;
end
end
count_ones = ret;
end
endfunction

function integer nth_one;
input integer n;
input [7:0] v;
integer i,ret,cnt;
begin
ret = -1;
cnt = 0;
for(i=0;i<8;i=i+1) begin
if (v[i]) begin
if (cnt == n) begin
ret = i;
end
cnt = cnt+1;
end
end
nth_one = ret;
end
endfunction

localparam integer w = count_ones(SELECT);
wire [w-1:0] y;

generate
genvar i;
for(i=0 ; i<w ; i=i+1) begin
assign y[i] = in[nth_one(i,SELECT)];
end
endgenerate

assign out = ^y; // specify gate here (e.g. ^y, &y, |y, etc)

endmodule;
``````

The above module for the default `SELECT = 8'b10010100` should end up generated as:

``````assign y = in;
assign y = in;
assign y = in;
assign out  = ^y;
``````

Which is the same as `xor(in,in,in)`.

Since genvars are always unrolled as constants inside the generates, the trick was to find constants that allow the proper conditions for the generate, and use functions for any temporary variable manipulation necessary to calculate them.