Rhodium has asked for the wisdom of the Perl Monks concerning the following question:

Hi all
Ok here is what I have..
My text file..
.SUBCKT testblock a b c vdd vcc vss vssa *.PININFO a:I b:I c:I vdd:I vcc:I + vss:G vssa:I RR0 a vss 9.99967K $[PO] XI48 a b c vdd vcc vss vssa / test2block .ENDS
Here is the variables
$runset{"POWER-NODE"}="vdd,vdda,vddb" $runset{"GROUND-NODE"}="vssa"
Now here is what I need for an output
.SUBCKT testblock a b c vdd vcc vss vssa *.PININFO a:I b:I c:I vdd:P vcc:I + vss:I vssa:G RR0 a vss 9.99967K $[PO] XI48 a b c vdd vcc vss vssa / cd_acore_porbuf .ENDS
Here is my code thus far..
while($line = shift @netlist){ chomp $line; if($line =~ ".SUBCKT $runset{SchCell}"{ #OK, where in the right area.. print NET_N "$line\n"; $line = shift @netlist; # Get the next line chomp $line; while($line !~ ".ENDS"){ # If we are at the END stop.. for ($line) { if (($line =~ "*.pininfo") { # Ok I'm here.. Now how do I get this line any other lines # denoted by the "+" into an array } # Now how do I do the search and replace.. for each of the pwrs # and grounds.. } } } }
Am I approaching this correctly.. Can someone help me out.. PLEASE:)

Replies are listed 'Best First'.
Re: Search and replace.. ..a bit different
by VSarkiss (Monsignor) on Apr 10, 2002 at 20:02 UTC

    Sorry, but it's entirely unclear to me how your input transforms to your output under those variables. It looks like you're trying to cook up a wiring control or some such from a netlist, but I'm not familiar with the format.

    Some general comments that may help:

    • You're doing a lot of regular expression matches "=~" when it looks like all you need is string equality "eq". The distinction is particularly important because you're trying to match characters like . and * which are meaningful in regular expressions.
    • You don't have to process the file one line at a time. If a block is delimited by .ENDS, for example, you can tell the diamond operator that it should stop at those rather than at newlines by setting $/. TheDamian once describe this variable as "it tells Perl when to stop reading"; that's the most useful characterization I've heard.
      In other words, you can do:
      { local $/ = '.ENDS'; @blocks = <INPUT>; #or whatever }
      and the @blocks array will contain the chunks of the file (with newlines embedded) that were separated by that symbol.
    • If you need to break up the parts of a block by where white space occurs, the split function is great for that. I say this because your for ($line) { statement makes me think you want to say "for each thing in the line"; the code you have will keep looping until $line is an empty string (or zero). Good way to hang up your program if you don't change it....
    All this stuff is by use of the PSI::ESP module. I hope I've guessed right. If not, please post a reply with clarifications.

Re: Search and replace.. ..a bit different
by tadman (Prior) on Apr 10, 2002 at 19:58 UTC
    First, instead of repeately using shift, you might just want to use a foreach or maybe even a for:
    foreach my $line (@netlist) { # ... }
    For those cases where you want to skip ahead a line, you can do something like this:
    for (my $i = 0; $i < @netlist; $i++) { my $line = $netlist[$i]; if ($yadda_yadda) { $line = $netlist[++$i]; # ... } }
    Keep in mind that =~, and !~ are string comparisons using regular expressions. This is different from the regular string comparators 'eq' and 'ne' in that they check for matches, not equivalence.

    As for what you mean by for ($line), you probably want to pass it an array or a list rather than a single element.

    IMHO, I don't think you're approaching this correctly. Think first, code second. You seem to be doing the reverse. You will probably have better results if you can think your problem through completely in terms of functionality and then translate these thoughts into Perl.
Re: Search and replace.. ..a bit different
by mrbbking (Hermit) on Apr 10, 2002 at 20:35 UTC
    I don't understand the logic behind the substitutions.
    This does what you said, though not in a very flexible way, I'm afraid...
    #!/usr/bin/perl -w use strict; while(<DATA>){ if( m!\+ vss:G vssa:I! ){ print "+ vss:I vssa:G\n"; } elsif( m!test2block! ){ print "XI48 a b c vdd vcc vss vssa / cd_acore_porbuf\n"; } else { print; } } __DATA__ .SUBCKT testblock a b c vdd vcc vss vssa *.PININFO a:I b:I c:I vdd:I vcc:I + vss:G vssa:I RR0 a vss 9.99967K $[PO] XI48 a b c vdd vcc vss vssa / test2block .ENDS
    Could you add a little more context to the question?
    s!!password!;y?sordid?binger?; y.paw.mrk.;;print chr 0x5b ;;; print;print chr(0x5b+0x2);;;;;
Re: Search and replace.. ..a bit different
by Rhodium (Scribe) on Apr 10, 2002 at 23:19 UTC
    Hi again
    Let me expand a bit further on this. Given any file that has a number of .SUBCKT calls I am looking to do a search and replace on the *.pininfo line. This line may extend multiple lines which are denoted by the presence of a + at the start of a line.
    .SUBCKT foo a b c *.pininfo vdd:I vss:I a:I b:I c:I vddw:I vddq:O + vddy:I
    Now, I want to first get the complete *.pininfo line and then do a replace on certain words. Those words are of two types:
  • Powers which is a comma separated list held by the $runset{"POWER-NODE"}. This comma separated list first needs to to be split up, and at the end of each word get :P concatonated to it
    $runset{"POWER-NODE"}="vdd,vddq,vcc" # translates to vdd:P vddq:P vcc:P
  • Ground which is also a comma separated list held by the $runset{"GROUND-NODE"}. This comma separated also need to be split and concatonated with :G
    $runset{"GROUND-NODE"}="vss,vsc" # translates to vss:G vsc:G
  • Now using the *.pininfo line look for the variables held by both $runset{"POWER-NODE"} and $runset{"GROUND-NODE"} and do a search and replace. The tricky part is dealing with the :P/G/I/O. Effectively, we are ingnoring it during the search but replacing it after the fact. So, given the above example you would end up with a new *.pininfo which looks like..
    .SUBCKT foo a b c *.pininfo vdd:P vss:G a:I b:I c:I vddw:I vddq:P + vddy:I
    Does this help?? Thanks so much
Re: Search and replace.. ..a bit different
by Rhodium (Scribe) on Apr 10, 2002 at 19:49 UTC
    Hi again
    I forgot to mention.. The POWER-NODE gets :P on the end of the power node, and a :G for ground nodes.. So
    $runset{"POWER-NODE"}="vdd,vdda,vddb" $runset{"GROUND-NODE"}="vssa"
    will look like
    vdd:P vdda:P vddb:P vssa:G
    if it exists in the *.pininfo section..
    Sorry for this..