1

I have a very big verilog file(~350 MiB). In that, I want to comment particular module names.So i took a sample file and tried my regular expression on it.

Sample file(abc) :-

module util_minor_rev_id(minor_rev);
 output [3:0] minor_rev;
 wire [3:0] minor_rev;
 wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
 HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
      (minor_rev[0]));
 HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
      (minor_rev[1]));
xyz
HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
      (minor_rev[2]));
HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
      (minor_rev[3]));
endmodule

I want to comment the lines containing HS55_LH_OPTALL_GND_Z till ; so the output should be like

module util_minor_rev_id(minor_rev);
 output [3:0] minor_rev;
 wire [3:0] minor_rev;
 wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
     (minor_rev[0]));*/
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
     (minor_rev[1]));*/
xyz
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
      (minor_rev[2]));*/
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
      (minor_rev[3]));*/
endmodule

I am first trying to verify my pattern using regular expression and grep. I had problem using multi line pattern search. So i googled and found that pcregrep is my buddy.

pcregrep -Mno '^\s\*HS55_LH_OPTALL_GND_Z.*(\n|.)+;$' abc

But the output is:-

5:  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
       (minor_rev[0]));
  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
       (minor_rev[1]));
xyz
HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
       (minor_rev[2]));
  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
       (minor_rev[3]));
7:  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
       (minor_rev[1]));
xyz
HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
       (minor_rev[2]));
  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
       (minor_rev[3]));
10:HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
       (minor_rev[2]));
  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
       (minor_rev[3]));
12:  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
       (minor_rev[3]));

I think its first matching from 5th line to last ;. Then, 7th line to last ;(semicolon). Then, 10th line to last ;. And then 12th line to last ;

How do I make it work as I want?

Rahul
  • 13,309
  • 3
  • 43
  • 54

2 Answers2

1

Use non-greedy matching:

pcregrep -Mno '^\s*HS55_LH_OPTALL_GND_Z.*(\n|.)*?;$' file

Output:

5:      HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
           (minor_rev[0]));
7:      HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
           (minor_rev[1]));
10:HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
           (minor_rev[2]));
12:      HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
           (minor_rev[3]));

You can also comment the lines with Vim:

:%s!^\s*\zsHS55_LH_OPTALL_GND_Z\_.\{-};$!/* & */!

Result:

module util_minor_rev_id(minor_rev);
    output [3:0] minor_rev;
    wire [3:0] minor_rev;
    wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
    /* HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
        (minor_rev[0])); */
    /* HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
        (minor_rev[1])); */
xyz
/* HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
        (minor_rev[2])); */
    /* HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
        (minor_rev[3])); */
    endmodule
Satō Katsura
  • 13,138
  • 2
  • 31
  • 48
0

Using GNU sed

This seems to comment out the lines that you want:

sed -z 's|HS55_LH_OPTALL_GND_Z[^;]*;|/*&*/|g' abc

For example:

$ sed -z 's|HS55_LH_OPTALL_GND_Z[^;]*;|/*&*/|g' abc
module util_minor_rev_id(minor_rev);
      output [3:0] minor_rev;
      wire [3:0] minor_rev;
      wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
           (minor_rev[0]));*/
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
           (minor_rev[1]));*/
xyz
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
           (minor_rev[2]));*/
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
           (minor_rev[3]));*/
    endmodule

The -z option (GNU only) tells sed to read the file in not a line at a time but until it finds a NUL character. Since sensible text files never have a NUL character, this has the effect of reading in the whole file at once.

The above uses a single substitute command to put /* and */ around the lines of interest.

To change the file in-place:

sed -i.bak -z 's|HS55_LH_OPTALL_GND_Z[^;]*;|/*&*/|g' abc

Using other sed

For BSD/OSX or other sed:

sed '/HS55_LH_OPTALL_GND_Z/{:a; /;/{bb}; N; ba; :b; s|H|/*H|; s|;|;*/|;}' abc

For example:

$ sed '/HS55_LH_OPTALL_GND_Z/{:a; /;/{bb}; N; ba; :b; s|H|/*H|; s|;|;*/|;}' abc
module util_minor_rev_id(minor_rev);
      output [3:0] minor_rev;
      wire [3:0] minor_rev;
      wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
           (minor_rev[0]));*/
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
           (minor_rev[1]));*/
xyz
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
           (minor_rev[2]));*/
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
           (minor_rev[3]));*/
    endmodule

To change a file in-place:

sed -i.bak '/HS55_LH_OPTALL_GND_Z/{:a; /;/{bb}; N; ba; :b; s|H|/*H|; s|;|;*/|;}' abc

Limitation: Since none of these sed commands parse your file, there may be situations where they do the wrong thing.

How it works

  • /HS55_LH_OPTALL_GND_Z/{...}

    This selects lines that contain HS55_LH_OPTALL_GND_Z and, for those lines, the commands inside the curly braces are performed. These commands are described below.

  • :a

    This defines a label a.

  • /;/{bb}

    If the pattern space currently contains ;, then branch to label b.

  • N

    Read in the next line from the file and store it in the pattern space.

  • ba

    Branch to label a.

  • :b

    This defines label b.

  • s|H|/*H|; s|;|;*/|;

    If we get to here, that means that the pattern space starts with a line that contains HS55_LH_OPTALL_GND_Z and ends with a line that contains ;. For this pattern space, we put a /* in front of the first H and a */ after the first ;.

John1024
  • 73,527
  • 11
  • 167
  • 163