read_verilog <<EOF
(* whitebox *)
(* final_name=$sformatf("aa%d", X) *)
module aa(input wire d, output wire q);
  parameter [1:0] X = 0;
  assign q = X[d];
endmodule

(* whitebox *)
(* final_name=$sformatf("bb%d", X) *)
module bb(input wire d, output wire q);
  parameter [1:0] X = 0;
  assign q = X[~d];
endmodule

(* whitebox *)
(* final_name=$sformatf("cc%d", X) *)
module cc(input wire d, output wire q);
  parameter [1:0] X = 0;
  assign q = ~X[d];
endmodule

module top;
	wire d, q1, q2, q3, q3, q4, q5, q6;

	aa #(.X(1)) aa1(.d(d), .q(q1));
	aa #(.X(2)) aa2(.d(d), .q(q2));

	bb #(.X(1)) bb1(.d(d), .q(q3));
	bb #(.X(3)) bb2(.d(d), .q(q4));

	cc #(.X(1)) cc1(.d(d), .q(q5));
	cc #(.X(1)) cc2(.d(d), .q(q6));
endmodule
EOF

box_derive -naming_attr final_name top

select -assert-mod-count 1 =aa1
select -assert-mod-count 1 =aa2
select -assert-mod-count 0 =aa3

select -assert-mod-count 1 =bb1
select -assert-mod-count 0 =bb2
select -assert-mod-count 1 =bb3

select -assert-mod-count 1 =cc1
select -assert-mod-count 0 =cc2
select -assert-mod-count 0 =cc3

# we are expecting the original aa, bb, cc modules
# and 5 specializations generated by box_derive
select -assert-mod-count 8 =A:whitebox