Project

General

Profile

[logo] 
 
Home
News
Activity
About/Contact
Major Tools
  Dinotrace
  Verilator
  Verilog-mode
  Verilog-Perl
Other Tools
  IPC::Locker
  Parallel::Forker
  Voneline
General Info
  Papers

Issue #1201

Can't get Verilog::Netlist::Net object from Pin for partial vector

Added by Leon Medpum over 2 years ago. Updated 8 months ago.

Status:
NoFixNeeded
Priority:
Normal
Assignee:
-
% Done:

0%


Description

using git version: 5f176d451876f859bce9ce294a67e3874aa2dfe6 I have the following Verilog:
module submod1 (
    output    net1,
    output    net2a,
    output [1:0] net3
);
endmodule

module submod2 (
    input [1:0]   net4a,
    input net5,
);
endmodule

module top ();
    wire       net1;
    wire       \net2[0] ;
    wire [1:0] net3;
    wire [3:0] net4;

    submod1 submod1
    (.net1,
     .net2a (net2[0]),
     .net3
    );
    submod2 submod2
     (.net4a (net4[2:1]),
      .net5 (net4[0])
    );
endmodule

If (after linking) I query the pins for submod2, I query the pins for cell submod2, I see net4a and net5. If I query the pinselects() for each pin, I see respectively 'net4[2:1]' and 'net40', but if i query the nets() for net4a or net5, I do not get any results. The PinSelection object does not provide any mechanism to locate the Verilog::Netlist::Net object. What is the recommended method to trace the connectivity? I thought this was the purpose of the msb/lsb attributes of the array returned by Verilog::Netlist::Pin->nets()

As a side note, the nets() fundtion works fine when tracing the connectivity through submod1

History

#1 Updated by Stefan Tauner over 2 years ago

Leon Medpum wrote:

using git version: 5f176d451876f859bce9ce294a67e3874aa2dfe6 I have the following Verilog:
> module top ();
> […]
>     wire       \net2[0] ;
> […]
>      .net2a (net2[0]),
> 

Hi Leon,

I don't think the declaration of the wire is correct thus there is no net2. I am not sure if Verilog-Perl should warn about that, but if this is fixed (wire [0:0] \net2 ;) the output of my test program (below) shows the correct nets with both methods.

#!/usr/bin/perl

use strict;
use warnings;

use Verilog::Netlist;
my $files = ['/tmp/issue1201.v'];
my $nl_opts = [link_read_nonfatal=>0, keep_comments => 1, use_pinselects => 1];
# Setup options so files can be found
use Verilog::Getopt;
my $opt = new Verilog::Getopt;
$opt->parameter( "+incdir+verilog",
         "-y","verilog",
         );
my $nl = new Verilog::Netlist (options => $opt,
                   link_read_nonfatal=>0,
                   keep_comments => 0,
                   @{$nl_opts});
foreach my $file (@{$files}) {
    $nl->read_file (filename=>$file);
}

$nl->link();

foreach my $mod ($nl->top_modules_sorted) {
    show_hier ($mod, "  ", "", "");
}

sub show_hier {
    my $mod = shift;
    my $indent = shift;
    my $hier = shift;
    my $cellname = shift;
    if (!$cellname) {$hier = $mod->name;} #top modules get the design name
    else {$hier .= ".$cellname";} #append the cellname
    printf ("%-45s %s\n", $indent."Module ".$mod->name,$hier);
    foreach my $sig ($mod->ports_sorted) {
    printf ($indent."     %sput %s\n", $sig->direction, $sig->name);
    }
    foreach my $cell ($mod->cells_sorted) {
    printf ($indent. "    Cell %s\n", $cell->name);
    foreach my $pin ($cell->pins_sorted) {
        printf ($indent."     .%s:\n", $pin->name);
        printf ($indent."     via nets:\n");
        foreach my $sel ($pin->nets) {
        printf ($indent.$indent."     .%s\n", $sel->{net}->name);
        }
        printf ($indent."     via pinselects:\n");
        foreach my $sel ($pin->pinselects) {
        printf ($indent.$indent."     .%s[%s:%s]\n", $sel->netname, defined($sel->msb) ? $sel->msb : "<undef>",  defined($sel->lsb) ? $sel->lsb : "<undef>");
        printf ($indent.$indent."     .%s\n", $sel->bracketed_msb_lsb);
        }
    }
    show_hier ($cell->submod, $indent."  ", $hier, $cell->name) if $cell->submod;
    }
}

@Wilson: However, the netnames function does not really make sense as is IMHO. I kinda lost track about who proposed which parts of the API but I guess the netnames function is a potpourri of both our ideas and the outcome is probably not what either of us wanted. :) As is the nets function is a bad copy of the pinselects function with the disadvantage of returning untyped hashes similar to Verilog::Netlist::PinSelection. I think the most useful change would be to simply store the Nets in there without the msb/lsb information. If that's needed the user could use the pinselects function anyway. What do you think?

KR, Stefan

#2 Updated by Leon Medpum over 2 years ago

The net2\[0] is legal verilog. I agree the net is not 'net2' it is actually 'net2\[0]' The '\' and space at the end make the special characters part of the net. Our verilog has a lot of crazy syntax, and I'm testing out different corner cases.

I don't think I communictaed my problem well. Here is the test program I used:
#!/usr/bin/env perl                                           

use strict;
use warnings;

use Verilog::Netlist;                                               
use Data::Dumper;                                                   

# prepare netlist
my $Opt = new Verilog::Getopt(filename_expansion=>1);
$Opt->libext(".sv");                                 

my $nl = new Verilog::Netlist(
                 options => $Opt,
                 synthesis => 0, 
                 # link_read_nonfatal => 1
                 );                       
$nl->read_file(filename => './top.sv');   

# read in any sub modules
$nl->link();             
$nl->lint();             
$nl->exit_if_error();    

print "Module names in netlist:\n";
for my $mod ( $nl->modules() ) {   
   print $mod->name(), "\n";       
}                                  
print "\n";                        

for my $mod ( $nl->top_modules_sorted() ) {
   show_hier($mod, '', '', '');            
}                                          

sub show_hier {
   # Recursively descend through module hierarchy,
   # printing each module name and full hierarchical
   # specifier, all module port names, and all
   # instance port connections.
   my $mod      = shift;
   my $indent   = shift;
   my $hier     = shift;
   my $cellname = shift;
   if ($cellname) {
       $hier .= ".$cellname";
   }
   else {
       $hier = $mod->name();
   }
   print "${indent}ModuleName=", $mod->name(), "  HierInstName=$hier\n";
   $indent .= '   ';

   for my $sig ($mod->ports_sorted()) {
       print $indent, 'PortDir=', sigdir($sig->direction()), ' PortName=', $sig->name(), "\n";
   }

   for my $cell ($mod->cells_sorted()) {
       for my $pin ($cell->pins_sorted()) {
          my @nets = map {netname($_)} $pin->nets();
          if (! @nets) {
              #@nets = $pin->pinselects();
              #print Dumper(@nets);
          }
          #my @nets = map {$_->name()} $pin->nets();
          print $indent, 'CellName=', $cell->name(), ' PinName=', $pin->name(), ' NetName=(', join(", ", @nets), ")", "\n";
       }

       show_hier($cell->submod(), $indent, $hier, $cell->name()) if $cell->submod();
   }
}

sub sigdir {
   # Change "in"  to "input" 
   # Change "out" to "output" 
   my $dir = shift;
   return ($dir eq 'inout') ? $dir : $dir . 'put';
}

sub netname {
    my($net) = @_;
    if (! $net->{msb}) {
        return $net->{net}->name();
    } else {
        #print Dumper($net);
        return $net->{net}->name() . "[$net->{msb}:$net->{lsb}]";
    }
}
The result looks like:
Module names in netlist:
submod2
top
submod1

ModuleName=top  HierInstName=top
   CellName=submod1 PinName=net1 NetName=(net1)
   CellName=submod1 PinName=net2a NetName=(\net2[0] )
   CellName=submod1 PinName=net3 NetName=(net3[1:0])
   ModuleName=submod1  HierInstName=top.submod1
      PortDir=output PortName=net1
      PortDir=output PortName=net2a
      PortDir=output PortName=net3
   CellName=submod2 PinName=net4a NetName=()
   CellName=submod2 PinName=net5 NetName=()
   ModuleName=submod2  HierInstName=top.submod2
      PortDir=input PortName=net4a
      PortDir=input PortName=net5
For CellName=submod1 this is exactly what i expect. For CellName=submod2, the 'NetName' is empty which is not what I expect.

#3 Updated by Leon Medpum over 2 years ago

After looking at it further, I don't understand why your code seems to misdetect the net\[0] and correctly handles the net4\[], whereas mine is the reverse...

#4 Updated by Leon Medpum over 2 years ago

On further follow up, this is due to the 'use_pinselects => 1' option. I do noty understand why the behavior changes when using this option.

#5 Updated by Stefan Tauner over 2 years ago

Leon Medpum wrote:

The net2\[0] is legal verilog. I agree the net is not 'net2' it is actually 'net2\[0]' The '\' and space at the end make the special characters part of the net. Our verilog has a lot of crazy syntax, and I'm testing out different corner cases.

No, net2\[0] is not valid (but that's not what you wrote initially anyway ;) The backslash has to be at the start of the identifier (cf. IEEE 1364-2005 Syntax Figure 12-6). If you really want to use an escaped identifier as in your wire specification then you need to use the complete identifier later on as well. The following works as expected:

module submod1 (
    output    net1,
    output    net2a,
    output [1:0] net3
);
endmodule

module submod2 (
    input [1:0]   net4a,
    input net5,
);
endmodule

module top ();
    wire       net1;
    wire       \net2[0] ;
    wire [1:0] net3;
    wire [3:0] net4;

    submod1 submod1
    (.net1,
     .net2a (\net2[0] ),
     .net3
    );
    submod2 submod2
     (.net4a (net4[2:1]),
      .net5 (net4[0])
    );
endmodule

#6 Updated by Stefan Tauner over 2 years ago

Leon Medpum wrote:

On further follow up, this is due to the 'use_pinselects => 1' option. I do noty understand why the behavior changes when using this option.

Because this option was added to parse the LSB/MSB syntax. Previously this was not covered at all in Verilog-Perl and the identifiers were not really distinguished from the indices at all.

#7 Updated by Leon Medpum over 2 years ago

Sorry, I don't know how to display the bus notation in this form without the pre tags. The backslash was just so it wouldn't superscript. Thank you for identifying the typo in my verilog, agreed that is not supposed to work.

Since the pinselect objects are created with and without the use_pinselect option, I hadn't realized it changed the behavior in this way. Thank you for your help. Feel free to close this issue.

#8 Updated by Wilson Snyder over 2 years ago

  • Status changed from New to NoFixNeeded

#9 Updated by Utkarsh Khanna 8 months ago

hello all ,

can u please tell me what is this Opt->libext(".sv") doing here? and also how can we use standard verilog libraries for perl scripts? Please help!

#10 Updated by Wilson Snyder 8 months ago

Your libext post seems unrelated to this issue, in the future please make a new issue or forum post. But anyways the libext setting is the same as libext.sv passed to your simulator, used to resolve module names to filenames. Or, just pass every filename needed through the command line (e.g. to read_file).

Also available in: Atom