system verilog parameters in generate block

I’d like to set a parameter based on a parameter which is set when the module is instantiated. I have the following.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
module foo #(WORDS = 8);

parameter P00 = 33;
logic [7:0] tmp;

generate
case (WORDS)
4: begin : A
assign tmp = 8'haa;
parameter P00 = 4;
end
8: begin : B
assign tmp = 8'hbb;
parameter P00 = 8;
end
16: begin : C
assign tmp = 8'hcc;
parameter P00 = 16;
end
default: begin : D
assign tmp = 8'hdd;
parameter P00 = 8;
end
endcase
endgenerate

initial begin
$display ("WORDS = %d", WORDS);
$display ("tmp = %h", tmp);
$display ("P00 = %d", P00);
end

endmodule

I expected to get an error for redefining P00 but it compiled and ran and displayed the following instead.

1
2
3
WORDS =       8
tmp = bb
P00 = 33

If I comment the “parameter P00 = 33” assignment, I get a “Identifier P00 has not been declared yet.” error.

It seems that the generate block is being ignored. What is wrong here?


For complex derived parameter assignments you can use functions. For example:

1
2
3
4
parameter P01 = FUNC01(WORDS,P00);
function byte FUNC01(input byte w,p);
/* ... */
endfunction

This is also legal: module foo #(parameter WORDS, P00=FUNC00(WORDS));

Reprint: https://stackoverflow.com/questions/17734329/system-verilog-parameters-in-generate-block