Variable in Hierarchical access

Need some help passing a string to hierarchical access
I am trying to access RTL signals in design, all RTL signal names are similar except for one number changes, for example, dut.csr.oport_p1.valid, dut.csr.oport_p2.valid, dut.csr.oport_p3.valid … This design is highly configurable, ports can be enabled and disabled using parameters. so, some times these registers are present, sometimes these are disabled. How can I access these signals?

I tried doing something like this, but it didn’t work

`define IPORT(n) dut.csr.oport_pn.valid

parameter P_NUMBER_INPUTS = 32;
parameter [P_NUMBER_INPUTS-1:0] P_INPUT_PORT_EN = 32’h1f01; // can be programmed to a different value from top

genvar p;
generate
for(p=0; p < P_NUMBER_INPUTS; p++) begin
if(P_INPUT_PORT_EN[P])begin
valid = `IPORT(p); I want it to be like this dut.csr.oport_p1.valid, .*p2.valid, .*p3.valid, .*p4.valid, .*p5.valid …instead it is getting expanded like this dut.csr.oport_pp.valid
end
end

I also tried this works but code becomes very lengthy so trying to find a better approach

for(p=0; p < P_NUMBER_INPUTS; p++) begin
if(P_INPUT_PORT_EN[P])begin
if(p == 1) begin
valid = IPORT(1); end if(p == 2) begin valid = IPORT(2);
end
if(p == 3) begin
valid = `IPORT(3);
end
.
.// for ohter ports
.
end
end

Please recommend me a better way to access these signals.

In reply to saikishorereddy:

Having a number as part of a signal or scope name might as well be a random character. There’s no way to iterate over signal names unless you use an external tool to generate code for you.

One thing you could to that would shorten the code is putting as much reputable code into the macro:

`define IPORT(n) if (p == n) valid = dut.csr.oport_p``n``.valid

for(int P=0; P < P_NUMBER_INPUTS; p++) begin
  if(P_INPUT_PORT_EN[P])begin
     `IPORT(0); 
     `IPORT(1); 
     `IPORT(2);  
     ...
    end

Thanks Dave.