Files
yosys/tests/opt/bug1793.ys
T
2026-09-14 10:21:17 +02:00

160 lines
3.1 KiB
Plaintext

# rmports: remove output ports which are driven internally but unused by all instances
# https://github.com/YosysHQ/yosys/issues/1793
read_verilog <<EOT
module sub(input a, input z, output x, output y);
assign x = a;
assign y = ~a;
endmodule
module top(input a, output o);
sub s(.a(a), .z(), .x(o), .y());
endmodule
EOT
hierarchy -top top
design -save simple
select -assert-count 2 sub/o:*
select -assert-count 2 sub/i:*
rmports
hierarchy -check
select -assert-count 0 sub/o:y
select -assert-count 1 sub/w:y
select -assert-count 1 sub/o:*
select -assert-count 1 sub/i:a
select -assert-count 1 sub/i:*
select -assert-count 1 top/o:*
select -assert-count 1 top/i:*
# a parent outside the selection is cleaned up as well
design -load simple
rmports sub
select -assert-count 1 sub/o:*
hierarchy -check
# an output is kept when any instance uses it
design -reset
read_verilog <<EOT
module sub(input a, output x, output y);
assign x = a;
assign y = ~a;
endmodule
module top(input a, output o, output p);
sub s1(.a(a), .x(o), .y());
sub s2(.a(a), .x(), .y(p));
endmodule
EOT
hierarchy -top top
rmports
hierarchy -check
select -assert-count 2 sub/o:*
# a cell which is not derived yet names its ports $1, $2, etc
design -reset
read_verilog <<EOT
module sub(input as, output xs, input bs, output ys, input cs);
assign xs = as & bs;
assign ys = as ^ cs;
endmodule
(* top *)
module top(input a, input b, output o);
wire t;
sub s(a, t, b);
assign o = t ^ a;
endmodule
EOT
rmports
hierarchy -check -top top
select -assert-count 2 sub/o:*
# a box parent is never selected, but should also be cleaned up
design -reset
read_verilog <<EOT
module sub(input a, output x, output y);
assign x = a;
assign y = ~a;
endmodule
module mid(input a, output x);
wire dead;
sub s(.a(a), .x(x), .y(dead));
endmodule
module top(input a, output o);
mid m(.a(a), .x(o));
endmodule
EOT
hierarchy -top top
# a public wire counts as a use
rename -hide mid/w:dead
setattr -mod -set whitebox 1 mid
select -clear
rmports
select -assert-count 1 sub/o:*
hierarchy -check
# no module has the top attribute, so driven outputs stay
design -reset
read_verilog <<EOT
module sub(input a, output x, output y);
assign x = a;
assign y = ~a;
endmodule
module use1(input a, output o);
sub s(.a(a), .x(o), .y());
endmodule
module use2(input a, output o);
sub s(.a(a), .x(o), .y());
endmodule
EOT
design -save roots
rmports
select -assert-count 2 sub/o:*
rmports -purge
hierarchy -check
select -assert-count 1 sub/o:x
design -load roots
delete use2
rmports
select -assert-count 2 sub/o:*
hierarchy -top use1
rmports
hierarchy -check
select -assert-count 1 sub/o:x
# repro
design -reset
read_verilog <<EOT
module TOP(a, b, y);
input [3:0] a, b;
output [2:0] y;
reg [2:0] tmp;
wire NC;
sub p(a, b, {NC, tmp});
assign y = tmp;
endmodule
module sub(as, bs, ys);
input [3:0] as, bs;
output [3:0] ys;
assign ys = as & bs;
endmodule
EOT
hierarchy -top TOP
delete w:NC
splitnets -ports
rmports
hierarchy -check
clean -purge
select -assert-count 3 sub/o:*
select -assert-count 8 sub/i:*
select -assert-count 3 TOP/o:*
select -assert-count 8 TOP/i:*